In vielen modernen WordPress-Projekten gibt es Anwendungsfälle, in denen ein Beitrag nicht als klassischer, langer Blogartikel fungiert, sondern als kompakter Verweis auf eine externe Primärquelle (Link-Post-Format), als News-Aggregator oder als kuratierte Linksammlung. In solchen Layouts soll der Beitragstitel im Archiv direkt zur referenzierten Zieladresse führen oder ein Button “Zur Originalquelle” automatisiert die erste im Text vorkommende URL ansteuern.
Um diese Funktionalität stabil umzusetzen, muss das Theme in der Lage sein, den Beitragsinhalt (the_content) programmatisch zu scannen und das href-Attribut des ersten Hyperlinks (<a>) zuverlässig auszulesen.
Viele Entwickler greifen hierbei reflexartig zu regulären Ausdrücken (Regex). Warum dieser Ansatz in der Praxis gefährlich ist und wie Sie mit der WordPress-Klasse WP_HTML_Tag_Processor, der Kernfunktion get_url_in_content(), dem WP_HTML_Processor, der klassischen PHP-Klasse DOMDocument oder dem neuen Dom\HTMLDocument aus PHP 8.4 robusten, fehlertoleranten Code schreiben, erfahren Sie in diesem Entwickler-Guide.
Warum Regex für HTML-Parsing in WordPress scheitert
Ein weit verbreitetes Code-Snippet, das man in vielen Foren findet, verwendet preg_match:
// Problematischer Ansatz mit Regex:
function unzuverlaessiger_link_regex( $content ) {
preg_match('/<a\s+(?:[^>]*?\s+)?href=(["\'])(.*?)\1/', $content, $treffer);
return $treffer[2] ?? false;
}Auf den ersten Blick scheint dies zu funktionieren. In der Praxis scheitert dieser Ansatz jedoch regelmäßig an realen redaktionellen Inhalten:
- HTML-Kommentare: Befindet sich im Text ein HTML-Kommentar wie
<!-- <a href="beispiel.de"> -->, matched der Regex fälschlicherweise diesen inaktiven Link. Gutenberg umschließt zudem jeden Block mit Kommentaren wie<!-- wp:paragraph -->. - Inhalte von
<script>und<style>: Ein Custom-HTML-Block, dessen JavaScript einen String wie"<a href=...>"zusammensetzt, enthält für den Regex einen gültigen Link. Ein HTML-Parser weiß, dass der Inhalt von<script>Text ist und kein Markup. - Whitespace und Zeilenumbrüche: Wenn Attribute über mehrere Zeilen formatiert sind oder einfache statt doppelte Anführungszeichen verwendet werden, bricht das Pattern schnell ab.
- Backtracking-Limit: Die PCRE-Engine von PHP bricht ab, sobald ein Muster
pcre.backtrack_limitüberschreitet, laut PHP-Handbuch standardmäßig 1000000.preg_match()gibt dannfalsestatt 0 oder 1 zurück, und nurpreg_last_error()meldetPREG_BACKTRACK_LIMIT_ERROR. Bei langen Beiträgen verschwindet der Link einfach, ohne Eintrag im Log.
HTML ist keine reguläre Sprache und sollte daher stets mit einem echten HTML-Parser verarbeitet werden. Der WordPress-Kern selbst hat diesen Weg genommen: get_url_in_content() lief über ein Jahrzehnt mit einem regulären Ausdruck, bevor die Funktion auf die HTML API umgestellt wurde, wie weiter unten gezeigt.
Wie WP_HTML_Tag_Processor den ersten Link extrahiert
Seit WordPress 6.2 steht Entwicklern die Klasse WP_HTML_Tag_Processor zur Verfügung. Die Dokumentation der Klasse beschreibt sie so: Sie parst HTML nicht vollständig und steigt nicht rekursiv in die Struktur ab, sondern liest das Dokument linear und analysiert nur die öffnenden Tags. Genau das braucht man, um ein href zu lesen, ohne den gesamten DOM-Baum im Arbeitsspeicher aufzubauen.
Wir haben das Verhalten mit dem Quellcode von WordPress 7.1.3 getestet: next_tag( 'a' ) überspringt HTML-Kommentare und den Inhalt von <script>, und get_attribute( 'href' ) liefert den bereits dekodierten Wert, sodass & in einem Query-String als & ankommt. Fehlt das Attribut, kommt null zurück; ein boolesches Attribut ohne Wert liefert true. Die Prüfung mit is_string() ist deshalb Pflicht.
Helper-Funktion für den ersten Link mit WP_HTML_Tag_Processor
Fügen Sie diesen Code in Ihre functions.php oder in ein Must-Use-Plugin ein. Die Funktion überspringt mailto:, Anker und relative Pfade und hält beim ersten http- oder https-Link an:
<?php
/**
* Extrahiert die Ziel-URL des ersten http(s)-Links aus einem Textabschnitt.
*
* @param string $content Der HTML-Inhalt des Beitrags.
* @return string|false Die bereinigte URL oder false, wenn kein Link existiert.
*/
function wppoland_get_first_link_tag_processor( string $content ): string|false {
if ( '' === trim( $content ) ) {
return false;
}
// Instanziierung des nativen WordPress HTML Processors
$processor = new WP_HTML_Tag_Processor( $content );
// Wir gehen die 'a'-Tags in Dokumentreihenfolge durch
while ( $processor->next_tag( 'a' ) ) {
$href = $processor->get_attribute( 'href' );
// Leere oder fehlende Attribute überspringen
if ( ! is_string( $href ) || '' === trim( $href ) ) {
continue;
}
$href = trim( $href );
$schema = strtolower( (string) wp_parse_url( $href, PHP_URL_SCHEME ) );
if ( in_array( $schema, array( 'http', 'https' ), true ) ) {
return esc_url_raw( $href );
}
}
return false;
}Ersten Link im WordPress-Loop ausgeben
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
// Rohen oder gefilterten Beitragsinhalt laden
$content = get_the_content();
$externe_url = wppoland_get_first_link_tag_processor( $content );
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h2>
<?php if ( $externe_url ) : ?>
<a href="<?php echo esc_url( $externe_url ); ?>" rel="external noopener" target="_blank">
<?php the_title(); ?>
</a>
<?php else : ?>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
<?php endif; ?>
</h2>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div>
</article>
<?php
endwhile;
endif;
?>Dieser Ansatz benötigt kaum zusätzlichen Speicher und funktioniert ab WordPress 6.2. In Archiven mit vielen Beiträgen lesen Sie den Wert trotzdem besser aus dem Post-Meta, wie im Abschnitt zu save_post gezeigt.
Wie get_url_in_content in WordPress funktioniert
Bevor Sie eine eigene Funktion schreiben: Der Kern hat bereits eine. get_url_in_content( $content ) “extrahiert die erste URL aus dem übergebenen Inhalt und gibt sie zurück”, so die offizielle Referenz (eigene Übersetzung). Die Funktion gibt es seit WordPress 3.6.0, und sie wird mit dem Beitragsformat “Link” verwendet: Das Theme Twenty Thirteen ruft sie in twentythirteen_get_link_url() auf und fällt ohne Treffer auf den Permalink zurück.
Die Implementierung hat sich deutlich geändert. Wir haben den Code der Branches 6.8 und 6.9 im offiziellen Repository verglichen:
- Bis WordPress 6.8 nutzte die Funktion
preg_match( '/<a\s[^>]*?href=([\'"])(.+?)\1/is', ... ). Mit demselben Test-HTML wie im Rest dieses Artikels lieferte das Muster den Link aus einem HTML-Kommentar, also einen Link, den kein Leser je gesehen hat. - Ab WordPress 6.9 erzeugt die Funktion einen
WP_HTML_Tag_Processor, geht dieA-Tags durch und gibt das erste nicht leerehrefnachsanitize_url()zurück. Der auskommentierte Link wird nicht mehr gefunden.
$url = get_url_in_content( get_the_content() );
if ( $url ) {
printf(
'<a href="%s" rel="noopener">Zur Quelle</a>',
esc_url( $url )
);
}Ohne Treffer kommt false zurück. Zwei Grenzen gelten. Die Funktion akzeptiert jedes Schema, ein mailto:-Link oder ein #kommentare-Anker am Textanfang wird also vor dem redaktionellen Link zurückgegeben. Und auf einer Website mit WordPress 6.8 oder älter bekommen Sie das Verhalten des regulären Ausdrucks. Ab 6.9 nehmen Sie die Kernfunktion, wenn das erste href genügt; brauchen Sie Schema-Filter oder Unterstützung älterer Versionen, passt die Funktion aus dem vorigen Abschnitt besser.
Wie Sie mit WP_HTML_Processor den ersten Link in einem Absatz finden
Der Tag Processor weiß nicht, wo er sich befindet. Der Link um ein Bild in einem core/image-Block und der Link mitten in einem Absatz sind für ihn einfach zwei a-Tags. Lautet die Regel “der erste im Text geschriebene Link, nicht der Bildlink”, brauchen Sie den WP_HTML_Processor, verfügbar seit WordPress 6.4. Er verfolgt den Stapel offener Elemente und stellt ihn über get_breadcrumbs() bereit.
<?php
function wppoland_erster_link_im_absatz( string $content ): ?string {
$processor = WP_HTML_Processor::create_fragment( $content );
if ( null === $processor ) {
return null;
}
while ( $processor->next_tag( 'A' ) ) {
$pfad = $processor->get_breadcrumbs();
// Nur Links innerhalb von <p> und außerhalb von <figure>
if ( ! in_array( 'P', $pfad, true ) || in_array( 'FIGURE', $pfad, true ) ) {
continue;
}
$href = $processor->get_attribute( 'href' );
if ( is_string( $href ) && '' !== trim( $href ) ) {
return esc_url_raw( trim( $href ) );
}
}
return null;
}Wir prüfen den Pfad selbst, statt die Abfrage next_tag( array( 'breadcrumbs' => array( 'P', 'A' ) ) ) zu verwenden. Diese Abfrage verlangt, dass A ein direktes Kind von P ist; in unserem Test übersprang sie einen Link in <p><strong><a>, während die Prüfung mit in_array() ihn fand.
Die Dokumentation der Klasse nennt eine klare Regel: Trifft der Prozessor auf Markup, das er noch nicht unterstützt, bricht er ab, statt zu raten. Dann gibt next_tag() false zurück und get_last_error() ist nicht mehr null. Erhalten Sie null für einen Beitrag mit sichtbaren Links, prüfen Sie get_last_error() und greifen Sie auf den Tag Processor zurück.
Wie Sie den ersten Link mit PHP DOMDocument extrahieren
Müssen Sie Code außerhalb von WordPress ausführen oder möchten Sie tiefergehende DOM-Manipulationen durchführen (z.B. den Linktext ebenfalls extrahieren oder den ersten Link aus dem Content entfernen), ist die in PHP integrierte Klasse DOMDocument das Mittel der Wahl.
Da DOMDocument intern auf dem HTML-Parser von libxml2 basiert, der Regeln aus der Zeit vor HTML5 folgt, gibt es zwei bekannte Fallstricke, die sauber abgefangen werden müssen:
- HTML5-Elemente: Der libxml-HTML-Parser kennt moderne Tags wie
<nav>,<section>oder<article>nicht und wirft Warnungen. - UTF-8-Zeichensatz: Umlaute und Sonderzeichen werden ohne explizite Codierung oft verstümmelt.
DOMDocument-Funktion mit Fehlerbehandlung
function wppoland_get_first_link_domdocument( string $content ): string|false {
if ( '' === trim( $content ) ) {
return false;
}
$dom = new DOMDocument();
// Warnungen über HTML5-Tags und unvollständige Fragmente unterdrücken
$previous_errors = libxml_use_internal_errors( true );
// UTF-8: Sicherstellen, dass deutsche Umlaute korrekt interpretiert werden
$html_encoded = mb_encode_numericentity(
$content,
[ 0x80, 0x10ffff, 0, 0x1fffff ],
'UTF-8'
);
// Laden des HTML-Fragments (ohne HTML/BODY-Wrapper)
$loaded = $dom->loadHTML(
'<?xml encoding="UTF-8">' . $html_encoded,
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
);
// libxml-Fehler leeren und vorherigen Zustand wiederherstellen
libxml_clear_errors();
libxml_use_internal_errors( $previous_errors );
if ( ! $loaded ) {
return false;
}
$links = $dom->getElementsByTagName( 'a' );
if ( $links->length > 0 ) {
/** @var DOMElement $first_link */
$first_link = $links->item( 0 );
$href = $first_link->getAttribute( 'href' );
if ( ! empty( $href ) ) {
return esc_url_raw( trim( $href ) );
}
}
return false;
}Fehlerhaft verschachteltes Redaktions-HTML erzeugt so nur interne libxml-Meldungen statt Warnungen im Log. mb_encode_numericentity() ist hier die richtige Wahl: Ältere Snippets verwenden mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ), doch PHP 8.2 hat die Kodierung HTML-ENTITIES für alle mbstring-Funktionen als veraltet markiert (Liste der Deprecations in PHP 8.2), und PHP 8.4 gibt bei jedem solchen Aufruf einen Deprecated-Hinweis aus.
Wie Sie Dom\HTMLDocument in PHP 8.4 nutzen
PHP 8.4 hat eine neue DOM-API im Namespace Dom eingeführt, mit “standardkonformer Unterstützung für das Parsen von HTML5-Dokumenten”, so die Release-Ankündigung (eigene Übersetzung). Dom\HTMLDocument parst HTML nach dem Living Standard. Damit entfallen die Warnungen zu HTML5-Tags und der Trick mit dem XML-Header. DOMDocument bleibt aus Kompatibilitätsgründen erhalten.
<?php
function wppoland_erster_link_dom84( string $html ): ?string {
if ( '' === trim( $html ) ) {
return null;
}
$doc = Dom\HTMLDocument::createFromString( $html, LIBXML_NOERROR, 'UTF-8' );
foreach ( $doc->querySelectorAll( 'a[href]' ) as $link ) {
$href = trim( $link->getAttribute( 'href' ) );
$schema = strtolower( (string) parse_url( $href, PHP_URL_SCHEME ) );
if ( in_array( $schema, array( 'http', 'https' ), true ) ) {
return $href;
}
}
return null;
}Drei Details aus der Handbuchseite zu createFromString(): Das zweite Argument nimmt LIBXML_*-Konstanten, per OR kombiniert; das dritte, overrideEncoding, legt die Kodierung fest, statt PHP raten zu lassen; eine unbekannte Kodierung wirft einen ValueError. Unter PHP 8.4.24 lieferte die Funktion https://exemplo.pt/ação?x=1&y=2 unverändert, mit dekodiertem &. CSS-Selektoren erlauben zudem Abfragen wie p > a[href^="https://"], für die DOMDocument XPath braucht.
Welche Methode für den ersten Link passt
Wir veröffentlichen keine Laufzeiten: Sie hängen von Server, PHP-Version und Beitragslänge ab, und aussagekräftig sind nur Messungen im eigenen Projekt. Die strukturellen Unterschiede sind dagegen stabil:
| Kriterium | Regex (preg_match) | DOMDocument (libxml2) | Dom\HTMLDocument | WP_HTML_Tag_Processor |
|---|---|---|---|---|
| Parsing-Modell | Textmuster | DOM-Baum, Regeln vor HTML5 | DOM-Baum, HTML5 | Lineares Lesen öffnender Tags |
| Speicher | Gering | Ganzer Baum | Ganzer Baum | Kein Baum |
Kommentare und <script> | Unzuverlässig | Korrekt | Korrekt | Korrekt |
| Kontext (Elternelement) | Nein | Ja | Ja, mit CSS-Selektoren | Nein (WP_HTML_Processor nutzen) |
| Typischer Fehler | false beim Backtracking-Limit | Warnungen und UTF-8 | ValueError bei falscher Kodierung | Kennt den Kontext des Links nicht |
| Mindestanforderung | Beliebiges PHP | DOM-Erweiterung | PHP 8.4 | WordPress 6.2+ |
Auf einer aktuellen WordPress-Website ist der Tag Processor die einfachste zuverlässige Wahl. Dom\HTMLDocument gewinnt, wenn der Code außerhalb von WordPress läuft oder Selektoren braucht.
Wann wp_extract_urls() für den ersten Link reicht
WordPress liefert eine native Hilfsfunktion mit, die häufig übersehen wird: wp_extract_urls().
$urls = wp_extract_urls( get_the_content() );
if ( ! empty( $urls ) ) {
$erste_url = $urls[0];
}Warum wp_extract_urls() auch Bild- und Text-URLs findet
wp_extract_urls() extrahiert alle Zeichenketten, die wie URLs aussehen. Das bedeutet:
- Es findet auch reine Text-URLs, die nicht in einem
<a>-Tag verlinkt sind. - Es findet URLs von eingebetteten Bildern (
<img src="...">), Videos oder iframes.
Wenn Ihr Ziel darin besteht, ausschließlich klickbare Hyperlinks zu erfassen, sollten Sie diese Funktion meiden und stattdessen auf den WP_HTML_Tag_Processor setzen.
Welche URLs wp_http_validate_url und FILTER_VALIDATE_URL ablehnen
Beide Namen klingen nach “ist das eine gültige URL”. Für redaktionelle Links beantwortet keine der beiden diese Frage.
wp_http_validate_url() schützt HTTP-Anfragen, die der Server selbst sendet. Laut Referenzseite und Quellcode gilt:
- Sie akzeptiert nur
httpundhttpsund lehnt URLs mit Benutzername und Passwort ab. - Sie lehnt relative URLs ab, weil sie einen Host verlangt.
- Für jeden Host außer der eigenen Website ruft sie
gethostbyname()auf, also eine DNS-Abfrage; ein Name, der in diesem Moment nicht auflöst, wird abgelehnt. - Sie lehnt Adressen aus privaten Netzen ab, sofern der Filter
http_request_host_is_externalsie nicht erlaubt. - Standardmäßig erlaubt sie nur die Ports 80, 443 und 8080 (Filter
http_allowed_safe_ports).
In einem save_post-Hook bedeutet das eine DNS-Abfrage pro Speichern und den stillen Verlust gültiger Links zu kurz nicht erreichbaren Domains oder zu Demo-Servern auf einem anderen Port. Die frühere Fassung dieses Artikels empfahl sie zur Prüfung im Template; nutzen Sie sie nur, wenn Ihr Code die URL tatsächlich abruft.
Der PHP-Filter FILTER_VALIDATE_URL hat ein anderes Problem, das im Handbuch steht: Der Filter “funktioniert nur mit ASCII-URLs”, internationalisierte Domainnamen werden immer abgelehnt (eigene Übersetzung). In unserem Test mit PHP 8.4 wurde https://exemplo.pt/ação abgelehnt, und FILTER_SANITIZE_URL machte aus derselben Adresse https://exemplo.pt/ao, ohne Warnung. Bei Adressen mit Umlauten wie /über-uns/ ist das ein echtes Problem. Prüfen Sie das Schema mit wp_parse_url(), bereinigen Sie den Wert vor dem Speichern mit esc_url_raw() und vor der Ausgabe mit esc_url().
Wie Post-Meta-Caching die Link-Extraktion beschleunigt
Wenn Sie in einer Archivübersicht viele Beiträge darstellen und bei jedem Beitrag den vollständigen Inhalt parsen müssen, summiert sich die Verarbeitungszeit. Besser ist es, den ersten Link bereits beim Speichern des Beitrags zu ermitteln und als Beitrags-Metadatum (postmeta) abzuspeichern.
Ersten Link beim Speichern per save_post cachen
/**
* Extrahiert beim Speichern des Beitrags die erste URL und legt sie als Metafeld ab.
*/
add_action( 'save_post', function ( int $post_id, WP_Post $post ): void {
// Autosaves, Revisionen und Fremd-Post-Types ignorieren
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( wp_is_post_revision( $post_id ) || 'post' !== $post->post_type ) {
return;
}
$erste_url = wppoland_get_first_link_tag_processor( $post->post_content );
if ( $erste_url ) {
update_post_meta( $post_id, '_wppoland_first_link', $erste_url );
} else {
delete_post_meta( $post_id, '_wppoland_first_link' );
}
}, 10, 2 );
/**
* Schneller Abruf im Theme: Liest das vorberechnete Metafeld aus.
*/
function wppoland_get_cached_first_link( int $post_id ): string|false {
$url = get_post_meta( $post_id, '_wppoland_first_link', true );
return ! empty( $url ) ? (string) $url : false;
}Mit dieser Architektur entfällt jegliches HTML-Parsing beim Aufruf von Archivseiten. WP_Query lädt die Metadaten der Beiträge im Loop standardmäßig in den WordPress Object Cache, sodass kein zusätzlicher Query pro Beitrag entsteht.
Ergänzen Sie den Hook um eine current_user_can()-Prüfung, bedenken Sie: Speichervorgänge ohne angemeldeten Benutzer, etwa wp post update per WP-CLI ohne --user oder ein Import per Cron, aktualisieren das Metafeld dann nicht mehr.
Wie Sie das Post-Meta älterer Beiträge mit WP-CLI befüllen
Der save_post-Hook erfasst nur Beiträge, die nach dem Deployment gespeichert werden. Für das bestehende Archiv genügen zwei dokumentierte WP-CLI-Befehle. wp post list --field=ID gibt eine ID pro Zeile aus und liefert laut Befehlsdokumentation standardmäßig alle passenden Beiträge (--posts_per_page steht auf -1). wp eval-file führt eine PHP-Datei mit geladenem WordPress aus und legt Positionsargumente in der Variable $args ab (Dokumentation).
<?php
// ersten-link-befuellen.php
foreach ( $args as $post_id ) {
$post = get_post( (int) $post_id );
if ( ! $post ) {
continue;
}
$url = wppoland_get_first_link_tag_processor( $post->post_content );
if ( $url ) {
update_post_meta( $post->ID, '_wppoland_first_link', $url );
} else {
delete_post_meta( $post->ID, '_wppoland_first_link' );
}
}wp post list --post_type=post --post_status=publish --field=ID \
| xargs -n 100 wp eval-file ersten-link-befuellen.phpxargs -n 100 übergibt die IDs in Paketen zu 100, und jedes Paket startet einen neuen PHP-Prozess, sodass der Speicherbedarf nicht mit dem Archiv wächst. Führen Sie das zuerst auf Staging aus und prüfen Sie einige Beiträge von Hand.
Warum Links aus dynamischen Blöcken und Shortcodes fehlen
Der in der Datenbank gespeicherte post_content ist nicht das HTML, das Besucher erhalten. get_the_content() liefert den gespeicherten Inhalt ohne die the_content-Filter. Es gibt zwei Fälle, in denen ein Link auf der Seite existiert, aber nicht im Rohinhalt:
- Dynamische Blöcke. Der Block
core/navigation-linkspeichert seineurlals Attribut im Blockkommentar (JSON), das HTML entsteht serverseitig.core/buttonspeichert den Link dagegen im eigenen HTML: In derblock.jsonwird das Attributurlaus demhrefdesa-Tags gelesen (Quelleattribute, Selektora). Die Referenz der Core-Blöcke listet die Attribute jedes Blocks. - Shortcodes und Embeds. Sie werden erst expandiert, wenn der Inhalt den Filter
the_contentdurchläuft.
Lautet die Regel “der erste Link, den die Redaktion geschrieben hat”, parsen Sie $post->post_content. Lautet sie “der erste Link, den Besucher sehen”, schicken Sie den Inhalt vorher durch do_blocks() und do_shortcode() oder durch apply_filters( 'the_content', $content ). Achtung: Der vollständige Filter führt auch aus, was Plugins anhängen (Teilen-Buttons, ähnliche Beiträge), und kann so Links vor Ihrem einfügen.
Wie Sie Anker, mailto und relative Links behandeln
Nicht jedes href-Attribut enthält eine externe Webadresse. Im Editor-Inhalt finden sich häufig:
- Lokale Anker:
#kommentare,#einleitung. - Kontaktlinks:
mailto:[email protected],tel:+4930000000. - Relative Pfade:
/ueber-uns/,./downloads/leitfaden.pdf.
Die Funktionen dieses Artikels auf Basis von WP_HTML_Tag_Processor und Dom\HTMLDocument verwerfen bereits alle Schemata außer http und https. Wollen Sie relative Pfade zulassen, wandeln Sie sie zuerst in absolute Adressen um. Der Kern bietet dafür WP_Http::make_absolute_url( $href, home_url( '/' ) ), verfügbar seit WordPress 3.4.0. Verwechseln Sie das nicht mit wp_make_link_relative(), das genau das Gegenteil tut.
Zusammenfassung zur Extraktion des ersten Links
Das Extrahieren von URLs aus WordPress-Inhalten ist eine Standardaufgabe, die jedoch eine saubere technische Grundlage verlangt. Durch den Wechsel von fehleranfälligen Regex-Mustern zum WP_HTML_Tag_Processor, zu get_url_in_content() ab WordPress 6.9 oder zu DOMDocument und Dom\HTMLDocument außerhalb von WordPress schaffen Sie wartungsfreundliche und fehlertolerante Themes.
Kombiniert mit save_post-Caching und einer einmaligen Befüllung per WP-CLI parsen Archivseiten kein HTML mehr bei jedem Aufruf.
Suchen Sie professionelle Unterstützung bei der Theme-Entwicklung oder der architektonischen Optimierung Ihrer WordPress-Plattform? Informieren Sie sich über unsere Leistungen im Bereich der WordPress-Entwicklung oder lassen Sie Ihre Codebasis im Rahmen einer technischen Wartung überprüfen.







