b.olzplatz für e.learning, me.diensachen und o.nlinekram

Templates basteln (WordPress-Theme, Teil 2)

1. Grundsätzliches zu PHP

Für diejenigen ohne jegliche Programmier-Erfahrung: PHP ist eine Skriptsprache, welche - stark vereinfacht - auf dem Webserver ausgeführt wird, auf dem auch die Webseite gehostet wird. Soweit ich das verstanden habe, führt der Aufruf von z.B. https://bemeo.de über die Browser-Adresszeile eines Clients zu einer Anfrage auf meinem Webserver nach der Blog-Startseite, die - bei den aktuellen Blog-Einstellungen - auf dem Template home.php basiert.

Der PHP-"Interpreter" (Bestandteil des auf dem Server laufenden PHP-Softwarepakets) organisiert sich diese Datei home.php, bastelt aus den darin stehenden Funktionen und Befehlen eine HTML-Datei und schickt diese über den Webserver zurück an den anfragenden Client, dessen Browser diese HTML-Datei zu einem "visuellen Erlebnis" 🙂 rendert. Ok, das ist wahrscheinlich nicht nur stark vereinfacht, sondern tlw. auch verkehrt, aber der Kern ist: Es werden keine PHP-Dateien an einen Client ausgeliefert, sondern diese werden auf dem Server verarbeitet.

Die Verarbeitung eines WordPress-Templates sollte also möglichst zu einer validen HTML-Struktur führen, die an den anfragenden Client ausgeliefert wird. Das ist vor allem dann nicht ganz einfach, wenn sich ein Template aus mehreren Template-Teilen zusammen setzt - dazu später mehr.

Ein HTML-Dokument wird ja bekanntlich mit einer <!DOCTYPE>-Angabe begonnen, auf die der <html>-Tag eröffnet wird. Dieser enthält den <head>...</head> und den <body>...</body> der Seite und wird am Ende via </html> geschlossen. So weit, so einfach:

HTML

<!-- Standard HTML Struktur -->
<!DOCTYPE html>
<html>
  <head> ... </head>
  <body> ... </body>
</html>

In PHP-Dateien kann PHP- mit HTML-Code gemischt werden. PHP wird normalerweise mit <?php eröffnet und mit ?> wieder geschlossen. So können sich HTML- und PHP-Code in einer Theme-Datei abwechseln:

  <?php ... ?>
  <h1>...</h1>
  <?php ... ?>
  <p>...</p>
  <?php ... ?>

Es kann auch PHP innerhalb von HTML und HTML innerhalb von PHP geschrieben werden, z.B. so:

/* PHP in HTML */
   <a href="<?php echo esc_url( home_url( '/' ) ); ?>">...</a>

/* HTML in PHP */
   <?php if ( is_sticky()) {
      printf( '<span class="marked-as-sticky">angepinnt</span>' );
   } ?>

Hier wird (oben) ein Link-Ziel (href="...") durch einen PHP-Befehl befüllt. Der PHP-Interpreter baut in die auszuliefernde HTML-Struktur dann dort eine "echte" URL ein, die im Browser anklickbar ist.

Im unteren Beispiel wird ein WordPress-Post, wenn er "oben gehalten" wird ("sticky“ ist), in der HTML-Struktur mit einem <span>-Tag und dem Text "angepinnt" versehen.

So. Und mehr weiß ich eigentlich auch nicht über PHP. 🙂

2. Vorsicht bei verschachtelten Templates!

Eine Besonderheit von WordPress-Templates ist, dass durch die Verschachtelung von Template-Teilen manchmal HTML-Tags in einer PHP-Datei geöffnet und in einer anderen PHP-Datei geschlossen werden. Hier besteht das Kunststück darin, den Überblick nicht zu verlieren, so dass am Ende der Verarbeitung aller beteiligten PHP-Skripte eine valide HTML-Datei steht:

/* page.php */

<!DOCTYPE html>
<html>
  <head> ... </head>
  <body>

/* page.php lädt header.php */
    <header> ... </header>
    <div id="content">

/* Ende header.php - weiter mit page.php */

    <div class=contentkram“> ... </div><!––.contentkram––>

/* page.php lädt sidebar.php */

    <div id="widgetarea"> ... </div><!––#widgetarea––>

/* Ende sidebar.php - page.php lädt footer.php */

    </div><!––#content––>
    <footer> ... </footer>
  </body>
</html>

/* Ende footer.php */

Dies Beispiel zeigt, wie die Tags <html> und <body> in der Datei page.php geöffnet, aber erst in der Datei footer.php wieder geschlossen werden. Und <div id="content"> wird in header.php geöffnet und in footer.php geschlossen. Um nicht völlig den Überblick zu verlieren, hat es sich als gute Idee erwiesen, hinter allen schließenden HTML-Tags auskommentiert (<!–– ... ––>)  zu vermerken, welches HTML-Element hier eigentlich geschlossen wird - jeweils durch Angabe der ID (#id) bzw. Klasse (.class).

Das ist dann besonders sinnvoll, wenn das Objekt keinen semantischen Knotennamen (z.B. <header>, <article>, <section> oder <footer>) hat, sondern es sich um <div>-Tags handelt, welche im Gegensatz dazu wegen hier fehlender Klassen- bzw. ID-Angabe ja nicht am schließenden Tag (der immer nur </div> heißt) erkennbar sind.

So, genug Theorie. Jetzt mal anfangen. Hier eine Checkliste, was an der Template-Baustelle noch alles zu tun ist (auf Basis der Überlegungen aus Teil 1):

  1. Ausgelagerte Template-Teile
    1. header.php
    2. comments.php
    3. sidebar.php
    4. footer.php
  2. Zusammengesetze Templates
    1. home.php
    2. single.php
    3. page.php
    4. search.php
    5. archive.php
    6. 404.php

Ich befülle alle Templates und Template-Teile nun zumindest schon einmal mit Platzhaltern und setze die Templates zusammen.

3. Erstellen der vier ausgelagerten Template-Teile

Jede PHP-Datei sollte einen "Kommentar-Kopf" beinhalten. Mehrzeilige PHP-Kommentare funktionieren mit der Auszeichnung /* ... */. In dem kann vermerkt werden, was das für ein Template (-Teil) ist und zu welchem Theme in welcher Version es gehört. Der Rest sind Platzhalter 🙂

3.1 Die Kopfzeile

Ich beginne mit dem einzubindenden Template-Teil header.php:

PHP: header.php

<?php
/*
 * Template Part for displaying the Header
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */
?>
<!DOCTYPE html>
<html lang="de">
   <head>
      <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <?php wp_head(); ?>
   </head>
   <body <?php body_class(); ?> >
      <header>
         <p>Ich bin 'header.php'.</p>
      </header>
      <main id="#content">

Erläuterung:
Nach dem einleitenden Kommentar folgt die Standard-HTML-Struktur bis zur Eröffnung des #content-Bereichs. Außerdem binde ich bereits die style.css-Datei über den <link>-Tag im <head>-Bereich ein. Das funktioniert über die WordPress-Funktion bloginfo(); (Doku), in deren Klammer ich verschiedene Werte abfragen kann. Hier: die Adresse des Stylesheets via 'stylesheet_url'. In dem ausgelieferten HTML-Dokument steht dann da die Adresse der style.css des entsprechenden Theme-Ordners drin.

Das <?php wp_head(); ?> (Doku) sollte man ebenfalls einbauen, da diese Funktion für viele (wesentliche!) WordPress-Funktionen und viele Plugins notwendig ist.

Außerdem setze ich via body_class(); (Doku) Klassen in den <body>-Tag, die ich später mit CSS ansprechen kann.

3.2 Die Fußzeile und die anderen Template-Teile

Die footer.php bekommt nur ein wenig HTML und einen Dummy-Text, außerdem (analog zu wp_head() in der Kopfzeile) die Funktion wp_footer() (Doku) ...

PHP: footer.php

<?php
/*
 * Template Part for displaying the Footer
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */
?>

      </main><!-- #content -->
      <footer>
         <p>Ich bin 'footer.php'.</p>
         <?php wp_footer(); ?>
      </footer>
   </body>
</html>

... ebenso wie die comments.php, ...

PHP: comments.php

<?php
/*
 * Template Part for displaying the Comments Section
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */
?>

      <!-- innerhalb von main -->
      <div id="comments">
         <p>Dies ist der Kommentarbereich 'comments.php'</p>
      </div><!-- #comments -->

... und die sidebar.php.

PHP: sidebar.php

<?php
/*
 * Template Part for displaying the Sidebar / Widgets Section
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */
?>

      <!-- innerhalb von main -->
      <aside>
         <p>Hier werden bald Widgets angezeigt: 'sidebar.php'</p>
      </aside>

Damit habe ich die ausgelagerten Template-Teile erst einmal „fertig“. Diese kann ich jetzt in meine Seitentemplates einbinden:

4. Einbinden der Template-Teile in die sechs Seitentemplates

4.1 home.php

Ich starte - weil es so schön schnell sichtbar wird - mit der home.php. Für das Startseiten-Template schreibe ich nach dem einleitenden Kommentar also nur die Funktion get_header();, welche die Datei header.php organisiert, gefolgt von HTML für unseren Seiten-Hauptteil (<article>) und den Funktionen zur Einbindung von sidebar.php und footer.php:

PHP: home.php

<?php
/*
 * Template Part for displaying the Home Page
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */

      get_header(); ?>

      <article>
         <p>Ich bin die 'home.php'.<br />Hier wird bald die Liste aller Beitr&auml;ge (Startseite) angezeigt.</p>
      </article>

      <?php get_sidebar();
            get_footer(); ?>

Und da diese home.php das Startseiten-Template (für die > Einstellung > Lesen > Deine Startseite zeigt = Deine letzten Beiträge) ist, kann man es bereits im Customizer betrachten. Der hat den Vorteil, dass ich eine Live-Vorschau bekomme, ohne ein Theme aktivieren (und damit für die Öffentlichkeit sichtber machen) zu müssen:

Der Customizer zeigt die home.php und diese läd Header, Sidebar und Footer.

Den Freunden schneller Ergebnisse können ein paar Zeilen CSS in der style.css das Gefühl vermitteln, ein "echter" Theme-Entwickler zu sein:

CSS: style.css

html, body {
  font-family:'Arial', sans-serif;
  font-size:1em;
  color:#333;
  max-width:1000px;
  margin:0 auto;
  background:#ddd;
}
header, article, #comments-area, aside, footer {
  padding:25px 70px;
}
header {
  background:#005566;
  color:#eee;
}
main {
  background:#fff;
  padding:0;
}
aside {
  background:#888;
  color:#ddd;
}
footer {
  background:#444;
  color:#ddd;
}

Ta-dah! Das Platzhalter-Theme in hübsch...

4.2 single.php und page.php

Die nächsten Templates aus unserer Liste sind single.php und page.php. Diese sind sich relativ ähnlich, eingebunden werden jeweils header.php, comments.php, sidebar.php und footer.php. Beim Einbinden des Kommentarbereiches unter dem Seiten- bzw. Artikeltext besteht eine Besonderheit: Diese werden nicht einfach mit get_comments(); sondern mit comments_template(); (Doku) eingebunden:

PHP: single.php

<?php
/*
 * Template Part for displaying a single Article
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */

      get_header(); ?>

      <article>
        <p>Ich bin 'single.php'. Hier w&uuml;rde ein einzelner Beitrag angezeigt.</p>
      </article>
      <?php comments_template();
            get_sidebar();
            get_footer(); ?>

Im Template für statische Seiten verzichte ich allerdings vorerst auf den Kommentarbereich:

PHP: page.php


<?php
/*
 * Template Part for displaying a single Page
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */

      get_header(); ?>

      <article>
        <p>Ich bin 'page.php'. Hier steht bald der Inhalt statischer Seiten.</p>
      </article>
      <?php get_sidebar();
            get_footer(); ?>

4.3 search.php, archive.php & 404.php

Jetzt fehlen nur noch die search.php, die archive.php und die 404.php. Auch diese drei bekommen wieder den eingebetteten Header, die Sidebar und die Fußzeile, jeweils mit einem individuellen Inhaltsblock (<article>), ebenfalls ohne den Kommentarbereich:

PHP: search.php

<?php
/*
 * Template Part for displaying the Search Results
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */

      get_header(); ?>

      <article>
        <p>Mein Name ist 'search.php'. Ta-dah: Die Suchergebnisse!</p>
      </article>
      <?php get_sidebar();
            get_footer(); ?>

PHP: archive.php

<?php
/*
 * Template Part for displaying all kinds of Archive
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */

      get_header(); ?>
      <article>
        <p>Gestatten, 'archive.php', zust&auml;ndig f&uuml;r Anzeige von Datums-, Autoren-, Schlagwort- und Kategorie-Archiven.</p>
      </article>
      <?php get_sidebar();
            get_footer(); ?>

PHP: 404.php


<?php
/*
 * Template Part for displaying an Error Page
 * theme: b.e.me.o Basic Theme
 * since: b.e.me.o Basic Theme v. 1.0
 * author: Martin Smaxwil
 */

      get_header(); ?>
      <article>
        <p>Ups! 404! Die aufgerufene Seite wurde nicht gefunden!</p>
      </article>
      <?php get_sidebar();
            get_footer(); ?>

Die Templates jenseits der home.php sind allerdings nicht so einfach im Customizer anzuzeigen, da sie nur für bestimmte Seiteninhalte verwendet werden. Der Customizer zeigt jedoch  standardmäßig die Startseite, und solange diese noch keinen Link zu z.B. einem Artikel oder einem Archiv beinhaltet, kann ich die anderen Seiten (-Arten) noch nicht im Customizer aufrufen. Das kommt aber direkt im nächsten Teil dieser Artikelserie...

Alle Teile der Serie bisher:

  1. Grundlagen und Planung
  2. Templates und Template-Teile (dieser hier)
  3. Der erste Loop

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Zustimmung zur Datenverarbeitung