WordPress Themes Step by Step Teil 2
Folgende Teile sind erschienen:
- WordPress Themes Step by Step Teil 1
- WordPress Themes Step by Step Teil 2
- WordPress Themes Step by Step Teil 3
- WordPress Themes Step by Step Teil 4
Inhaltsverzeichnis:
- Lizenz
- Download
- Einleitung
- Die header.php
- Der <head> Bereich
- Übersicht Template Tag bloginfo()
- Der Titel
- Die Kopfleiste
- Die horizontale Navigation
- Die footer.php
Lizenz
YAML wurde unter der Creative Commons Attribution 2.0 Lizenz (CC-A 2.0) veröffentlicht. Aus diesem Grund stehen die Downloadpakete ebenfalls unter der CC-A 2.0. Eine kostenlose private und kommerzielle Nutzung ist gestattet.
Bedingung: Für die kostenfreie Nutzung des YAML Framework und des hier erstellten Themes ist die Namensnennung der Autoren/Rechteinhaber und die Rückverlinkung zur YAML Homepage (http://www.yaml.de) sowie zu meiner Homepage (http://dynamicinternet.eu) in der Fußzeile der Webseite oder im Impressum vorgeschrieben.
Download
Die erforderlichen Dateien können als Zip-Datei heruntergeladen werden. Sie beinhalten alle in Teil 1 durchgeführten Schritte. Download Beginn Teil 2.
Einleitung
Wir haben im ersten Teil dieser Serie das Ausgangslayout in die Bestandteile header.php, index.php, sidebar.php und footer.php zerlegt. Danach wurden in der index.php mit den Include Tags get_header(), get_sidebar() und get_footer() die Dateien header.php, sidebar.php und footer.php in die index.php eingebunden, so dass wir am Ende von Teil 1 die index.php im Browser aufrufen konnten.
In diesem zweiten Teil werden wir die header.php und die footer.php mit mit WordPress Funktionen ausstatten.
Die header.php
Obwohl die header.php eine sehr wichtige Datei ist, die in allen Templates verwendet wird, ist sie nicht unbedingt die spannendste Datei. Das liegt daran, dass man von der header.php relativ wenig auf der Webseite sieht. Wir würden uns sicherlich zuerst lieber auf die index.php stürzen, nur dazu benötigen wir eine funktionierende header.php.
Bei der dynamischen Erzeugung des Seitentitels und bei der Handhabung des Meta Tags “robots” werden wir aber trotzdem eine Menge zum Nachdenken haben. Mit der Kopfleiste und horizontalen Navigation haben wir am Ende der header.php auch die ersten sichtbaren Elemente auf unserer Webseite.
Wir öffnen nun die header.php im Editor und nehmen uns aus Gründen der Übersichtlichkeit zuerst dem <head> Bereich vor.
Der <head> Bereich
Hier noch einmal zur der Quellcode, wie wir ihn am Ende von Teil 1 abgespeichert haben:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>YAML | Example "2col_right_seo"</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="<?php bloginfo('stylesheet_url'); ?>" rel="stylesheet" type="text/css"/>
<!--[if lte IE 7]>
<link href="<?php bloginfo('template_url'); ?>/css/patches/patch_2col_right_seo.css" rel="stylesheet" type="text/css" />
<![endif]-->
</head>
Es fehlen eine Menge Angaben, die auf jeder Webseite enthalten sein sollten. Diese werden wir jetzt ergänzen.
Jede Webseite sollte mit der Doctype Deklaration beginnen. Wir verwenden XHTML 1.0 Transitional, welches auch WordPress bei den mitgelieferten Themes verwendet. Diese Deklaration ist sehr wichtig, da wir damit den Browser in den Standardmodus versetzten. Der Standardmodus bietet mehr Sicherheit bei der browserübergreifenden einheitlichen Darstellung der Webseite. In diesem Modus ist der Browser aber nicht sehr tolerant und es kann schnell zu Darstellungsfehlern kommen. Umso wichtiger ist es, immer wieder den Quelltext validieren zu lassen. Nach dem Doctype ersetzen wir die Zeile mit dem öffnenden <html> Tag durch diese Zeile:
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
Das Template Tag language_ attributes() schreibt 2 Attribute mit samt seinen Werten in diese Zeile. Einmal das lang-Attribut, welches in der wp-config.php als Konstante definiert ist:
define ('WPLANG', 'de_DE');
und das dir-Attribut, welches WordPress aus den lokalen Einstellungen holt. Es gibt die Schreibrichtung an, in unserem Falle left to right.
Im Browserquelltext sieht die Zeile dann so aus:
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="de-DE">
Darunter fügen wir diese Zeile ein:
<head profile="http://gmpg.org/xfn/11">
Das Attribut profile besitzt als Wert den Link zum XHTML Friends Network. Damit können Beziehungen zu Personen, die ebenfalls eine Webseite haben, abgebildet werden. Die Möglichkeit dazu findet ihr in der Blogroll, wenn ihr einen Link anlegt oder bearbeitet, unter Link-Beziehungen (XFN).
Die nächste Zeile in der header.php ist das title Tag. Diese Zeile schneiden wir aus und fügen sie unter der Zeile
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
wieder ein.
Den Content-Type versehen wir mit einem weiteren Template Tag.
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
Das Template Tag bloginfo() haben wir schon im ersten Teil bei der Einbindung des Stylesheets kennengelernt. Innerhalb der Klammern von bloginfo() wird als Argument angegeben, was bloginfo() zurückliefern soll. Vieles davon sind Einstellungen, die wir im Adminbereich getan haben.
Übersicht Template Tag bloginfo()
Möglich sind folgende Argumente:
- ‘name’ – der Titel des Blogs aus Allgemeine Einstellungen
- ‘description’ – Blog Thema aus Allgemeine Einstellungen
- ‘url’ – Blog-Adresse (URL) aus Allgemeine Einstellungen
- ‘rdf_url’ – URL des RDF/RSS 1.0 Feeds
- ‘rss_url’ – URL des RSS 0.92 Feeds
- ‘rss2_url’ – URL des RSS 2.0 Feeds
- ‘atom_url’ – URL des Atom Feeds
- ‘comments_rss2_url’ – URL der Kommentare als RSS 2.0 Feed
- ‘pingback_url’ – Pingback URL
- ‘admin_email’ – Emailadresse des Administrators aus Allgemeine Einstellungen
- ‘charset’ – Zeichensatz für Seiten und Feeds aus Leseeinstellungen
- ‘version’ – zeigt die verwendete WordPress Version an
- ‘html_type’ – gibt text/html zurück, nicht änderbar
- ‘wpurl’ – WordPress-Adresse (URL) aus Allgemeine Einstellungen (nicht mit ‘url’ verwechseln, kann uU. eine andere sein)
- ‘template_url’ – die URL des benutzen Templates
- ‘template_directory’ – die URL des aktiven Themes
- ‘stylesheet_url’ – die URL zum Stylesheet style.css (http://domain.de/wp-content/themes/yourTheme/style.css)
- ‘stylesheet_directory’ – die URL in der sich das Stylesheet befindet
Es gibt noch 2 weitere, die nicht in der WordPress Dokumentation stehen, falls die einer mal braucht:
- ‘language’ – wp-config.php Spracheinstellung
- ‘text_direction’ – lokale Einstellungen für das lang Attribut
Sollte man sich nicht sicher sein, ob man gerade das richtige Argument verwendet hat, einfach in der index.php oberhalb des Loops einmal bloginfo mit dem Argument ausgeben lassen, zB:
<?php bloginfo('url');?>
Hier wird http://localhost/tutorialblog/wordpress ausgeben. Damit kann schnell und einfach überprüft werden, ob man richtig liegt.
Nach so viel bloginfo() kommen wir zum <title> Tag.
Der Titel
Erstmal löschen alles innerhalb des <title></title> Tags und geben den Namen unseres Blogs aus:
<title><?php bloginfo('name'); ?></title>
Das würde uns den Titel, den wir in Allgemeine Einstellungen->Blog-Titel eingetragen haben, liefern. Da wir die header.php aber in allen späteren Templates ebenfalls einbinden werden, ist diese Variante nicht besonders toll, da wir dann ja überall den gleichen Titel hätten. WordPress stellt uns für solche Fälle so genannte Conditional Tags zur Verfügung. Damit können wir eine Schleife schreiben und für verschiedene Ansichten unseres Blogs die entsprechende Überschrift zusammen bauen.
<?php
echo'<title>';
if ( is_home() ) {
echo get_bloginfo('name') . ' » Mein cooler Blog!';
}
echo'</title>';
?>
Wir fragen hier mit is_home() die Startseite des Blogs ab. Wenn die aufgerufene Seite die Startseite ist, liefert is_home() true zurück und alles, was innerhalb der geschweiften Klammern steht, wird ausgeführt. Liefert is_home() false zurück, wird in diesem Fall gar nichts ausgegeben, weil wir keine andere Bedingung angegeben haben.
Also erweitern wir das Ganze etwas:
<?php
echo '<title>';
if ( is_home() ) {
echo get_bloginfo('name');
} elseif ( is_single() or is_page() ) {
wp_title(''); echo ' » ' . get_bloginfo('name');
} elseif ( is_search() ) {
echo get_bloginfo('name') . ' » Suche: ‹' . wp_specialchars($s, 1) . '›';
} elseif ( is_404() ) {
echo get_bloginfo('name') . ' » 404 - Angeforderte Seite nicht gefunden';
} else {
echo get_bloginfo('name');
}
echo '</title>';
?>
Hier haben wir für die Startseite, die Beitragsansicht is_single(), die Ansicht einer statischen Seite is_page(), die Suchergebnisseite is_search() und für die Fehlerseite is_404() jeweils einen ansprechenden Titel produziert. Die Suchergebnisseite zeigt den Suchstring ($s) im Titel an. Wichtig ist hier, dass man mit wp_specialchars den Suchstring maskiert. Außerdem haben wir innerhalb des else Zweigs einen Titel definiert, falls alle darüber genannten Bedingungen nicht zutreffen. Diese Schleife lässt sich locker noch verdoppeln.
Michael Wöhrer vom Software-Guide hat ein schönes Beispiel, wie man den Seitentitel ausgeben kann. Ich habe diese Variante in die Downloaddateien mit eingearbeitet.
Ein paar kleine Stolperfallen gibt es jedoch. Das Blogarchiv kann man mit is_archive() abfragen. Das wäre aber dann das Archiv generell. Ein Archiv kann aber ein Tages-, Monats- oder Jahresarchiv sein, sogar stündlich ist möglich. Dann muss man is_time(), is_day(), is_month(), is_year() verwenden und kann so präziser unterscheiden. Außerdem hat man die Möglichkeit, innerhalb der Klammern genauer zu spezifizieren: is_category(’2′) für die Kategorie mit der ID 2 is_category(‘Allgemein’) für die Kategorie Allgemein is_page(‘Impressum’) für die statische Seite Impressum. Je nach Bedarf lassen sich die Coditional Tags auch negieren:
if ( !is_category(’5′) ) {tue etwas}
Wir sehen, WordPress gibt uns seine Menge Funktionen in die Hand, damit wir unser Theme in jedem Detail individuell gestalten können. Wir werden im Laufe dieser Serie immer wieder auf die Conditional Tags stossen und mehr darüber lernen, wie man sie benutzen kann. Mit der nächsten Zeile wird das Stylesheet eingebunden. Das haben wir im ersten Teil schon getan, folgen also die <meta> Tags.
Welche Angaben ihr machen möchtet, ist euch überlassen. Ich habe in den Downloaddateien ein paar eingearbeitet. Drei möchte ich hier erwähnen. Da wären einmal
<meta name="generator" content="WordPress <?php bloginfo('version'); ?>" /> <!-- leave this for stats -->
Das möchte WordPress gerne mit dabei haben und zeigt die verwendete WordPress Version an. Im Falle von Herrn Basic Version 1.5.2 (Robert hat ein Update gemacht). So kann man natürlich auch seine Sicherheitsmängel der breiten Masse bekannt geben
<meta name="siteinfo" content="<?php bloginfo('url'); ?>/robots.txt" />
Hier benutzen wir bloginfo(‘url’), um den Pfad zur robots.txt anzugeben, vorausgesetzt, ihr habt eine angelegt.
<meta name="robots" content="index, follow" />
Hierzu gab es bei Frank Bültge vor kurzem eine Diskussion, welche Seiten man von den Suchmaschinen ausschliessen sollte. Darüber kann sich jeder selbst den Kopf zerbrechen, ich möchte lediglich hier Möglichkeiten aufzeigen, was man so alles tun kann.
Um nur die Startseite indexieren zu lassen und nicht die Seiten 2, 3 …, welche ja eh ständig andere Inhalte haben, kann man folgendes benutzen:
<?php
If (is_paged() ){
echo '<meta name="robots" content="noindex, follow" />';
}else{
echo '<meta name="robots" content="index, follow" />';
} ?>
Wenn man jetzt nur die Startseite, die Beitragsansichten und die statischen Seiten indexieren lassen möchte, setzt man diesen Code ein:
<?php
if( (is_home() && !is_paged() ) || is_single() || is_page() ) {
echo '<meta name="robots" content="index, follow" />';
}else{
echo '<meta name="robots" content="noindex, follow" />';
}
?>
Das würde bedeuten, dass keine „paged“- , Kategorie-, Archiv-, Tag- und Suchseiten indexiert werden.
Viel Spass beim Nachdenken
<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="<?php bloginfo('rss2_url'); ?>" />
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
Hier wird auch wieder bloginfo() benutzt, um die absoluten Pfade auszugeben. Eine meiner Meinung nach überflüssige Zeile ist die standardmäßig auskommentierte Zeile
<?php //comments_popup_script(); // off by default ?>
Damit wird ein Javascript eingebunden, welche es ermöglicht, nach einem Klick auf den Kommentar-Link die Datei comments-popup.php in einem Popup-Fenster zu öffnen. Ich halte nichts von solchen Popupfenstern, viele Nutzer haben eh einen Popupblocker eingeschaltet, darum habe ich sie bei mir komplett entfernt. Der Vollständigkeit halber wollte ich diese Möglichkeit trotzdem erwähnen. Wenn ihr es unbedingt nutzen wollt, einfach nur die beiden Slashes entfernen.
Danach kommt eine sehr wichtige Zeile:
<?php wp_head(); ?>
Dieser Hook (Haken) wird von WordPress und zahlreichen Plugins benötigt. Zum Beispiel nutzt ein Plugin diesen Hook zum Ausgeben einer Funktion ( add_action(‘wp_head’, ‘plugin_function’); ). wp_head() würde dann diese Funktion ausführen. Also bitte nicht enfernen.
Als letzte Zeile sehen wir den Conditional Comment für die Internet Explorer, den haben wir im ersten Teil schon eingefügt. Hier noch einmal der Quellcode zur Übersicht vom Anfang der header.php bis zum schießenden </head> Tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
<?php
echo'<title>';
if ( is_home() ) {
// Blog's Home
echo get_bloginfo('name') . ' » Weblog';
} elseif ( is_single() or is_page() ) {
// Single blog post or page
wp_title(''); echo ' - ' . get_bloginfo('name');
} elseif ( is_category() ) {
// Archive: Category
echo get_bloginfo('name') . ' » Kategorie: '; single_cat_title();
} elseif ( is_day() ) {
// Archive: By day
echo get_bloginfo('name') . ' » Alle Artikel vom ' . get_the_time('d') . '. ' . get_the_time('F') . ' ' . get_the_time('Y');
} elseif ( is_month() ) {
// Archive: By month
echo get_bloginfo('name') . ' » Alle Artikel vom ' . get_the_time('F') . ' ' . get_the_time('Y');
} elseif ( is_year() ) {
// Archive: By year
echo get_bloginfo('name') . ' » Alle Artikel vom Jahr ' . get_the_time('Y');
} elseif ( is_search() ) {
// Search
echo get_bloginfo('name') . ' » Suche: ‹' . wp_specialchars($s, 1) . '›';
} elseif ( is_404() ) {
// 404
echo get_bloginfo('name') . ' » 404 - Angeforderte Seite nicht gefunden';
} else {
// Everything else. Fallback
echo wp_title(''); echo ' - ' . get_bloginfo('name');
}
echo'</title>';
?>
<link href="<?php bloginfo('stylesheet_url'); ?>" rel="stylesheet" type="text/css"/>
<meta name="author" content="" />
<meta name="publisher" content="" />
<meta name="copyright" content="" />
<meta name="distribution" content="" />
<meta name="description" content= "" />
<meta name="keywords" content="" />
<?php
if( (is_home() && !is_paged()) || is_single() || is_page() ){
echo '<meta name="robots" content="index, follow" />';
}else{
echo '<meta name="robots" content="noindex, follow" />';
}
?>
<link rel="alternate" type="application/rss+xml" title="<?php bloginfo('name'); ?> RSS Feed" href="<?php bloginfo('rss2_url'); ?>" />
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
<?php //comments_popup_script(); // off by default ?>
<?php wp_head(); ?>
<!--[if lte IE 7]>
<link href="<?php bloginfo('template_url'); ?>/css/patches/patch_2col_right_seo.css" rel="stylesheet" type="text/css" />
<![endif]-->
</head>
Nach diesem nicht so spannenden Exkurs wird es nun um Einiges interessanter.
Die Kopfleiste
Zuerst werfen wir einen Blick auf den Quellcode:
<body>
<div id="page_margins">
<div id="page">
<div id="header">
<div id="topnav">
<!-- start: skip link navigation -->
<a class="skip" href="#navigation" title="skip link">Skip to the navigation</a><span class="hideme">.</span>
<a class="skip" href="#content" title="skip link">Skip to the content</a><span class="hideme">.</span>
<!-- end: skip link navigation -->
<span><a href="#">Login</a> | <a href="#">Contact</a> | <a href="#">Imprint</a></span>
</div>
<h1>Example | Beispiel <em>"2col_right_seo"</em></h1>
<span>YAML • (X)HTML/CSS Framework</span>
</div>
Unsere Kopfleiste befindet sich in dem Div-Container mit der id #header. Sie besteht aus einer Skip-Link-Navigation (div #topnav) sowie der Hauptüberschrift. Skiplinks sind wichtig für Leser mit Screenreadern. Sie haben damit die Möglichkeit, gleich am Anfang zu entscheiden, ob sie die Navigation ansteuern wollen oder zum Inhalt springen möchten. Wir werden später in der Fußzeile zusätzlich einen Anker integrieren, wo der Nutzer wieder an den Seitenanfang springen kann. Das verbessert wesentlich die Benutzbarkeit einer Webseite und sollte auf keinen Fall vergessen werden. Die Skiplinks sind im Browser nicht sichtbar, sie werden mit der Klasse .skip aus dem sichtbaren Bereich der Seite geschoben. Diese Klasse ist im YAML Framework bereits in der base.css definiert und wir brauchen uns darum nicht extra zu kümmern.
Ob die nachfolgende Zeile mit den Links zu Login usw. Sinn für einen Blog macht, möchte ich hier nicht entscheiden. Da wir dieses Theme aber widget-ready machen wollen, und es bei den Widgets auch das Meta-Widget mit Login/Logout gibt, hätten wir dann 2x den Login. Aus diesem Grund entferne ich diese Zeile.
Danach kommen wir zur Überschrift. Diese ist als <h1> notiert und stellt somit die wichtigste Überschrift dar. Diese nutzen wir für den Blogtitel.
<h1><?php bloginfo('name'); ?></h1>
Jetzt haben wir aber noch eine Menge Platz in unserem Header und können zusätzlich das Blog-Thema in die Überschrift mit aufnehmen. Damit die Zeile aber nicht zu lang wird, brechen wir sie nach dem Blognamen um und verkleinern die Schrift des Blogthemas etwas. Auch können wir sie farblich verändern:
<h1><?php bloginfo('name'); ?><br /><span><?php bloginfo('description'); ?></span></h1>
Im Stylesheet css/screen/content.css habe ich bei den Überschriften h1-h6 zuerst die font-family entfernt, weil mir diese Schriftfamilie nicht so gefällt und ich habe das font-weight von bold auf normal geändert, ebenfalls Geschmackssache.
#header h1 {
font-size:2.5em;
letter-spacing:-2px;
line-height:100%;
color:#000;
}
#header h1 span {
color:#999;
font-size:0.7em;
}
Viele Nutzer sind es gewöhnt, beim klicken auf den Blognamen zur Startseite wechseln zu können. Um das zu realisieren, brauchen wir lediglich einen Link in die Überschrift einzubauen.
<h1><a href="<?php bloginfo('home'); ?>" title="Zur Startseite wechseln"><?php bloginfo('name'); ?></a><br /><span><?php bloginfo('description'); ?></span></h1>
Die text-decoration des Ankers setzten wir auf none, da es in der Überschrift meiner Meinung nach nicht so gut aussieht.
#header h1 a { text-decoration: none; }
Wir werden uns an dieser Stelle nicht weiter um die Kopfleiste kümmern, sondern wollen in erster Linie unser Blog zum Laufen bringen. In einem späteren Teil werde ich auf weitere Lösungsansätze eingehen
Die horizontale Navigation
Das letzte Stück Quellcode in der header.php ist die horizontale Navigationsleiste. Hier der Quellcode:
<!-- begin: main navigation #nav -->
<div id="nav"> <a id="navigation" name="navigation"></a>
<!-- skiplink anchor: navigation -->
<div id="nav_main">
<ul>
<li id="current"><a href="#">Button 1</a></li>
<li><a href="#">Button 2</a></li>
</ul>
</div>
</div>
<!-- end: main navigation -->
Um den Anker der SkipLink-Navigation brauchen wir uns nicht kümmern. Die eigentliche Navigationsleiste beginnt mit dem Div #nav_main und beinhaltet eine ungeordnete Liste.
Das Stylesheet der Navigation ist in yaml/navigation/nav_shinybuttons.css zu finden, welches nicht verändert werden sollte.
In diesem Layoutbeispiel wurde das Aussehen der Navigation in der css/screen/basemod.css überschrieben. Etwaige Änderungen sollten auch da vorgenommen werden.
Wir kümmern uns aber erstmal um die Funktionalität der Navigation.
Zunächst brauchen wir ein paar statische Seiten, damit in der Navigation auch etwas zu sehen ist. Wir erstellen eine Seite „Kontakt“ als Hauptseite. Danach erstellen wir eine Seite „Impressum“, welche eine Unterseite von der Kontaktseite ist. Dann noch eine Hauptseite „über mich“. So sollte die Seitenstruktur aussehen:

Diese Seiten dienen hier nur als Beispiel, ihr könnt natürlich euch die Seitenstruktur so bauen, wie ihr sie tatsächlich benötigt.
Ok, jetzt wirds spannend. Wir löschen die beiden Listenelemente und benutzen wieder einen Template Tag, um unsere statischen Seiten abzubilden: wp_list_pages(). wp_list_pages(‘arguments’) listet statische Seiten auf. Wir schauen erst einmal, was wp_list_pages() ohne Argumente tut:
<div id="nav_main">
<ul>
<?php wp_list_pages(); ?>
</ul>
</div>
Wir rufen unser Blog auf und schauen uns das Ergebnis an.

Völlig unbrauchbar. Das liegt daran, dass wir wp_list_pages() ohne Argumente aufgerufen haben und es dadurch default Werte benutzt, die wir aber nicht unbedingt haben wollen. Schauen wir uns aber zuerst den Browserquelltext an.
<ul>
<li class="pagenav">Seiten
<ul>
<li class="page_item">Kontakt
<ul>
<li class="page_item">Impressum</li>
</ul>
</li>
<li class="page_item">über mich</li>
</ul>
</li>
</ul>
Ich habe die Anker entfernt, damit der Quelltext nicht zu lang wird. Wir sehen eine verschachtelte Liste mit all unseren Seiten. Zusätzlich steht „Seiten“ im ersten Listelement. Das zerstört uns natürlich die Navigation.
Als erstes muss die Überschrift weg.
<?php wp_list_pages('title_li=0'); ?>
Das Argument title_li=0 unterdrückt die Ausgabe einer Überschrift.
Dann wollen wir nur die Hauptseiten darstellen.
<?php wp_list_pages('depth=1&title_li=0'); ?>
Mit depth=1 wird die Tiefe der Seitenstruktur auf Level 1 beschränkt. Mehrere Argumente müssen mit & aneinandergereiht werden.
Wir können die Reihenfolge der Sortierung ebenfalls bestimmen.
<?php wp_list_pages('depth=1&title_li=0&sort_column=menu_order'); ?>
Wir können die Seiten auch nach dem Namen sortieren lassen, sort_column=post_name. Ebenfalls ist es möglich Seiten ein- oder auszuschließen:
<?php wp_list_pages('include=1,2,3&depth=1&title_li=0&sort_column=menu_order'); ?>
<?php wp_list_pages('exclude=1,2,3&depth=1&title_li=0&sort_column=menu_order'); ?>
Die Zahlen hinter include oder exclude sind die IDs der betroffenen Seiten. Mehrere Seiten müssen kommagetrennt angegeben werden. Wir schließen hier aber keine Seiten aus. Ihr könnt ja einmal in eurem lokalen Blog mit den Argumenten spielen und dabei schauen, was dabei herauskommt, passieren kann nichts dabei.
Jetzt fehlt aber in der Navigation noch die Startseite des Blogs. Da das keine statische Seite ist, hilft uns wp_list_pages() auch nicht weiter. Das müssen wir manuell erledigen.
<ul>
<li><a href="<?php echo get_option('home'); ?>/" title="Startseite">Home</a></li>
<?php wp_list_pages('depth=1&title_li=0&sort_colunm=menu_order'); ?>
</ul>
get_option(‘home’) liefert den absoluten Pfad zu der Blogstartseite, get_settings(‘home’) ist als deprecated gekennzeichnet und sollte nicht mehr verwendet werden.
Jetzt schauen wir nochmal den Quelltext im Browser an. Wir sehen, das WordPress den Listenelementen, die mit wp_list_pages() erstellt wurden sind, eine Klasse page_item zugeordnet hat. Dazu muß man folgendes wissen: page_item bekommt von wp_list_pages() automatisch jedes Listenelement. Klickt man im Browser nun eine Seite an, bekommt sie zusätzlich die Klasse current_page_item. Diese Klassen nutzen wir um das jeweils aktive Menüelement optisch hervorzuheben. Vorher reparieren wir aber das manuelle Listenelement:
<ul>
<?php if(is_home()) {
$cssclass = 'page_item current_page_item';
}else{
$cssclass = 'page_item';
} ?>
<li class="<?php echo $cssclass; ?>"><a href="<?php echo get_option('home'); ?>/" title="Startseite">Home</a></li>
<?php wp_list_pages('depth=1&title_li=0&sort_colunm=menu_order'); ?>
</ul>
Hier hilft uns wieder der Conditional Tag is_home() weiter.
Jetzt nehmen wir in der basemod.css aus dem Verzeichnis css/screen/noch einige Änderungen vor, da die Klasse page_current_item dort nicht bekannt ist. Die Klasse page_item können wir vernachlässigen, da das der Defaultwert ist. Wir müssen dazu lediglich alle #nav_main ul li#current durch #nav_main ul li.current_page_item ersetzen.
#nav_main ul li.current_page_item { background: transparent }
#nav_main ul li.current_page_item strong,
#nav_main ul li.current_page_item a,
#nav_main ul li.current_page_item a:focus,
#nav_main ul li.current_page_item a:active { color: #4D87C7; font-weight: bold }
#nav_main ul li.current_page_item a:hover { color: #fff; font-weight: bold }
Der Pseudoklasse li.current_page_item a:hover habe ich als Schriftfarbe weiss notiert, weil sie sich dadurch besser abhebt.
Zu wp_list_pages() habe ich schon mal einen Beitrag geschrieben, ihr findet ihn hier.
Die header.php ist nun funktionstüchtig. Änderungen werden wir in einem späteren Teil noch durchführen.
Die footer.php
Da die footer.php eine sehr kleine Datei ist, werde ich sie hier gleich mit unterbringen. Der Code:
<!-- begin: #footer -->
<div id="footer">Footer with copyright notice and status information<br />
Layout based on <a href="http://www.yaml.de/">YAML</a> | Theme YAML basic by <a href="http://dynamicinternet.eu/">dynamicinternet</a>
</div>
<!-- end: #footer -->
</div>
</div>
</body>
</html>
Welche Informationen ihr in eurer Fußleiste unterbringen wollt, darüber dürft ihr euch den Kopf selbst zerbrechen.
Die Auszeichnungen für div #footer stehen in css/screen/basemod.css.Ich für meinen Teil habe die Lizenzhinweise in ein <p> Tag gesetzt und möchte die Anordnung zentriert im Footer. Dazu verwende die Klasse .center, welche in css/screen/content.css schon vordefiniert ist. Oben bei der Skip-Links-Navigation hatte ich schon angesprochen, im Footer noch einen Link zum Beginn des Inhaltsbereiches zu setzten.Den Template Hook wp_footer() müssen wir ebenfalls einbauen. Er hat den selben Zweck wie in der header.php der Hook wp_header(). Hier der endgültige Quellcode der footer.php:
<!-- begin: #footer -->
<div id="footer">
<p class="float_left"><a href="#content" title="zum Seitenanfang springen">nach oben</a></p>
<p class="center">Layout based on <a href="http://www.yaml.de/">YAML</a> | Theme YAML basic by <a href="http://dynamicinternet.eu/">dynamicinternet</a>
<!--<?php echo get_num_queries(); ?> queries. <?php timer_stop(1); ?> seconds.-->
</div>
<!-- end: #footer -->
</div>
</div>
<?php wp_footer(); ?>
</body>
</html>
Die auskommentierte Zeile
<!--<?php echo get_num_queries(); ?> queries. <?php timer_stop(1); ?> seconds.-->
zeigt uns die Anzahl der Datenbankabfragen an und die dazu benötigte Zeit. Zu sehen ist es im Quelltext des Browsers.
Obwohl wir noch nicht einen einzigen Beitrag auf den Schirm gezaubert haben, sind wir schon bei 11 Queries angelangt. Die Anzahl der Queries sollte man bei der Entwicklung seines Themes immer im Auge behalten.
Sollten Fragen auftauchen, Fehler gefunden werden oder auch Anregungen für den Weitergang dieser Serie, bitte das Kommentarformular benutzen.
Den aktuellen Stand werde ich ab jetzt immer am Ende eines jeden Teils zum Download anbieten, da braucht keiner bis zum nächsten Teil warten.
Download Ende Teil 2

Hallo,
Super Anleitung. Noch 2 Anmerkungen:
Hat wohl inzwischen ein Update eingespielt.
(kurz vor “Die footer.php”)
Der Link zeigt ins Leere.
Viele Grüße
Georg
Danke Georg, Robert hat doch tatsächlich ein Update gemacht.
Den Link zur Seitennavigation habe ich gefixt, ein Slash hat gefehlt.
Habe einige Zeit gebraucht, bis ich herausgefunden habe wie “Unterseiten” funktionieren.
Wäre vielleicht einen Hinweis wert, dass man beim Bearbeiten einer Seite im rechten Bereich die übergeordnete Seite bestimmen kann (was die aktuelle Seite dann logischerweise zu einer untergeordneten Seite der übergeordneten Seite macht
sorry Christian, hätte ich machen sollen.
Das war keinesfalls ein Vorwurf, sondern nur eine Anregung. Ist es doch immer wieder erstaunlich, wie viel man selber weiss, was ungeübte Benutzer vielleicht nicht wissen.
Deine Serie ist auf alle Fälle sehr aufschlussreich und hilfreich. Ich beginne die Philosophie und Methode von WordPress und Themes etc. nun langsam zu verstehen. Echt genial deine Step by Step Erklärung. Zusammen mit Peruns WordPress-Themes verstehen eine wirklich sensationelle Hilfe. Danke!
Sehr schönes Tutorial, Micha, bekommst ein dickes Lob von mir!
Kleiner Hinweis:
In den Inhaltsverzeichnissen von Teil 1-3 stimmen die Links nicht, ich lande auf Deiner Admin-Seite.
Danke Martin!
Ich habe jetzt absolute Pfade ins Inhaltsverzeichnis gepackt. Irgendwie verhaut der Editor die kurzen Verweise.
Klasse tutorial – an dem Problem Hervorhebung page_item / current_page_item habe ich geschlagene 2 Tage ohne Lösung herumgedoktort. Jetzt funktionierts endlich und ich kann bald mein erstes komplett handgecodetes wp-theme nutzen. Thanks!
Ein Hinweis: in der header.php wird fälschlicherweise get_bloginfo(…) verwendet, welches zwar die Information zurückliefert, aber nicht ausgibt.
Da muß enweder ein “echo” vor, oder man verwendet bloginfo(…).
Sorry Christoph, ich seh den Fehler nicht. Kannst du ihn bitte genauer beschreiben?
Im Absatz “Der Titel” z.B., dort steht (ich hoffe das HTML kommt durch):
get_bloginfo(‘name’) liefert zwar den Wert zurück, gibt ihn aber nicht direkt aus. Das holen und direkte ausgeben in die Seite ist über bloginfo(‘name’) möglich (also ohne get_ Präfix.)
Es muß also entweder
heissen, oder
Argh,
HTML kam natürlich nicht durch, also auf die kurze Art:
Statt
get_bloginfo('name')muß im PHP Statement entwederecho get_bloginfo('name')oder einfach nurbloginfo('name')stehenAh danke! Habs korrigiert.
hat einer eine idee wie man das submenue in diesem beispiel auslagern kann z.b. in die sidebar oder in ein DIV unter die hauptnavigation? und das die submenue-punkte nur erscheinen wenn man ein parent angeklickt hat?