Du hast deinen AdBlocker an?

Es wäre ein Traum, wenn du ihn für t3n.de deaktivierst. Wir zeigen dir gerne, wie das geht. Und natürlich erklären wir dir auch, warum uns das so wichtig ist. Digitales High-five, deine t3n-Redaktion

Entwicklung & Design

Das eigene WordPress-Theme erstellen – #3: Die header.php und der Kopf eures Themes

Der große t3n-Guide zum eigenen WordPress-Theme. (Grafik: t3n)

In dieser Serie geht es darum, ein WordPress-Theme zu erstellen – von Grund auf. Im dritten Teil geht es um die header.php, die das head-Element sowie den Header des Themes ausliefert.

In der header.php sind die Angaben zu finden, die auf jeder Seite der Website benötigt werden. Das ist natürlich zuallererst der Doctype, gefolgt vom öffnenden html-Tag sowie dem head-Element mit Meta-Tags, Skripten und Stylesheets. Auch der sichtbare Header findet hier seinen Platz.

Wir legen also erst mal in unserem Theme-Ordner auf oberster Ebene die Datei header.php an. Ich zeige euch gleich einmal die komplette header.php. Anschließend werde ich sie in kleinere Teile zerlegen und erklären.

<!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js">
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<?php if ( is_singular() && pings_open() ) { ?>
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<?php }
wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<header id="header" class="clearfix" role="banner">
<div>
<h1 class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php if ( get_header_image() ) { ?>
<img src="<?php echo esc_url( get_header_image() ); ?>" alt="<?php echo esc_html( get_bloginfo( 'title' ) ); ?>" />
<?php } else {
bloginfo( 'title' );
} ?>
</a>
</h1>
<?php if ( get_bloginfo( 'description' ) != '' ) { ?>
<h2 class="blog-description">
<?php bloginfo( 'description' ); ?>
</h2>
<?php } ?>
</div>
<button class="menu-button show-menu">≡</button>
<nav role="navigation">
<button class="hide-menu menu-button">×</button>
<?php wp_nav_menu( array(
'theme_location' => 'header-menu',
'container' => '',
'fallback_cb' => false
) ); ?>
<button class="hide-menu menu-button">×</button>
</nav>
</header>
<div id="wrapper" class="clearfix">

Unverzichtbare Bestandteile für ein valides und funktionierendes WordPress-Theme

Widmen wir uns zuerst dem Teil, der in keinem WordPress-Theme und auch keiner anderen Seite fehlen sollte: Doctype, html- und head-Element.

<!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js">
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<?php if ( is_singular() && pings_open() ) { ?>
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<?php }
wp_head(); ?>
</head>
<body <?php body_class(); ?>>

Doctype und Meta-Tags

Wir beginnen mit dem Einfügen des HTML5-Doctype. Dem html-Tag geben wir mit der language_attributes()-Funktion das gefüllte lang-Attribut mit. Wenn ihr eure WordPress-Seite auf Deutsch eingestellt habt, sieht die Ausgabe so aus: lang="de-DE". Die no-js-Klasse brauchen wir für ein paar CSS-Fallback-Angaben, wenn JavaScript nicht aktiviert sein sollte.

Innerhalb des head-Elements wird die Zeichenkodierung durch die bloginfo()-Funktion ausgegeben, der als Parameter charset übergeben wird. Für responsive Webdesign unerlässlich ist natürlich der viewport-Meta-Tag.

Pingbacks ermöglichen und wp_head() nicht vergessen

Um Pingbacks möglich zu machen, muss ein link-Tag integriert werden. Das möchten wir aber nur laden, wenn eine Einzelseite aufgerufen ist und Pingbacks im Backend auch aktiviert sind. Wir prüfen also mit is_singular() && pings_open(), ob diese beiden Bedingungen gegeben sind. Wenn das der Fall ist, geben wir das link-Tag aus. Das href-Attribut nutzt wieder die bloginfo()-Funktion, diesmal mit dem Parameter pingback_url.

Sehr wichtig ist die Nutzung der wp_head()-Funktion. Darüber bindet WordPress beispielsweise das title-Element, jQuery und den canonical-Tag ein. Außerdem wird er für Styles und Skripte von Plugins genutzt. Die Funktion body_class() im öffnenden body-Tag fügt abhängig von der dargestellten Seite unterschiedliche Klassen ein. Wenn wir uns auf der Startseite befinden, wird beispielsweise unter anderem die home-Klasse eingefügt.

Der sichtbare Header des Themes

Header-Bild oder Titel als Link auf die Startseite

<header id="header" class="clearfix" role="banner">
<div>
<h1 class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php if ( get_header_image() ) { ?>
<img src="<?php echo esc_url( get_header_image() ); ?>" alt="<?php echo esc_html( get_bloginfo( 'title' ) ); ?>" />
<?php } else {
bloginfo( 'title' );
} ?>
</a>
</h1>

Wir umschließen den Inhalt des Headers mit einem header-Element. Innerhalb eines div-Elements und einer Überschrift erster Ordnung möchten wir den Titel des Blogs darstellen und auf die Startseite verlinken. Wenn allerdings ein Header-Bild im WordPress-Backend festgelegt ist, soll das statt des Titels angezeigt werden. Für die Verlinkung auf die Startseite nutzen wir die home_url()-Funktion und escapen diese zur Sicherheit mittels esc_url().

Hier ein kleiner Hinweis zu den Escape-Funktionen mit esc_-Präfix: Während des Theme-Reviews bei WordPress.org wurde ich darauf hingewiesen, dass ich diese Funktionen an einigen Stellen vergessen hatte. Euch wird diese Funktionen also noch an einigen Stellen begegnen. Nun prüfen wir, ob die get_header_image()-Funktion etwas zurückgibt. Wenn dem so ist, wurde ein Header-Bild festgelegt.

<img src="<?php echo esc_url( get_header_image() ); ?>" alt="<?php echo esc_html( get_bloginfo( 'title' ) ); ?>" />

Die URL des Header-Bildes liefert uns einfach die get_header_image()-Funktion. Wir nutzen hierfür wieder die Escape-Funktion esc_url(). Als Alternativtext geben wir den Titel des Blogs aus, den wir uns wieder mit der get_bloginfo()-Funktion ausgeben lassen können. Hier nutzen wir die Escape-Funktion esc_html(). Wenn kein Header-Bild festgelegt wurde, wird einfach der Titel der Website ausgegeben.

Die Beschreibung der Website

    <?php if ( get_bloginfo( 'description' ) != '' ) { ?>
<h2 class="blog-description">
<?php bloginfo( 'description' ); ?>
</h2>
<?php } ?>
</div>

Wenn eine Beschreibung für die Website festgelegt wurde, wollen wir diese in Form einer h2-Überschrift ausgeben. Wir prüfen mit get_bloginfo( 'description' ) != '', ob die Beschreibung nicht leer ist. Wenn etwas eingetragen wurde, dann geben wir die Überschrift aus und als Inhalt – wiederum mit der bloginfo()-Funktion – die Beschreibung.

Wichtig für einen guten Benutzerfluss: Das Menü

    <button class="menu-button show-menu">≡</button>
<nav role="navigation">
<button class="hide-menu menu-button">×</button>
<?php wp_nav_menu( array(
'theme_location' => 'header-menu',
'container' => '',
'fallback_cb' => '__return_false'
) ); ?>
<button class="hide-menu menu-button">×</button>
</nav>
</header>
<div id="wrapper" class="clearfix">

Um ein Menü auszugeben, braucht es nicht sehr viel. Für kleine Viewports erstellen wir zuerst einen Button mit dem altbekannten -Symbol. Innerhalb des nav-Elements kommt zuerst und am Schluss jeweils ein weiterer Button, der das aufgeklappte Menü auf kleineren Viewports wieder schließt.

Dazwischen wird es interessant: Um ein WordPress-Menü anzuzeigen, gibt es die wp_nav_menu()-Funktion, der alle möglichen Parameter übergeben werden können. Mit dem Parameter theme_location bestimmen wir, welche Menüposition wir anzeigen wollen. Den Namen dieser Menüposition, die ihr im Backend bei der Menüverwaltung auswählen könnt, legen wir in einem späteren Teil in der functions.php fest.

Normalerweise wird die Menüliste von einem div-Element umschlossen. Das brauchen wir nicht, weshalb wir einen leeren Wert für den container-Parameter übergeben. Einen Fallback dafür, dass dieser Position kein Menü zugeordnet ist, möchten wir nicht. Standardmäßig würden die wp_page_menu()-Funktion genutzt werden, die eine Linkliste der WordPress-Seiten ausgibt. Wir schließen danach noch unser header-Element und öffnen einen Wrapper.

Der Code zu Teil 3 auf GitHub

Den Code zu dem Theme gibt es auf GitHub. Ihr findet den aktuellen Stand des Themes nach diesem Teil im Tag „v0.2“.

Die weiteren Teile unserer WordPress-Reihe:

Bitte beachte unsere Community-Richtlinien

11 Reaktionen
Lukas Adler

Hallo,
in welchem Ordner etc befinden sich denn die von dir erwähnten Dateien?

Danke für die Antwort.

Florian Brinkmann

Hi Lukas,

die Dateien liegen in dem Ordner „wp-content/themes/namedesthemes“. Wenn dein Theme also beispielsweise „lukas“ heißen soll, dann wäre der richtige Ordner für die Theme-Dateien „wp-content/themes/lukas“.

Viele Grüße.

238870 (abgemeldet)

Ich kann einfach den hype um wordpress nicht ganz nachvollziehen, wie das ganze teil zusammengebaut wurde erinnert mich immer noch an php 4 oder ähnliches... Hatte ewig keinen Code von wordpress gesehen und eigentlich gehofft, dass bei der Maße an blogs und content, dass mit dem Teil betrieben wird, die ein wenig erwachsen geworden sind...
Leider weit gefehlt :-)

nicmare

dann sieh dir mal roots sage an. da gibts namespacing und wenig redundanten code. ich vermute das verstehst du unter erwachsen ;) https://roots.io/sage/

nicmare

als WP-Experte bin ich im großen und ganzen bisher einverstanden mit deiner Vorgehensweise aber auf jeder Seite für das Logo bzw. dem Sitename zu verwenden ist eine Eigenheit die sich aus irgendwelchen Gründen vor ca. 10 Jahren entwickelt hat und heutzutage total altmodisch ist. Damals als die oraganischen SERPs ein Revival erfahren haben und heutzutage natürlich unabdingbar sind. Aber nicht so! in der h1 sollte das Thema der aktuellen Seite oder des aktuellen Beitrages stehen. Eben das, was in der ersten Zeile in der Wordpressbearbeitung steht. Aber gewiss nicht der Sitename! Es reicht dass dieser in der Domain, im und im semantisch korrekt sortieren Quelltext sehr weit oben steht. Und dafür muss man kein WP-Experte sein! ;-)

nicmare

mist. da fehlt ein h1: "aber auf jeder Seite h1 für das Logo bzw. dem Sitename zu verwenden ist eine Eigenheit"

Florian Brinkmann

Hey!
Wie würdest du den Seitennamen beziehungsweise alternativ das Logo auszeichnen?

thomasenzler

Hallo
Ein Tutorial dieser Art ist genau das, wonach ich suche. Super. Bevor ich mich aber an die Arbeit mache würde ich gerne wissen, ob es nach dem Teil 3 noch weiter geht mit der Veröffentlichung etc.?
Danke für deine Antwort, Grüsse

Florian Brinkmann

Hi,

ich plane auf jeden Fall, die Reihe noch zu Ende zu bringen :)
Ich werde allerdings vermutlich den Code des Themes noch mal überarbeiten beziehungsweise habe das teilweise schon gemacht, da das aktuell etwas suboptimal war.
Außerdem werde ich das Theme voraussichtlich zuerst fertig stellen und anschließend die Beiträge schreiben, damit die Fertigstellung der Reihe nicht davon abhängig ist, ob ich nebenbei auch mit dem Theme voran komme – daher kann ich dir leider keinen verbindlichen Termin nennen, wann es weiter geht.

Viele Grüße,
Florian

thomasenzler

hi Florian,
danke für die Rückmeldung.
Deine persönliche Empfehlung: soll ich warten, bis du alles final im Kasten hast oder doch schon mal mit deinem Tutorial beginnen?
Grüsse aus der Schweiz
thomas

Florian Brinkmann

Hi Thomas,

ich würde warten, es wird sich auch einiges an dem Code der bisherigen Teile ändern :)

Viele Grüße,
Florian

Du musst angemeldet sein, um einen Kommentar schreiben zu können.

Jetzt anmelden

Finde einen Job, den du liebst