Skip to content

Instantly share code, notes, and snippets.

@florianbrinkmann
Created November 13, 2018 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save florianbrinkmann/4e9e4d23eaefb8b23484badddd848196 to your computer and use it in GitHub Desktop.
Save florianbrinkmann/4e9e4d23eaefb8b23484badddd848196 to your computer and use it in GitHub Desktop.
Für meine Bachelorarbeit im Studiengang Informationsmanagement habe ich das Thema „Entwicklung eines WordPress-Themes mit Zielgruppe Fotografen“ gewählt – die Arbeit beschäftigt sich detailliert mit der Erstellung des <a href="https://florianbrinkmann.com/wordpress-themes/hannover/">Hannover-Themes</a>. Weil das Thema gut zu den anderen Themen dieses Blogs passt, möchte ich sie an dieser Stelle veröffentlichen.<!--more-->
<em><a href="https://florianbrinkmann.com/wp-content/uploads/2016/02/bachelorarbeit-final.pdf">PDF-Version mit Deckblatt, allen Verzeichnissen et cetera</a></em>
<h2>Abstract</h2>
Die vorliegende Arbeit befasst sich mit der Entwicklung eines WordPress-Themes mit der Zielgruppe Fotografen unter besonderer Berücksichtigung der Richtlinien, die für das offizielle Theme-Verzeichnis erfüllt werden müssen. Dabei werden zuerst die Anforderungen an das Theme ermittelt – sowohl durch die Zielgruppe als auch durch das Theme-Verzeichnis. Anschließend beschäftigt sich die Arbeit mit der Untersuchung bereits bestehender Themes auf diese Funktionen hin, wobei keins der untersuchten alle Funktionen vorweist.
Der größte Teil der Arbeit widmet sich der konkreten Programmierung des Themes, wobei der Code detailliert erläutert wird. Abschließend wird das Theme für die kostenlose Bereitstellung in das <em>WordPress Theme Directory</em> hochgeladen und der damit einhergehende Review-Prozess sowie die notwendigen Korrekturen behandelt.
<h2 id="inhaltsverzeichnis">Inhaltsverzeichnis</h2>
<ol style="list-style-type: none;">
<li>1 <a href="#einleitung">Einleitung</a></li>
<li>2 <a href="#anforderungen-an-das-wordpress-theme">Anforderungen an das WordPress-Theme</a>
<ol style="list-style-type: none;">
<li>2.1 <a href="#funktionen">Funktionen</a>
<ol style="list-style-type: none;">
<li>2.1.1 <a href="#trennung-von-portfolio-elementen-und-blogbeitraegen">Trennung von Portfolio-Elementen und Blogbeiträgen</a></li>
<li>2.1.2 <a href="#galerie-als-slider-oder-einzelne-bilder-anzeigen">Galerie als Slider oder einzelne Bilder anzeigen</a></li>
<li>2.1.3 <a href="#slider-oder-zufaelliges-bild-auf-der-startseite">Slider oder zufälliges Bild auf der Startseite</a></li>
<li>2.1.4 <a href="#uebersicht-aller-arbeiten-auf-einer-seite-und-archiv">Übersicht aller Arbeiten auf einer Seite und Archiv</a></li>
<li>2.1.5 <a href="#kategorie-seiten-fuer-arbeiten">Kategorie-Seiten für Arbeiten</a></li>
<li>2.1.6 <a href="#verschiedene-darstellungsmoeglichkeiten-fuer-portfolio-und-kategorie-uebersicht">Verschiedene Darstellungsmöglichkeiten für Portfolio- und Kategorie-Übersicht</a></li>
</ol>
</li>
<li>2.2 <a href="#regeln-und-richtlinien-des-theme-verzeichnisses">Regeln und Richtlinien des Theme-Verzeichnisses</a>
<ol style="list-style-type: none;">
<li>2.2.1 <a href="#erforderliche-regeln">Erforderliche Regeln</a></li>
<li>2.2.2 <a href="#empfohlene-regeln">Empfohlene Regeln</a></li>
</ol>
</li>
</ol>
</li>
<li>3 <a href="#analyse-bereits-vorhandener-fotografen-themes">Analyse bereits vorhandener Fotografen-Themes</a>
<ol style="list-style-type: none;">
<li>3.1 <a href="#kostenlose-themes-im-theme-verzeichnis">Kostenlose Themes im Theme-Verzeichnis</a></li>
<li>3.2 <a href="#kostenpflichtige-themes-von-themeforest">Kostenpflichtige Themes von ThemeForest</a></li>
</ol>
</li>
<li>4 <a href="#vorbereitung-auf-die-theme-entwicklung">Vorbereitung auf die Theme-Entwicklung</a>
<ol style="list-style-type: none;">
<li>4.1 <a href="#debug-modus">Debug-Modus</a></li>
<li>4.2 <a href="#entwickler-plugins">Entwickler-Plugins</a></li>
<li>4.3 <a href="#test-daten">Test-Daten</a></li>
</ol>
</li>
<li>5 <a href="#entwicklung-des-wordpress-themes">Entwicklung des WordPress-Themes</a>
<ol style="list-style-type: none;">
<li>5.1 <a href="#template-hierarchie-in-wordpress">Template-Hierarchie in WordPress</a>
<ol style="list-style-type: none;">
<li>5.1.1 <a href="#archiv-seite-mit-beispiel">Archiv-Seite mit Beispiel</a></li>
<li>5.1.2 <a href="#einzelseite">Einzelseite</a></li>
<li>5.1.3 <a href="#startseite-der-website-blog-uebersicht-kommentar-pop-up-404-seite-und-suchergebnisse">Startseite der Website, Blog-Übersicht, Kommentar-Pop-Up, 404-Seite und Suchergebnisse</a></li>
</ol>
</li>
<li>5.2 <a href="#hooks-in-wordpress">Hooks in WordPress</a>
<ol style="list-style-type: none;">
<li>5.2.1 <a href="#action-hooks">Action-Hooks</a></li>
<li>5.2.2 <a href="#filter-hooks">Filter-Hooks</a></li>
</ol>
</li>
<li>5.3 <a href="#customizer">Customizer</a></li>
<li>5.4 <a href="#metadaten-des-themes-in-der-style-css">Metadaten des Themes in der style.css</a></li>
<li>5.5 <a href="#kopfbereich-des-themes-in-der-header-php">Kopfbereich des Themes in der header.php</a>
<ol style="list-style-type: none;">
<li>5.5.1 <a href="#unsichtbarer-teil-des-headers">Unsichtbarer Teil des Headers</a></li>
<li>5.5.2 <a href="#skip-to-content-link">Skip-To-Content-Link</a></li>
<li>5.5.3 <a href="#sichtbarer-header">Sichtbarer Header</a></li>
</ol>
</li>
<li>5.6 <a href="#theme-support-fuer-post-formate-feed-links-title-tag-beitragsbilder-header-bild-und-html5">Theme-Support für Post-Formate, Feed-Links, Title-Tag, Beitragsbilder, Header-Bild und HTML5</a></li>
<li>5.7 <a href="#blog-uebersicht">Blog-Übersicht</a></li>
<li>5.8 <a href="#vorschau-eines-normalen-beitrags">Vorschau eines normalen Beitrags</a>
<ol style="list-style-type: none;">
<li>5.8.1 <a href="#titel-ausgeben">Titel ausgeben</a></li>
<li>5.8.2 <a href="#datum-und-uhrzeit-ausgeben">Datum und Uhrzeit ausgeben</a></li>
<li>5.8.3 <a href="#inhalt-mit-angepasstem-weiterlesen-link">Inhalt mit angepasstem Weiterlesen-Link</a></li>
<li>5.8.4 <a href="#meta-daten-im-footer-des-beitrags">Meta-Daten im Footer des Beitrags</a></li>
</ol>
</li>
<li>5.9 <a href="#die-sidebar">Die Sidebar</a></li>
<li>5.10 <a href="#der-footer-des-themes">Der Footer des Themes</a></li>
<li>5.11 <a href="#archiv-ansicht">Archiv-Ansicht</a></li>
<li>5.12 <a href="#suchergebnis-template">Suchergebnis-Template</a></li>
<li>5.13 <a href="#einzelansicht-von-seiten">Einzelansicht von Seiten</a></li>
<li>5.14 <a href="#einzelansicht-von-beitraegen">Einzelansicht von Beiträgen</a></li>
<li>5.15 <a href="#kommentarbereich">Kommentarbereich</a>
<ol style="list-style-type: none;">
<li>5.15.1 <a href="#anzeige-der-kommentare">Anzeige der Kommentare</a></li>
<li>5.15.2 <a href="#anzeige-der-trackbacks">Anzeige der Trackbacks</a></li>
</ol>
</li>
<li>5.16 <a href="#404-template">404-Template</a></li>
<li>5.17 <a href="#portfolio-uebersicht">Portfolio-Übersicht</a>
<ol style="list-style-type: none;">
<li>5.17.1 <a href="#option-zur-auswahl-der-portfolio-kategorie">Option zur Auswahl der Portfolio-Kategorie</a></li>
<li>5.17.2 <a href="#option-zum-auschluss-der-portfolio-elemente-vom-blog">Option zum Ausschluss der Portfolio-Elemente vom Blog</a></li>
<li>5.17.3 <a href="#option-zum-festlegen-der-anzahl-von-portfolio-elementen-auf-einer-seite">Option zum Festlegen der Anzahl von Portfolio-Elementen auf einer Seite</a></li>
<li>5.17.4 <a href="#portfolio-elemente-auf-einer-seite-anzeigen">Portfolio-Elemente auf einer Seite anzeigen</a></li>
<li>5.17.5 <a href="#portfolio-elemente-vom-blog-ausschliessen">Portfolio-Elemente vom Blog ausschließen</a></li>
</ol>
</li>
<li>5.18 <a href="#archiv-ansicht">Archiv-Ansicht</a>
<ol style="list-style-type: none;">
<li>5.18.1 <a href="#optionen-fuer-die-archiv-funktion">Optionen für die Archiv-Funktion</a></li>
<li>5.18.2 <a href="#archiv-elemente-auf-einer-seite-anzeigen">Archiv-Elemente auf einer Seite anzeigen</a></li>
<li>5.18.3 <a href="#archiv-elemente-aus-der-portfolio-uebersicht-ausschliessen">Archiv-Elemente aus der Portfolio-Übersicht ausschließen</a></li>
</ol>
</li>
<li>5.19 <a href="#kategorie-seiten-fuer-portfolio-elemente">Kategorie-Seiten für Portfolio-Elemente</a>
<ol style="list-style-type: none;">
<li>5.19.1 <a href="#optionen-fuer-portfolio-seiten">Optionen für Portfolio-Seiten</a></li>
<li>5.19.2 <a href="#portfolio-elemente-einer-kategorie-anzeigen">Portfolio-Elemente einer Kategorie anzeigen</a></li>
</ol>
</li>
<li>5.20 <a href="#alternatives-layout-fuer-portfolio-elemente">Alternatives Layout für Portfolio-Elemente</a>
<ol style="list-style-type: none;">
<li>5.20.1 <a href="#alternatives-layout-in-portfolio-uebersicht">Alternatives Layout in Portfolio-Übersicht</a></li>
<li>5.20.2 <a href="#alternatives-layout-im-archiv">Alternatives Layout im Archiv</a></li>
<li>5.20.3 <a href="#alternatives-layout-fuer-portfolio-kategorie-seiten">Alternatives Layout für Portfolio-Kategorie-Seiten</a></li>
</ol>
</li>
<li>5.21 <a href="#einzelansicht-von-portfolio-elementen">Einzelansicht von Portfolio-Elementen</a></li>
<li>5.22 <a href="#portfolio-und-archiv-kategorien-vom-widget-ausschliessen">Portfolio- und Archiv-Kategorien vom Widget ausschließen</a>
<ol style="list-style-type: none;">
<li>5.22.1 <a href="#optionen-fuer-ausschluss-der-portfolio-und-archiv-kategorie-im-customizer">Optionen für Ausschluss der Portfolio- und Archiv-Kategorie im Customizer</a></li>
<li>5.22.2 <a href="#entfernen-der-kategorien-aus-dem-widget">Entfernen der Kategorien aus dem Widget</a></li>
</ol>
</li>
<li>5.23 <a href="#seiten-template-ohne-sidebar">Seiten-Template ohne Sidebar</a></li>
<li>5.24 <a href="#seiten-templates-fuer-die-startseite">Seiten-Templates für die Startseite</a>
<ol style="list-style-type: none;">
<li>5.24.1 <a href="#slider-auf-der-startseite">Slider auf der Startseite</a></li>
<li>5.24.2 <a href="#zufaelliges-bild-auf-der-startseite">Zufälliges Bild auf der Startseite</a></li>
</ol>
</li>
<li>5.25 <a href="#galerien-als-slider-oder-einzelne-bilder">Galerien als Slider oder einzelne Bilder</a></li>
<li>5.26 <a href="#vorschau-eines-galerie-oder-bild-beitrags">Vorschau eines Galerie- oder Bild-Beitrags</a></li>
<li>5.27 <a href="#read-more-sprung-verhindern">Read-More-Sprung verhindern</a></li>
<li>5.28 <a href="#menue">Menü</a></li>
<li>5.29 <a href="#footer-bereich-erweitern">Footer-Bereich erweitern</a>
<ol style="list-style-type: none;">
<li>5.29.1 <a href="#social-media-menue">Social-Media-Menü</a></li>
<li>5.29.2 <a href="#footer-menue-und-theme-autor-hinweis">Footer-Menü und Theme-Autor-Hinweis</a></li>
</ol>
</li>
<li>5.30 <a href="#design">Design</a>
<ol style="list-style-type: none;">
<li>5.30.1 <a href="#notwendige-css-selektoren">Notwendige CSS-Selektoren</a></li>
<li>5.30.2 <a href="#lightbox-einbinden">Lightbox einbinden</a></li>
<li>5.30.3 <a href="#schrift">Schrift</a></li>
<li>5.30.4 <a href="#inhaltsbreite-definieren-und-grosse-bildgroesse-anpassen">Inhaltsbreite definieren und große Bildgröße anpassen</a></li>
<li>5.30.5 <a href="#screenshot">Screenshot</a></li>
</ol>
</li>
<li>5.31 <a href="#readme">Readme</a></li>
<li>5.32 <a href="#uebersetzung">Übersetzung</a></li>
<li>5.33 <a href="#dokumentation">Dokumentation</a></li>
<li>5.34 <a href="#child-theme-check">Child-Theme-Check</a></li>
</ol>
</li>
<li>6 <a href="#upload-und-review-korrekturen-des-themes">Upload und Review-Korrekturen des Themes</a>
<ol style="list-style-type: none;">
<li>6.1 <a href="#upload-ins-theme-verzeichnis">Upload ins Theme-Verzeichnis</a></li>
<li>6.2 <a href="#korrekturen">Korrekturen</a>
<ol style="list-style-type: none;">
<li>6.2.1 <a href="#notwendig">Notwendig</a></li>
<li>6.2.2 <a href="#stark-empfohlen">Stark Empfohlen</a></li>
<li>6.2.3 <a href="#empfohlen">Empfohlen</a></li>
</ol>
</li>
</ol>
</li>
<li>7 <a href="#fazit">Fazit</a></li>
<li><a href="#literaturverzeichnis">Literaturverzeichnis</a></li>
<li><a href="#anhang-a">Anhang A: Preisträger-Websites des Photo Contest von der World Press Photo Foundation</a></li>
<li><a href="#anhang-b">Anhang B: Untersuchung der kostenlosen WordPress-Themes</a></li>
<li><a href="#anhang-c">Anhang C: Untersuchung der kostenpflichtigen Themes</a></li>
<li><a href="#anhang-d">Anhang D: Template-Hierarchie in WordPress-Themes</a></li>
</ol>
<h2 id="einleitung">1 Einleitung</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<strong>Ausgangssituation</strong>
Die vorliegende Arbeit setzt sich mit der Entwicklung eines Themes für das Content-Management-System WordPress auseinander, das die Zielgruppe Fotografen ansprechen soll. Nach Fertigstellung soll das Theme in das offizielle Theme-Verzeichnis aufgenommen werden und kostenlos zur Verfügung stehen. Besondere Aufmerksamkeit wird auf die Aspekte gelegt, die für eine Aufnahme in das Verzeichnis erfüllt werden müssen.
<strong>Forschungsstand</strong>
Da das Thema im Bereich der Webentwicklung angesiedelt ist, lässt sich kaum aktuelle Printliteratur finden. Diese Situation ist der Tatsache geschuldet, dass der Fortschritt in den Bereichen Webentwicklung und WordPress zu schnell ist, um den aktuellen Stand in einem Buch festzuhalten. Besser geeignet sind Online-Dokumentationen, die das jeweilige Thema umfangreich und aktuell beleuchten können.
Für die Funktionen, Klassen und Hooks von WordPress liegt eine umfangreiche Referenz vor.<a href="#_ftn1" name="_ftnref1">[1]</a> Die Voraussetzungen, die ein Theme für das Theme-Verzeichnis erfüllen muss, sind im Handbuch des Theme-Review-Teams zu finden.<a href="#_ftn2" name="_ftnref2">[2]</a> Für CSS, HTML und JavaScript können viele Lösungen und Erläuterungen in den jeweiligen Dokumentationen von Mozilla gefunden werden.<a href="#_ftn3" name="_ftnref3">[3]</a> Wenn der Einsatz von PHP-Funktionen, -Klassen oder ähnlichem notwendig wird, ist die erste Anlaufstelle das PHP-Handbuch.<a href="#_ftn4" name="_ftnref4">[4]</a>
<strong>Fragestellung und Zielsetzung</strong>
Die Zielsetzung der Bachelorarbeit besteht in der Entwicklung eines WordPress-Themes für Fotografen, das in das offizielle Theme-Verzeichnis hochgeladen wird und somit kostenlos zur Verfügung steht. Damit können Fotografen, Foto-Blogger und andere Nutzer sich und ihre Arbeit bestmöglich im Web präsentieren. Darüber hinaus wird das Ergebnis der Arbeit als Referenz für meine spätere Tätigkeit in diesem Bereich dienen.
Als Fragestellung wurde im Studienabschlussseminar formuliert: „Welche Funktionen sollte ein kostenloses WordPress-Theme für Fotografen auf jeden Fall bieten?“ Diese Frage muss in jedem Fall beantwortet werden um zu begründen, warum bestimmte Funktionen in das WordPress-Theme integriert werden.
Im Gespräch mit dem Zweitbetreuer der Arbeit, Herrn Kreutzmann, wurde eine weitere Frage aufgeworfen, mit der sich die Arbeit detailliert auseinandersetzen sollte: „Welche Voraussetzungen müssen erfüllt werden, damit ein WordPress-Theme mit Nutzeranforderung in das Theme-Verzeichnis aufgenommen wird?“. Mit dieser Frage im Hinterkopf wird sich die Arbeit genau mit den Anforderungen und Richtlinien beschäftigen, die ein Theme für die Aufnahme in das Verzeichnis erfüllen muss.
<strong>Methodische Vorüberlegungen</strong>
Die Bachelorarbeit hat einen hohen Praxisbezug, sie beschäftigt sich zum größten Teil detailliert mit der Programmierung des Themes. Davor steht die Beantwortung der Frage nach den Funktionen, die Fotografen benötigen, sowie einer Analyse bestehender WordPress-Themes bezüglich dieser Funktionen.
Um die Frage zu beantworten, welche Funktionen ein WordPress-Theme für Fotografen erfüllen muss, wird eine Analyse von Fotografen-Seiten durchgeführt. Ein Experten-Interview, wie im Studienabschlussseminar als Lösung festgehalten, hat sich als nicht besonders geeignet herausgestellt. Zu diesem Eindruck haben die – natürlich – sehr subjektiven Antworten des befragten Experten geführt. Ein besserer Weg dürfte hier die Analyse von praktischen Beispielen sein.
Damit nicht zufällig irgendwelche Fotografen-Seiten ausgewählt werden, sind die Websites der Preisträger von dem Photo Contest 2015 der World Press Photo Foundation Gegenstand dieser Analyse.<a href="#_ftn5" name="_ftnref5">[5]</a> Auch wenn nicht alle Preisträger eine Website betreiben, verbleiben 28 für die Analyse.
Nach der Analyse müssen die bereits vorhandenen kostenlosen Themes untersucht werden um auszuschließen, dass es ein solches Theme bereits gibt. Dabei wird das Angebot des offiziellen Theme-Verzeichnissess als Untersuchungsobjekt verwendet.<a href="#_ftn6" name="_ftnref6">[6]</a> Zudem werden kostenpflichtige Themes begutachtet – auch wenn diese Themes keine direkte Konkurrenz darstellen.
<strong>Aufbau der Arbeit</strong>
Zunächst behandelt die Arbeit die verschiedenen Anforderungen an das Theme, die sowohl aus der Analyse der bestehenden Websites als auch aus den Richtlinien und Regeln des Theme-Verzeichnisses hervorgehen. Darauf folgen die Analyse der bereits vorhandenen kostenlosen und einiger kostenpflichtigen Themes aus dem Bereich sowie die Vorbereitung auf die Entwicklung mit nützlichen Einstellungen, Plugins und Test-Daten. Im Anschluss befasst sich der größte Teil der Arbeit mit der Entwicklung des Themes, gefolgt von der Einarbeitung von Review-Korrekturen.
<h2 id="anforderungen-an-das-wordpress-theme">2 Anforderungen an das WordPress-Theme</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
An das WordPress-Theme werden von verschiedenen Seiten Anforderungen gestellt. Auf der einen Seite sind das die der Zielgruppe, also der Fotografen, die bestimmte Funktionen erwarten. Auf der anderen Seite werden bestimmte Anforderungen an Themes gestellt, die in das Theme-Verzeichnis von WordPress.org aufgenommen werden sollen.
<h3 id="funktionen">2.1 Funktionen</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um herauszufinden, welche Funktionen ein Fotograf in einem WordPress-Theme oder allgemein einer Website benötigt, bietet sich die Analyse von bestehenden Websites an. Hierzu wurden die Internetauftritte der Preisträger des Photo Contest 2015 untersucht, der von der World Press Photo Foundation veranstaltet wird.
Von den 41 verschiedenen Preisträgern konnten für 28 Websites ausfindig gemacht werden.<a href="#_ftn7" name="_ftnref7">[7]</a> Aus der Untersuchung dieser Seiten, die der Arbeit im Anhang A beiliegt, ergeben sich die folgenden Funktionen, die das WordPress-Theme mitbringen sollte, um für eine möglichst große Zahl von Nutzern aus der Zielgruppe interessant zu sein.
<h4 id="trennung-von-portfolio-elementen-und-blogbeitraegen">2.1.1 Trennung von Portfolio-Elementen und Blogbeiträgen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Auf den Fotografen-Websites, die ein Blog beinhalten, sind die Portfolio-Elemente streng davon getrennt. Für das Erstellen von Portfolio-Elementen bieten sich in WordPress allerdings eher die Beiträge als die Seiten an, da diese auch kategorisiert werden können.
Hier muss demnach eine Funktion integriert werden, die es dem Nutzer des Themes erlaubt, bestimmte Beiträge aus dem Blog auszuschließen. Das sollte aber nicht die Standard-Lösung sein, damit die Portfolio-Elemente auch im Blog angezeigt werden können. Hier könnte mit einer Kategorie oder einem Tag gearbeitet werden, die der Nutzer für Beiträge, die nicht im Blog aufgeführt werden sollen, vergeben muss. Ebenfalls denkbar wäre eine Option, dass alle Beiträge vom Post-Format <em>Galerie</em> und <em>Bild</em> aus dem Blog ausgeschlossen werden können.
<h4 id="galerie-als-slider-oder-einzelne-bilder-anzeigen">2.1.2 Galerie als Slider oder einzelne Bilder anzeigen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Im Grunde gibt es zwei Varianten, wie mehrere Bilder einer Serie auf den untersuchten Websites angezeigt werden: Entweder in einem Slider oder als einzelne Bilder, die meist vergrößert in einer Lightbox angezeigt werden können. Die einzelnen Bilder werden als Thumbnails dargestellt, die nach einem Klick das große Bild in einer Lightbox anzeigen oder einfach in voller Größe untereinander.
Dem Nutzer müssen demnach diese zwei Möglichkeiten geboten werden. Um die größte Flexibilität zu erreichen, müsste diese Einstellung für jeden Beitrag möglich sein. Einfacher und realistischer ist eine generelle Einstellung, sodass alle Galerien entweder als Slider oder als einzelne Bilder dargestellt werden.
<h4 id="slider-oder-zufaelliges-bild-auf-der-startseite">2.1.3 Slider oder zufälliges Bild auf der Startseite</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Neben einer normalen Inhaltsseite als Startseite haben einige Websites aus der Untersuchung einen Slider eingebaut. Eine Seite hat nur ein Bild angezeigt, dieses aber bei einem erneuten Seitenaufruf zufällig geändert. Dieses Verhalten lässt sich mit zwei verschiedenen Page-Templates erreichen.
<h4 id="uebersicht-aller-arbeiten-auf-einer-seite-und-archiv">2.1.4 Übersicht aller Arbeiten auf einer Seite und Archiv</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Auf mehreren Websites werden auf einer Seite alle Serien oder Galerien des Fotografen angezeigt. Das ist meist ein Bild, der Titel und eventuell beschreibender Text, der dann auf die Einzelansicht der Arbeit verlinkt. Auch dafür ist die Lösung der Wahl ein Page-Template.
Als weitere Funktion in diesem Zusammenhang ist mehrfach ein Archiv verwendet worden, wie in Abbildung 1 zu sehen ist. Der Fotograf muss also Galerien markieren können, sodass sie nicht mehr in dieser Übersicht, sondern separat in einem Archiv aufgeführt werden. Hier kann wieder – wie bei den Beiträgen, die nicht im Blog angezeigt werden sollen – mit einer Kategorie beziehungsweise einem Tag gearbeitet werden.
[caption id="attachment_2238" align="alignnone" width="718"]<img class="size-full wp-image-2238" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/screenshot-portfolio-uebersicht-mit-archivlink.png" alt="Abbildung 1: Übersicht der Arbeiten mit Archiv-Link auf der Website von Tomas van Houtryve Quelle: Screenshot von tomasvh.com am 1. November 2015" width="718" height="605" /> Abbildung 1: Übersicht der Arbeiten mit Archiv-Link auf der Website von Tomas van Houtryve<br />Quelle: Screenshot von tomasvh.com am 1. November 2015[/caption]
<h4 id="kategorie-seiten-fuer-arbeiten">2.1.5 Kategorie-Seiten für Arbeiten</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Auf einer Website hat der Fotograf im Menü seine Arbeiten nach Kategorien verlinkt, damit der Besucher sich nur die aus einer Kategorie anzeigen lassen kann. Die Darstellung der Kategorie-Übersicht findet auf ähnliche Weise statt, wie die Übersicht aller Galerien.
Auch hier wird wieder ein Seiten-Template zum Einsatz kommen. Für jede Seite mit diesem Seiten-Template wird im Customizer, der in WordPress Anpassungen mit einer Live-Vorschau ermöglicht, dann eine Option angezeigt, mit der die Kategorie festgelegt werden kann, aus der die Galerien angezeigt werden sollen.
<h4 id="verschiedene-darstellungsmoeglichkeiten-fuer-portfolio-und-kategorie-uebersicht">2.1.6 Verschiedene Darstellungsmöglichkeiten für Portfolio- und Kategorie-Übersicht</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Verweise auf die einzelnen Arbeiten werden auf den untersuchten Websites in verschiedenen Arten dargestellt. Ein Beispiel ist da die Website von Tomas van Houtryve aus Abbildung 1, die neben Titel und Bild noch einen Text anzeigt. In Abbildung 2 ist die Website von Sergei Ilnitsky zu sehen, auf der standardmäßig nur Thumbnails zu den Serien gezeigt werden. Der Titel wird beim Hovern mit der Maus eingeblendet, was auf Touchscreens allerdings nicht funktioniert und deshalb nicht optimal ist.
[caption id="attachment_2239" align="alignnone" width="800"]<img class="size-large wp-image-2239" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/screenshot-portfolio-uebersicht-800x519.png" alt="Abbildung 2: Übersicht des Portfolios von Sergei Ilnitsky. Quelle: Screenshot von ilnitsky-photography.com am 1. November 2015" width="800" height="519" /> Abbildung 2: Übersicht des Portfolios von Sergei Ilnitsky.<br />Quelle: Screenshot von ilnitsky-photography.com am 1. November 2015[/caption]
Diese zwei Varianten sollte der Nutzer des Themes mindestens auswählen können: Entweder werden die Verweise auf die Einzelansichten mit Titel, Bild und Beschreibung angezeigt, oder nur mit Thumbnail.
<h3 id="regeln-und-richtlinien-des-theme-verzeichnisses">2.2 Regeln und Richtlinien des Theme-Verzeichnisses</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um in das Theme-Verzeichnis von WordPress.org aufgenommen zu werden, muss ein WordPress-Theme bestimmte Regeln erfüllen. Hier gibt es zwei Abstufungen: Einerseits gibt es verbindliche Regeln, deren Verletzung ein Ausschlusskriterium darstellt.<a href="#_ftn8" name="_ftnref8">[8]</a> Andererseits gibt es noch sogenannte <em>Best-Practices</em>, deren Einhaltung empfohlen, bei deren Verletzung ein Theme aber nicht ausgeschlossen wird.<a href="#_ftn9" name="_ftnref9">[9]</a>
<h4 id="erforderliche-regeln">2.2.1 Erforderliche Regeln</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<strong>Code</strong>
Der Code eines WordPress-Themes darf keine PHP- oder JavaScript-Fehler auswerfen. Darüber hinaus muss ein Theme einen validen Doctype sowie das <code class="lang-markup">lang</code>-Attribut enthalten. Zudem müssen Benutzereingaben bereinigt werden und es dürfen keine Hooks verändert oder entfernt werden, die nichts mit der Präsentation und damit den Aufgaben eines Themes zu tun haben.
Außerdem muss das Theme den Test mit dem Theme-Check-Plugin bestehen und seine Funktionen, globale Variablen, Konstanten, et cetera, die im globalen Namensraum definiert werden, mit einem einzigartigen Präfix kennzeichnen, damit es keine versehentlichen Namensgleichheiten mit anderen Funktionen gibt.<a href="#_ftn10" name="_ftnref10">[10]</a>
<strong>Core-Funktionalität und Funktionen</strong>
Wenn vorhanden, müssen Themes zuerst Funktionalitäten aus dem WordPress-Core verwenden. Themes dürfen keine Hinweise im Backend einbinden, die auf eine Funktion des Themes verweisen und keine WordPress-eigenen Funktionen hinter einer Paywall verstecken oder die Admin-Toolbar deaktivieren. Darüber hinaus ist es Theme-Entwicklern nicht erlaubt, den Pfad zum Theme mit <code class="lang-php">TEMPLATEPATH</code> und den Pfad zum Stylesheet mit <code class="lang-php">STYLESHEETPATH</code> auszugeben. Hierfür gibt es die beiden Funktionen <code class="lang-php">get_template_directory()</code> sowie <code class="lang-php">get_stylesheet_directory()</code>.
Daneben sollten Änderungen am Inhalt nicht fest im Code verankert sein, sondern über Funktionsparameter, Filter- oder Action-Hooks umgesetzt werden, und es muss möglich sein, für das Theme ein Child-Theme anzulegen. Das Kommentar-Template eines Themes muss über die <code class="lang-php">comments_template()</code>-Funktion eingebunden sein und Theme-Tags sowie die Beschreibung müssen zutreffend für Funktionen und Design des Themes gewählt beziehungsweise formuliert werden. Template-Tags sowie Action- und Filter-Hooks müssen im Theme korrekt eingesetzt werden.<a href="#_ftn11" name="_ftnref11">[11]</a>
<strong>Präsentation versus Funktion</strong>
Dieser Abschnitt ist im Handbuch etwas knapp gehalten und fordert lediglich, dass Themes keine Nutzerinhalte generieren sowie keine Optionen oder Funktionen integrieren dürfen, die nicht im Bereich der Themes angesiedelt sind.<a href="#_ftn12" name="_ftnref12">[12]</a>
Justin Tadlock, einer der Admins aus dem Theme-Review-Team, verdeutlicht diesen Punkt in einem Kommentar. Mit diesem Absatz sei gemeint, dass Custom-Post-Types, Custom-Taxonomies und Shortcodes nicht erlaubt sind.<a href="#_ftn13" name="_ftnref13">[13]</a>
<strong>Dokumentation und Übersetzungsfähigkeit</strong>
Theme-Entwickler sollen Besonderheiten ihres Themes ausreichend dokumentieren. Dazu gehören beispielsweise Limitierungen bei Menü-Items oder eigene Funktionen, die das Theme mitbringt.<a href="#_ftn14" name="_ftnref14">[14]</a> Überdies müssen alle Strings des Themes übersetzbar sein. Zudem muss eine Text-Domain in der <code class="lang-markup">style.css</code> festgelegt werden, die auch als Theme-Slug für die Übersetzungen fungiert. In welcher Sprache das Theme in das Theme-Verzeichnis hochgeladen wird, ist egal – diese Sprache muss aber für alle Strings verwendet werden.<a href="#_ftn15" name="_ftnref15">[15]</a> Da der WordPress-Core amerikanisches Englisch als Standard-Sprache nutzt, ist es am sinnvollsten, für das Theme ebenfalls diese Sprache zu nutzen.<a href="#_ftn16" name="_ftnref16">[16]</a>
Für die Übersetzung gibt es in WordPress verschiedene Funktionen.&gt;<a href="#_ftn17" name="_ftnref17">[17]</a> Diese teilen sich grob in die Gruppen mit und ohne Kontext auf. Die Funktionen erwarten immer als ersten Parameter den String, der übersetzt werden soll, und als letzten die Text-Domain des Themes. Dazwischen kommt bei den Kontext-Funktionen der Kontext, damit gleiche Wörter mit unterschiedlichen Bedeutungen, wie der englische Begriff <em>Post</em>, mehrfach im Übersetzungs-Tool aufgeführt werden. Andernfalls könnte <em>Post</em> nur einmal übersetzt werden – entweder als <em>Beitrag</em> oder <em>Veröffentlichen</em>.<a href="#_ftn18" name="_ftnref18">[18]</a> Um eine Beschreibung für Übersetzer zu hinterlegen, wofür ein String genau steht, kann ein PHP-Kommentar mit <code class="lang-php">translators:</code> am Anfang genutzt werden. Dieser muss der letzte Kommentar vor Aufruf der Übersetzungsfunktion sein.<a href="#_ftn19" name="_ftnref19">[19]</a>
<strong>Lizenzierung und Theme-Name</strong>
Das Theme und die verwendeten Skripte, Bilder und andere Ressourcen müssen zu 100 Prozent unter der GPL oder einer kompatiblen Lizenz stehen. Darüber hinaus muss die Lizenz in der <code class="lang-markup">style.css</code> angegeben werden, ebenso wie die URL zu der Lizenz. Auch die Lizenzen von verwendeten Schriften, Bildern und Skripten müssen ersichtlich sein. Der komplette Code und das Design des Themes müssen vom Entwickler stammen oder ihm legal gehören.<a href="#_ftn20" name="_ftnref20">[20]</a>
Bei der Namensgebung des Themes muss beachtet werden, dass die Begriffe <em>WordPress</em> oder <em>Theme</em> nicht verwendet werden. In allen öffentlich sichtbaren Texten muss WordPress korrekt geschrieben werden – mit großem <em>W</em> und <em>P</em>.<a href="#_ftn21" name="_ftnref21">[21]</a>
<strong>Optionen und Einstellungen</strong>
Optionen des Themes müssen in einem einzelnen Array gespeichert werden. Hinzu kommt, dass Standardwerte nicht in der Datenbank, sondern nur als sogenannte <em>sane defaults</em> gespeichert werden dürfen.<a href="#_ftn22" name="_ftnref22">[22]</a>
Um herauszufinden, ob ein Nutzer die Rechte für die Bearbeitung von Optionen hat, sollte auf die <code class="lang-php">edit_theme_options</code>-Fähigkeit geprüft werden, nicht auf eine bestimmte Rolle wie <em>Administrator</em>. Theme-Optionen müssen in den Customizer integriert werden.<a href="#_ftn23" name="_ftnref23">[23]</a>
<strong>Plugins und Screenshot</strong>
Themes dürfen Plugins empfehlen, aber keine Plugins in ihren eigenen Code integrieren. Darüber hinaus dürfen Themes keine Aufgaben übernehmen, die besser von Plugins erledigt werden können.<a href="#_ftn24" name="_ftnref24">[24]</a>
Der Screenshot für das Theme sollte das Theme so zeigen, wie es mit den Standard-Optionen aussieht. Als Screenshot ein Logo oder einen Entwurf des Themes zu verwenden, ist nicht erlaubt. Er sollte nicht größer als 1.200 x 900 Pixel sein.<a href="#_ftn25" name="_ftnref25">[25]</a>
<strong>Sicherheit und Privatsphäre</strong>
Ein Theme sollte ohne die Zustimmung des Nutzers keine Daten an einen anderen Server senden. Darüber hinaus darf jede Art der Nutzerdaten-Erhebung nur nach Aktivierung durch den Nutzer erfolgen.
Um keine unsicheren Einträge in der Datenbank zu speichern, müssen alle vertrauensunwürdigen Dateneingaben vor Speicherung validiert und bereinigt (im Englischen: <em>sanitize</em>) werden. Vor der Ausgabe sollten alle Eingaben, die nicht vertrauenswürdig sind, mit Escaping-Funktionen behandelt werden – für normale Eingabefelder gibt es die <code class="lang-php">esc_attr()</code>-Funktion und für Textareas die <code class="lang-php">esc_textarea()</code>-Funktion. Zudem darf der Theme-Entwickler keine URL-Shortener für Links im Theme verwenden.<a href="#_ftn26" name="_ftnref26">[26]</a>
<strong>Theme-Shop und Links</strong>
Wenn in dem Theme ein Link zu dem Entwickler eingebaut wird, sollte es davon nur einen geben. Für den Fall, dass ein Theme-Entwickler auf seiner Website Themes verkauft, sollte er das nur unter der GPL oder einer vergleichbaren Lizenz tun, um mit seinen kostenfreien Themes in das Theme-Verzeichnis aufgenommen zu werden.<a href="#_ftn27" name="_ftnref27">[27]</a> Justin Tadlock verdeutlicht diesen letzten Aspekt wie folgt:
<blockquote>„In a nutshell, if you want to have themes in the directory, all the WordPress themes/plugins on your site need to be 100% GPL or compatible. No split licensing with part of the package under a more restrictive license.“<a href="#_ftn28" name="_ftnref28">[28]</a></blockquote>
<strong>Stylesheets und Skripte</strong>
Skripte, Stylesheets und Favicons dürfen nicht hart in ein Theme geschrieben werden. Eine Ausnahme sind Skripte, die einen Workaround für bestimmte Browser einbinden. Alle anderen Skripte und Stylesheets müssen mit den vorgesehenen Funktionen eingebunden werden. Der Theme-Entwickler darf außerdem keine Analyse- oder Tracking-Codes einbauen und Skripte und Stylesheets nicht minifizieren, außer die Original-Version wird ebenfalls bereitgestellt.
Die Entwickler von Themes müssen die bereits mit dem Core ausgelieferten Skripte verwenden, statt eigene Versionen derselben einzubinden. Wenn Themes eigene Skripte einbinden, müssen diese mit dem Theme ausgeliefert werden und dürfen – mit Ausnahme von Google-Bibliotheken – nicht von fremden Servern eingebunden werden. Wenn ein Theme ein bestimmtes Tag im Stylesheet angibt, muss es die erwartete Funktion auch unterstützen beziehungsweise liefern, wofür das Tag steht.
<strong>Template</strong>
Wenn ein Theme Templates verwendet, müssen die entsprechenden Dateien mit der <code class="lang-php">get_template_path()</code>- oder <code class="lang-php">locate_template()</code>-Funktion eingebunden werden. Anstatt der <code class="lang-php">bloginfo()</code>-Funktion mit entsprechenden Parametern sollen die äquivalenten <code class="lang-php">*_url()</code>-Template-Tags genutzt werden. Zudem muss der Entwickler der Template-Hierarchie folgen.<a href="#_ftn29" name="_ftnref29">[29]</a>
<h4 id="empfohlene-regeln">2.2.2 Empfohlene Regeln</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<strong>Core-Funktionalität und Funktionen</strong>
Themes sollten für das Login- und Suchformular das Markup vom Core verwenden. Des Weiteren müssen einige Funktionen, wenn sie eingebunden sind, die Core-Implementierung von WordPress unterstützen. So müssen automatische Feed-Links über die <code class="lang-php">add_theme_support()</code>-Funktion mit dem entsprechenden Parameter aktiviert werden, ebenso wie Beitragsbilder, der Custom-Header und Custom-Backgrounds. Beitragsbilder müssen über die <code class="lang-php">the_post_thumbnail()</code>-Funktion ausgegeben werden.
Des Weiteren müssen Sidebars mit der <code class="lang-php">register_sidebar()</code>-Funktion registriert und der <code class="lang-php">dynamic_sidebar()</code>-Funktion ausgegeben werden. Wenn ein Theme eigene Widgets bereitstellt, müssen die mit der <code class="lang-php">register_widget()</code>-Funktion an den Action-Hook <code class="lang-php">widgets_init</code> gehängt werden. Für die Ausgabe von Menüs ist die <code class="lang-php">wp_nav_menu()</code>-Funktion vorgesehen – um die Menüs in der functions.php zu registrieren, gibt es die <code class="lang-php">register_nav_menu()</code>- oder <code class="lang-php">register_nav_menus()</code>-Funktion. Um das Design des Editors anzupassen, muss die <code class="lang-php">add_editor_style()</code>-Funktion im Zusammenspiel mit der <code class="lang-markup">editor-style.css</code>-Datei verwendet werden.<a href="#_ftn30" name="_ftnref30">[30]</a>
<strong>Design</strong>
Die verwendete Schrift eines Themes sollte gut lesbar sein. Das bedeutet, mindestens 14 Pixel groß, es sei denn, die Schrift hat eine große x-Höhe. Daneben sollte bei Fließtext auf eine ausreichende Zeilenhöhe geachtet und die Überschriften so gestaltet werden, dass sie sich deutlich vom Fließtext unterscheiden. Neben der Zeilenhöhe muss auch auf die Zeilenlänge geachtet werden, die sich im Bereich von 45 bis 75 Zeichen bewegen sollte.
Bei der Farbwahl sollte in jedem Fall auf einen ausreichenden Kontrast zwischen Schriftfarbe und Hintergrund geachtet werden. Zudem sollten Nutzer mit Farbfehlsichtigkeit berücksichtigt werden: Wichtige Informationen oder ähnliches sollten nicht lediglich durch eine andere Farbe hervorgehoben werden.
Im Detail sollte ein Theme responsive sein, sich also an den Viewport anpassen und auch auf Smartphones gut dargestellt werden. Design-Details sollten nicht vom Inhalt ablenken, Vektor-Icons mit einem Bild-Fallback für ältere Browser und Animationen nicht nur um ihretwillen eingesetzt werden.<a href="#_ftn31" name="_ftnref31">[31]</a>
<strong>Dokumentation und Links</strong>
Für die Dokumentation gilt, dass eine <code class="lang-markup">readme.txt</code>-Datei beigefügt werden kann. Zudem wäre es wünschenswert, eine Liste der Änderungen in einer <code class="lang-markup">changelog.txt</code> bereitzustellen – ein Changelog sollte es in jedem Fall geben. Überdies sollten alle Funktionen, die das Theme bereitstellt, ausreichend dokumentiert werden, damit sich auch andere Nutzer gut in dem Code zurechtfinden.<a href="#_ftn32" name="_ftnref32">[32]</a>
Die Angabe der Theme-URI im Stylesheet ist optional. Wenn sie genutzt wird, muss sie auf eine Seite mit weiteren Informationen zu dem Theme verweisen, nicht auf eine Demo. Wenn eine Demo verlinkt ist, muss deren Inhalt das Theme näher beschreiben. Auch die URI des Theme-Autors ist optional und muss bei Nutzung auf die private Website oder eine Projekt- beziehungsweise Entwickler-Website verweisen.<a href="#_ftn33" name="_ftnref33">[33]</a>
<strong>Template</strong>
Wenn ein WordPress-Theme bestimmte Dateien verwendet, muss es für deren Einbindung die entsprechenden Funktionen nutzen. Das ist beispielsweise für die <code class="lang-markup">header.php</code> die <code class="lang-php">get_header()</code>-Funktion und <code class="lang-php">get_footer()</code> für die <code class="lang-markup">footer.php</code>. Wenn eigene Templates erstellt werden, sollten sie entsprechend dokumentiert werden.
Themes können die Ausgabe von Funktionen über die Parameter oder Filter steuern. Wenn sie die entsprechenden Theme-Dateien verwenden, müssen relevante Funktionen eingefügt werden, wie etwa die <code class="lang-php">wp_head()</code>-Funktion zum Einbinden von Stylesheets, Skripten und mehr.<a href="#_ftn34" name="_ftnref34">[34]</a>
<h2 id="analyse-bereits-vorhandener-fotografen-themes">3 Analyse bereits vorhandener Fotografen-Themes</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um kein Theme zu erstellen, dessen Anspruch an Funktion und Design bereits ein anderes kostenloses Theme erfüllt, müssen die bestehenden WordPress-Themes in diesem Bereich untersucht werden. Die direkte Konkurrenz für das Theme befindet sich im Theme-Verzeichnis, weshalb sich die Untersuchung kostenloser Themes auf dieses Verzeichnis beschränkt.
Darüber hinaus wird auch bei den kostenpflichtigen Themes nach gleichwertigen Themes gesucht, um eventuelle Funktionsunterschiede festzustellen, die nur diese Themes bieten können, weil sie nicht im Theme-Verzeichnis angeboten werden und damit nicht den Anforderungen aus Kapitel 2.2 unterliegen. Für diese Analyse werden zehn WordPress-Themes von ThemeForest, einem der führenden Marktplätze auf dem Gebiet, untersucht.<a href="#_ftn35" name="_ftnref35">[35]</a>
<h3 id="kostenlose-themes-im-theme-verzeichnis">3.1 Kostenlose Themes im Theme-Verzeichnis</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Das Theme-Verzeichnis bietet zur Einschränkung bei der Auswahl verschiedene Tags an, die der Besucher auswählen kann. Eins davon ist das <em>photoblogging</em>-Tag, das einen wahrscheinlichen Sucheinstieg für potenzielle Interessenten des Themes bietet. Zum Untersuchungszeitpunkt am 2. November 2015 gibt es unter diesem Tag 154 Themes.<a href="#_ftn36" name="_ftnref36">[36]</a> Einige davon scheinen doppelt ausgegeben zu werden, weshalb am Ende 126 Themes zur Analyse übrig bleiben.
Wie aus der Analyse hervorgeht, die der Arbeit in Anhang B beigefügt ist, bietet kein Theme alle Funktionen, die ein Fotografen-Theme nach den Untersuchungen in Kapitel 2.1 bieten sollte. Einige der untersuchten Themes bieten die Möglichkeit, bestimmte Beiträge auf einer Portfolio-Übersicht anzuzeigen, wie etwa das Theme <em>Pinboard</em> oder <em>Virtue</em>. Bei Virtue muss für diese Funktion allerdings ein Plugin installiert werden – von Haus aus liefert das Theme diese Funktion nicht.
Keins der untersuchten Themes bietet die Möglichkeit, auf einer Seite nur bestimmte Bilder aus dem Portfolio anzuzeigen. Auch die Möglichkeit einer Archiv-Funktion wird von keinem unterstützt.
<h3 id="kostenpflichtige-themes-von-themeforest">3.2 Kostenpflichtige Themes von ThemeForest</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
ThemeForest bietet am 9. November 2015 insgesamt 5.773 WordPress-Themes zum kostenpflichtigen Download an.<a href="#_ftn37" name="_ftnref37">[37]</a> Für die Untersuchung werden die zehn meistverkauften Themes mit den Tags <em>portfolio</em> und <em>photography</em> gewählt, die den Begriff <em>Photography</em> oder Abwandlungen im Titel tragen.<a href="#_ftn38" name="_ftnref38">[38]</a> Das Theme <em>Anan</em> wird dabei ausgelassen, da bei der Untersuchung am 9. November die Demo nicht funktioniert hat.<a href="#_ftn39" name="_ftnref39">[39]</a> Die Untersuchungsergebnisse sind in Anhang C zu finden.
Auch bei den hier untersuchten Themes bietet keins alle Funktionen, die aus der Fotografen-Website-Analyse als nützlich hervorgegangen sind. Die Möglichkeit, einen Slider einzubauen, bieten alle untersuchten Themes. Eine Portfolio-Ansicht ist bei acht der zehn Themes möglich, die sich oft auch direkt filtern lässt – einige Themes bieten auch verschiedene Varianten des Portfolio-Layouts an. Eine bestimmte Seite festzulegen, die nur eine Kategorie davon anzeigt, scheint häufig nicht möglich zu sein.
Bei einigen Themes lassen sich Galerien in verschiedenen Arten darstellen – sowohl als Slider als auch als Thumbnail-Übersicht. Die Möglichkeit eines Portfolio-Archivs bietet kein Theme. In allen Fällen scheinen die Portfolio-Elemente strikt von den Blogbeiträgen getrennt und mit einer anderen Inhaltsart umgesetzt zu sein, als WordPress ursprünglich mitbringt – diese Tatsache würde die Themes vom Theme-Verzeichnis bereits ausschließen.
<strong>Nachteile von Premium-Themes</strong>
Auch wenn ein Theme mit fast unbegrenzten Möglichkeiten in der Anpassung auf den ersten Blick für einen Nutzer sehr attraktiv scheint, gibt es große Nachteile, die mit der Nutzung sogenannter <em>Premium-Themes</em> einhergehen. Ein großes Problem sind Shortcodes, die von Themes mitgebracht werden. Wenn beispielsweise eine Meldung mit dem Shortcode des Fluxus-Themes umgesetzt wird, dann sieht das in dem Beitrag oder der Seite im Backend folgendermaßen aus:<a href="#_ftn40" name="_ftnref40">[40]</a>
<pre class="lang-markup"><code class="lang-markup">[alert]This theme is available at ThemeForest for a price of $45. Buy It.[/alert]</code></pre>
<em>Listing 1: Shortcode für eine Meldung im Fluxus-Theme</em>
Im Frontend wird dann eine Meldung ausgegeben, wie in Abbildung 3 zu sehen ist. Wenn der Nutzer aber zu einem anderen Theme wechselt und in seinen Beiträgen und Seiten Shortcodes eingesetzt hat, werden einfach die Shortcodes ausgegeben. Das Ergebnis im Frontend würde dann so aussehen, wie in Listing 1.
[caption id="attachment_2240" align="alignnone" width="783"]<img class="size-full wp-image-2240" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/screenshot-meldung-shortcode.png" alt="Abbildung 3: Mit Shortcode erzeugte Meldung im Fluxus-Theme. Quelle: Screenshot von inthe.me/demo/fluxus/features/alerts/ am 10. November 2015" width="783" height="85" /> Abbildung 3: Mit Shortcode erzeugte Meldung im Fluxus-Theme.<br />Quelle: Screenshot von inthe.me/demo/fluxus/features/alerts/ am 10. November 2015[/caption]
Wenn Shortcodes also nicht von einem Plugin bereitgestellt werden, gehen diese Funktionen bei einem Theme-Wechsel verloren. Der Nutzer muss dann für funktionierende Inhaltselemente entweder das alte Theme weiternutzen oder alle Shortcodes durch eine andere Lösung ersetzen.
Ein ähnliches Problem bekommen Nutzer durch die inhaltserstellenden Funktionen solcher Themes. Bei dem Invictus-Theme werden die Galerien vermutlich durch einen Custom-Post-Type realisiert, wie in dem Video auf der Hilfe-Seite zu sehen ist.<a href="#_ftn41" name="_ftnref41">[41]</a> Das bedeutet, dass nach einem Theme-Wechsel sämtliche Galerien, die über diese Funktion angelegt wurden, nicht mehr vorhanden sind. Der Nutzer muss sich die Galerien mit einer anderen Lösung wieder neu anlegen.
Das ist der Grund, warum im Theme-Verzeichnis keine Themes erlaubt sind, die Shortcodes, Custom-Post-Types oder andere Funktionen beinhalten, über die der Nutzer Inhalte erstellen kann, die nach einem Theme-Wechsel verloren gehen. Justin Tadlock hat nicht erlaubte Funktionen und einige Grauzonen-Situationen in einem Blog-Post erläutert.<a href="#_ftn42" name="_ftnref42">[42]</a>
<h2 id="vorbereitung-auf-die-theme-entwicklung">4 Vorbereitung auf die Theme-Entwicklung</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Außer einer funktionierenden WordPress-Installation gibt es einige Dinge, mit denen die Theme-Entwicklung leichter von der Hand geht. Dazu gehören hilfreiche Plugins, WordPress-Einstellungen sowie Demo-Inhalte, die auch verschiedene Grenzfälle behandeln.
<h3 id="debug-modus">4.1 Debug-Modus</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Allgemein für die Entwicklung mit WordPress nützlich und empfehlenswert ist die Aktivierung des Debug-Modus. Wenn sich eine WordPress-Installation in diesem Modus befindet, werden PHP-Fehlermeldungen sowohl im Frontend als auch im Backend angezeigt.
Um den Debug-Modus zu aktivieren, muss eine Zeile in der <code class="lang-markup">wp-config.php</code> angepasst werden, die sich im obersten Ordner der WordPress-Installation oder eine Ebene höher befindet:
<pre class="lang-php"><code class="lang-php">define('WP_DEBUG', false);</code></pre>
<em>Listing 2: Debug-Modus deaktiviert</em>
Hier muss der Wert <code class="lang-php">false</code> in <code class="lang-php">true</code> geändert werden, um den Debug-Modus zu aktivieren.<a href="#_ftn43" name="_ftnref43">[43]</a>
<h3 id="entwickler-plugins">4.2 Entwickler-Plugins</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Das Theme-Review-Team empfiehlt ihren Testern verschiedene Plugins, die sie bei dem Theme-Review nutzen sollen.<a href="#_ftn44" name="_ftnref44">[44]</a> Das bedeutet im Umkehrschluss, dass diese Plugins auch nützlich bei der Entwicklung von Themes sind. In dem Beitrag vom 24. Juli 2015 sind folgende Plugins empfohlen:
<strong>Developer</strong>
Mit dem Developer-Plugin können verschiedene Plugins installiert werden, die bei der Entwicklung hilfreich sind, wie beispielsweise ein Plugin zum schnellen Wechseln des Backend-Nutzers.<a href="#_ftn45" name="_ftnref45">[45]</a> Die Plugins, die <em>Developer</em> zur Installation anbietet, überschneiden sich zum großen Teil mit den weiteren empfohlenen Plugins – lediglich das Beta-Tester-Plugin kann nicht über dieses Plugin installiert werden.
<strong>Theme Check</strong>
Das Theme-Check-Plugin ist das wichtigste Plugin für die Theme-Entwicklung, da alle Reviewer ein Theme mit diesem Plugin testen und bereits ein automatischer Test beim Upload durchgeführt wird. Dabei prüft das Plugin beispielsweise, ob keine Shortcodes und Custom-Post-Types erstellt werden.<a href="#_ftn46" name="_ftnref46">[46]</a>
<strong>Debug Bar</strong>
Das Plugin <em>Debug Bar</em> fügt ein Debug-Menü in die Admin-Toolbar ein, das die Daten-bankabfragen, Cache und Weiteres anzeigt. Wenn der Debug-Modus aktiviert ist, zeigt es auch PHP-Warnungen und -Notizen an.<a href="#_ftn47" name="_ftnref47">[47]</a>
<strong>Log Deprecated Notices</strong>
Das Plugin <em>Log Deprecated Notices</em> macht genau das, was der Name vermuten lässt: Es meldet veraltete Funktionen, Funktionsargumente und Dateien. Darüber hinaus meldet es auch falsch genutzte Funktionen, die WordPress seit Version 3.1 meldet.<a href="#_ftn48" name="_ftnref48">[48]</a>
<strong>Monster Widget</strong>
Mit dem Plugin <em>Monster Widget</em> wird ein Widget bereitgestellt, das alle Core-Widgets enthält. Um alle Widgets zu testen, muss also lediglich dieses eine Widget in eine Sidebar gezogen werden.<a href="#_ftn49" name="_ftnref49">[49]</a>
<strong>WordPress Beta Tester</strong>
Um immer die neueste Entwickler-Version von WordPress zu nutzen, kann das Plugin <em>WordPress Beta Tester</em> genutzt werden. Dieses Plugin ermöglicht es, zwei verschiedene Entwickler-Zweige zu testen: Standardmäßig aktualisiert das Plugin eine WordPress-Installation auf die neuesten Beta- oder Release-Candidate-Versionen. Es gibt aber auch die Möglichkeit, den allerneuesten Entwicklungsstand als Ziel einzustellen, in dem allerdings mehr Bugs auftreten können.<a href="#_ftn50" name="_ftnref50">[50]</a>
<strong>Regenerate Thumbnails</strong>
WordPress generiert beim Hochladen von Bildern verschiedene Thumbnail-Größen. Diese Größen können vom Theme-Entwickler verändert werden oder es können weitere hinzugefügt werden. Um die Thumbnails bereits hochgeladener Bilder neu zu erstellen, gibt es das Plugin <em>Regenerate Thumbnails</em>.<a href="#_ftn51" name="_ftnref51">[51]</a>
<h3 id="test-daten">4.3 Test-Daten</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um möglichst viele Anwendungsfälle wie etwa Artikel ohne Titel, einen Titel aus einem langen Wort oder einen Beitrag ohne Inhalt abzudecken, gibt es Test-Daten, die sich an Entwickler richten. Neben den offiziellen Test-Daten von dem Theme-Review-Team gibt es noch ein weiteres Test-Set, das auf Grundlage der offiziellen Daten erstellt aber auch weiterentwickelt wurde.<a href="#_ftn52" name="_ftnref52">[52]</a>, <a href="#_ftn53" name="_ftnref53">[53]</a> Diese Test-Daten können im WordPress-Backend unter <em>Werkzeuge</em> › <em>Daten importieren</em> in die WordPress-Installation integriert werden.
<h2 id="entwicklung-des-wordpress-themes">5 Entwicklung des WordPress-Themes</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Das Theme soll einen klassischen Aufbau haben. Oben findet ein Header-Bereich Platz, in dem auf der linken Seite der Titel der Website steht und auf der rechten Seite eine horizontale Navigation. Darunter befindet sich der eigentliche Inhaltsbereich, der von einem Footer abgeschlossen wird.
<h3 id="template-hierarchie-in-wordpress">5.1 Template-Hierarchie in WordPress</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Ein WordPress-Theme besteht aus verschiedenen Dateien. Darunter gibt es einige, die normalerweise immer verwendet werden, wie die <code class="lang-markup">header.php</code> mit den Header-Informationen und die <code class="lang-markup">footer.php</code>. Es gibt in WordPress sieben verschiedene Arten von angezeigten Seiten, für die jeweils unterschiedliche Dateien in einer bestimmten Reihenfolge von WordPress gesucht werden, um den Inhalt anzuzeigen. Einen guten Überblick über die Template-Hierarchie bietet eine Grafik, die in Anhang D der Arbeit beigefügt ist.
<h4 id="archiv-seite-mit-beispiel">5.1.1 Archiv-Seite mit Beispiel</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Eine Archiv-Seite kann die Beiträge eines Autors anzeigen, die Beiträge aus einer Kategorie, die mit einem bestimmten Tag, zeitliche Archive sowie Archive zu Custom-Post-Types. Wenn beispielsweise eine Kategorie-Seite angezeigt werden soll, dann sucht WordPress in dem Theme zuerst nach einer Datei, die dem Muster <code class="lang-markup">category-$slug.php</code> entspricht. Der Slug ist dabei die URL-Form der Kategorie – bei der Kategorie <em>WordPress</em> wäre der Slug standardmäßig <em>wordpress</em>.
Es würde also zuerst nach der Datei <code class="lang-markup">category-wordpress.php</code> gesucht. Wenn diese Datei nicht gefunden wird, wird eine Datei nach dem Muster <code class="lang-markup">category-$id.php</code> gesucht, wobei <code class="lang-php">$id</code> der ID der Kategorie entspricht. Wenn auch diese Datei nicht vorhanden ist, wird auf die <code class="lang-markup">category.php</code> zurückgegriffen. Danach würde WordPress nach der <code class="lang-markup">archive.php</code> suchen, die ein Fallback für alle Archiv-Arten darstellt. Wenn es sich um ein Archiv mit einer Pagination handelt und keine <code class="lang-markup">archive.php</code> gefunden wird, sucht WordPress die <code class="lang-markup">paged.php</code>. Als letzten Fallback gibt es die <code class="lang-markup">index.php</code>, die für alle Inhaltsarten die letzte Möglichkeit und deshalb eine notwendige Datei in jedem WordPress-Theme ist.
<h4 id="einzelseite">5.1.2 Einzelseite</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Neben den Archiv-Seiten gibt es die Einzelseiten, die entweder die Einzelansicht eines Beitrags oder einer Seite sein können. Die gängigen Dateien, die für diesen Typ verwendet werden, sind die <code class="lang-markup">single.php</code> für die Einzelansicht eines Beitrags und die <code class="lang-markup">page.php</code> für eine Seite.
Außerdem gibt es hier unter anderem wie bei den Archiv-Seiten noch die Möglichkeit, ein Template für eine bestimmte Seite anzulegen, die anhand des Slugs oder der ID erkannt wird. Auch Templates für bestimmte Anhang-Typen wie etwa Bilder oder MP3-Dateien sind möglich. Seit WordPress 4.3 gibt es vor dem Fallback <code class="lang-markup">index.php</code> noch eine <code class="lang-markup">singular.php</code>, die das Äquivalent zur <code class="lang-markup">archive.php</code> darstellt.
<h4 id="startseite-der-website-blog-uebersicht-kommentar-pop-up-404-seite-und-suchergebnisse">5.1.3 Startseite der Website, Blog-Übersicht, Kommentar-Pop-Up, 404-Seite und Suchergebnisse</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Startseite der WordPress-Installation darzustellen, wird zuerst nach der <code class="lang-markup">front-page.php</code> gesucht. Wenn die nicht vorhanden ist und es sich um eine statische Seite als Startseite handelt, wird auf dieselben Dateien wie bei einer normalen Seite zurückgegriffen. Wenn die letzten Beiträge auf der Startseite angezeigt werden, wird vor der <code class="lang-markup">index.php</code> noch die <code class="lang-markup">home.php</code> gesucht.
Die <code class="lang-markup">home.php</code> ist die erste Datei, die für die Blog-Übersicht genutzt wird. Ist sie nicht vorhanden, wird auf die <code class="lang-markup">index.php</code> zurückgegriffen. Für die Anzeige des Kommentar-Pop-Ups kann die <code class="lang-markup">comments-popup.php</code> vom Theme-Entwickler bereitgestellt werden oder es wird wieder die <code class="lang-markup">index.php</code> verwendet. Für die 404-Seite gibt es in der Template-Hierarchie die <code class="lang-markup">404.php</code> und für die Suchergebnisse die <code class="lang-markup">search.php</code>.
<h3 id="hooks-in-wordpress">5.2 Hooks in WordPress</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Wichtig in der WordPress-Entwicklung sind die sogenannten Hooks, die standardisierte Möglichkeiten bieten, sich in das System <em>einzuhängen</em>. Dabei werden zwei Arten von Hooks unterschieden: Action- und Filter-Hooks.<a href="#_ftn54" name="_ftnref54">[54]</a>
<h4 id="action-hooks">5.2.1 Action-Hooks</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Action-Hooks werden bei einer bestimmten Aktion ausgeführt, zum Beispiel beim Veröffentlichen eines Kommentars. Durch diese Action-Hooks kann ein Theme- oder Plugin-Entwickler auf bestimmte Aktionen reagieren. Um beispielsweise eine E-Mail an den Administrator zu schicken, wenn ein neuer Kommentar geschrieben wurde, kann der Hook <code class="lang-php">comment_post</code> verwendet werden, wie in Listing 3 zu sehen ist – das Beispiel ist abgewandelt dem Werk von Williams, Damstra und Stern entnommen.<a href="#_ftn55" name="_ftnref55">[55]</a>, <a href="#_ftn56" name="_ftnref56">[56]</a>
<pre class="lang-php"><code class="lang-php">function email_new_comment() {
wp_mail( 'admin@example.com', 'Neuer Kommentar',
'Es gibt einen neuen Kommentar auf deiner Website!' );
}
add_action( 'comment_post', 'email_new_comment' );</code></pre>
<em>Listing 3: Beispiel für einen Action-Hook</em>
An die <code class="lang-php">add_action()</code>-Funktion wird zuerst der Hook übergeben und als zweiter Parameter der Name der Funktion. Darüber hinaus gibt es noch Parameter um die Priorität sowie die Anzahl der Funktionsparameter anzugeben.<a href="#_ftn57" name="_ftnref57">[57]</a>
<h4 id="filter-hooks">5.2.2 Filter-Hooks</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Im Gegensatz zu Action-Hooks kann mittels Filter-Hooks der Inhalt vor dem Speichern in die Datenbank oder vor der Anzeige im Frontend verändert werden. So kann beispielsweise vor Ausgabe des Beitragsinhaltes dieser mit einem Filter-Hook verändert werden, wie das Beispiel in Listing 4 zeigt, das leicht umgestellt aus dem Werk von Brad Williams, David Damstra und Hal Stern entnommen ist.<a href="#_ftn58" name="_ftnref58">[58]</a>
<pre class="lang-php"><code class="lang-php">function prowp_profanity_filter( $content ) {
$profanities = array( 'sissy', 'dummy' );
$content = str_ireplace(
$profanities, '[censored]', $content
);
return $content;
}
add_filter( 'the_content', 'prowp_profanity_filter' );</code></pre>
<em>Listing 4: Beispiel für einen Filter-Hook</em>
Statt der <code class="lang-php">add_action()</code>-Funktion wird hier <code class="lang-php">add_filter()</code> verwendet, das dieselben Parameter wie <code class="lang-php">add_action()</code> erwartet.<a href="#_ftn59" name="_ftnref59">[59]</a> Als Hook wird in diesem Beispiel the_content verwendet, das die Veränderung des Seiten- oder Beitragsinhalts ermöglicht.<a href="#_ftn60" name="_ftnref60">[60]</a> Hier werden beispielsweise in <code class="lang-php">prowp_profanity_filter()</code> die Begriffe <em>sissy</em> und <em>dummy</em> durch [censored] ersetzt, bevor der Inhalt ausgegeben wird.
<h3 id="customizer">5.3 Customizer</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Der Customizer ermöglicht dem Anwender eine Live-Vorschau von Änderungen und ist über den Menüpunkt <em>Design</em> › <em>Anpassen</em> zu erreichen. Seit April 2015 müssen Themes für das Theme-Verzeichnis den Customizer nutzen, um Theme-Optionen einzubinden – eigene Optionsseiten sind nicht mehr erlaubt.<a href="#_ftn61" name="_ftnref61">[61]</a>
Um eine Customizer-Option zu erstellen, müssen mindestens die Methoden <code class="lang-php">add_setting()</code> sowie <code class="lang-php">add_control()</code> von <code class="lang-php">WP_Customize_Manager</code> verwendet werden.<a href="#_ftn62" name="_ftnref62">[62]</a>, <a href="#_ftn63" name="_ftnref63">[63]</a>, <a href="#_ftn64" name="_ftnref64">[64]</a>&lt; Die Funktion, die diese Methoden nutzt, muss an den Action-Hook <code class="lang-php">customize_register</code> übergeben werden.<a href="#_ftn65" name="_ftnref65">[65]</a> Mit <code class="lang-php">add_setting()</code> wird eine Customizer-Einstellung erstellt – sie kümmert sich um die Speicherung und die Bereinigung der Daten. <code class="lang-php">add_control()</code> hingegen erstellt zu einer bestimmten Einstellung das Formularelement, über das der Nutzer die Werte anpassen kann.
Daneben gibt es noch weitere Methoden, beispielsweise kann mit <code class="lang-php">add_section()</code> und <code class="lang-php">add_panel()</code> ein eigener Bereich erstellt werden, um die Theme-Optionen zusammenzufassen.<a href="#_ftn66" name="_ftnref66">[66]</a>, <a href="#_ftn67" name="_ftnref67">[67]</a>
<h3 id="metadaten-des-themes-in-der-style-css">5.4 Metadaten des Themes in der style.css</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Ein Theme muss in jedem Fall eine <code class="lang-markup">style.css</code> beinhalten.<a href="#_ftn68" name="_ftnref68">[68]</a> Hier werden die Metadaten eingetragen, die bei der Theme-Auswahl im WordPress-Backend angezeigt werden. Hierbei können eine Reihe von Tags wie etwa <code class="lang-markup">Theme Name</code> und <code class="lang-markup">Licence URI</code> genutzt werden.<a href="#_ftn69" name="_ftnref69">[69]</a> Um in das Theme-Verzeichnis aufgenommen zu werden, sind mindestens die Tags <code class="lang-markup">Theme Name</code>, <code class="lang-markup">Description</code>, <code class="lang-markup">Author</code>, <code class="lang-markup">Version</code> sowie <code class="lang-markup">License</code> und <code class="lang-markup">License URI</code> zu verwenden – auf diese Tags prüft das Theme-Check-Plugin.<a href="#_ftn70" name="_ftnref70">[70]</a>
Die <code class="lang-markup">style.css</code> des WordPress-Themes sieht folgendermaßen aus:
<pre class="lang-css"><code class="lang-css">/*
Theme Name: Hannover
Theme URI: https://florianbrinkmann.com/wordpress-themes/hannover/
Author: Florian Brinkmann
Author URI: https://florianbrinkmann.com
Description: Hannover is great for photographers. You can show all gallery and image posts on one portfolio page.
Version: 1.0
License: GNU General Public License v2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: photoblogging, white, responsive-layout
Text Domain: hannover
*/</code></pre>
<em>Listing 5: Metadaten in der style.css</em>
Zuerst wird mit <em>Hannover</em> der Name des Themes festgelegt und die URI angegeben, die nähere Informationen zum Theme bereithält. Im Anschluss wird der Entwickler sowie dessen Website angegeben und eine Beschreibung des Themes eingefügt. Nach Angabe der aktuellen Theme-Version wird die Lizenz sowie ein Link dazu eingetragen. Durch Angabe von Tags kann das Theme besser im Theme-Verzeichnis gefunden werden – hier sind nur Werte erlaubt, die sich im englischsprachigen Directory filtern lassen. Die Angabe <code class="lang-markup">Text Domain</code> ist wichtig für die Übersetzbarkeit des Themes.<a href="#_ftn71" name="_ftnref71">[71]</a>
<h3 id="kopfbereich-des-themes-in-der-header-php">5.5 Kopfbereich des Themes in der header.php</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
In die <code class="lang-markup">header.php</code> eines WordPress-Themes gehören sowohl der sichtbare als auch unsichtbare Header.<a href="#_ftn72" name="_ftnref72">[72]</a> Der unsichtbare Bereich ist alles, was vor dem öffnenden <code class="lang-markup">body</code>-Tag steht, also der Doctype, das öffnende <code class="lang-markup">html</code>-Tag sowie das <code class="lang-markup">head</code>-Element mit den entsprechenden Inhalten. Der sichtbare Teil ist der Header, den der Website-Besucher sehen kann.
<h4 id="unsichtbarer-teil-des-headers">5.5.1 Unsichtbarer Teil des Headers</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="lang-php">&lt;!DOCTYPE html&gt;
&lt;html &lt;?php language_attributes(); ?&gt; class="no-js"&gt;
&lt;head&gt;
&lt;meta charset="&lt;?php bloginfo( 'charset' ); ?&gt;"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
&lt;?php if ( is_singular() &amp;&amp; pings_open() ) { ?&gt;
&lt;link rel="pingback" href="&lt;?php bloginfo( 'pingback_url' ); ?&gt;"&gt;
&lt;?php }
wp_head(); ?&gt;
&lt;/head&gt;
&lt;body &lt;?php body_class(); ?&gt;&gt;</code></pre>
<em>Listing 6: Unsichtbare Seiteninformationen in der header.php</em>
Zuerst wird in Listing 6 nach dem HTML5-Doctype innerhalb des <code class="lang-markup">html</code>-Elements mit der <code class="lang-php">language_attributes()</code>-Funktion das <code class="lang-markup">lang</code>-Attribut ausgegeben, dessen Inhalt abhängig von der gewählten Sprache im WordPress-Backend ist.<a href="#_ftn73" name="_ftnref73">[73]</a> Um den Zeichensatz der Website auszugeben, wird die Funktion <code class="lang-php">bloginfo()</code> mit dem Parameter <code class="lang-php">charset</code> genutzt.<a href="#_ftn74" name="_ftnref74">[74]</a>
Damit das responsive Layout auf mobilen Geräten richtig angezeigt wird, muss das <code class="lang-markup">viewport</code>-Meta-Tag eingefügt werden.<a href="#_ftn75" name="_ftnref75">[75]</a> Im Anschluss wird mit den Funktionen <code class="lang-php">is_singluar()</code> und <code class="lang-php">pings_open()</code> geprüft, ob der Nutzer sich auf einer Einzelansicht befindet und ob Pingbacks aktiviert sind.<a href="#_ftn76" name="_ftnref76">[76]</a>, <a href="#_ftn77" name="_ftnref77">[77]</a> Wenn das der Fall ist, wird die Pingback-URL mittels der <code class="lang-php">bloginfo()</code>-Funktion und dem Parameter <code class="lang-php">pingback_url</code> ausgegeben.<a href="#_ftn78" name="_ftnref78">[78]</a> Darüber ist es möglich, automatisch andere Websites im Kommentarbereich zu erwähnen, die auf den Beitrag verlinkt haben.<a href="#_ftn79" name="_ftnref79">[79]</a>
Wichtig ist der Einsatz von <code class="lang-php">wp_head()</code>.<a href="#_ftn80" name="_ftnref80">[80]</a> Diese Funktion führt den Action-Hook <code class="lang-php">wp_head</code> aus, mit dem WordPress die Skripte, Stylesheets, Meta-Tags und beispielsweise das <code class="lang-markup">title</code>-Element einfügt.<a href="#_ftn81" name="_ftnref81">[81]</a> Darüber hinaus nutzen auch Plugins diesen Hook, um Skripte, Stylesheets und Ähnliches einzubinden.
Abschließend werden im <code class="lang-markup">body</code>-Element mit <code class="lang-php">body_class()</code> abhängig von der angezeigten Seite unterschiedliche Klassen eingefügt.<a href="#_ftn82" name="_ftnref82">[82]</a> Welche das sind, kann in der <code class="lang-php">get_body_class()</code>-Funktion eingesehen werden, die von <code class="lang-php">body_class()</code> aufgerufen wird. Bei einem Blick in den Quellcode wird beispielsweise ersichtlich, dass auf der Startseite die Klasse <code class="lang-markup">home</code> ausgegeben wird.<a href="#_ftn83" name="_ftnref83">[83]</a>
<h4 id="skip-to-content-link">5.5.2 Skip-To-Content-Link</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Bevor der dauerhaft sichtbare Teil des Headers eingefügt wird, muss eine Hilfe für Screen-Reader-Nutzer sowie Nutzer, die nur die Tastatur nutzen, eingefügt werden. Sie müssen die Möglichkeit haben, den Header zu überspringen, und gleich beim Inhalt der Seite weiterzumachen, damit sie nicht gezwungen sind, bei jedem neuen Seitenaufruf die komplette Navigation durchzugehen.
<pre class="lang-php"><code class="lang-php">&lt;a class="screen-reader-text skip-link" href="#content"&gt;
&lt;?php _e( '[Skip to Content]', 'hannover' ); ?&gt;
&lt;/a&gt;</code></pre>
<em>Listing 7: Skip-To-Content-Link in der header.php</em>
Listing 7 zeigt den Code, der diese Möglichkeit umsetzt. Ein Link-Element wird mit den Klassen screen-reader-text und skip-link ausgetauscht, damit er mit CSS versteckt und beim Fokus-Zustand mit der Tastatur angezeigt werden kann. Der Link verweist auf die ID <code class="lang-markup">content</code>, in der sich der Hauptinhalt des Themes befinden wird. Der Link-Text wird mit der Übersetzungsfunktion <code class="lang-php">_e()</code> angezeigt, damit er direkt ausgegeben wird.<a href="#_ftn84" name="_ftnref84">[84]</a>
<h4 id="sichtbarer-header">5.5.3 Sichtbarer Header</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Im sichtbaren Header-Bereich werden die Elemente eingebunden, die auf jeder Seite gleich sind. Das sind im Fall des Hannover-Themes das Logo beziehungsweise der Seitentitel und die optionale Beschreibung auf der linken und das Menü auf der rechten Seite. Wie der Teil nach Fertigstellung aussieht, ist in Abbildung 4 zu sehen.
[caption id="attachment_2241" align="alignnone" width="800"]<img class="size-large wp-image-2241" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/sichtbarer-header-800x107.png" alt="Abbildung 4: Screenshot des Theme-Headers." width="800" height="107" /> Abbildung 4: Screenshot des Theme-Headers.[/caption]
Um ein Logo festlegen zu können, soll die Header-Bild-Funktion von WordPress eingesetzt werden. Wenn der Theme-Nutzer kein Bild auswählt, wird stattdessen der Titel der Website angezeigt.
<strong>Ausgabe des Header-Bildes</strong>
<pre class="lang-php"><code class="lang-php">&lt;header id="header"&gt;
&lt;div class="site-branding"&gt;
&lt;?php if ( get_header_image() ) {
if ( is_front_page() &amp;&amp; is_home() ) { ?&gt;
&lt;h1 class="logo"&gt;&lt;img src="&lt;?php header_image(); ?&gt;"
alt="&lt;?php bloginfo( 'name' ); ?&gt;"&gt;&lt;/h1&gt;
&lt;?php } else {
if ( ! is_front_page() ) { ?&gt;
&lt;a href="&lt;?php echo esc_url( home_url( '/' ) ); ?&gt;"
rel="home"&gt;
&lt;?php } ?&gt;
&lt;img class="logo" src="&lt;?php header_image(); ?&gt;"
alt="&lt;?php bloginfo( 'name' ); ?&gt;"&gt;
&lt;?php if ( ! is_front_page() ) { ?&gt;
&lt;/a &gt;
&lt;?php }
}
} else {</code></pre>
<em>Listing 8: Ausgabe vom Header-Bild in der header.php</em>
In Listing 8 ist der Quellcode abgebildet, der für die Ausgabe des Header-Bildes sorgt, sofern es im Backend eingestellt ist. Innerhalb des <code class="lang-markup">header</code>-Elements werden diese Informationen in ein <code class="lang-markup">div</code> verpackt, um später einfach auf der linken Seite platziert werden zu können.
Anschließend wird mit <code class="lang-php">if ( get_header_image() )</code> überprüft, ob ein Header-Bild gesetzt ist.<a href="#_ftn85" name="_ftnref85">[85]</a> Danach muss vor der Ausgabe des Bildes erneut eine Entscheidung getroffen werden, um die bestmögliche Barrierefreiheit des Themes zu gewährleisten. Rian Rietveld, WordPress-Entwicklerin mit Fokus auf Barrierefreiheit, hat dazu einen interessanten Artikel geschrieben, nach dem nur auf der Startseite der Website-Titel oder das Logo in ein <code class="lang-markup">h1</code>-Element eingefasst werden soll. Auf anderen Seiten ist die <code class="lang-markup">h1</code> der Titel der Seite, der Beitragstitel et cetera.<a href="#_ftn86" name="_ftnref86">[86]</a>
Aus diesem Grund wird mit <code class="lang-php">if ( is_front_page() &amp;&amp; is_home() )</code> geprüft, ob der Header gerade auf der Startseite angezeigt wird, die gleichzeitig die Blog-Seite ist.<a href="#_ftn87" name="_ftnref87">[87]</a>, <a href="#_ftn88" name="_ftnref88">[88]</a> Ist diese Bedingung erfüllt, wird innerhalb einer <code class="lang-markup">h1</code>-Überschrift das Logo ausgegeben. Die URL zu dem Bild liefert die Funktion <code class="lang-php">header_image()</code> und als alternativen Text, wenn das Bild nicht geladen werden kann, wird mit der <code class="lang-php">bloginfo()</code>-Funktion und dem Parameter <code class="lang-php">name</code> der Name der Website ausgegeben.<a href="#_ftn89" name="_ftnref89">[89]</a>, <a href="#_ftn90" name="_ftnref90">[90]</a> Falls der Nutzer sich auf einer anderen Seite befindet, wird das Logo mittels der <code class="lang-php">home_url()</code>-Funktion auf die Startseite verlinkt und ohne Überschriften-Element ausgegeben.<a href="#_ftn91" name="_ftnref91">[91]</a> Um sicherzugehen, dass die zurückgegebene URL valide ist, wird die Ausgabe mit <code class="lang-php">esc_url()</code> bereinigt.<a href="#_ftn92" name="_ftnref92">[92]</a>
<strong>Ausgabe des Website-Titels</strong>
<pre class="lang-php"><code class="lang-php"> if ( is_front_page() &amp;&amp; is_home() ) { ?&gt;
&lt;h1 class="site-title"&gt;&lt;?php bloginfo( 'name' ); ?&gt;&lt;/h1&gt;
&lt;?php } else {
if ( ! is_front_page() ) { ?&gt;
&lt;a href="&lt;?php echo esc_url( home_url( '/' ) ); ?&gt;" rel="home"&gt;
&lt;?php } ?&gt;
&lt;p class="site-title"&gt;&lt;?php bloginfo( 'name' ); ?&gt;&lt;/p&gt;
&lt;?php if ( ! is_front_page() ) { ?&gt;
&lt;/a &gt;
&lt;?php }
}
}</code></pre>
<em>Listing 9: Ausgabe des Website-Titels in der header.php</em>
Wenn kein Header-Bild festgelegt ist, soll stattdessen der Website-Titel ausgegeben werden. Hierbei müssen dieselben Gesichtspunkte der Barrierefreiheit beachtet werden wie bei dem Logo. Deshalb wird zuerst geprüft, ob die Startseite angezeigt wird und es sich dabei um die Blog-Ansicht handelt. In diesem Fall wird der Seitentitel ohne Verlinkung als <code class="lang-markup">h1</code>-Überschrift ausgegeben. Andernfalls wird der Name als einfacher Absatz ausgezeichnet und – sofern nicht die Startseite angezeigt wird – verlinkt.
<strong>Ausgabe der Beschreibung</strong>
Unter dem Header-Bild oder dem Website-Titel soll die Beschreibung angezeigt werden, wenn sie vom Theme-Nutzer im Backend eingetragen wurde.
<pre class="lang-php"><code class="lang-php"> $description = get_bloginfo( 'description', 'display' );
if ( $description ) { ?&gt;
&lt;p class="site-description"&gt;&lt;?php echo $description; ?&gt;&lt;/p&gt;
&lt;?php } ?&gt;
&lt;/div&gt;</code></pre>
<em>Listing 10: Ausgabe der Beschreibung in der header.php</em>
An die <code class="lang-php">get_bloginfo()</code>-Funktion können dieselben Parameter übergeben werden, wie an <code class="lang-php">bloginfo()</code>, da <code class="lang-php">bloginfo()</code> lediglich das Ergebnis des <code class="lang-php">get_bloginfo()</code>-Aufrufs ausgibt.<a href="#_ftn93" name="_ftnref93">[93]</a>, <a href="#_ftn94" name="_ftnref94">[94]</a> Bei direkter Nutzung der get_bloginfo()-Funktion wird das Ergebnis nicht gleich im Frontend ausgegeben sondern kann für weitere Operationen genutzt werden.<a href="#_ftn95" name="_ftnref95">[95]</a>
Mit <code class="lang-php">get_bloginfo( 'description', 'display' )</code> wird die Beschreibung der Website ermittelt und durch Angabe des zweiten Parameters für die Anzeige im Frontend bereinigt. Wenn die Variable <code class="lang-php">$descriptio</code>n nicht leer ist, der Nutzer also eine Beschreibung im Backend eingetragen hat, wird diese als Absatz angezeigt.
<strong>Ausgabe des Menüs</strong>
Auf der rechten Seite des Headers soll das Hauptmenü der Website dargestellt werden. Die entsprechende Funktion, die für die Ausgabe von Menüs sorgt, ist <code class="lang-php">wp_nav_menu()</code>:
<pre class="lang-php"><code class="lang-php"> &lt;?php if ( has_nav_menu( 'primary' ) ) { ?&gt;
&lt;button id="menu-toggle" class="menu-toggle"&gt;
&lt;?php _e( 'Menu', 'hannover' ); ?&gt;
&lt;/button&gt;
&lt;nav&gt;
&lt;h2 class="screen-reader-text"&gt;
&lt;?php /* translators: hidden screen reader headline for the
main navigation */
_e( 'Main navigation', 'hannover' ); ?&gt;
&lt;/h2&gt;
&lt;?php wp_nav_menu(
array(
'theme_location' =&gt; 'primary',
'menu_class' =&gt; 'primary-menu',
'container' =&gt; ''
)
); ?&gt;
&lt;/nav&gt;
&lt;?php } ?&gt;
&lt;/header&gt;
&lt;div id="content"&gt;</code></pre>
<em>Listing 11: Ausgabe des Menüs in der header.php</em>
Wie in Listing 11 dargestellt, wird zunächst geprüft, ob ein Menü zur Ausgabe vorhanden ist. Dafür wird <code class="lang-php">has_nav_menu()</code> verwendet, der als Parameter eine Menüposition übergeben werden muss.<a href="#_ftn96" name="_ftnref96">[96]</a> Anschließend wird ein <code class="lang-markup">button</code>-Element angelegt, das nachher für die Anzeige des Menüs in kleinen Viewports genutzt wird, dessen Beschriftung erneut über <code class="lang-php">_e()</code> ausgegeben wird. Die Navigation selbst wird von dem HTML5-Element <code class="lang-markup">nav</code> umschlossen, innerhalb dessen für Screen-Reader-Nutzer eine <code class="lang-markup">h2</code>-Überschrift platziert wird.<a href="#_ftn97" name="_ftnref97">[97]</a> Um den Übersetzern die Arbeit zu erleichtern, wird vor <code class="lang-php">_e()</code> ein <code class="lang-php">translators:</code>-Kommentar eingefügt, der in Übersetzungs-Tools als Hilfe angezeigt wird.<a href="#_ftn98" name="_ftnref98">[98]</a>
Im Anschluss wird das Menü angezeigt. Die <code class="lang-php">wp_nav_menu()</code>-Funktion erwartet als Parameter ein Options-Array, dessen wichtigster Schlüssel <code class="lang-php">theme_location</code> ist – der entsprechende Wert gibt an, welche Menüposition angezeigt werden soll. Dieser Position muss der Nutzer im Backend ein Menü zuweisen, um es im Frontend darstellen zu lassen. Als Klasse soll dem Menü <code class="lang-php">primary-menu</code> zugewiesen und ein zusätzlicher Container zu dem <code class="lang-markup">nav</code>-Element soll nicht ausgegeben werden. Der Standard-Wert wäre hier ein <code class="lang-markup">div</code>.<a href="#_ftn99" name="_ftnref99">[99]</a>
Um diesen Teil in späteren Dateien nicht wiederholen zu müssen, wird auch das umschließende <code class="lang-markup">div</code> für den Inhalt inklusive eventuell vorhandener Sidebar in der <code class="lang-markup">header.php</code> geöffnet.
<strong>Menüposition registrieren</strong>
Damit die Menüposition im Backend ausgewählt werden kann, muss sie in der <code class="lang-markup">functions.php</code> registriert werden. Hierfür gibt es in WordPress zwei verschiedene Möglichkeiten: Mit der <code class="lang-php">register_nav_menu()</code>-Funktion kann ein einzelnes Menü registriert werden – <code class="lang-php">register_nav_menus()</code> erlaubt die Registrierung mehrerer Menüs.<a href="#_ftn100" name="_ftnref100">[100]</a>, <a href="#_ftn101" name="_ftnref101">[101]</a>
Um später leichter weitere Menüpositionen einrichten zu können, wird in Listing 12 auf die <code class="lang-php">register_nav_menus()</code>-Funktion zurückgegriffen. Als Parameter muss ein Array übergeben werden, das als Schlüssel einen eindeutigen Bezeichner der Position festlegt und als Wert die Beschriftung für das Backend enthält. An dieser Stelle kommt die Übersetzungs-Funktion <code class="lang-php">__()</code> zum Einsatz, die wie <code class="lang-php">_e()</code> funktioniert, aber den String nicht sofort ausgibt.<a href="#_ftn102" name="_ftnref102">[102]</a> Davor wird ein Kommentar für Übersetzer eingefügt, damit klar ist, wofür dieser String ist. Damit <code class="lang-php">hannover_register_menus()</code> früh genug ausgeführt wird, wird sie an den <code class="lang-php">init</code>-Hook gehängt. <a href="#_ftn103" name="_ftnref103">[103]</a>
<pre class="lang-php"><code class="lang-php">&lt;?php
function hannover_register_menus() {
register_nav_menus(
array(
/* translators: Name of menu position in the header */
'primary' =&gt; __( 'Primary Menu', 'hannover' )
)
);
}
add_action( 'init', 'hannover_register_menus' );</code></pre>
<em>Listing 12: Registrierung der Hauptmenüs in der functions.php</em>
<h3 id="theme-support-fuer-post-formate-feed-links-title-tag-beitragsbilder-header-bild-und-html5">5.6 Theme-Support für Post-Formate, Feed-Links, Title-Tag, Beitragsbilder, Header-Bild und HTML5</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
In WordPress gibt es einige Funktionen, die mit der <code class="lang-php">add_theme_support()</code>-Funktion aktiviert werden müssen. Dazu gehören beispielsweise Beitragsbilder, Post-Formate wie <em>Galerie</em> und <em>Bild</em> sowie automatische Feed-Links. Wie in Listing 13 zu sehen, wird die <code class="lang-php">hannover_add_theme_support()</code>-Funktion an den Hook <code class="lang-php">after_setup_theme</code> angehängt, da <code class="lang-php">init</code> in diesem Fall zu spät sein könnte.<a href="#_ftn104" name="_ftnref104">[104]</a>
<pre class="lang-php"><code class="lang-php">function hannover_add_theme_support() {
add_theme_support( 'custom-header' );
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'title-tag' );
add_theme_support( 'post-formats', array(
'aside',
'link',
'gallery',
'status',
'quote',
'image',
'video',
'audio',
'chat'
) );
add_theme_support( 'html5', array(
'comment-list',
'comment-form',
'search-form',
'gallery',
'caption',
) );
add_theme_support( 'post-thumbnails' );
}
add_action( 'after_setup_theme', 'hannover_add_theme_support' );</code></pre>
<em>Listing 13: add_theme_support() in der functions.php</em>
Um eine Funktion zu aktivieren, muss sie als Parameter an die Funktion <code class="lang-php">add_theme_support()</code> übergeben werden. Mit der Übergabe des Parameters <code class="lang-php">custom-header</code> wird dem Theme-Nutzer ermöglicht, im Customizer ein Header-Bild festzulegen, das im Fall des Hannover-Themes als Logo verwendet wird.<a href="#_ftn105" name="_ftnref105">[105]</a>
<code class="lang-php">automatic-feed-links</code> fügt Links zu RSS-Feeds in das <code class="lang-markup">head</code>-Element der Website ein und mit Angabe von <code class="lang-php">title-tag</code> wird seit WordPress 4.1 der Dokumenttitel eingefügt. <a href="#_ftn106" name="_ftnref106">[106]</a>, <a href="#_ftn107" name="_ftnref107">[107]</a> Um die Unterstützung für Post-Formate zu aktivieren, müssen zwei Parameter an die <code class="lang-php">add_theme_support()</code>-Funktion übergeben werden: Zuerst <code class="lang-php">post-formats</code>, gefolgt von einem Array mit den Formaten, die aktiviert werden sollen. Das Hannover-Theme wird alle möglichen Formate unterstützen.<a href="#_ftn108" name="_ftnref108">[108]</a>
Zudem ist es möglich, das Markup von WordPress-Funktionen, wie beispielsweise das Galerie-Markup, auf HTML5 umzustellen. Dazu wird als erster Parameter <code class="lang-php">html5</code> und als zweiter ein Array übergeben, das die Bereiche enthält, die mit dem modernen Markup ausgeliefert werden sollen. Auch hier wird das Theme alle möglichen Bereiche unterstützen.<a href="#_ftn109" name="_ftnref109">[109]</a> Um Beitragsbilder zu ermöglichen, muss der Parameter <code class="lang-php">post-thumbnails</code> übergeben werden.<a href="#_ftn110" name="_ftnref110">[110]</a>
<h3 id="blog-uebersicht">5.7 Blog-Übersicht</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
[caption id="attachment_2242" align="alignnone" width="800"]<img class="size-large wp-image-2242" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/blog-uebersicht-800x633.png" alt="Abbildung 5: Screenshot von der Blog-Übersicht." width="800" height="633" /> Abbildung 5: Screenshot von der Blog-Übersicht.[/caption]
Für die Blog-Übersicht ist die <code class="lang-markup">index.php</code> zuständig, die wie die <code class="lang-markup">style.css</code> in jedem Fall notwendig ist.<a href="#_ftn111" name="_ftnref111">[111]</a> In Abbildung 5 ist zu sehen, wie die Blog-Übersicht des Hannover-Themes aussehen wird: Links werden die Beiträge dargestellt, rechts eine Sidebar.
<pre class="lang-php"><code class="lang-php">&lt;?php get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php if ( have_posts() ) {
if ( is_home() &amp;&amp; ! is_front_page() ) { ?&gt;
&lt;header&gt;
&lt;h1 class="page-title screen-reader-text"&gt;
&lt;?php single_post_title(); ?&gt;
&lt;/h1&gt;
&lt;/header&gt;
&lt;?php }
while ( have_posts() ) {
the_post();
get_template_part(
'template-parts/content', get_post_format()
);
}
}
the_posts_pagination( array( 'type' =&gt; 'list' ) ); ?&gt;
&lt;/main&gt;
&lt;?php get_sidebar();
get_footer();</code></pre>
<em>Listing 14: Blog-Übersicht in der index.php</em>
In Listing 14 ist die <code class="lang-markup">index.php</code> abgebildet, in der zuerst mit der <code class="lang-php">get_header()</code>-Funktion die header.php eingebunden wird.<a href="#_ftn112" name="_ftnref112">[112]</a> Innerhalb des <code class="lang-markup">main</code>-Elements, das den Hauptinhalt enthält, wird zunächst mit <code class="lang-php">is_home()</code> und <code class="lang-php">! is_front_page()</code> überprüft, ob die Blog-Übersicht auf einer anderen Seite als der Startseite angezeigt wird.<a href="#_ftn113" name="_ftnref113">[113]</a>, <a href="#_ftn114" name="_ftnref114">[114]</a> In diesem Fall wird innerhalb eines <code class="lang-markup">header</code>- und <code class="lang-markup">h1</code>-Elements mit <code class="lang-php">single_post_title()</code> der Titel der Seite ausgegeben.<a href="#_ftn115" name="_ftnref115">[115]</a>
Anschließend werden die Beiträge ausgegeben. Dafür wird zuerst mit <code class="lang-php">have_posts()</code> geprüft, ob Beiträge aus der aktuellen Anfrage zurückgegeben wurden.<a href="#_ftn116" name="_ftnref116">[116]</a> Ist das der Fall, wird mit einer <code class="lang-php">while</code>-Schleife jeder Beitrag durchlaufen. Innerhalb der Schleife werden mit <code class="lang-php">the_post()</code> die Daten des aktuellen Beitrags zugänglich gemacht und mit <code class="lang-php">get_template_part()</code> die Datei eingebunden, die ihn in der Übersicht anzeigt.<a href="#_ftn117" name="_ftnref117">[117]</a>, <a href="#_ftn118" name="_ftnref118">[118]</a> Als Parameter wird zuerst ein Slug übergeben, der zweite Parameter ist ein optionaler Name der spezialisierten Template-Datei.
In diesem Fall mit <code class="lang-php">template-parts/content</code> und <code class="lang-php">get_post_format()</code> als Parameter sucht WordPress Theme-Dateien abhängig von dem Post-Format – mit <code class="lang-php">get_post_format()</code> wird der Slug des verwendeten Post-Formats ausgegeben.<a href="#_ftn119" name="_ftnref119">[119]</a> Wenn beispielsweise ein Beitrag mit dem Post-Format <em>Galerie</em> angezeigt wird, sucht WordPress nach einer Datei namens <code class="lang-markup">content-gallery.php</code> in dem Ordner <code class="lang-markup">template-parts</code>. Gibt es diese Datei nicht, wird die <code class="lang-markup">content.php</code> geladen, ebenso wie für Beiträge ohne spezielles Post-Format. An dieser Stelle können somit einfach verschiedene Ausgaben für die unterschiedlichen Post-Formate erreicht werden.
Mit <code class="lang-php">the_posts_pagination()</code> wird nach Anzeige der Beiträge gegebenenfalls eine Pagination ausgegeben, über die ältere Beiträge erreicht werden können.<a href="#_ftn120" name="_ftnref120">[120]</a> <code class="lang-php">get_sidebar()</code> und <code class="lang-php">get_footer()</code> binden abschließend die Dateien <code class="lang-markup">sidebar.php</code> und <code class="lang-markup">footer.php</code> ein.<a href="#_ftn121" name="_ftnref121">[121]</a>, <a href="#_ftn122" name="_ftnref122">[122]</a>
<h3 id="vorschau-eines-normalen-beitrags">5.8 Vorschau eines normalen Beitrags</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Wie in Kapitel 5.7 beschrieben, wird zur Darstellung normaler Beiträge ohne Post-Format die content.php genutzt. Dabei gibt es zwei Unterscheidungen: Mit Beitragsbild oder ohne.
[caption id="attachment_2243" align="alignnone" width="800"]<img class="size-large wp-image-2243" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/normaler-beitrag-mit-featured-image-800x633.png" alt="Abbildung 6: Ansicht eines normalen Beitrags mit Beitragsbild in der Übersicht." width="800" height="633" /> Abbildung 6: Ansicht eines normalen Beitrags mit Beitragsbild in der Übersicht.[/caption]
Abbildung 6 zeigt den Entwurf eines Beitrags mit Beitragsbild. Unter dem Beitragsbild wird der Titel angezeigt, gefolgt vom Veröffentlichungsdatum. Danach steht der Inhalt des Beitrags und ein Link zu der Einzelansicht. Abschließend werden die Kategorien, Tags, der Autor sowie Trackback- und Kommentar-Anzahl dargestellt. Wenn kein Beitragsbild gesetzt ist, fällt es einfach weg.
Da einige dieser Elemente voraussichtlich später in anderen Dateien wiederverwendet werden, werden sie in die <code class="lang-markup">functions.php</code> ausgelagert. In Listing 15 ist die komplette <code class="lang-markup">content.php</code> des Hannover-Themes abgebildet.
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class(); ?&gt; id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;header class="entry-header"&gt;
&lt;?php the_post_thumbnail( 'large' );
hannover_the_title( 'h2', true ); ?&gt;
&lt;a href="&lt;?php the_permalink(); ?&gt;" class="entry-date"&gt;
&lt;?php hannover_the_date(); ?&gt;
&lt;/a&gt;
&lt;/header&gt;
&lt;div class="entry-content"&gt;
&lt;?php hannover_the_content(); ?&gt;
&lt;/div&gt;
&lt;footer&gt;
&lt;p&gt;&lt;?php hannover_entry_meta() ?&gt;&lt;/p&gt;
&lt;/footer&gt;
&lt;/article&gt;</code></pre>
<em>Listing 15: content.php</em>
Um jeden Beitrag mit hilfreichen Klassen anzureichern, wird die Funktion <code class="lang-php">post_class()</code> verwendet.<a href="#_ftn123" name="_ftnref123">[123]</a> Mit Hilfe von <code class="lang-php">the_ID()</code>, womit die ID des aktuellen Beitrags ausgegeben wird, wird darüber hinaus noch eine eindeutige ID für jeden Beitrag erstellt. In das <code class="lang-markup">header</code>-Element sollen das Beitragsbild, der Titel sowie das Veröffentlichungsdatum eingefügt werden. Um das Beitragsbild auszugeben, wird die <code class="lang-php">the_post_thumbnail()</code>-Funktion verwendet und als Parameter die Größe angegeben, die angezeigt werden soll.<a href="#_ftn124" name="_ftnref124">[124]</a>
<h4 id="titel-ausgeben">5.8.1 Titel ausgeben</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Mit der Funktion <code class="lang-php">hannover_the_title()</code>, die in Listing 16 abgebildet ist, wird der Titel des Beitrags ausgegeben. Als Parameter wird die Überschriften-Hierarchie angegeben sowie ein boolescher Wert, ob die Überschrift verlinkt sein soll oder nicht.
<pre class="lang-php"><code class="lang-php">function hannover_the_title( $heading, $link ) {
if ( $link ) {
the_title( sprintf(
'&lt;%1$s class="entry-title"&gt;&lt;a href="%2$s" rel="bookmark"&gt;',
$heading, esc_url( get_permalink() )
), sprintf( '&lt;/a&gt;&lt;/%s&gt;', $heading ) );
} else {
the_title( sprintf(
'&lt;%1$s class="entry-title"&gt;',
$heading, esc_url( get_permalink() )
), sprintf( '&lt;/%s&gt;', $heading ) );
}
}</code></pre>
<em>Listing 16: hannover_the_title()-Funktion in der functions.php</em>
In der Funktion wird lediglich die <code class="lang-php">the_title()</code>-Funktion ausgeführt und angepasst. <code class="lang-php">the_title()</code> erwartet als ersten Parameter den Code, der vor dem Titel eingefügt werden soll und als zweiten den für danach.<a href="#_ftn125" name="_ftnref125">[125]</a> Um möglichst einfach die Überschriftenebene und den Link in den HTML-Code einzusetzen, wird in beiden Fällen die Funktion <code class="lang-php">sprintf()</code> genutzt.
Als ersten Parameter erwartet die Funktion den String, der formatiert werden soll. Danach kommen die Werte, die die Platzhalter ersetzen sollen.<a href="#_ftn126" name="_ftnref126">[126]</a> Der erste Platzhalter stellt dabei die Überschriftenebene dar – dieser Platzhalter wird durch die Variable <code class="lang-php">$heading</code> ersetzt. Der zweite Platzhalter wird durch die URL des Beitrags ersetzt und erzeugt so einen funktionsfähigen Link. Hinter dem Titel wird das schließende Link-Tag sowie die korrekte Überschriftenebene ausgegeben. Wenn als boolescher Wert <code class="lang-php">false</code> angegeben wurde, wird die Verlinkung einfach weggelassen.
<h4 id="datum-und-uhrzeit-ausgeben">5.8.2 Datum und Uhrzeit ausgeben</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Wie in Listing 15 zu sehen, wird nach dem Titel ein Link auf den Beitrag ausgegeben, der die <code class="lang-php">hannover_the_date()</code>-Funktion umschließt. Auch diese Funktion gehört in die <code class="lang-markup">functions.php</code> und ist in Listing 17 abgebildet.
<pre class="lang-php"><code class="lang-php">function hannover_the_date() {
/* translators: 1=date, 2=time */
printf( __( '%1$s @ %2$s', 'hannover' ),
get_the_date(),
get_the_time()
);
}</code></pre>
<em>Listing 17: hannover_the_date()-Funktion in der functions.php</em>
Ähnlich wie bei <code class="lang-php">hannover_the_title()</code> wird in dieser Funktion mit dem Ersetzen von Platzhaltern gearbeitet. Diesmal wird jedoch die <code class="lang-php">printf()</code>-Funktion verwendet, da das Ergebnis nicht von einer anderen PHP-Funktion genutzt, sondern gleich ausgegeben werden soll.<a href="#_ftn127" name="_ftnref127">[127]</a>
Das Standardformat soll dem Muster <code class="lang-markup">Datum @ Uhrzeit</code> entsprechen – Übersetzer haben die Möglichkeit, dieses Muster anzupassen, weshalb in einem Übersetzer-Kommentar angegeben wird, welcher Platzhalter wodurch ersetzt wird. Mit <code class="lang-php">get_the_date()</code> und <code class="lang-php">get_the_time()</code> werden die beiden Platzhalter durch das Datum beziehungsweise die Uhrzeit ersetzt. Um dasselbe Datum- und Uhrzeit-Format anzuzeigen, wie der Nutzer im Backend eingestellt hat, wird kein Parameter an die beiden Funktionen übergeben.<a href="#_ftn128" name="_ftnref128">[128]</a>, <a href="#_ftn129" name="_ftnref129">[129]</a>
<h4 id="inhalt-mit-angepasstem-weiterlesen-link">5.8.3 Inhalt mit angepasstem Weiterlesen-Link</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="lang-php">function hannover_the_content() {
/* translators: text for the more tag. s= title */
the_content(
sprintf(
__( 'Continue reading “%s”', 'hannover' ),
esc_html( get_the_title() )
)
);
}</code></pre>
<em>Listing 18: hannover_the_content()-Funktion in der functions.php</em>
Um den Inhalt des Beitrags inklusive Weiterlesen-Link auszugeben, würde theoretisch der <code class="lang-php">the_content()</code>-Aufruf ohne Parameter ausreichen.<a href="#_ftn130" name="_ftnref130">[130]</a> Der Standard-Weiterlesen-Link sieht allerdings so aus: <code class="lang-markup">(mehr …)</code>. Für Screen-Reader-Nutzer ist das nicht besonders hilfreich, da der Kontext fehlt. Im Theme-Review-Handbuch wird im Bereich <em>Accessibility</em> zu diesem Thema geschrieben, dass der Titel des Beitrags mit in den Weiterlesen-Link integriert werden sollte.<a href="#_ftn131" name="_ftnref131">[131]</a>
Aus diesem Grund wird eine eigene Funktion erstellt, um <code class="lang-php">the_content()</code> mit verändertem Weiterlesen-Link auszugeben, die in Listing 18 abgebildet ist. An die <code class="lang-php">the_content()</code>-Funktion wird mittels <code class="lang-php">sprintf()</code> ein Muster mit Platzhalter übergeben, dessen Platzhalter <code class="lang-php">%s</code> durch den Titel des Beitrags ersetzt wird, der über <code class="lang-php">get_the_title()</code> ermittelt wird.<a href="#_ftn132" name="_ftnref132">[132]</a> Daraus entsteht ein Weiterlesen-Link des Formats <em>Continue reading “Beitragstitel”</em>.
<h4 id="meta-daten-im-footer-des-beitrags">5.8.4 Meta-Daten im Footer des Beitrags</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Im Footer eines normalen Beitrags sollen der Autor, die Kategorien, Tags sowie Anzahl von Kommentaren und Trackbacks angezeigt werden. Die Funktion, die den Footer anzeigt, heißt <code class="lang-php">hannover_entry_meta()</code> und wird hier der Länge wegen stückweise abgebildet.
<strong>Den Autoren ausgeben</strong>
<pre class="lang-php"><code class="lang-php">function hannover_entry_meta() { ?&gt;
&lt;span class="author"&gt;&lt;?php
/* translators: name of the author in entry footer. s=author name*/
printf( __( 'Author %s', 'hannover' ),
'&lt;span&gt;' . get_the_author() . '&lt;/span&gt;' ) ?&gt;&lt;/span&gt;</code></pre>
<em>Listing 19: Ausgabe des Autors in hannover_entry_meta() in der functions.php</em>
Listing 19 zeigt den Anfang der Funktion, mit dem der Autor des Beitrags ausgegeben wird. Da es in jedem Fall einen Autor gibt, muss hier nicht geprüft werden, ob ein Autor vorliegt. Innerhalb des <code class="lang-markup">span</code>-Elements wird in dem Formatierungs-String die Formatierungs-Anweisung durch den Autor ersetzt, der mit der <code class="lang-php">get_the_author()</code>-Funktion ermittelt wird.<a href="#_ftn133" name="_ftnref133">[133]</a>
<strong>Die Kategorien ausgeben</strong>
<pre class="lang-php"><code class="lang-php">&lt;?php if ( get_the_category() ) { ?&gt;
&lt;span class="categories"&gt;&lt;?php /* translators: Label for category list
in entry footer. s=categories */
printf( _n(
'Category %s',
'Categories %s',
count( get_the_category() ),
'hannover'
), /* translators: term delimiter */
'&lt;span&gt;' . get_the_category_list( __( ', ', 'hannover' ) )
. '&lt;/span&gt;' ) ?&gt;&lt;/span&gt;
&lt;?php }</code></pre>
<em>Listing 20: Ausgabe der Kategorien in hannover_entry_meta() in der functions.php</em>
In Listing 20 ist dargestellt, wie die Kategorien des Beitrags ausgegeben werden. Standardmäßig ist es nicht möglich, einen Beitrag ohne Kategorie zu veröffentlichen. Um sicherzugehen, wird mit <code class="lang-php">get_the_category()</code> dennoch geprüft, ob eine Kategorie übergeben wurde.<a href="#_ftn134" name="_ftnref134">[134]</a>
Für den Fall, dass ein Beitrag nur einer einzelnen Kategorie zugewiesen wurde, soll die Beschriftung <em>Category</em> anstatt <em>Categories</em> ausgegeben werden. Für diese Singular-Plural-Unterscheidung gibt es eigene Übersetzungsfunktionen – eine davon ist <code class="lang-php">_n()</code>. Als ersten Parameter erwartet die Funktion den Singular-String, gefolgt vom Plural. Der dritte Parameter ist eine Zahl, anhand derer die Funktion den Singular oder Plural ausgibt: Wenn die Zahl größer als eins ist, wird der Plural angezeigt, ansonsten der Singular. Der vierte Parameter ist die Text-Domain.<a href="#_ftn135" name="_ftnref135">[135]</a>
Um die Anzahl von Kategorien zu ermitteln, wird das Ergebnis-Array aus dem <code class="lang-php">get_the_category()</code>-Aufruf mit der <code class="lang-php">count()</code>-Funktion gezählt.<a href="#_ftn136" name="_ftnref136">[136]</a> Um die Kategorie-Liste auszugeben, gibt es die <code class="lang-php">get_the_category_list()</code>-Funktion, der als erster Parameter das Trennzeichen übergeben wird.<a href="#_ftn137" name="_ftnref137">[137]</a>
<strong>Die Tags ausgeben</strong>
Die Tags werden mit einem ähnlichen System angezeigt, wie die Kategorien.
<pre class="lang-php"><code class="lang-php">if ( get_the_tags() ) { ?&gt;
&lt;span class="tags"&gt;&lt;?php
/* translators: Label for tag list in entry footer. s=tags */
printf( _n(
'Tag %s',
'Tags %s',
count( get_the_tags() ),
'hannover'
), /* translators: term delimiter */
'&lt;span&gt;' . get_the_tag_list( '', __( ', ', 'hannover' ) )
. '&lt;/span&gt;' ) ?&gt;&lt;/span&gt;
&lt;?php }</code></pre>
<em>Listing 21: Anzeige der Tags in der hannover_entry_meta() in der functions.php</em>
Zunächst wird in Listing 21 mit der <code class="lang-php">get_the_tags()</code>-Funktion überprüft, ob dem Beitrag Tags zugewiesen wurden.<a href="#_ftn138" name="_ftnref138">[138]</a> Ist das der Fall, wird nach demselben Schema wie bei den Kategorien der Singular oder Plural des Begriffs <em>Tag</em> ausgegeben. Um die Tag-Liste zu ermitteln, stellt WordPress <code class="lang-php">get_the_tag_list()</code> bereit. Vor dem Trennzeichen erwartet diese Funktion als ersten Parameter einen String, der vor der Liste angezeigt werden soll.<a href="#_ftn139" name="_ftnref139">[139]</a> Da die Beschriftung bereits innerhalb der Übersetzungsfunktion <code class="lang-php">_n()</code> geregelt ist, wird ein leerer String übergeben.
<strong>Kommentare und Trackbacks trennen</strong>
Der besseren Übersichtlichkeit halber sollen Kommentare und Trackbacks nicht vermischt dargestellt werden, wie WordPress es normalerweise tun würde. Um die Kommentare und Trackbacks zu trennen, gibt es die <code class="lang-php">separate_comments()</code>-Funktion, die in Listing 22 zum Einsatz kommt.<a href="#_ftn140" name="_ftnref140">[140]</a> Der Code ist zum großen Teil aus der <code class="lang-php">comments_template()</code>-Funktion entliehen, die die Kommentar-Arten ebenfalls getrennt zurückgeben kann.<a href="#_ftn141" name="_ftnref141">[141]</a> Zunächst werden das <code class="lang-php">$wp_query</code>-Objekt für Abfragen und das <code class="lang-php">$post</code>-Objekt für die Daten des aktuellen Beitrags zugänglich gemacht. Anschließend wird ein Array an Argumenten für <code class="lang-php">get_comments()</code> vorbereitet. Die Reaktionen sollen absteigend nach dem Datum sortiert werden und nur abgefragt werden, wenn sie den Status <code class="lang-php">approve</code> besitzen, also freigeschaltet sind. Außerdem müssen es Reaktionen zu dem Beitrag sein, der gerade angezeigt wird.
Diese Argumente werden an die <code class="lang-php">get_comments()</code>-Funktion übergeben, die die Reaktionen als Array zurückgibt – hier sind die Reaktionen aber noch gemischt und nicht nach Typ getrennt.<a href="#_ftn142" name="_ftnref142">[142]</a> Dafür wird im nächsten Schritt das Reaktions-Array an die <code class="lang-php">separate_comments()</code>-Funktion übergeben und das Ergebnis in der Eigenschaft <code class="lang-php">comments_by_type</code> des <code class="lang-php">$wp_query</code>-Objekts gespeichert. Auf diesen Wert wird in der nächsten Zeile referenziert und das Ergebnis in <code class="lang-php">$comments_by_type</code> gespeichert, die abschließend zurückgegeben wird.
<pre class="lang-php"><code class="lang-php">function hannover_get_comments_by_type() {
global $wp_query, $post;
$comment_args = array(
'order' =&gt; 'ASC',
'orderby' =&gt; 'comment_date_gmt',
'status' =&gt; 'approve',
'post_id' =&gt; $post-&gt;ID,
);
$comments = get_comments( $comment_args );
$wp_query-&gt;comments_by_type = separate_comments( $comments );
$comments_by_type = &amp;$wp_query-&gt;comments_by_type;
return $comments_by_type;
}</code></pre>
<em>Listing 22: Funktion zur Zählung von Kommentaren und Trackbacks in der functions.php</em>
<strong>Anzahl der Kommentare ausgeben</strong>
Um die Anzahl der Kommentare in dem Fußbereich des Beitrags auszugeben, wird der Code in Listing 23 benötigt. Zunächst wird mit dem Aufruf der Funktion <code class="lang-php">hannover_get_comments_by_type()</code> das Array mit den Reaktionen bereitgestellt, die nach Typ gruppiert sind. Im Anschluss wird überprüft, ob das Unter-Array mit dem Schlüssel <code class="lang-php">comment</code> existiert, in dem die Kommentare vorliegen. Ist das der Fall, werden mit der <code class="lang-php">count()</code>-Funktion die Kommentare gezählt.
<pre class="lang-php"><code class="lang-php">$comments_by_type = hannover_get_comments_by_type();
if ( $comments_by_type['comment'] ) {
$comment_number = count( $comments_by_type['comment'] ); ?&gt;
&lt;span class="comments"&gt;&lt;?php /* translators: Label for comment number
in entry footer. s=comment number */
printf( _n(
'%s Comment',
'%s Comments',
$comment_number,
'hannover'
), '&lt;span&gt;' . number_format_i18n( $comment_number )
. '&lt;/span&gt;' ) ?&gt;&lt;/span&gt;
&lt;?php }</code></pre>
<em>Listing 23: Anzeige der Kommantarzahl in hannover_entry_meta() in der functions.php</em>
Danach wird wieder ähnlich verfahren wie bei der Anzeige von Kategorien und Tags. Es wird nach Singular und Plural unterschieden und als Zahl für die <code class="lang-php">_n()</code>-Funktion die <code class="lang-php">$comment_number</code>-Variable genutzt. Um die Anzahl der Kommentare im richtigen Format für die eingestellte Sprache anzuzeigen, wird das Ergebnis an <code class="lang-php">number_format_i18n()</code> übergeben.<a href="#_ftn143" name="_ftnref143">[143]</a>
<strong>Anzahl der Trackbacks ausgeben</strong>
<pre class="lang-php"><code class="lang-php"> &amp;nbsif ( $comments_by_type['pings'] ) {
$trackback_number = count( $comments_by_type['pings'] ); ?&gt;
&lt;span class="trackbacks"&gt;&lt;?php /* translators: Label for trackback
number in entry footer. s=trackback number */
printf( _n(
'%s Trackback',
'%s Trackbacks',
$trackback_number,
'hannover'
), '&lt;span&gt;' . number_format_i18n( $trackback_number ) . '&lt;/span&gt;' )
?&gt;&lt;/span&gt;
&lt;?php };
}</code></pre>
<em>Listing 24: Ausgabe der Trackback-Zahl in hannover_entry_meta() in der functions.php</em>
Wie in Listing 24 ersichtlich, ähnelt die Ausgabe der Trackback-Anzahl sehr dem Code aus Listing 23. Statt auf den Array-Abschnitt mit dem Schlüssel <code class="lang-php">comment</code> wird hier auf <code class="lang-php">pings</code> geprüft. Entsprechend wird auch dieser Array-Zweig im Anschluss gezählt und das Ergebnis in <code class="lang-php">$trackback_number</code> gespeichert.
<h3 id="die-sidebar">5.9 Die Sidebar</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Auf der Übersichtsseite des Blogs und der Einzelansicht soll rechts eine Sidebar angezeigt werden. In der <code class="lang-markup">index.php</code> wurde die <code class="lang-markup">sidebar.php</code> bereits mit der Funktion <code class="lang-php">get_sidebar()</code> eingebunden – jetzt muss sie erstellt werden.
In Listing 25 ist die gesamte <code class="lang-markup">sidebar.php</code> abgebildet. Um das <code class="lang-markup">aside</code>-Element und die Überschrift für Screen-Reader-Nutzer nur dann auszugeben, wenn der Sidebar auch wirklich Widgets zugewiesen sind, wird mit <code class="lang-php">is_active_sidebar()</code> dieser Umstand überprüft. Als Parameter wird der Funktion die eindeutige Bezeichnung der Sidebar übergeben, die angezeigt werden soll.<a href="#_ftn144" name="_ftnref144">[144]</a> Nach der Überschrift für Screen-Reader-Nutzer wird mit <code class="lang-php">dynamic_sidebar()</code> die Sidebar ausgegeben – als Parameter muss auch hier wieder der Bezeichner übergeben werden.
<pre class="lang-php"><code class="lang-php">&lt;?php if ( is_active_sidebar( 'sidebar-1' ) ) { ?&gt;
&lt;aside id="secondary" role="complementary"&gt;
&lt;h2 class="screen-reader-text"&gt;
&lt;?php /* translators: screen reader text for the sidebar */
_e( 'Sidebar', 'hannover' ) ?&gt;
&lt;/h2&gt;
&lt;?php dynamic_sidebar( 'sidebar-1' ); ?&gt;
&lt;/aside&gt;
&lt;?php }</code></pre>
<em>Listing 25: sidebar.php</em>
Damit der Theme-Nutzer die Sidebar im Backend mit Widgets befüllen kann, muss sie registriert werden. In Listing 26 ist die entsprechende Funktion abgebildet.
<pre class="lang-php"><code class="lang-php">function hannover_register_sidebars() {
register_sidebar( array(
'name' =&gt; __( 'Main Sidebar', 'hannover' ),
'id' =&gt; 'sidebar-1',
'description' =&gt; __( 'Widgets in this area will be shown
on all normal posts and pages.', 'hannover' ),
'before_widget' =&gt; '&lt;div id="%1$s" class="widget %2$s"&gt;',
'after_widget' =&gt; '&lt;/div&gt;',
'before_title' =&gt; '&lt;h3 class="widget-title"&gt;',
'after_title' =&gt; '&lt;/h3&gt;',
) );
}
add_action( 'widgets_init', 'hannover_register_sidebars' );</code></pre>
<em>Listing 26: Registrierung der Sidebar in der functions.php</em>
Um eine Sidebar in WordPress zu registrieren, gibt es <code class="lang-php">register_sidebar()</code>.<a href="#_ftn145" name="_ftnref145">[145]</a> Der Funktion kann ein Options-Array übergeben werden, um die Standard-Werte zu überschreiben. Der Wert zum Schlüssel <code class="lang-php">name</code> wird im Backend als Name der Sidebar angezeigt – <code class="lang-php">__()</code> ist an dieser Stelle eine weitere Übersetzungsfunktion, der kein Kontext übergeben wird und die den String nicht sofort ausgibt.<a href="#_ftn146" name="_ftnref146">[146]</a> <code class="lang-php">id</code> ist der Wert, der als Parameter an <code class="lang-php">is_active_sidebar()</code> übergeben wird und muss eindeutig sein. Die <code class="lang-php">description</code> wird wie der Name der Sidebar auch im Backend angezeigt. Um Code vor und nach dem Widget auszugeben, werden <code class="lang-php">before_widget</code> und <code class="lang-php">after_widget</code> bereitgestellt – der erste Platzhalter in <code class="lang-php">before_widget</code> wird durch einen eindeutigen Bezeichner ersetzt, der aus der Art des Widgets und einer Zahl besteht. Der zweite Platzhalter wird durch die Art des Widgets ersetzt, beispielsweise <code class="lang-php">widget_recent_entries</code> für das Widget, das die neuesten Beiträge anzeigt.
Mit den Werten für <code class="lang-php">before_title</code> und <code class="lang-php">after_title</code> kann HTML-Code angegeben werden, der vor und hinter dem Titel des Widgets ausgegeben werden soll.
<h3 id="der-footer-des-themes">5.10 Der Footer des Themes</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Zu diesem frühen Stadium der Entwicklung kommt in die <code class="lang-markup">footer.php</code> nur das Notwendige. Später finden hier noch ein Menü für Social-Media-Icons, ein normales Menü sowie ein Link zum Theme-Autor Platz. In Listing 27 ist die gesamte Datei abgebildet. Das schließende <code class="lang-markup">div</code>-Tag gehört zu dem <code class="lang-markup">div</code>-Element mit der ID <code class="lang-markup">content</code>, das in der <code class="lang-markup">header.php</code> geöffnet wurde.
Im Anschluss muss vor dem schließenden <code class="lang-markup">body</code>- und <code class="lang-markup">html</code>-Tag noch die Funktion <code class="lang-php">wp_footer()</code> aufgerufen werden, mit der Skripte und Stylesheets eingebunden werden, die im Fußbereich der Website platziert werden sollen.<a href="#_ftn147" name="_ftnref147">[147]</a>
<pre class="lang-php"><code class="lang-php">&lt;/div&gt;
&lt;?php wp_footer(); ?&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<em>Listing 27: footer.php</em>
<h3 id="archiv-ansicht">5.11 Archiv-Ansicht</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um sämtliche Archiv-Arten etwas anders darzustellen als mit der <code class="lang-markup">index.php</code>, ohne für jede Variante eine eigene Datei anzulegen, muss die <code class="lang-markup">archive.php</code> erstellt werden. Der einzig größere Unterschied zu der <code class="lang-markup">index.php</code> ist, dass der Titel und die Beschreibung des Archivs angezeigt werden.
<pre class="lang-php"><code class="lang-php">&lt;?php get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php if ( have_posts() ) { ?&gt;
&lt;header class="page-header"&gt;
&lt;?php the_archive_title(
'&lt;h1 class="archive-title"&gt;', '&lt;/h1&gt;'
);
the_archive_description(
'&lt;div class="taxonomy-description"&gt;', '&lt;/div&gt;'
); ?&gt;
&lt;/header&gt;
&lt;?php while ( have_posts() ) {
the_post();
get_template_part( 'content', get_post_format() );
}
}
the_posts_pagination( array( 'type' =&gt; 'list' ) ); ?&gt;
&lt;/main&gt;
&lt;?php get_sidebar();
get_footer();</code></pre>
<em>Listing 28: archive.php</em>
In Listing 28 ist die <code class="lang-markup">archive.php</code> abgebildet, die, wie bereits erwähnt, der in Kapitel 5.7 behandelten <code class="lang-markup">index.php</code> recht ähnlich ist. Statt gegebenenfalls den Titel der Seite auszugeben, wird in der <code class="lang-markup">archive.php</code> innerhalb des <code class="lang-markup">header</code>-Elements mit <code class="lang-php">the_archive_title()</code> der Titel des Archives ausgegeben.<a href="#_ftn148" name="_ftnref148">[148]</a> Im Fall einer Kategorie wäre das beispielsweise <em>Kategorie: Porträt</em>. Als ersten Parameter erwartet die Funktion Markup, das vor dem Titel angezeigt werden soll – als zweiten Parameter wird das Markup hinter dem Titel übergeben.
Zusätzlich zum Titel kann der Theme-Nutzer für Kategorien und Tags noch optional eine Beschreibung vergeben. Diese Beschreibung kann mit der Funktion <code class="lang-php">the_archive_description()</code> angezeigt werden.<a href="#_ftn149" name="_ftnref149">[149]</a> Auch dieser Funktion kann über die Parameter jeweils ein String für die Anzeige vor und nach der Beschreibung übergeben werden.
<h3 id="suchergebnis-template">5.12 Suchergebnis-Template</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Für die Anzeige der Suchergebnisse ist die Datei <code class="lang-markup">search.php</code> verantwortlich. Die Auflistung der Beiträge gleicht der im Blog oder anderen Archiv-Ansichten, es wird jedoch vorher noch einmal der Suchbegriff aufgegriffen und im Fall von keinem Ergebnis ein Hinweis sowie ein Suchformular angezeigt.
<pre class="lang-php"><code class="lang-php">&lt;?php get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php if ( have_posts() ) { ?&gt;
&lt;header class="page-header"&gt;
&lt;h1&gt;&lt;?php printf( __( 'Search Results for: %s', 'hannover' ),
esc_html( get_search_query() ) ); ?&gt;&lt;/h1&gt;
&lt;/header&gt;
&lt;?php while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content',
get_post_format() );
}
} else { ?&gt;
&lt;header class="page-header"&gt;
&lt;h1&gt;&lt;?php printf( __( 'Nothing found for “%s”', 'hannover' ),
esc_html( get_search_query() ) ); ?&gt;&lt;/h1&gt;
&lt;/header&gt;
&lt;?php get_search_form();
}
the_posts_pagination( array( 'type' =&gt; 'list' ) ); ?&gt;
&lt;/main&gt;
&lt;?php get_sidebar();
get_footer();</code></pre>
<em>Listing 29: search.php</em>
Listing 29 zeigt den Code für die Datei <code class="lang-markup">search.php</code>. Sie ähnelt der <code class="lang-markup">archive.php</code> aus Listing 28 auf Seite 44 mit einigen Neuerungen. Innerhalb des <code class="lang-markup">h1</code>-Elements wird eine Nachricht für den Nutzer angezeigt, die besagt <code class="lang-markup">Search Results for: Suchbegriff</code>. Der Suchbegriff kann mit der <code class="lang-php">get_search_query()</code>-Funktion ermittelt werden und wird durch <code class="lang-php">printf()</code> in den String eingesetzt.<a href="#_ftn150" name="_ftnref150">[150]</a> Anschließend wird die Schleife durchlaufen und die Beiträge werden ausgegeben.
Falls keine Beiträge vorhanden sind, wird als <code class="lang-markup">h1</code>-Headline der Hinweis ausgegeben, dass für den Begriff oder die Begriffe nichts gefunden wurde. Anschließend wird <code class="lang-php">get_search_form()</code> aufgerufen, die ein Suchformular einbindet.<a href="#_ftn151" name="_ftnref151">[151]</a> Die Funktion sucht nach einer Suchformular-Datei in dem Theme oder gegebenenfalls dem Eltern-Theme – stellt das Theme kein Formular bereit, wird das Standard-Formular eingebunden.
<h3 id="einzelansicht-von-seiten">5.13 Einzelansicht von Seiten</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Einzelansicht einer Seite darzustellen, gibt es in WordPress die Datei <code class="lang-markup">page.php</code>, die in Listing 30 abgebildet ist.
<pre class="lang-php"><code class="lang-php">&lt;?php get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', 'page' );
if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
} ?&gt;
&lt;/main&gt;
&lt;?php get_sidebar();
get_footer();</code></pre>
<em>Listing 30: page.php</em>
Zuerst muss mit <code class="lang-php">get_header()</code> die <code class="lang-markup">header.php</code> eingebunden werden.<a href="#_ftn152" name="_ftnref152">[152]</a> Innerhalb der Schleife wird im Anschluss die <code class="lang-markup">content-page.php</code> aus dem <code class="lang-markup">template-parts</code>-Ordner eingebunden. Abschließend wird innerhalb der <code class="lang-php">while</code>-Schleife mit <code class="lang-php">comments_open()</code> und <code class="lang-php">get_comments_number()</code> geprüft, ob Kommentare erlaubt und/oder vorhanden sind.<a href="#_ftn153" name="_ftnref153">[153]</a>, <a href="#_ftn154" name="_ftnref154">[154]</a> Wenn die Bedingung erfüllt ist, wird mit <code class="lang-php">comments_template()</code> die <code class="lang-markup">comments.php</code> des Themes eingebunden.<a href="#_ftn155" name="_ftnref155">[155]</a> Da die Kommentare und Trackbacks getrennt aufgeführt werden sollen, wird als zweiter Parameter der Wert <code class="lang-php">true</code> übergeben. Abschließend werden Sidebar und Footer angezeigt.
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class(); ?&gt; id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;header class="entry-header"&gt;
&lt;?php hannover_the_title( 'h1', false ); ?&gt;
&lt;/header&gt;
&lt;div class="entry-content"&gt;
&lt;?php hannover_the_content();
wp_link_pages(); ?&gt;
&lt;/div&gt;
&lt;/article&gt;</code></pre>
<em>Listing 31: content-page.php</em>
In Listing 31 ist die <code class="lang-markup">content-page.php</code> des Themes dargestellt. Sie ähnelt der <code class="lang-markup">content.php</code> aus Kapitel 5.8, mit dem Unterschied, dass der Titel innerhalb einer <code class="lang-markup">h1</code>-Überschrift ausgegeben und nicht verlinkt wird. Außerdem werden weder das Datum noch die Meta-Informationen ausgegeben, da diese auf einer statischen Seite wie etwa dem Impressum irrelevant sind. Darüber hinaus wird zusätzlich noch die <code class="lang-php">wp_link_pages()</code>-Funktion aufgerufen, um gegebenenfalls die Pagination auszugeben, die mit dem <code class="lang-marku">&lt;!--nextpage--&gt;</code>-Kommentar in Beiträge und Seiten eingefügt werden kann.<a href="#_ftn156" name="_ftnref156">[156]</a>
<h3 id="einzelansicht-von-beitraegen">5.14 Einzelansicht von Beiträgen</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Für die Einzelansicht eines Beitrags gibt es in WordPress die <code class="lang-markup">single.php</code>, die beim Hannover-Theme in großen Teilen der <code class="lang-markup">page.php</code> ähnelt.
<pre class="lang-php"><code class="lang-php">&lt;?php get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content-single',
get_post_format() );
the_post_navigation();
if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
} ?&gt;
&lt;/main&gt;
&lt;?php get_sidebar();
get_footer();</code></pre>
<em>Listing 32: single.php</em>
Listing 32 zeigt die <code class="lang-markup">single.php</code>, deren Unterschiede zur <code class="lang-markup">page.php</code> darin bestehen, dass sie über die <code class="lang-php">get_template_parts()</code>-Funktion die <code class="lang-markup">content-single.php</code> einbindet oder, soweit vorhanden, eine entsprechende Datei mit einem Post-Format-Suffix, wie beispielsweise die <code class="lang-markup">content-single-gallery.php</code>, sodass diese Ansichten anders dargestellt werden können. Darüber hinaus wird mit der <code class="lang-php">the_post_navigation()</code>-Funktion vor dem Kommentarbereich ein Link auf den vorherigen und nächsten Beitrag angezeigt.<a href="#_ftn157" name="_ftnref157">[157]</a>
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class(); ?&gt; id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;header class="entry-header"&gt;
&lt;?php the_post_thumbnail( 'large' );
hannover_the_title( 'h1', false ); ?&gt;
&lt;span&gt;&lt;?php hannover_the_date(); ?&gt;&lt;/span&gt;
&lt;/header&gt;
&lt;div class="entry-content"&gt;
&lt;?php hannover_the_content();
wp_link_pages(); ?&gt;
&lt;/div&gt;
&lt;footer&gt;
&lt;p&gt;&lt;?php hannover_entry_meta() ?&gt;&lt;/p&gt;
&lt;/footer&gt;
&lt;/article&gt;</code></pre>
<em>Listing 33: content-single.php</em>
Die <code class="lang-markup">content-single.php</code> aus Listing 33 unterscheidet sich nur im Detail von der <code class="lang-markup">content.php</code>. Die Überschrift wird nicht verlinkt und als <code class="lang-markup">h1</code> ausgegeben, auch das Datum wird nicht verlinkt – außerdem wird wie in der <code class="lang-markup">content-page.php</code> die Funktion <code class="lang-php">wp_link_pages()</code> aufgerufen.
<h3 id="kommentarbereich">5.15 Kommentarbereich</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Über die <code class="lang-php">comments_template()</code>-Funktion wird die <code class="lang-markup">comments.php</code> des Themes aufgerufen, oder – falls keine vom Theme bereitgestellt wird – die Datei des aktuellen Standard-Themes. Zuerst muss, wie in Listing 34 zu sehen, mit <code class="lang-php">post_password_required()</code> geprüft werden, ob der Beitrag mit einem Passwort geschützt ist und ob das richtige Passwort <em>nicht</em> vorliegt.<a href="#_ftn158" name="_ftnref158">[158]</a> Ist das der Fall, wird der Durchlauf der Datei abgebrochen.
<pre class="lang-php"><code class="lang-php">&lt;?php if ( post_password_required() ) {
return;
} ?&gt;</code></pre>
<em>Listing 34: Prüfung auf Passwortschutz in der comments.php</em>
Die Kommentare und Trackbacks sollen getrennt voneinander angezeigt werden. Durch die Übergabe des booleschen Wertes <code class="lang-php">true</code> als zweiten Parameter an <code class="lang-php">comments_template()</code> steht die Variable <code class="lang-php">$comments_by_type</code> mit demselben Inhalt zur Verfügung, wie aus Listing 22 bekannt.
<pre class="lang-php"><code class="lang-php">&lt;div id="comments" class="comments-area"&gt;
&lt;?php if ( have_comments() ) {
if ( ! empty( $comments_by_type['comment'] ) ) {
$comment_number = count( $comments_by_type['comment'] ); ?&gt;
&lt;h2 id="comments-title"&gt;
&lt;?php /* translators: Title for comment list.
1=comment number, 2=post title */
printf( _n(
'%1$s Comment on "%2$s"',
'%1$s Comments on "%2$s"',
$comment_number,
'hannover'
), number_format_i18n( $comment_number ),
get_the_title() ) ?&gt;
&lt;/h2&gt;</code></pre>
<em>Listing 35: Anfang der Kommentar-Anzeige in der comments.php</em>
In Listing 35 ist der nächste Teil der <code class="lang-markup">comments.php</code> abgebildet. Nach Öffnen des <code class="lang-markup">div</code>-Tags, das den gesamten Bereich mit Kommentaren, Trackbacks und Kommentarfeld umschließen wird, prüft <code class="lang-php">if ( have_comments() )</code>, ob Reaktionen irgendwelchen Typs ausgegeben werden müssen.<a href="#_ftn159" name="_ftnref159">[159]</a> Ist das der Fall, wird geprüft, ob Kommentare vorhanden sind und anschließend die Anzahl der Kommentare als Überschrift ausgegeben. Dieses Vorgehen ist weitgehend aus Listing 23 auf Seite 41 bekannt. Der größte Unterschied ist an dieser Stelle, dass über einen zweiten Platzhalter noch der Titel des Beitrags in die Überschrift eingefügt wird.
<pre class="lang-php"><code class="lang-php"> &lt;ol class="commentlist"&gt;
&lt;?php wp_list_comments( array(
'callback' =&gt; 'hannover_comments',
'style' =&gt; 'ol',
'type' =&gt; 'comment'
) ); ?&gt;
&lt;/ol&gt;
&lt;?php }</code></pre>
<em>Listing 36: Ausgabe der Kommentare in der comments.php</em>
Listing 36 sorgt für die Ausgabe der Kommentarliste. Da <code class="lang-php">wp_list_comments()</code> kein umschließendes <code class="lang-markup">ol</code>-Element zurückgibt, wird es händisch eingetragen. Als Options-Array wird der Funktion die Callback-Funktion übergeben, die die Darstellung der Kommentare steuert. Wenn hier kein Wert angegeben wird, kümmert sich WordPress intern um die Anzeige der Liste. Als Listenstil soll eine <code class="lang-mark">ol</code>-Liste angezeigt werden und die angezeigten Elemente müssen vom Typ <code class="lang-php">comment</code> sein.<a href="#_ftn160" name="_ftnref160">[160]</a> Die Callback-Funktion wird, genau wie die zur Anzeige von Trackbacks, später in diesem Kapitel erläutert.
<pre class="lang-php"><code class="lang-php">if ( ! empty( $comments_by_type['pings'] ) ) {
$trackback_number = count( $comments_by_type['pings'] ); ?&gt;
&lt;h2 id="trackbacks-title"&gt;
&lt;?php /* translators: Title for trackback list. 1=trackback number,
2=post title */
printf( _n(
'%1$s Trackback on "%2$s"',
'%1$s Trackbacks on "%2$s"',
$trackback_number,
'hannover'
), number_format_i18n( $trackback_number ), get_the_title() ) ?&gt;
&lt;/h2&gt;</code></pre>
<em>Listing 37: Ausgabe der Überschrift für die Trackback-Liste in der comments.php</em>
In der <code class="lang-markup">comments.php</code> geht es weiter mit dem Code aus Listing 37, der im Prinzip dasselbe für Trackbacks erledigt, was Listing 35 für Kommentare macht. Statt auf den <code class="lang-php">comment</code>-Teil des <code class="lang-php">$comments_by_type</code>-Arrays wird hier auf <code class="lang-php">pings</code> geprüft. Dementsprechend wird die Zählung im Vergleich zu den Kommentaren angepasst, ebenso wie der Inhalt der Überschrift.
<pre class="lang-php"><code class="lang-php"> &lt;ol class="commentlist"&gt;
&lt;?php wp_list_comments( array(
'callback' =&gt; 'hannover_trackbacks',
'type' =&gt; 'pings'
) ); ?&gt;
&lt;/ol&gt;
&lt;?php }</code></pre>
<em>Listing 38: Ausgabe der Trackbacks in der comments.php</em>
Um die Liste der Trackbacks mit dem Code aus Listing 38 anzuzeigen, kann wieder <code class="lang-php">wp_list_comments()</code> eingesetzt werden. Als Callback-Funktion wird <code class="lang-php">hannover_trackbacks()</code> übergeben und als Typ <code class="lang-php">pings</code>.
<pre class="lang-php"><code class="lang-php"> the_comments_navigation();
if ( ! comments_open() &amp;&amp; get_comments_number() ) { ?&gt;
&lt;p class="nocomments"&gt;
&lt;?php _e( 'Comments are closed.', 'hannover' ); ?&gt;
&lt;/p&gt;
&lt;?php }
}
comment_form( array(
'label_submit' =&gt; __( 'Submit Comment', 'hannover' )
) ); ?&gt;
&lt;/div&gt;</code></pre>
<em>Listing 39: Letzter Teil der comments.php</em>
In Listing 39 sind die letzten Code-Zeilen der <code class="lang-markup">comments.php</code> abgebildet. Mit der Funktion <code class="lang-php">the_comments_navigation()</code> kann seit WordPress 4.4 eine Navigation für Kommentare angezeigt werden, falls diese nicht alle auf einer Seite angezeigt werden sollen.<a href="#_ftn161" name="_ftnref161">[161]</a> Anschließend wird geprüft, ob Kommentare geschlossen sind und ob es bereits Kommentare gibt. Nur in diesem Fall wird ein Hinweis darauf ausgegeben, dass Kommentare geschlossen sind.
Abschließend wird mit <code class="lang-php">comment_form()</code> das Kommentar-Formular ausgegeben und mit dem Wert für den <code class="lang-mark">label_submit</code>-Schlüssel die Standard-Beschriftung des Absende-Buttons verändert.<a href="#_ftn162" name="_ftnref162">[162]</a> Um die Anzeige der Reaktionen abzuschließen, fehlen noch die zwei Callback-Funktionen für die Liste der Kommentare sowie der Trackbacks.
<h4 id="anzeige-der-kommentare">5.15.1 Anzeige der Kommentare</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="lang-php">function hannover_comments( $comment, $args, $depth ) { ?&gt;
&lt;li &lt;?php comment_class(); ?&gt;
id="li-comment-&lt;?php comment_ID(); ?&gt;"&gt;
&lt;article id="comment-&lt;?php comment_ID(); ?&gt;" class="comment"&gt;
&lt;header class="comment-meta comment-author vcard clearfix"&gt;
&lt;?php echo get_avatar( $comment, 50 ); ?&gt;
&lt;cite class="fn"&gt;&lt;?php comment_author_link(); ?&gt;&lt;/cite&gt;
&lt;?php printf(
'&lt;a href="%1$s"&gt;&lt;time datetime="%2$s"&gt;%3$s&lt;/time&gt;&lt;/a&gt;',
get_comment_link( $comment-&gt;comment_ID ),
get_comment_time( 'c' ),
/* translators: 1=date 2=time */
sprintf( __( '%1$s @ %2$s', 'hannover' ),
get_comment_date(),
get_comment_time()
)
); ?&gt;
&lt;/header&gt;</code></pre>
<em>Listing 40: Ausgabe des Kommentar-Headers in hannover_comments() in der functions.php</em>
Der <code class="lang-php">hannover_comments()</code>-Funktion werden die Parameter <code class="lang-php">$comment</code>, <code class="lang-php">$args</code> sowie <code class="lang-php">$depth</code> übergeben. <code class="lang-php">$comment</code> enthält das Kommentar-Objekt, mit dem der Autor, Inhalt des Kommentars und Ähnliches zugänglich sind. Mit <code class="lang-php">$args</code> werden die Argumente vorgehalten, die an <code class="lang-php">wp_list_comments()</code> übergeben wurden, wie etwa die maximale Verschachtelungstiefe der Kommentare. Zu guter Letzt beinhaltet <code class="lang-php">$depth</code> die Ebene des gerade angezeigten Kommentars als Zahl.
Zunächst wird in der Funktion ein Listenelement geöffnet, das mit <code class="lang-php">comment_class()</code> nützliche Klassen zugewiesen bekommt – ähnlich der bereits besprochenen Funktionen <code class="lang-php">post_class()</code> und <code class="lang-php">body_class()</code>. Dieses Listenelement muss später nicht geschlossen werden, da WordPress das von sich aus erledigt.<a href="#_ftn163" name="_ftnref163">[163]</a>
Für eine eindeutige Kommentar-ID wird in dem <code class="lang-markup">article</code>-Element <code class="lang-php">comment_ID()</code> genutzt, um die ID des Kommentars auszugeben.<a href="#_ftn164" name="_ftnref164">[164]</a> Mit <code class="lang-php">get_avatar()</code> wird das Gravatar-Bild des Kommentators eingebunden, sofern die E-Mail-Adresse mit dem Dienst verbunden ist.<a href="#_ftn165" name="_ftnref165">[165]</a> Der erste Parameter für die Funktion ist das Kommentar-Objekt, der zweite die Größe des quadratischen Bildes. Mit der Funktion <code class="lang-php">comment_author_link()</code> wird der Name des Kommentators ausgegeben, der auf die Website verlinkt, die im Kommentarformular eingegeben wurde.<a href="#_ftn166" name="_ftnref166">[166]</a>
Nach dem Namen des Autors soll als Permalink für den Kommentar das Datum innerhalb des <code class="lang-markup">time</code>-Elements ausgegeben werden.<a href="#_ftn167" name="_ftnref167">[167]</a> Um den Link des Kommentars zu ermitteln, wird dessen ID an die <code class="lang-php">get_comment_link()</code>-Funktion übergeben.<a href="#_ftn168" name="_ftnref168">[168]</a> Für das <code class="lang-markup">datetime</code>-Attribut wird mit <code class="lang-php">get_comment_time()</code> und dem Parameter <code class="lang-php">c</code> das Datum und die Uhrzeit im ISO-8601-Format ausgegeben.<a href="#_ftn169" name="_ftnref169">[169]</a>, <a href="#_ftn170" name="_ftnref170">[170]</a> Angezeigt werden soll das Datum nach dem Muster <code class="lang-markup">Uhrzeit @ Datum</code>, wobei das jeweilige Format aus dem Backend übernommen werden soll. Das Format aus dem Backend wird für das Datum mit der Funktion <code class="lang-php">get_comment_date()</code> ermittelt, für die Zeit mit <code class="lang-php">get_comment_time()</code>, wobei jeweils kein Parameter übergeben werden darf.<a href="#_ftn171" name="_ftnref171">[171]</a>
<pre class="lang-php"><code class="lang-php">&lt;?php if ( '0' == $comment-&gt;comment_approved ) { ?&gt;
&lt;p class="comment-awaiting-moderation"&gt;
&lt;?php
_e( 'Your comment is awaiting moderation.', 'hannover' );
?&gt;
&lt;/p&gt;
&lt;?php } ?&gt;</code></pre>
<em>Listing 41: Ausgabe eines Moderationshinweises in hannover_comments()</em>
Um dem Anwender einen Hinweis anzuzeigen, wenn sein Kommentar noch freigeschaltet werden muss, wird in Listing 41 überprüft, ob die Eigenschaft <code class="lang-php">comment_approved</code> des Kommentar-Objekts <code class="lang-php">0</code> ist, und in dem Fall ein Hinweis ausgegeben.
<pre class="lang-php"><code class="lang-php">&lt;div class="comment-content comment"&gt;
&lt;?php comment_text(); ?&gt;
&lt;?php edit_comment_link( __( 'Edit', 'hannover' ), '&lt;p class="edit-link"&gt;', '&lt;/p&gt;' ); ?&gt;
&lt;/div&gt;</code></pre>
<em>Listing 42: Ausgabe des Kommentar-Inhalts in hannover_comments()</em>
Der Code in Listing 42 kümmert sich um die Ausgabe des Kommentars – mit der Funktion <code class="lang-php">comment_text(</code>) wird der Inhalt ausgegeben.<a href="#_ftn172" name="_ftnref172">[172]</a> Um berechtigten Nutzern gleich einen Link ins Backend anzuzeigen, wo sie den Kommentar bearbeiten können, wird dieser nach dem Inhalt mit <code class="lang-php">edit_comment_link()</code> angezeigt.<a href="#_ftn173" name="_ftnref173">[173]</a> Der erste Parameter für die Funktion ist der Text, der verlinkt angezeigt werden soll, gefolgt von dem Markup davor und dahinter.
<pre class="lang-php"><code class="lang-php"> &lt;div class="reply"&gt;
&lt;?php comment_reply_link(
array(
'reply_text' =&gt; __( 'Reply', 'hannover' ),
'depth' =&gt; $depth,
'max_depth' =&gt; $args['max_depth']
)
); ?&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;?php
}</code></pre>
<em>Listing 43: Ausgabe des Antworten-Links in hannover_comments()</em>
Listing 43 zeigt das Ende der <code class="lang-php">hannover_comments()</code>-Funktion. Um die direkte Antwort auf einen anderen Kommentar zu ermöglichen, falls verschachtelte Kommentare auf der Website aktiviert sind, wird mit <code class="lang-php">comment_reply_link()</code> ein entsprechender Link ausgegeben.<a href="#_ftn174" name="_ftnref174">[174]</a> In dem Options-Array wird mit <code class="lang-php">reply_text</code> der anzuzeigende Text festgelegt, mit <code class="lang-php">depth</code> die Tiefe der Kommentarebene und über <code class="lang-php">max_depth</code> die Ebene, bis zu der Antworten möglich sind.
Standardmäßig ist es nun so, dass nach einem Klick auf den Link für die Antwort auf einen Kommentar die Seite komplett neu geladen wird. WordPress stellt allerdings ein Skript zur Verfügung, das nach einem Klick das Kommentarfeld unter dem entsprechenden Kommentar erscheinen lässt und die Antwort ohne Neuladen der Seite entgegennimmt. Alle Skripte und Stylesheets, die das Theme benötigt, werden in der <code class="lang-php">hannover_scripts_styles()</code>-Funktion in der <code class="lang-markup">functions.php</code> eingebunden. Dafür gibt es von WordPress die Funktionen <code class="lang-php">wp_enqueue_script()</code> für Skripte sowie <code class="lang-php">wp_enqueue_style()</code> für Stylesheets.<a href="#_ftn175" name="_ftnref175">[175]</a>, <a href="#_ftn176" name="_ftnref176">[176]</a> Vorteil dieser Funktionen gegenüber einer festen Integrierung in der <code class="lang-markup">header.php</code> ist beispielsweise, dass Abhängigkeiten von Skripten berücksichtigt werden können.
<pre class="lang-php"><code class="lang-php">function hannover_scripts_styles() {
if ( is_singular() &amp;&amp; comments_open()
&amp;&amp; get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'hannover_scripts_styles' );</code></pre>
<em>Listing 44: Einbinden des Comment-Reply-Skripts in hannover_scripts_styles()</em>
In Listing 44 ist die Funktion <code class="lang-php">hannover_scripts_styles()</code> zu sehen, die bisher nur das Skript für Kommentarantworten einbindet. Zunächst wird geprüft, ob das Skript überhaupt eingebunden werden muss, also ob sich der Nutzer auf einer Einzelseite befindet, deren Kommentare offen sind und ob verschachtelte Kommentare erlaubt sind. Ist das der Fall, wird mit <code class="lang-php">wp_euqueue_script()</code> das Skript mit dem Bezeichner <code class="lang-php">comment-reply</code> eingebunden. Da das Skript bereits im WordPress-Core registriert wird, reicht hier der erste Parameter aus, um das Skript einzubinden. Später, wenn das Theme beispielsweise eine Lightbox integriert, werden auch die übrigen Parameter zum Einsatz kommen.
<h4 id="anzeige-der-trackbacks">5.15.2 Anzeige der Trackbacks</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="lang-php">function hannover_trackbacks( $comment ) { ?&gt;
&lt;li &lt;?php comment_class(); ?&gt; id="comment-&lt;?php comment_ID(); ?&gt;"&gt;
&lt;?php _e( 'Trackback:', 'hannover' ); ?&gt;
&lt;?php comment_author_link(); ?&gt;
&lt;?php edit_comment_link(
__( '(Edit)', 'hannover' ),
'&lt;span class="edit-link"&gt;', '&lt;/span&gt;' );
}</code></pre>
<em>Listing 45: hannover_trackbacks() in der functions.php</em>
Die Trackbacks sollen in einer Liste angezeigt werden – vorne wird der übersetzbare Begriff <em>Trackback</em> angezeigt, gefolgt von dem Titel und einem Bearbeiten-Link für berechtigte Nutzer. Listing 45 zeigt die <code class="lang-php">hannover_trackbacks()</code>-Funktion, die dafür zuständig ist. Zuerst wird – wie aus der Funktion für die Kommentare bekannt – das Listenelement geöffnet. Anschließend wird <code class="lang-markup">Trackback:</code> angezeigt, gefolgt von dem Titel des verlinkenden Beitrags, der mit <code class="lang-php">comment_author_link()</code> ausgegeben wird. Abschließend wird mit <code class="lang-php">edit_comment_link()</code> ein Link ins Backend angezeigt, über den berechtigte Benutzer direkt zu der Bearbeitungsansicht des Trackbacks gelangen können.
<h3 id="404-template">5.16 404-Template</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Wenn es eine eingegebene Adresse nicht gibt, und WordPress daraus auch keine Weiterleitung auf einen bestehenden Inhalt erstellen kann, wird nach einer <code class="lang-markup">404.php</code> im Theme gesucht. Hier kann ein kurzer Hinweis platziert sowie das Suchformular angezeigt werden, damit der Nutzer sein Glück damit versuchen kann.
<pre class="lang-php"><code class="lang-php">&lt;?php get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;article id="post-0" class="post no-results not-found"&gt;
&lt;header class="entry-header"&gt;
&lt;h1 class="entry-title"&gt;
&lt;?php _e( 'Nothing Found', 'hannover' ); ?&gt;
&lt;/h1&gt;
&lt;/header&gt;
&lt;div class="entry-content"&gt;
&lt;p&gt;&lt;?php _e( 'Apologies, but no results were found for the
requested archive. Perhaps searching will help find a
related post.', 'hannover' ); ?&gt;&lt;/p&gt;
&lt;?php get_search_form(); ?&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;/main&gt;
&lt;?php get_sidebar();
get_footer();</code></pre>
<em>Listing 46: 404.php</em>
In Listing 46 ist die gesamte <code class="lang-markup">404.php</code> abgebildet. Nachdem auf altbekannte Art und Weise der Header des Themes eingebunden wurde, wird in dem <code class="lang-markup">article</code>-Element ein kurzer Hinweis ausgegeben. Anschließend wird <code class="lang-php">get_search_form()</code> aufgerufen, um das Suchformular einzubinden.<a href="#_ftn177" name="_ftnref177">[177]</a>
<h3 id="portfolio-uebersicht">5.17 Portfolio-Übersicht</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Wie bereits in Kapitel 2.1 ausgeführt, soll der Nutzer eine Seite festlegen können, auf der alle Arbeiten angezeigt werden. Dafür muss zuerst festgelegt werden können, welche Galerien und Bild-Beiträge er als Portfolio-Elemente nutzen möchte. Hier sollen zwei verschiedene Ansätze umgesetzt werden, um dem Nutzer mehr Flexibilität zu bieten: Entweder werden alle Beiträge vom Typ <em>Galerie</em> und <em>Bild</em> als Portfolio-Elemente behandelt, oder der Nutzer wählt eine Kategorie aus, der alle Portfolio-Elemente angehören müssen. Diese Einstellung soll im Customizer vorgenommen werden.
<h4 id="option-zur-auswahl-der-portfolio-kategorie">5.17.1 Option zur Auswahl der Portfolio-Kategorie</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Für die Auswahl der Kategorie wird eine <code class="lang-markup">select</code>-Liste erstellt, aus der der Nutzer wählen kann. Um diese Auswahl anstatt aller Galerie- und Bild-Beiträge zu nutzen, wird darüber eine Checkbox eingefügt, die der Nutzer anhaken muss. Die Funktion für den Customizer wird in die <code class="lang-markup">customizer.php</code> innerhalb des <code class="lang-markup">inc</code>-Ordners ausgelagert, damit die <code class="lang-markup">functions.php</code> übersichtlicher ist. Um die Datei in die <code class="lang-marku">functions.php</code> einzubinden, ist die Code-Zeile aus Listing 47 notwendig.
<pre class="lang-php"><code class="lang-php">require get_template_directory() . '/inc/customizer.php';</code></pre>
<em>Listing 47: Einbinden der customizer.php in die functions.php</em>
Mit dem <code class="lang-php">require</code>-Statement aus PHP wird die Datei eingebunden.<a href="#_ftn178" name="_ftnref178">[178]</a> Den Pfad zum Verzeichnis des Hannover-Themes gibt die <code class="lang-php">get_template_directory()</code>-Funktion aus.<a href="#_ftn179" name="_ftnref179">[179]</a>
<strong>Code für die Checkbox</strong>
<pre class="lang-php"><code class="lang-php">function hannover_customize_register( $wp_customize ) {
$wp_customize-&gt;add_setting(
'portfolio_from_category', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
'portfolio_from_category', array(
'label' =&gt; __( 'Use a category instead of all gallery and
image posts for portfolio elements', 'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_elements',
'settings' =&gt; 'portfolio_from_category'
)
);
$wp_customize-&gt;add_panel(
'theme_options', array(
'title' =&gt; __( 'Theme Options', 'hannover' ),
)
);
$wp_customize-&gt;add_section(
'portfolio_elements', array(
'title' =&gt; __( 'Portfolio elements', 'hannover' ),
'panel' =&gt; 'theme_options'
)
);
}
add_action( 'customize_register', 'hannover_customize_register' );</code></pre>
<em>Listing 48: Erstellung der Portfolio-Kategorie-Checkbox für den Customizer in der customizer.php</em>
In Listing 48 ist der Code abgebildet, der die Checkbox in den Customizer einfügt. <code class="lang-php">add_setting()</code> erwartet als ersten Parameter eine ID und danach ein Array von Optionen. Als Optionen können beispielsweise ein Standard-Wert sowie der Typ der Einstellung übergeben werden.<a href="#_ftn180" name="_ftnref180">[180]</a> An dieser Stelle wird kein Standard benötigt und die übrigen Default-Parameter können ebenso übernommen werden. Als <code class="lang-php">sanitize_callback</code> muss eine Funktion angegeben werden, die den eingegebenen Wert überprüft.
Die <code class="lang-php">add_control()</code>-Funktion, die für die Darstellung des Formularelements zuständig ist, erwartet ebenfalls als ersten Parameter eine ID. Als Parameter wird an <code class="lang-php">label</code> die Beschriftung übergeben, die im Customizer sichtbar ist. Darüber hinaus muss mit <code class="lang-php">type</code> der Formular-Typ angegeben werden – WordPress unterstützt hier die gängigen Typen.<a href="#_ftn181" name="_ftnref181">[181]</a> Um eine Checkbox zu erzeugen, muss der Schlüssel <code class="lang-php">checkbox</code> übergeben werden. Mit <code class="lang-php">section</code> wird angegeben, in welchem Teil des Customizers die Option dargestellt werden soll. Hier können entweder Core-Bereiche oder ein eigener angegeben werden. Der Wert für den <code class="lang-php">settings</code>-Schlüssel muss mit der ID aus der <code class="lang-php">add_setting()</code>-Methode übereinstimmen, für die das Formular-Element ist – wenn dieser Schlüssel nicht angegeben wird, dann nutzt WordPress die ID aus der <code class="lang-php">add_control()</code>-Methode.
Um die Theme-Optionen übersichtlich in einem eigenen Bereich zu bündeln, werden sie in einem <em>Panel</em> angeordnet. Innerhalb dieses Panels können mit <em>Sections</em> wiederum Unterbereiche erstellt werden, innerhalb derer die Formular-Elemente angezeigt werden. Die <code class="lang-php">add_panel()</code>-Funktion erwartet als ersten Parameter eine ID und im Anschluss ein Options-Array, in dem der Titel, eine Beschreibung sowie die Priorität des Panels übergeben werden können. An dieser Stelle wird nur der Titel angegeben.
Um den Bereich zu erstellen, in dem die Checkbox angezeigt werden soll, wird mit der <code class="lang-php">add_section()</code>-Methode der Portfolio-Bereich erstellt. Die ID muss dabei mit dem Wert übereinstimmen, der in <code class="lang-php">add_control()</code> für den <code class="lang-php">section</code>-Schlüssel übergeben wurde. Neben dem Titel wird die ID des Panels übergeben, in dem die Section angezeigt werden soll.
Als <code class="lang-php">sanitize_callback</code> wurde <code class="lang-php">hannover_sanitize_checkbox</code> angegeben, diese Funktion ist in Listing 49 abgebildet, die aus der hilfreichen Code-Sammlung des Theme-Review-Teams übernommen ist.<a href="#_ftn182" name="_ftnref182">[182]</a> Innerhalb von <code class="lang-php">return</code> wird überprüft, ob der übergebene Wert gesetzt und <code class="lang-php">true</code> ist und in diesem Fall <code class="lang-php">true</code> zurückgegeben, andernfalls <code class="lang-php">false</code>.
<pre class="lang-php"><code class="lang-php">function hannover_sanitize_checkbox( $checked ) {
return ( ( isset( $checked ) &amp;&amp; true == $checked ) ? true : false );
}</code></pre>
<em>Listing 49: hannover_sanitize_checkbox() in der customizer.php</em>
<strong>Code für die Kategorie-Liste</strong>
Damit der Nutzer die Kategorie auswählen kann, aus der die Portfolio-Elemente entnommen werden sollen, muss eine <code class="lang-markup">select</code>-Liste erstellt werden, die alle Kategorien der WordPress-Installation enthält.
<pre class="lang-php"><code class="lang-php">$categories = get_categories();
$category_array = array();
if ( ! empty( $categories ) ) {
foreach ( $categories as $category ) {
$category_array[ $category-&gt;term_id ] = $category-&gt;name;
}
}
$wp_customize-&gt;add_setting(
'portfolio_category', array(
'sanitize_callback' =&gt; 'hannover_sanitize_select'
)
);
$wp_customize-&gt;add_control(
'portfolio_category', array(
'label' =&gt; __( 'Portfolio category', 'hannover' ),
'type' =&gt; 'select',
'section' =&gt; 'portfolio_elements',
'settings' =&gt; 'portfolio_category',
'choices' =&gt; $category_array,
'active_callback' =&gt; 'hannover_use_portfolio_category_callback'
)
);</code></pre>
<em>Listing 50: Kategorie-Liste in hannover_customize_register() in der customizer.php</em>
Der Code aus Listing 50 gehört in die <code class="lang-php">hannover_customize_register()</code>-Funktion. Um im Customizer ein <code class="lang-markup">select</code>-Formularelement erstellen zu können, muss ein Array mit den Auswahloptionen übergeben werden, das als Schlüssel das <code class="lang-markup">value</code>-Attribut und als jeweiligen Wert die sichtbare Beschriftung enthält. Um ein Array für die Kategorien zu erstellen, werden mit <code class="lang-php">get_categories()</code> sämtliche Kategorien als Array in <code class="lang-php">$categories</code> gespeichert.<a href="#_ftn183" name="_ftnref183">[183]</a> Anschließend wird ein leeres Array erzeugt, das später das Ergebnisarray sein wird. In einer Schleife werden die Kategorien durchlaufen und das Array gefüllt. Als Schlüssel wird immer die <code class="lang-php">term_id</code> der Kategorie festgelegt, als Wert der Name.
Um die Einstellung hinzuzufügen, wird erneut die <code class="lang-php">add_setting()</code>-Methode verwendet, deren Callback-Funktion später besprochen wird. Um das Formular-Element zu erzeugen, werden dem Array der <code class="lang-php">add_control()</code>-Methode die bereits aus Listing 48 bekannten Schlüssel übergeben. Der einzige Unterschied ist der Schlüssel <code class="lang-php">choices</code>, der bei einem Element von Typ <code class="lang-php">select</code> übergeben werden muss. Dieser <code class="lang-php">choices</code>-Schlüssel erwartet das Array mit den Auswahloptionen, das im Fall der Kategorie-Liste mit dem Array in der Variable <code class="lang-php">$category_array</code> vorbereitet wurde. Um das <code class="lang-markup">select</code>-Element nur anzuzeigen, wenn die Checkbox angewählt ist, wird ein <code class="lang-php">active_callback</code> übergeben.
Die Auswahl des Nutzers wird von <code class="lang-php">hannover_sanitize_select()</code> als Callback-Funktion geprüft, die in Listing 51 abgebildet ist und wie die Funktion für die Checkbox dem Code-Beispiel des Theme-Review-Teams entnommen ist.<a href="#_ftn184" name="_ftnref184">[184]</a>
<pre class="lang-php"><code class="lang-php">function hannover_sanitize_select( $input, $setting ) {
$input = sanitize_key( $input );
$choices = $setting-&gt;manager-&gt;get_control( $setting-&gt;id )-&gt;choices;
return (
array_key_exists( $input, $choices ) ? $input : $setting-&gt;default
);
}</code></pre>
<em>Listing 51: hannover_sanitize_select() in der customizer.php</em>
Dabei wird der Funktion als erster Parameter der Wert des gewählten Eintrags übergeben und als zweiter das Settings-Objekt. Zuerst wird mit <code class="lang-php">sanitize_key()</code> sichergestellt, dass der gewählte Wert nur aus kleinen alphanumerischen Zeichen, Bindestrichen und Unterstrichen besteht.<a href="#_ftn185" name="_ftnref185">[185]</a> Im Anschluss werden die Auswahlmöglichkeiten des Formularelements in der <code class="lang-php">$choices</code>-Variable gespeichert und danach überprüft, ob der Wert aus <code class="lang-php">$input</code> als Schlüssel in dem Array der vorhandenen Auswahlmöglichkeiten vorkommt. Ist das der Fall, wird der Wert zurückgegeben, andernfalls der Standard-Wert.
Die <code class="lang-php">hannover_use_portfolio_category_callback()</code>-Funktion, mit der geprüft wird, ob das <code class="lang-markup">select</code>-Element angezeigt werden muss, ist in Listing 52 abgebildet.
<pre class="lang-php"><code class="lang-php">function hannover_use_portfolio_category_callback( $control ) {
if ( $control-&gt;manager-&gt;get_setting(
'portfolio_from_category'
)-&gt;value() == 'checked' ) {
return true;
} else {
return false;
}
}</code></pre>
<em>Listing 52: hannover_use_portfolio_category_callback() in der customizer.php</em>
Wenn der Wert der <code class="lang-php">portfolio_from_category</code>-Checkbox <code class="lang-php">checked</code> entspricht, wird als Ergebnis <code class="lang-php">true</code> zurückgegeben, andernfalls <code class="lang-php">false</code>. Die erstellten Einstellungen im Customizer sind in Abbildung 7 zu sehen. Wenn der Haken nicht gesetzt ist, wird auch das Auswahl-Element für die Kategorie nicht angezeigt.
[caption id="attachment_2244" align="alignnone" width="755"]<img class="size-full wp-image-2244" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/screenshot-customizer-01.png" alt="Abbildung 7: Customizer-Einstellungen für die Auswahl der Portfolio-Kategorie" width="755" height="272" /> Abbildung 7: Customizer-Einstellungen für die Auswahl der Portfolio-Kategorie[/caption]
<h4 id="option-zum-auschluss-der-portfolio-elemente-vom-blog">5.17.2 Option zum Ausschluss der Portfolio-Elemente vom Blog</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Als weitere Funktion muss dem Nutzer ermöglicht werden, die Portfolio-Elemente vom Blog auszuschließen. Auch diese Funktion wird über eine einfache Checkbox gelöst, die im Customizer angezeigt wird. Listing 53, das den Code für diese Funktion anzeigt, ähnelt dem ersten Code-Teil aus Listing 48. Als Callback-Funktion wird die bereits verwendete <code class="lang-php">hannover_sanitize_callback()</code> eingesetzt und der Titel des Formularelements sowie die ID, die an <code class="lang-php">add_setting()</code> und <code class="lang-php">add_control()</code> übergeben wird, sind angepasst.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'exclude_portfolio_elements_from_blog', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
'exclude_portfolio_elements_from_blog', array(
'label' =&gt;
__( 'Exclude the portfolio elements from the blog',
'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_elements',
'settings' =&gt; 'exclude_portfolio_elements_from_blog'
)
);</code></pre>
<em>Listing 53: Portfolio-Elemente vom Blog ausschließen in hannover_register_customize()</em>
<h4 id="option-zum-festlegen-der-anzahl-von-portfolio-elementen-auf-einer-seite">5.17.3 Option zum Festlegen der Anzahl von Portfolio-Elementen auf einer Seite</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um dem Theme-Nutzer auch die Möglichkeit zu geben, die Portfolio-Ansicht mit einer Pagination zu versehen, muss er die Anzahl von Elementen für eine Seite angeben können.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_elements_per_page', array(
'default' =&gt; 0,
'sanitize_callback' =&gt; 'absint'
)
);
$wp_customize-&gt;add_control(
'portfolio_elements_per_page', array(
'label' =&gt;
__( 'Number of portfolio elements to show on one page
(0 to show all elements on one page).', 'hannover' ),
'type' =&gt; 'number',
'section' =&gt; 'portfolio_elements',
'settings' =&gt; 'portfolio_elements_per_page',
)
);</code></pre>
<em>Listing 54: Option zum Festlegen der Anzahl von Portfolio-Elemententen pro Seite</em>
Für diese Option wird ein Nummernfeld erstellt, das standardmäßig den Wert <code class="lang-php">0</code> hat. In Listing 54 ist der entsprechende Code zu sehen. Als Callback-Funktion wird <code class="lang-php">absint()</code> genutzt.<a href="#_ftn186" name="_ftnref186">[186]</a> Als <code class="lang-php">type</code> muss der <code class="lang-php">add_control()</code>-Methode der Wert <code class="lang-php">number</code> übergeben werden.
<h4 id="portfolio-elemente-auf-einer-seite-anzeigen">5.17.4 Portfolio-Elemente auf einer Seite anzeigen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Portfolio-Elemente auf einer Seite anzuzeigen, wird ein Seiten-Template erstellt, das der Nutzer beim Bearbeiten einer Seite im Backend auswählen kann. Um die Ordnerstruktur übersichtlich zu halten, werden die Seiten-Templates im Ordner <code class="lang-php">page-templates</code> platziert, die WordPress neben der obersten Theme-Ordner-Ebene nach Seiten-Templates durchsucht.<a href="#_ftn187" name="_ftnref187">[187]</a>
<strong>Das Seiten-Template</strong>
Um ein Seiten-Template zu erstellen, muss am Anfang der PHP-Datei ein Kommentar nach bestimmtem Schema geschrieben werden, damit WordPress erkennt, dass es sich um ein Seiten-Template handelt.<a href="#_ftn188" name="_ftnref188">[188]</a>
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template Name: Portfolio page
*/</code></pre>
<em>Listing 55: Kommentar zur Identifizierung des Seiten-Templates in der portfolio-page.php</em>
In Listing 55 ist der Anfang der <code class="lang-markup">portfolio-page.php</code>-Datei mit dem entsprechenden Kommentar zu sehen. Wichtig ist der Teil <code class="lang-php">Template Name:</code>, der WordPress mitteilt, dass es sich um ein Seiten-Template handelt.
<pre class="lang-php"><code class="lang-php">get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;header&gt;
&lt;h1 class="page-title"&gt;&lt;?php single_post_title(); ?&gt;&lt;/h1&gt;
&lt;/header&gt;</code></pre>
<em>Listing 56: Seitentitel auf der Portfolio-Übersicht in der portfolio-page.php</em>
Ebenso unspektakulär geht es in der Datei mit dem Inhalt von Listing 56 weiter. Die <code class="lang-markup">header.php</code> wird eingebunden und innerhalb des <code class="lang-markup">main</code>-Elements sowie einem <code class="lang-mark">header</code> wird der Titel der Seite ausgegeben.
Um nur Beiträge zu erhalten, die bestimmten Bedingungen entsprechen, muss eine angepasste Anfrage an die Datenbank gestellt werden. Dazu muss zunächst das Array erstellt werden, das die Bedingungen für die Abfrage enthält. Da es ganz grundsätzlich die zwei möglichen Fälle gibt, dass die Portfolio-Beiträge anhand der Kategorie oder nur anhand des Post-Formats ermittelt werden, müssen zwei Arrays erstellt werden – abhängig von der Wahl im Customizer wird dann das korrekte für die Anfrage verwendet.
<pre class="lang-php"><code class="lang-php">&lt;?php
$use_portfolio_category = get_theme_mod( 'portfolio_from_category' );
$portfolio_category = get_theme_mod( 'portfolio_category' );
$elements_per_page = get_theme_mod( 'portfolio_elements_per_page',
0 );
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
if ( $elements_per_page == 0 ) {
$elements_per_page = - 1;
}
if ( $use_portfolio_category == 'checked' &amp;&amp; $portfolio_category !== '' ) {
$args = array(
'posts_per_page' =&gt; $elements_per_page,
'paged' =&gt; $paged,
'tax_query' =&gt; array(
'relation' =&gt; 'AND',
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category ),
),
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
),
)
);
} else {
$args = array(
'posts_per_page' =&gt; $elements_per_page,
'tax_query' =&gt; 'tax_query' =&gt; array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
),
'paged' =&gt; $paged
);
}</code></pre>
<em>Listing 57: Vorbereitung der Argument-Arrays für die QP_Query</em>
In Listing 57 werden zunächst die Werte aus dem Customizer ermittelt, mit denen der Nutzer bisher die Portfolio-Übersicht beeinflussen kann. Dabei kommt immer die Funktion <code class="lang-php">get_theme_mod()</code> zum Einsatz, die als ersten Parameter die ID erwartet, die an die <code class="lang-php">add_setting()</code>-Methode übergeben wurde.<a href="#_ftn189" name="_ftnref189">[189]</a> Als zweiter Parameter kann ein Standard-Wert übergeben werden, wie bei der Anzahl der Portfolio-Elemente.
Damit die Pagination trotz angepasster Abfrage funktioniert, muss in der Datei <code class="lang-markup">portfolio-page.php</code> als nächstes der Wert für den Schlüssel <code class="lang-php">paged</code> vorbereitet werden, der in <code class="lang-php">$paged</code> gespeichert wird.<a href="#_ftn190" name="_ftnref190">[190]</a> Im Anschluss wird überprüft, ob der Nutzer bei der Anzahl der Elemente pro Seite eine <code class="lang-php">0</code> eingestellt hat, um keine Pagination zu erhalten. In diesem Fall wird der Wert auf <code class="lang-php">-1</code> geändert, da das als Wert bei dem Schlüssel <code class="lang-php">posts_per_page</code> für unendlich steht.
Danach wird geprüft, ob der Nutzer die Checkbox angehakt hat, um eine Portfolio-Kategorie zu verwenden und ob die Kategorie gesetzt ist. In dem Fall wird das Argument-Array für die Abfrage wie folgt zusammengebaut: Für die Beiträge pro Seite wird der Wert eingesetzt, der in <code class="lang-php">$elements_per_page</code> gespeichert ist. Für die korrekte Pagination bekommt der Schlüssel <code class="lang-php">paged</code> den vorbereiteten Wert aus der <code class="lang-php">$paged</code>-Variablen. Um Bedingungen zu erstellen, die die Taxonomien der Beiträge betreffen, gibt es den Schlüssel <code class="lang-php">tax_query</code>.<a href="#_ftn191" name="_ftnref191">[191]</a> Innerhalb dieses Schlüssels sind auch Beziehungen zwischen verschiedenen Bedingungen möglich, die mit dem <code class="lang-php">relation</code>-Schlüssel angegeben werden. In der <code class="lang-markup">portfolio-page.php</code> sollen die Beiträge geholt werden, die sowohl in der Kategorie, die der Nutzer ausgewählt hat, als auch vom Typ Galerie oder Bild sind.
Es müssen also die zwei Bedingungen der Kategorie und der Post-Formate mit <code class="lang-php">AND</code> verknüpft werden – dieser Wert wird an den Schlüssel <code class="lang-php">relation</code> übergeben. Im Anschluss wird die Kategorie-Bedingung formuliert, indem an das Array für den Schlüssel <code class="lang-php">taxonomy</code> der Wert <code class="lang-php">category</code> übergeben wird, dessen <code class="lang-php">term_id</code> der ID entsprechen soll, die die Kategorie besitzt, die vom Nutzer im Customizer ausgewählt wurde. Um auf bestimmte Post-Formate einzuschränken, wird im nächsten Array der Wert <code class="lang-php">post_format</code> genutzt. Der Slug dieser Taxonomie soll für den Beitrag entweder <code class="lang-php">post-format-gallery</code> oder <code class="lang-php">post-format-image</code> entsprechen.<a href="#_ftn192" name="_ftnref192">[192]</a>
Wenn der Nutzer hingegen keine Kategorie ausgewählt hat, wird als Wert für <code class="lang-php">tax_query</code> nur das Array für die Post-Format-Bedingung übergeben, sodass alle Beiträge vom Typ <em>Galerie</em> und <em>Bild</em> unabhängig von der Kategorie ausgegeben werden.
<pre class="lang-php"><code class="lang-php">$portfolio_query = new WP_Query( $args );
$temp_query = $wp_query;
$wp_query = null;
$wp_query = $portfolio_query;
if ( $portfolio_query-&gt;have_posts() ) {
while ( $portfolio_query-&gt;have_posts() ) {
$portfolio_query-&gt;the_post();
get_template_part('template-parts/content','portfolio-element');
}
}</code></pre>
<em>Listing 58: Durchführung der angepassten Query-Loop in der portfolio-page.php</em>
In Listing 58 ist die Durchführung und Vorbereitung der Beitragsschleife zu sehen. Um die Abfrage mit dem entsprechenden Argumente-Array durchzuführen, wird in <code class="lang-php">$portfolio_query</code> ein Objekt der <code class="lang-php">WP_Query</code>-Klasse erstellt, dem das Array übergeben wird. Um später wieder auf die Ursprungs-Query zugreifen zu können, wird diese in <code class="lang-php">$temp_query</code> zwischengespeichert und das Standard-Query-Objekt von WordPress, <code class="lang-php">$wp_query</code>, auf <code class="lang-php">Null</code> gesetzt. Im Anschluss wird dieser Variable das angepasste Query-Objekt aus <code>$portfolio_query</code> zugewiesen, damit die Funktion für die Pagination, die mit <code class="lang-php">$wp_query</code> arbeitet, später das korrekte Ergebnis ausgibt.
Nun können die bereits bekannten Methoden <code class="lang-php">have_posts()</code> und <code class="lang-php">the_post()</code> von dem Query-Objekt <code class="lang-php">$portfolio_query</code> genutzt werden, um die Beiträge in einer Schleife zu durchlaufen. Für die Ausgabe wird die Datei <code class="lang-markup">content-portfolio-element.php</code> eingebunden – für eine zweite Variante der Ausgabe muss dann lediglich diese Zeile mit dem <code class="lang-php">get_template_part()</code>-Aufruf verändert werden.
<pre class="lang-php"><code class="lang-php"> wp_reset_postdata();
the_posts_pagination( array( 'type' =&gt; 'list' ) );
$wp_query = null;
$wp_query = $temp_query; ?&gt;
&lt;/main&gt;
&lt;?php get_footer();</code></pre>
<em>Listing 59: Ende der portfolio-page.php</em>
Im Anschluss wird, wie in Listing 59 zu sehen, mit <code class="lang-php">wp_reset_postdata()</code> das globale <code class="lang-php">$post</code>-Objekt zurückgesetzt und danach mit <code class="lang-php">the_posts_pagination()</code> die Pagination ausgegeben.<a href="#_ftn193" name="_ftnref193">[193]</a>, <a href="#_ftn194" name="_ftnref194">[194]</a> Zum Schluss wird <code class="lang-php">$wp_query</code> wieder das ursprüngliche Query-Objekt zugewiesen. Diese komplette Lösung mit der Query für die Pagination ist – entsprechend angepasst – der umfangreichen Antwort von Chip Bennett auf eine ähnliche Frage bei wordpress.stackexchange.com entnommen.<a href="#_ftn195" name="_ftnref195">[195]</a>
<strong>Ausgabe der Portfolio-Elemente in content-portfolio-page.php</strong>
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class( 'element' ); ?&gt; id="post-&lt;?php the_ID();
?&gt;"&gt;
&lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;
&lt;h2 class="screen-reader-text"&gt;&lt;?php the_title(); ?&gt;&lt;/h2&gt;
&lt;?php hannover_image_from_gallery_or_image_post(
'thumbnail', $post
); ?&gt;
&lt;/a&gt;
&lt;/article&gt;</code></pre>
<em>Listing 60: content-portfolio-page.php</em>
Listing 60 zeigt die Datei, die standardmäßig für die Ausgabe der Portfolio-Elemente zuständig ist. Durch den Parameter für die <code class="lang-php">post_class()</code>-Funktion wird eine zusätzliche Klasse eingefügt, damit die Elemente nachher mit CSS eindeutig von dem alternativen Layout abgegrenzt werden können.<a href="#_ftn196" name="_ftnref196">[196]</a> Innerhalb des <code class="lang-markup">article</code>-Elements wird der verlinkte Titel für Screen-Reader-Nutzer ausgegeben sowie <code class="lang-php" style="word-wrap: break-word; white-space: normal;">hannover_image_from_gallery_or_image_post()</code> aufgerufen, um das erste Bild aus dem Galerie- oder Bild-Beitrag anzuzeigen. Damit diese Funktion etwas flexibler ist und eventuell noch an weiteren Stellen genutzt werden kann, wird als erster Parameter die gewünschte Größe des Bildes übergeben, gefolgt von dem Post-Objekt.
<pre class="lang-php"><code class="lang-php">function hannover_image_from_gallery_or_image_post( $size, $post ) {
if ( has_post_thumbnail() ) {
the_post_thumbnail( $size );
} else {</code></pre>
<em>Listing 61: Anfang der hannover_image_from_gallery_or_image_post() in der functions.php</em>
In Listing 61 sind die ersten Zeilen dieser Funktion zu sehen. Der Nutzer soll ein eigenes Vorschaubild über die Beitragsbild-Funktion festlegen können, weshalb zuerst mit <code class="lang-php">has_post_thumbnail()</code> geprüft wird, ob bei dem Beitrag ein Beitragsbild gesetzt ist.<a href="#_ftn197" name="_ftnref197">[197]</a> Ist das der Fall, wird dies in der gewünschten Größe ausgegeben.
<pre class="lang-php"><code class="lang-php">$post_format = get_post_format( $post );
if ( $post_format == 'gallery' ) {
$images = hannover_get_gallery_images( $post-&gt;ID );
$image = array_shift( $images );
$img_tag = wp_get_attachment_image( $image-&gt;ID, $size );
}</code></pre>
<em>Listing 62: Ausgabe des ersten Galerie-Bildes</em>
Wenn kein Beitragsbild gesetzt ist, müssen die beiden Post-Formate <em>Bild</em> und <em>Galerie</em> unterschiedlich behandelt werden, um jeweils das erste Bild zu ermitteln. Um zu prüfen, welches Post-Format der aktuelle Beitrag besitzt, wird in Listing 62 die Funktion <code class="lang-php">get_post_format()</code> genutzt, der das Post-Objekt übergeben wird. Wenn das Ergebnis des Aufrufs <code class="lang-php">gallery</code> ist, es sich bei dem Beitrag also um eine Galerie handelt, werden die Bilder der Galerien von diesem Beitrag über die <code class="lang-php">hannover_get_gallery_images()</code>-Funktion ermittelt, die ein Array von Bildern zurückgibt. Da nur das erste Bild benötigt wird, wird mit <code class="lang-php">array_shift()</code> alles außer dem ersten Array-Element gelöscht.<a href="#_ftn198" name="_ftnref198">[198]</a> Anschließend wird über die Funktion <code class="lang-php">wp_get_attachment_image()</code> das <code class="lang-markup">img</code>-Tag des Bildes in <code class="lang-php">$img_tag</code> gespeichert – als Parameter erwartet die Funktion die ID des Bildes sowie die Größe.<a href="#_ftn199" name="_ftnref199">[199]</a> Die Funktion <code class="lang-php">hannover_get_gallery_images()</code> wird nach Behandlung der aktuellen Funktion erläutert.
<pre class="lang-php"><code class="lang-php">elseif ( $post_format == 'image' ) {
$first_img_url = hannover_get_first_image_from_post_content();
$pattern = '/-\d+x\d+(\.\wWordPress$)/i';
$first_img_url = preg_replace( $pattern, '${1}', $first_img_url );
$first_img_id = attachment_url_to_postid( $first_img_url );
if ( $first_img_id == 0 ) {
$attachments = get_children( array(
'post_parent' =&gt; $post-&gt;ID,
'post_status' =&gt; 'inherit',
'post_type' =&gt; 'attachment',
'post_mime_type' =&gt; 'image',
'order' =&gt; 'ASC',
'orderby' =&gt; 'menu_order',
) );
$first_img = array_shift( $attachments );
$img_tag = wp_get_attachment_image( $first_img-&gt;ID, $size );
} else {
$img_tag = wp_get_attachment_image( $first_img_id, $size );
}
}</code></pre>
<em>Listing 63: Ausgabe des ersten Bildes eines Bild-Beitrags</em>
In Listing 63 ist der Code zu sehen, der das erste Bild eines <em>Bild</em>-Beitrags ausgibt. <code class="lang-php">hannover_get_first_image_from_post_content()</code> liefert die URL des ersten Bildes aus dem Beitrag zurück – auch diese Funktion wird nach Besprechung der aktuellen erläutert. Um wie bei dem ersten Bild der Galerie die Funktion <code class="lang-php">wp_get_attachment_image()</code> nutzen zu können, ist die ID des Bildes notwendig.
Seit WordPress 4.2 gibt es <code class="lang-php">attachment_url_to_postid()</code>, um von einer URL auf die ID zu kommen.<a href="#_ftn200" name="_ftnref200">[200]</a> Diese Funktion arbeitet nur dann korrekt, wenn die URL der vollständigen Bildgröße übergeben wird – nicht die einer kleineren Größe, die WordPress beim Upload eines Bildes generiert. Aus diesem Grund muss zuerst sichergestellt werden, dass die URL einer generierten Bildgröße angepasst wird, sodass sie der URL von der vollen Größe entspricht. WordPress fügt bei den generierten Größen vor die Dateiendung einen Teil nach dem Schema <code class="lang-markup">-BreitexHöhe</code>, also beispielsweise <code class="lang-markup">-800x430</code>, ein. Dieser Teil inklusive der folgenden Dateiendung kann durch den regulären Ausdruck <code class="lang-php">/-\d+x\d+(\.\wWordPress$)/i</code> beschrieben werden. Dieser Ausdruck wird mit der <code class="lang-php">preg_replace()</code>-Funktion auf die URL angewendet. Als ersten Parameter erwartet die Funktion den regulären Ausdruck, als zweiten das, womit die gefundene Stelle ersetzt werden soll und als dritten den String, der durchsucht werden soll. Ersetzt werden soll der Treffer durch die Dateiendung, weshalb diese im regulären Ausdruck von runden Klammern umschlossen ist, sodass sie mit <code class="lang-php">${1}</code> angesprochen werden kann. Falls das Bild in voller Größe eingefügt wurde, wird der reguläre Ausdruck nichts finden und die URL unverändert bleiben.
Danach wird die URL an <code class="lang-php">attachment_url_to_postid()</code> übergeben und die ID in <code class="lang-php">$first_img_id</code> gespeichert. Wenn diese Funktion kein Bild findet, wird <code class="lang-php">0</code> zurückgegeben – das kann beispielsweise der Fall sein, wenn der Nutzer kein Bild in den Beitrag eingefügt hat oder das Bild im Beitrag nicht in die eigene WordPress-Installation hochgeladen wurde. In diesem Fall wird versucht, mit <code class="lang-php">get_children()</code> die Bilder zu ermitteln, die zu dem Beitrag hochgeladen wurden. Hier werden dann auch Bilder gefunden, die nicht in den Beitrag eingefügt, aber dazu hochgeladen wurden. Dafür wird als Wert für <code class="lang-php">post_parent</code> die ID des Beitrags übergeben. Für <code class="lang-php">post_status</code> soll derselbe Wert genutzt werden, den der Beitrag hat. Gesucht werden nur die Anhänge vom Typ <code class="lang-php">image</code>, die in aufsteigender Reihenfolge sortiert werden sollen.
Auch hier wird ein Array von Objekten zurückgegeben, von dem wieder nur das erste gebraucht wird. Nach Einsatz von <code class="lang-php">array_shift()</code> wird die ID des Objekts an <code class="lang-php">wp_get_attachment_image()</code> übergeben. Wenn das Ergebnis aus dem <code class="lang-php">attachment_url_to_postid()</code>-Aufruf nicht <code class="lang-php">0</code> ist, kann gleich die <code class="lang-php">wp_get_attachment_image()</code>-Funktion aufgerufen werden.
<pre class="lang-php"><code class="lang-php"> echo $img_tag;
}
}</code></pre>
<em>Listing 64: Ende der hannover_image_from_gallery_or_image_post()</em>
Abschließend wird das <code class="lang-markup">img</code>-Element in der <code class="lang-php">$img_tag</code>-Variable ausgegeben, wie in Listing 64 dargestellt.
<pre class="lang-php"><code class="lang-php">function hannover_get_gallery_images( $post_id ) {
$post = get_post( $post_id );
if ( ! $post || empty ( $post-&gt;post_content ) ) {
return array();
}
$galleries = get_post_galleries( $post, false );
if ( empty ( $galleries ) ) {
return array();
}
$ids = array();
foreach ( $galleries as $gallery ) {
if ( ! empty ( $gallery['ids'] ) ) {
$ids = array_merge( $ids, explode( ',', $gallery['ids'] ) );
}
}
$ids = array_unique( $ids );
if ( empty ( $ids ) ) {
$attachments = get_children( array(
'post_parent' =&gt; $post_id,
'post_status' =&gt; 'inherit',
'post_type' =&gt; 'attachment',
'post_mime_type' =&gt; 'image',
'order' =&gt; 'ASC',
'orderby' =&gt; 'menu_order',
) );
if ( empty ( $attachments ) ) {
return array();
}
}
$images = get_posts(
array(
'post_type' =&gt; 'attachment',
'post_mime_type' =&gt; 'image',
'orderby' =&gt; 'post__in',
'numberposts' =&gt; 999,
'include' =&gt; $ids
)
);
if ( ! $images &amp;&amp; ! $attachments ) {
return array();
} elseif ( ! $images ) {
$images = $attachments;
}
return $images;
}</code></pre>
<em>Listing 65: Ermitteln der Galerie-Bilder in hannover_get_gallery_images()</em>
In Listing 65 ist die Funktion abgebildet, die die Bilder aus den Galerien eines Galerie-Beitrags herausholt – zum Großteil entspricht die Funktion einer Lösung von Thomas Scholz, die leicht angepasst wurde. Zunächst werden mit <code class="lang-php">get_post()</code> die Daten des Beitrags zur übergebenen ID in der <code class="lang-php">$post</code>-Variable gespeichert.<a href="#_ftn201" name="_ftnref201">[201]</a> Im Anschluss wird überprüft, ob der Beitrag nicht vorhanden oder leer ist. In beiden Fällen wird von der Funktion ein leeres Array zurückgegeben.
Mit <code class="lang-php">get_post_galleries()</code> können die Galerien aus einem Beitrag ermittelt werden.<a href="#_ftn202" name="_ftnref202">[202]</a> Zurückgegeben wird von der Funktion ein Array, das für jeden Galerie-Shortcode wiederum ein Array enthält, welches die Daten zu den Bildern bereitstellt. Danach wird geprüft, ob keine Galerien gefunden wurden und in dem Fall ein leeres Array zurückgegeben. Nun werden nur die IDs der Bilder benötigt, die als Galerie eingefügt wurden – dafür wird ein leeres Array angelegt und danach die Galerien nacheinander in einer <code class="lang-php">foreach</code>-Schleife durchlaufen. Wenn der Wert zu dem Schlüssel <code class="lang-php">ids</code> nicht leer ist, werden die mit Komma getrennten IDs an den Kommata zu Arrays aufgespalten. Dafür wird die <code class="lang-php">explode()</code>-Funktion genutzt, die einen String an einem übergebenen Zeichen – in diesem Fall das Komma – auftrennt und die einzelnen Bestandteile als Werte eines Arrays zurückgibt.<a href="#_ftn203" name="_ftnref203">[203]</a> Dieses Ergebnis-Array wird mit der <code class="lang-php">array_merge()</code>-Funktion an das bereits vorhandene Array <code class="lang-php">$ids</code> angehängt.<a href="#_ftn204" name="_ftnref204">[204]</a>
Anschließend werden mit <code class="lang-php">array_unique()</code> alle doppelt vorhandenen IDs aus dem zusammengesetzten Array entfernt.<a href="#_ftn205" name="_ftnref205">[205]</a> Falls das IDs-Array leer ist, wird mit derselben Vorgehensweise wie in Listing 63 versucht, Bilder zu ermitteln, die zu dem Beitrag hochgeladen wurden. Falls auch hier kein Ergebnis erzielt wird, wird ein leeres Array zurückgegeben. Um alle Informationen zu den Bildern zu bekommen, von denen die IDs ermittelt wurden, wird <code class="lang-php">get_posts()</code> aufgerufen.<a href="#_ftn206" name="_ftnref206">[206]</a> In dem Argumente-Array wird als Post-Typ <code class="lang-php">attachment</code> angegeben, als Mime-Typ <code class="lang-php">image</code>. Sortiert werden sollen die Bilder in der Reihenfolge, in der die IDs aus der <code class="lang-php">$ids</code>-Variable dem <code class="lang-php">include</code>-Schlüssel übergeben werden – das entspricht der Reihenfolge, wie sie in dem Beitrag vorkommen. Wenn danach weder Werte für die Variable <code class="lang-php">$images</code> noch <code class="lang-php">$attachment</code>s vorliegen, wird ein leeres Array zurückgegeben. Wenn nur <code class="lang-php">$images</code> leer ist, wurden keine Bild-Objekte aus dem <code class="lang-php">get_posts()</code>-Aufruf zurückgegeben und der <code class="lang-php">$images</code>-Variable wird der Wert von <code class="lang-php">$attachments</code> zugewiesen. Abschließend werden die Bilder zurückgegeben.
<pre class="lang-php"><code class="lang-php">function hannover_get_first_image_from_post_content() {
global $post;
$first_img = '';
$output = preg_match( '/&lt;img.+src=[\'"]([^\'"]+)[\'"].*&gt;/i',
$post-&gt;post_content, $matches );
if ( ! empty( $matches[1] ) ) {
$first_img = $matches[1];
}
return $first_img;
}</code></pre>
<em>Listing 66: hannover_get_first_image_from_post_content() in functions.php</em>
In Listing 66 ist die Funktion abgebildet, die die URL des ersten Bildes aus dem Beitragsinhalt extrahiert. Dafür wird zuerst das Post-Objekt zugänglich gemacht und eine leere Variable angelegt. Mit der Funktion <code class="lang-php">preg_match()</code> kann ein String nach dem ersten Vorkommen eines bestimmten Musters durchsucht werden – hier ein <code class="lang-markup">img</code>-Element.<a href="#_ftn207" name="_ftnref207">[207]</a> Die URL wird in dem regulären Ausdruck in Klammern geschrieben, sodass dieser Teil in der <code class="lang-markup">$matches</code>-Variable gespeichert wird. Als zu durchsuchender String ist mit <code class="lang-php">$post-&gt;post_content</code> der Inhalt des Beitrags angegeben.
Im Anschluss wird überprüft, ob der Schlüssel <code class="lang-php">1</code> des Arrays einen Wert, nämlich die URL des ersten <code class="lang-markup">img</code>-Elements, enthält. Ist das der Fall, wird dieser Wert in <code class="lang-php">$first_img</code> gespeichert und die URL zurückgegeben.
<h4 id="portfolio-elemente-vom-blog-ausschliessen">5.17.5 Portfolio-Elemente vom Blog ausschließen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Portfolio-Elemente auszuschließen, muss in der Blog- und Archiv-Übersicht die Query angepasst werden – ungefähr in der Art und Weise, wie das in der <code class="lang-markup">portfolio-page.php</code> geschehen ist. Dafür muss vor <code class="lang-php">if ( have_posts() ) {</code> aus Listing 14 auf Seite 33 der Code eingefügt werden, der nachfolgend schrittweise erläutert wird.
<pre class="lang-php"><code class="lang-php">$exclude_portfolio_elements = get_theme_mod(
'exclude_portfolio_elements_from_blog' );
if ( $exclude_portfolio_elements == 'checked' ) {
$use_portfolio_category = get_theme_mod(
'portfolio_from_category' );
$portfolio_category = get_theme_mod( 'portfolio_category' );
$paged = ( get_query_var( 'paged' ) ) ?
get_query_var( 'paged' ) : 1;
if ( $use_portfolio_category == 'checked'
&amp;&amp; $portfolio_category !== '' ) {
$args = array(
'category__not_in' =&gt; array( $portfolio_category ),
'paged' =&gt; $paged,
);
} else {
$args = array(
'paged' =&gt; $paged,
'tax_query' =&gt; array(
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery', 'post-format-image' ),
'operator' =&gt; 'NOT IN'
),
)
);
}</code></pre>
<em>Listing 67: Vorbereitung der Index-Query ohne Portfolio-Objekte in der index.php</em>
Listing 67 zeigt den Code, der die Argument-Arrays für <code class="lang-php">WP_Query</code> vorbereitet, wie es in etwa bereits aus Listing 57 von Seite 64 bekannt ist. Zuerst wird mit der Funktion <code class="lang-php">get_theme_mod()</code> und dem übergebenen Parameter der Wert der Checkbox ermittelt. Wenn die Checkbox angehakt ist, muss die Query verändert werden. Nach diesem Test werden die Werte benötigt, ob das Portfolio anhand einer Kategorie erstellt werden soll und welche Kategorie dafür ausgewählt ist. Der <code class="lang-php">$paged</code>-Variable wird der aus Listing 57 bekannte Wert zugewiesen, um die korrekte Funktion der Pagination zu gewährleisten.
Danach wird überprüft, ob eine Kategorie für die Portfolio-Elemente genutzt werden soll und ob eine Kategorie gewählt ist. Wenn das der Fall ist, wird an das Argument-Array neben dem bekannten Wert für <code class="lang-php">paged</code> die Kategorie-ID an den Schlüssel <code class="lang-php">category__not_in</code> übergeben. So werden alle Artikel ausgeschlossen, die der Kategorie angehören, die der Nutzer im Customizer für die Portfolio-Elemente ausgewählt hat. Wenn keine Kategorie gewählt ist oder die Portfolio-Elemente alle <em>Bild</em>- und <em>Galerie</em>-Beiträge sein sollen, kommt wieder der Schlüssel <code class="lang-php">tax_query</code> zum Einsatz. Neben den bereits bekannten Schlüsseln wird mit der Angabe von <code class="lang-php">NOT IN</code> für <code class="lang-php">operator</code> festgelegt, dass diese Taxonomien nicht aufgeführt werden sollen. Damit sind die Beiträge mit den beiden entsprechenden Post-Formaten ausgeschlossen.
<pre class="lang-php"><code class="lang-php"> $index_query = new WP_Query( $args );
$temp_query = $wp_query;
$wp_query = null;
$wp_query = $index_query;
if ( $index_query-&gt;have_posts() ) {
if ( is_home() &amp;&amp; ! is_front_page() ) { ?&gt;
&lt;header&gt;
&lt;h1 class="page-title screen-reader-text"&gt;
&lt;?php single_post_title(); ?&gt;
&lt;/h1&gt;
&lt;/header&gt;
&lt;?php }
while ( $index_query-&gt;have_posts() ) {
$index_query-&gt;the_post();
get_template_part( 'template-parts/content',
get_post_format() );
}
}
wp_reset_postdata();
the_posts_pagination( array( 'type' =&gt; 'list' ) );
$wp_query = null;
$wp_query = $temp_query;
} else {</code></pre>
<em>Listing 68: Angepasste Query in der index.php für Ausgabe ohne Portfolio-Elemente</em>
Im Anschluss wird die Query in Listing 68 nach demselben Prinzip umgesetzt, wie bereits in Listing 58 und Listing 59 auf Seite 66 beschrieben.
<h3 id="archiv-ansicht">5.18 Archiv-Ansicht</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<h4 id="optionen-fuer-die-archiv-funktion">5.18.1 Optionen für die Archiv-Funktion</h4>
Der Nutzer soll Elemente für das Archiv durch Zuweisen einer Kategorie festlegen können, wobei standardmäßig kein Archiv verwendet wird. Um die Optionen im Customizer umzusetzen, wird eine Lösung mit Radio-Buttons und abhängig von der Auswahl eingeblendeten Formular-Elementen umgesetzt, vom Prinzip ähnlich der Lösung für die Portfolio-Kategorie.
<strong>Radio-Buttons</strong>
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_archive', array(
'default' =&gt; 'no_archive',
'sanitize_callback' =&gt; 'hannover_sanitize_select'
)
);
$wp_customize-&gt;add_control(
'portfolio_archive', array(
'label' =&gt; __(
'Choose if you want to select
portfolio elements for the archive.',
'hannover'
),
'type' =&gt; 'radio',
'section' =&gt; 'portfolio_archive',
'settings' =&gt; 'portfolio_archive',
'choices' =&gt; array(
'no_archive' =&gt; 'No archive',
'archive_category' =&gt; 'Archive category',
)
)
);</code></pre>
<em>Listing 69: Radio-Buttons im Customizer für das Portfolio-Archiv</em>
In Listing 69 wird für die <code class="lang-php">add_setting()</code>-Methode diesmal mit <code class="lang-php">no_archive</code> auch ein Standard-Wert vergeben, damit ein Radio-Button ausgewählt ist. Als Sanitization-Callback kann dieselbe Funktion verwendet werden, wie für die Select-Liste. In <code class="lang-php">add_control()</code> wird als Typ <code class="lang-php">radio</code> angegeben und als Section <code class="lang-php">portfolio_archive</code>. An den Schlüssel <code class="lang-php">choices</code> werden als Array die zwei Radio-Buttons mit ihrer Beschriftung und dem Schlüssel übergeben. Der Code für die neue Section ist in Listing 70 zu sehen und vom Prinzip bereits aus Kapitel 5.17.1 bekannt.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_section(
'portfolio_archive', array(
'title' =&gt; __( 'Portfolio archive', 'hannover' ),
'panel' =&gt; 'theme_options'
)
);</code></pre>
<em>Listing 70: Portfolio-Archive-Section im Customizer</em>
<strong>Archiv-Kategorie</strong>
Die Einstellung für die Archiv-Kategorie ähnelt deutlich der für die Auswahl der Portfolio-Kategorie und ist in Listing 71 abgebildet.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_archive_category', array(
'sanitize_callback' =&gt; 'hannover_sanitize_select'
)
);
$wp_customize-&gt;add_control(
'portfolio_archive_category', array(
'label' =&gt; __( 'Archive category', 'hannover' ),
'type' =&gt; 'select',
'section' =&gt; 'portfolio_archive',
'settings' =&gt; 'portfolio_archive_category',
'choices' =&gt; $category_array,
'active_callback' =&gt; 'hannover_choice_callback'
)
);</code></pre>
<em>Listing 71: Archiv-Kategorie im Customizer</em>
Ein wichtiger Unterschied ist die angepasste Funktion für <code class="lang-php">active_callback</code>.
<pre class="lang-php"><code class="lang-php">function hannover_choice_callback( $control ) {
$radio_setting = $control-&gt;manager-&gt;
get_setting( 'portfolio_archive' )-&gt;value();
$control_id = $control-&gt;id;
if ( $control_id == 'portfolio_archive_category'
&amp;&amp; $radio_setting == 'archive_category' ) {
return true;
}
return false;
}</code></pre>
<em>Listing 72: hannover_choice_callback() in der customizer.php</em>
In Listing 72 ist die Funktion zu sehen, die für die situationsabhängige Anzeige der Formularelemente für die Archiv-Kategorie zuständig ist. In <code class="lang-php">$radio_setting</code> wird der Wert des ausgewählten Radio-Buttons und in <code class="lang-php">$control_id</code> der eindeutige Bezeichner des Formularelements, von dem der Callback aufgerufen wurde, gespeichert. Anschließend wird in einer <code class="lang-php">if</code>-Bedingung geprüft, ob das Element für die Archiv-Kategorie den Callback aufgerufen hat und das entsprechende Radio-Element gewählt ist – in dem Fall wird <code class="lang-php">true</code> zurückgegeben, ansonsten <code class="lang-php">false</code>.
Zum Schluss soll dem Nutzer noch ermöglicht werden, äquivalent zu der Zahl von Portfolio-Elementen pro Seite auch die Anzahl von archivierten Elementen je Seite einzustellen. Dafür wird einfach der Code aus Listing 54 von Seite 62 übernommen und die Beschreibung etwas angepasst sowie der eindeutige Bezeichner von Setting und Control auf <code class="lang-php">portfolio_archive_elements_per_page</code> geändert – das Ergebnis ist in Listing 73 zu sehen.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_archive_elements_per_page', array(
'default' =&gt; 0,
'sanitize_callback' =&gt; 'absint'
)
);
$wp_customize-&gt;add_control(
'portfolio_archive_elements_per_page', array(
'label' =&gt; __( 'Number of archived portfolio elements to show on
one page (0 to show all elements on one page).', 'hannover' ),
'type' =&gt; 'number',
'section' =&gt; 'portfolio_archive',
'settings' =&gt; 'portfolio_archive_elements_per_page',
)
);</code></pre>
<em>Listing 73: Option für Beitrags-Anzahl in Archiv-Ansicht</em>
<h4 id="archiv-elemente-auf-einer-seite-anzeigen">5.18.2 Archiv-Elemente auf einer Seite anzeigen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Archiv-Elemente auf einer Seite anzuzeigen, wird ein ähnliches Seiten-Template angelegt wie das, welches für die Portfolio-Übersicht erstellt wurde.
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template Name: Portfolio archive page
*/
get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;header&gt;
&lt;h1 class="page-title"&gt;&lt;?php single_post_title(); ?&gt;&lt;/h1&gt;
&lt;/header&gt;
&lt;?php $use_portfolio_category =
get_theme_mod( 'portfolio_from_category' );
$portfolio_category = get_theme_mod( 'portfolio_category' );
$archive_type = get_theme_mod( 'portfolio_archive' );
$archive_category = get_theme_mod(
'portfolio_archive_category' );
$elements_per_page = get_theme_mod(
'portfolio_archive_elements_per_page', 0 );
$paged =
( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array();
if ( $elements_per_page == 0 ) {
$elements_per_page = - 1;
}</code></pre>
<em>Listing 74: Anfang der Archiv-Seite in der portfolio-archive-page.php</em>
Listing 74 zeigt den Anfang der Archiv-Seite des Themes, das in der Datei <code class="lang-markup">portfolio-archive-page.php</code> in dem <code class="lang-markup">page-templates</code>-Ordner Platz findet. Zuerst kommt der Kommentar, damit WordPress das Seiten-Template erkennt. Anschließend werden der Header eingebunden und im <code class="lang-markup">main</code>-Element die notwendigen Informationen aus dem Customizer geholt. Wenn als Anzahl an Elementen pro Seite <code class="lang-php">0</code> gesetzt ist, wird der Wert wieder in <code class="lang-php">-1</code> umgewandelt, damit alle Elemente auf einer Seite angezeigt werden.
<pre class="lang-php"><code class="lang-php">if( $archive_category !== '' &amp;&amp; $archive_type == 'archive_category' ){
if ( $use_portfolio_category == 'checked'
&amp;&amp; $portfolio_category !== '' ) {
$args = array(
'posts_per_page' =&gt; $elements_per_page,
'paged' =&gt; $paged,
'tax_query' =&gt; array(
'relation' =&gt; 'AND',
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category ),
),
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
),
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
),
)
);
} else {</code></pre>
<em>Listing 75: Vorbereitung der Query-Argumente für das Archiv bei gewählter Portfolio-Kategorie</em>
Nachdem in Listing 75 geprüft wurde, ob eine Archiv-Kategorie gewählt und der entsprechende Radio-Button ausgewählt wurde, wird zuerst der Fall behandelt, dass die Portfolio-Elemente ebenfalls über eine Kategorie ausgewählt werden. Dafür wird geprüft, ob eine Kategorie ausgewählt wurde und die Checkbox gesetzt ist. Wenn das der Fall ist, dürfen nur Elemente angezeigt werden, die sowohl der Portfolio-Kategorie, die in <code class="lang-php">$portfolio_category</code> gespeichert ist, als auch der Archiv-Kategorie aus <code class="lang-php">$archive_category</code> zugewiesen sind. Darüber hinaus müssen die Beiträge entweder vom Post-Format <em>Bild</em> oder <em>Galerie</em> sein. Um diese Bedingung kümmert sich wieder der <code class="lang-php">tax_query</code>-Schlüssel, dem für jede der Einzelbedingung ein Array übergeben wird, die mit <code class="lang-php">AND</code> verknüpft werden.
<pre class="lang-php"><code class="lang-php"> $args = array(
'posts_per_page' =&gt; $elements_per_page,
'tax_query' =&gt; array(
'relation' =&gt; 'AND',
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
),
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
),
),
'paged' =&gt; $paged
);
}
}</code></pre>
<em>Listing 76: Vorbereitung der Query-Argumente für das Archiv ohne Portfolio-Kategorie</em>
Listing 76 zeigt die Vorbereitung für das Argument-Array, wenn keine Kategorie für die Portfolio-Elemente angegeben ist. In diesem Fall kann das Array für die Portfolio-Kategorie in dem <code class="lang-php">tax_query</code>-Schlüssel wegfallen, sodass alle Elemente angezeigt werden, die in der Archiv-Kategorie sind und das Format <em>Bild</em> oder <em>Galerie</em> haben.
<pre class="lang-php"><code class="lang-php"> $archive_query = new WP_Query( $args );
$temp_query = $wp_query;
$wp_query = null;
$wp_query = $archive_query;
if ( $archive_query-&gt;have_posts() ) {
while ( $archive_query-&gt;have_posts() ) {
$archive_query-&gt;the_post();
get_template_part( 'template-parts/content',
'portfolio-element' );
}
}
wp_reset_postdata();
the_posts_pagination( array( 'type' =&gt; 'list' ) );
$wp_query = null;
$wp_query = $temp_query; ?&gt;
&lt;/main&gt;
&lt;?php get_footer();</code></pre>
<em>Listing 77: Loop für die Archiv-Ansicht</em>
Der Code in Listing 77 entspricht dem aus Listing 58 und Listing 59 auf Seite 66 und gibt die Elemente aus.
<h4 id="archiv-elemente-aus-der-portfolio-uebersicht-ausschliessen">5.18.3 Archiv-Elemente aus der Portfolio-Übersicht ausschließen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Funktion des Archivs zu vervollständigen, dürfen Archiv-Elemente nicht auf der Portfolio-Seite angezeigt werden. Die Query muss demnach dahingehend verändert werden, dass Elemente, die der Archiv-Kategorie zugewiesen sind, nicht ausgegeben werden.
<pre class="lang-php"><code class="greyed"> &lt;h1 class="page-title"&gt;&lt;?php single_post_title(); ?&gt;&lt;/h1&gt;
&lt;/header&gt;</code> <code class="lang-php">&lt;?php $archive_type = get_theme_mod( 'portfolio_archive' );
$archive_category = get_theme_mod( 'portfolio_archive_category' );</code></pre>
<em>Listing 78: Ergänzung in der portfolio-page.php, um die Archiv-Customizer-Werte zu ermitteln</em>
Zusätzlich zu den bereits ermittelten Customizer-Werten müssen am Anfang der <code class="lang-marku">portfolio-page.php</code> noch die für das Archiv gespeichert werden. Dafür zuständig sind die beiden letzten Zeilen aus Listing 78, die ergänzt wurden – bereits vorhandener Code ist ausgegraut.
<pre class="lang-php"><code class="lang-php">if ( $archive_type !== 'archive_category' ) {
$archive_category = '';
}</code> <code class="greyed">if ( $elements_per_page == 0 ) {
$elements_per_page = - 1;</code></pre>
<em>Listing 79: Leeren der Archiv-Kategorie, wenn kein Archiv genutzt wird</em>
Es kann vorkommen, dass ein Nutzer zwar den Radio-Button gewählt hat, kein Archiv anzulegen, obwohl er vorher eins hatte. In diesem Fall ist die Kategorie noch gespeichert. In Listing 79 wird geprüft, ob bei den Radio-Buttons etwas anderes gewählt ist als das Kategorie-Archiv und dann der eventuell vorhandene Wert der Variablen, die in Listing 78 die Archiv-Kategorie speichert, geleert.
<pre class="lang-php"><code class="greyed">'tax_query' =&gt; array(
'relation' =&gt; 'AND',</code><code class="lang-php">
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
'operator' =&gt; 'NOT IN'
),</code><code class="greyed">
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category ),
),</code></pre>
<em>Listing 80: Anpassung des Argument-Arrays für die Portfolio-Query mit Kategorie</em>
In Listing 80 wird das Argument-Array für den Fall, dass die Portfolio-Elemente via Kategorie festgelegt werden, durch einen Zusatz innerhalb von <code class="lang-php">tax_query</code> erweitert. Durch die Angabe von <code class="lang-php">NOT IN</code> für <code class="lang-php">operator</code> werden alle Beiträge ausgeschlossen, die in der Kategorie für die Archive vorhanden sind.
<h3 id="kategorie-seiten-fuer-portfolio-elemente">5.19 Kategorie-Seiten für Portfolio-Elemente</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Der Nutzer soll neben der Portfolio-Übersicht die Möglichkeit bekommen, Portfolio-Elemente in Kategorien aufzuteilen und diese auf je einer Seite anzuzeigen. Wenn der Nutzer beispielsweise Portfolio-Elemente der Kategorie <em>Sports</em> zugewiesen hat, dann soll es möglich sein, eine Seite zu erstellen, auf der nur diese Portfolio-Elemente angezeigt werden.
Auch diese Funktion wird mit einem Seiten-Template umgesetzt. Im Customizer werden automatisch für jede Seite, die dieses Seiten-Template hat, drei Einstellungen eingefügt.
<h4 id="optionen-fuer-portfolio-seiten">5.19.1 Optionen für Portfolio-Seiten</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um jeweils ein Formularelement pro Seite mit dem entsprechenden Seiten-Template anzuzeigen, müssen zunächst diese Seiten ermittelt werden. In den nachfolgenden Code-Blöcken sind die bereits vorhandenen Zeilen wieder ausgegraut, die neuen hervorgehoben.
<pre class="lang-php"><code class="greyed">$wp_customize-&gt;add_control(
'portfolio_archive_elements_per_page', array(
'label' =&gt; __( 'Number of archived portfolio elements to show on
one page (0 to show all elements on one page).', 'hannover' ),
'type' =&gt; 'number',
'section' =&gt; 'portfolio_archive',
'settings' =&gt; 'portfolio_archive_elements_per_page',
)
);</code> <code class="lang-php">$portfolio_category_pages = get_posts(
array(
'post_type' =&gt; 'page',
'meta_key' =&gt; '_wp_page_template',
'meta_value' =&gt; 'page-templates/portfolio-category-page.php'
)
);</code></pre>
<em>Listing 81: Ermitteln der Seiten mit dem Kategorie-Seiten-Template</em>
In Listing 81 werden mit der <code class="lang-php">get_posts()</code>-Funktion die Seiten des entsprechenden Seiten-Templates ermittelt und in <code class="lang-php">$portfolio_category_pages</code> gespeichert.<a href="#_ftn208" name="_ftnref208">[208]</a> Um das Ergebnis auf Seiten einzuschränken, wird als <code class="lang-php">post_type</code> der Wert <code class="lang-php">page</code> übergeben. Um das Seiten-Template zu prüfen, können die beiden Datenbankspalten <code class="lang-php">meta_key</code> und <code class="lang-php">meta_value</code> genutzt werden. In der Zeile mit dem <code class="lang-php">meta_key</code>-Wert <code class="lang-php">_wp_page_template</code> wird das Template der Seite gespeichert. Wenn kein spezielles Template gewählt ist, ist der dazugehörende Wert der <code class="lang-php">meta_value</code>-Spalte <code class="lang-php">standard</code>. Sonst entspricht der Wert dem Dateinamen des Seiten-Templates, gegebenenfalls mit dem Pfad, wie in diesem Fall: <code class="lang-php" style="word-wrap: break-word; white-space: normal;">page-templates/portfolio-category-page.php</code>.
<pre class="lang-php"><code class="lang-php">if ( ! empty( $portfolio_category_pages ) ) {
foreach ( $portfolio_category_pages as $portfolio_category_page ) {
$id = $portfolio_category_page-&gt;ID;
$wp_customize-&gt;add_setting(
"portfolio_category_page_$id", array(
'sanitize_callback' =&gt; 'hannover_sanitize_select'
)
);</code></pre>
<em>Listing 82: Setting für jede Portfolio-Kategorie-Seite im Customizer</em>
Listing 82 zeigt den Anfang der Schleife, die im Anschluss an Listing 81 für jede Seite mit dem entsprechenden Seiten-Template die Customizer-Einstellungen baut. Zuerst muss allerdings geprüft werden, ob das Ergebnis aus <code class="lang-php">get_posts()</code> nicht leer ist. Wenn das so ist, startet eine <code class="lang-php">foreach</code>-Schleife für jede der einzelnen Seiten. Darin wird die ID der Seite in der Variable <code class="lang-php">$id</code> gespeichert, damit sie später platzsparend ausgegeben werden kann. Mit der <code class="lang-php">add_setting()</code>-Methode wird, wie bereits aus früheren Kapiteln bekannt, eine Einstellung für den Customizer angelegt.<a href="#_ftn209" name="_ftnref209">[209]</a> Damit die ID auch bei mehreren Seiten mit dem Seiten-Template eindeutig ist, wird an ein Präfix die ID der aktuellen Seite angehängt. Wichtig ist, dass die ID statt in eine einfache Prime in eine doppelte eingefasst wird, damit der PHP-Code ausgeführt wird.
<pre class="lang-php"><code class="lang-php">/* translators: Label for portfolio category pages customizer control.
s=page title */
$label = sprintf(
__( 'Choose portfolio category to show on “%s”', 'hannover' ),
esc_html( $portfolio_category_page-&gt;post_title )
);</code></pre>
<em>Listing 83: Generierung des Labels für die Kategorie-Auswahlliste</em>
Damit der Nutzer genau weiß, für welche Seite er gerade die anzuzeigende Kategorie auswählt, muss die Beschriftung des <code class="lang-markup">select</code>-Elements entsprechend dynamisch sein. Um die noch folgende <code class="lang-php">add_control()</code>-Methode übersichtlicher zu halten, wird die Beschriftung in Listing 83 generiert. Mit <code class="lang-php">sprintf()</code> wird der Platzhalter <code class="lang-php">%s</code> in der Beschriftung durch den Titel der Seite ersetzt, der mit <code class="lang-php">$portfolio_category_page-&gt;post_title</code> ermittelt wird.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_control(
"portfolio_category_page_$id", array(
'label' =&gt; $label,
'type' =&gt; 'select',
'section' =&gt; 'portfolio_category_pages',
'settings' =&gt; "portfolio_category_page_$id",
'choices' =&gt; $category_array,
)
);</code></pre>
<em>Listing 84: Hinzufügen des Formularelements für Kategorieauswahl</em>
In Listing 84 wird mit der add_control()-Methode das Formular-Element für das bereits erstellte Setting eingefügt.<a href="#_ftn210" name="_ftnref210">[210]</a> Um die Einzigartigkeit der ID zu sichern, wird vorgegangen wie in Listing 82 – nach derselben Art und Weise wird der Wert für setting gesetzt. Als Beschriftung wird der String aus Listing 83 angegeben, als Typ select und für den choices-Schlüssel kann das Array genutzt werden, das bereits für die Auswahl der Portfolio- und Archiv-Kategorie zum Einsatz gekommen ist.
Damit der Nutzer für jede der Seiten auch die Anzahl der anzuzeigenden Elemente pro Seite festlegen kann, wird innerhalb der Schleife des Weiteren ein Zahlen-Element erstellt.
<pre class="lang-php"><code class="lang-php"> $wp_customize-&gt;add_setting(
"portfolio_category_page_elements_per_page_$id", array(
'default' =&gt; 0,
'sanitize_callback' =&gt; 'absint'
)
);
$wp_customize-&gt;add_control(
"portfolio_category_page_elements_per_page_$id", array(
'label' =&gt; __( 'Number of elements to show on one page
(0 to show all).', 'hannover' ),
'type' =&gt; 'number',
'section' =&gt; 'portfolio_category_pages',
'settings' =&gt;
"portfolio_category_page_elements_per_page_$id",
)
);
}
}</code></pre>
<em>Listing 85: Erstellen des Zahlen-Elements für die Anzahl auf Portfolio-Kategorie-Seiten</em>
Listing 85 zeigt den dafür verantwortlichen Code. Für die Eindeutigkeit wird wieder die ID der Seite genutzt, ansonsten gleicht er dem Code aus Listing 54 auf Seite 62.
Als Section wird für beide Controls <code class="lang-php">portfolio_category_pages</code> angegeben, die in Listing 86 nach bekanntem Muster erstellt wird. Neu ist hier lediglich der Array-Schlüssel <code class="lang-php">description</code>, an den eine Beschreibung übergeben werden kann, die oberhalb der Elemente aus der Section angezeigt wird – dieser Code wird außerhalb der Schleife notiert.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_section(
'portfolio_category_pages', array(
'title' =&gt; __( 'Portfolio category pages', 'hannover' ),
'description' =&gt; __(
'Here you can choose the category to display on the
respective portfolio category page. The category must
include portfolio elements—otherwise all portfolio elements
will be displayed.', 'hannover' ),
'panel' =&gt; 'theme_options'
)
);</code></pre>
<em>Listing 86: Erstellung der Customizer-Section portfolio_category_pages</em>
<h4 id="portfolio-elemente-einer-kategorie-anzeigen">5.19.2 Portfolio-Elemente einer Kategorie anzeigen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Datei für das Seiten-Template heißt <code class="lang-marku">portfolio-category-page.php</code> und kommt zu den bereits erstellten Templates in den Ordner <code class="lang-markup">page-templates</code>.
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template Name: Portfolio category page
*/
get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;header&gt;
&lt;h1 class="page-title"&gt;&lt;?php single_post_title(); ?&gt;&lt;/h1&gt;
&lt;/header&gt;
&lt;?php $page_id = $post-&gt;ID;
$archive_type = get_theme_mod( 'portfolio_archive' );
$archive_category = get_theme_mod('portfolio_archive_category');
$use_portfolio_category = get_theme_mod(
'portfolio_from_category' );
$portfolio_category = get_theme_mod( 'portfolio_category' );
$portfolio_category_page_category = get_theme_mod(
"portfolio_category_page_$page_id" );
$elements_per_page = get_theme_mod(
"portfolio_category_page_elements_per_page_$page_id", 0 );
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if ( $archive_type !== 'archive_category' ) {
$archive_category = '';
}
if ( $elements_per_page == 0 ) {
$elements_per_page = - 1;
}</code></pre>
<em>Listing 87: Anfang der portfolio-category-page.php</em>
Listing 87 zeigt den Anfang der <code class="lang-markup">portfolio-category-page.php</code>. Zunächst wird die ID der Seite ermittelt und in <code class="lang-php">$page_id</code> gespeichert. Danach werden die notwendigen Werte aus dem Customizer abgerufen – neu im Vergleich zu Listing 74 auf Seite 77 sind hier lediglich die Werte für die Kategorie, die auf der Seite angezeigt werden soll, sowie die Elemente pro Seite. Bei beiden wird mit dem Zusatz <code class="lang-php">$page_id</code> der Wert aus dem Customizer geholt, der zur aktuellen Seite gehört. Auch die übrige Datei ähnelt stark der für die Portfolio-Übersicht. Neu ist lediglich, dass in den <code class="lang-php">tax_query</code>-Bereichen der Argument-Arrays eine Bedingung hinzukommt, nämlich die Kategorie, die der Nutzer für die aktuelle Seite im Customizer gewählt hat.
<pre class="lang-php"><code class="lang-php">if ( $use_portfolio_category == 'checked' &amp;&amp;
$portfolio_category !== '' ) {
$args = array(
'posts_per_page' =&gt; $elements_per_page,
'paged' =&gt; $paged,
'tax_query' =&gt; array(
'relation' =&gt; 'AND',
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
'operator' =&gt; 'NOT IN'
),
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category ),
),</code><code class="bold">
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category_page_category ),
),</code><code class="lang-php">
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
),
)
);</code></pre>
<em>Listing 88: Argument-Array mit Portfolio-Elementen aus einer Kategorie in der portfolio-category-page.php</em>
In Listing 88 ist damit im Vergleich zu dem Array aus der <code class="lang-markup">portfolio-page.php</code> lediglich der fett gedruckte Teil dazugekommen – der Rest ist bereits bekannt.
<pre class="lang-php"><code class="lang-php">} else {
$args = array(
'posts_per_page' =&gt; $elements_per_page,
'paged' =&gt; $paged,
'tax_query' =&gt; array(
'relation' =&gt; 'AND',
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
'operator' =&gt; 'NOT IN'
),</code><code class="bold">
array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category_page_category ),
),</code><code class="lang-php">
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
),
)
);
}</code></pre>
<em>Listing 89: Argument-Array ohne Portfolio-Kategorie in der portfolio-category-page.php</em>
Ähnlich sieht es in Listing 89 aus – auch hier ist das Argument-Array identisch mit dem aus der Portfolio-Übersicht, lediglich der Teil für die Seiten-Kategorie ist dazugekommen.
<pre class="lang-php"><code class="lang-php"> $portfolio_query = new WP_Query( $args );
$temp_query = $wp_query;
$wp_query = null;
$wp_query = $portfolio_query;
if ( $portfolio_query-&gt;have_posts() ) {
while ( $portfolio_query-&gt;have_posts() ) {
$portfolio_query-&gt;the_post();
get_template_part( 'template-parts/content',
'portfolio-element' );
}
}
wp_reset_postdata();
the_posts_pagination( array( 'type' =&gt; 'list' ) );
$wp_query = null;
$wp_query = $temp_query; ?&gt;
&lt;/main&gt;
&lt;?php get_footer();</code></pre>
<em>Listing 90: Angepasste Query in der portfolio-category-page.php</em>
Auch Listing 90 hält keine Neuerungen bereit. Die Query entspricht Eins zu Eins der aus Listing 58 und Listing 59 von Seite 66.
<h3 id="alternatives-layout-fuer-portfolio-elemente">5.20 Alternatives Layout für Portfolio-Elemente</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Ein anfangs formuliertes Ziel war, dass der Nutzer das Layout der Portfolio-Elemente in der Übersicht anpassen kann. Neben der bereits realisierten Version, dass nur das erste Bild angezeigt wird, soll eine weitere Layout-Version neben dem Bild zusätzlich den Titel und eine Beschreibung anzeigen.
Dafür muss der Nutzer zuerst im Customizer die Möglichkeit haben, das alternative Layout auszuwählen. Diese Möglichkeit soll ihm unabhängig voneinander für die Portfolio-Übersicht, die Archiv-Ansicht und jede Kategorie-Seite gegeben werden. Als Formularelement wird in allen Fällen eine einfache Checkbox eingesetzt.
<h4 id="alternatives-layout-in-portfolio-uebersicht">5.20.1 Alternatives Layout in Portfolio-Übersicht</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_alt_layout', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
'portfolio_alt_layout', array(
'label' =&gt; __( 'Use alternative layout for portfolio
overview', 'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_elements',
'settings' =&gt; 'portfolio_alt_layout'
)
);</code> <code class="greyed">
$wp_customize-&gt;add_setting(
'portfolio_archive', array(</code></pre>
<em>Listing 91: Option für alternatives Layout auf Portfolio-Übersicht</em>
In Listing 91 ist der Code abgebildet, der die Einstellung für den Layout-Wechsel in der Portfolio-Übersicht im Customizer erstellt, der fast identisch mit dem ersten Teil aus Listing 48 von Seite 57 ist. Angepasst sind hier lediglich die ID und Beschriftung.
Innerhalb der <code class="lang-mark">portfolio-page.php</code> muss nur ein geringfügiger Teil angepasst werden, um das andere Layout der Portfolio-Elemente anzuzeigen, wenn der Nutzer die Checkbox angehakt hat.
<pre class="lang-php"><code class="greyed">$wp_query = $portfolio_query;</code> <code class="lang-php">$portfolio_alt_layout = get_theme_mod( 'portfolio_alt_layout' );</code> <code class="greyed">if ( $portfolio_query-&gt;have_posts() ) {
while ( $portfolio_query-&gt;have_posts() ) {
$portfolio_query-&gt;the_post();</code><code class="lang-php">
if ( $portfolio_alt_layout == 'checked' ) {
get_template_part( 'template-parts/content',
'portfolio-element-alt' );
} else {</code><code class="greyed">
get_template_part( 'template-parts/content',
'portfolio-element' );</code><code class="lang-php">
}</code><code class="greyed">
}
}</code></pre>
<em>Listing 92: Angepasste Loop für alternatives Layout der Elemente in der Portfolio-Übersicht</em>
In Listing 92 sind die neu hinzugekommenen Code-Zeilen bunt dargestellt, die bereits vorhandenen ausgegraut. Vor dem Start der Loop muss mit der Funktion <code class="lang-php">get_theme_mod()</code> der Wert der <code class="lang-php">portfolio_alt_layout</code>-Einstellung ermittelt werden.<a href="#_ftn211" name="_ftnref211">[211]</a> Im Anschluss wird innerhalb der Loop mit einer <code class="lang-php">if</code>-Bedingung abgefragt, ob die Checkbox angehakt ist. Wenn das der Fall ist, wird die noch zu erstellende <code class="lang-markup">content-portfolio-element-alt.php</code> aus dem <code class="lang-markup">template-parts</code>-Ordner eingefügt, andernfalls die Datei, die nur das Bild anzeigt.
In dem alternativen Layout sollen neben dem ersten Bild auch der Titel sowie der Auszug sichtbar sein, der vom Autor in der Bearbeitungsansicht eines Beitrags festgelegt werden kann. Wenn keiner angelegt wurde, werden lediglich das Bild und der Titel angezeigt.
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class( 'element-alt' ); ?&gt;
id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;
&lt;?php hannover_image_from_gallery_or_image_post( 'medium_large',
$post ); ?&gt;
&lt;/a&gt;
&lt;div&gt;
&lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;
&lt;h2&gt;&lt;?php the_title(); ?&gt;&lt;/h2&gt;
&lt;/a&gt;
&lt;?php if ( has_excerpt() ) {
the_excerpt();
} ?&gt;
&lt;/div&gt;
&lt;/article&gt;</code></pre>
<em>Listing 93: Alternatives Layout in der content-portfolio-element-alt.php</em>
In Listing 93 ist der gesamte Code dieser Datei zu sehen. Innerhalb des Links wird mit <code class="lang-php" style="word-wrap: break-word; white-space: normal;">hannover_image_from_gallery_or_image_post()</code> das erste Bild ausgegeben, was bereits ab Listing 61 auf Seite 67 erläutert wurde. Als Größe wird hier <code class="lang-php">medium_large</code> angegeben, die seit WordPress 4.4 verfügbar ist. Im Anschluss werden innerhalb eines <code class="lang-markup">div</code>-Elements der verlinkte Titel sowie der Auszug ausgegeben – mit <code class="lang-php">has_excerpt()</code> wird geprüft, ob ein Auszug vorhanden ist und mit <code class="lang-php">the_excerpt()</code> wird er angezeigt.<a href="#_ftn212" name="_ftnref212">[212]</a>, <a href="#_ftn213" name="_ftnref213">[213]</a>
<h4 id="alternatives-layout-im-archiv">5.20.2 Alternatives Layout im Archiv</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Integration der Einstellungsmöglichkeit für das alternative Layout in der Archiv-Ansicht verläuft ähnlich wie bei der Portfolio-Übersicht.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_archive_alt_layout', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
'portfolio_archive_alt_layout', array(
'label' =&gt; __( 'Use alternative layout for archive',
'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_archive',
'settings' =&gt; 'portfolio_archive_alt_layout'
)
);</code> <code class="greyed">$portfolio_category_pages = get_posts(
array(</code></pre>
<em>Listing 94: Option für alternatives Layout auf der Archiv-Seite</em>
Listing 94 zeigt den Code für die Customizer-Option, die der aus Listing 91 gleicht. Auch die Anpassung in der <code class="lang-markup">portfolio-archive-page.php</code>, die in Listing 95 abgebildet ist, zeigt nichts Neues.
<pre class="lang-php"><code class="lang-php">$archive_alt_layout = get_theme_mod( 'portfolio_archive_alt_layout' );</code> <code class="greyed">if ( $archive_query-&gt;have_posts() ) {
while ( $archive_query-&gt;have_posts() ) {
$archive_query-&gt;the_post();</code><code class="lang-php">
if ( $archive_alt_layout == 'checked' ) {
get_template_part( 'template-parts/content', 'portfolio-element-alt' );
} else {</code><code class="greyed">
get_template_part( 'template-parts/content',
'portfolio-element' );</code><code class="lang-php">
}</code><code class="greyed">
}
}</code></pre>
<em>Listing 95: Angepasste Loop für alternatives Layout des Archivs</em>
<h4 id="alternatives-layout-fuer-portfolio-kategorie-seiten">5.20.3 Alternatives Layout für Portfolio-Kategorie-Seiten</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Auch für jede einzelne Seite vom Typ <em>Portfolio category page</em> soll der Nutzer das alternative Layout aktivieren können. Dafür muss die zusätzliche Option in die <code class="lang-markup">foreach</code>-Schleife aus Listing 82 von Seite 82 integriert werden.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
"portfolio_category_page_alt_layout_$id", array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
"portfolio_category_page_alt_layout_$id", array(
'label' =&gt; __( 'Use alternative layout', 'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_category_pages',
'settings' =&gt; "portfolio_category_page_alt_layout_$id"
)
);</code></pre>
<em>Listing 96: Option für alternatives Layout auf den Kategorie-Seiten</em>
Der Code aus Listing 96 steht am Ende dieser Schleife und macht im Prinzip nichts anderes als die beiden Optionen, die bereits besprochen wurden. Mit der Seiten-ID, die in $id gespeichert ist, wird nach demselben Schema wie bei den anderen Settings und Controls aus der Schleife eine eindeutige ID erzeugt.
Auch die Wahl der richtigen Template-Datei in der Seiten-Template-Datei, die in Listing 97 abgebildet ist, ist identisch mit der aus den vorangehenden zwei Unterkapiteln.
<pre class="lang-php"><code class="lang-php">$portfolio_category_alt_layout = get_theme_mod(
"portfolio_category_page_alt_layout_$page_id" );</code> <code class="greyed">if ( $portfolio_query-&gt;have_posts() ) {
while ( $portfolio_query-&gt;have_posts() ) {
$portfolio_query-&gt;the_post();</code><code class="lang-php">
if ( $portfolio_category_alt_layout == 'checked' ) {
get_template_part( 'template-parts/content',
'portfolio-element-alt' );
} else {</code><code class="greyed">
get_template_part( 'template-parts/content',
'portfolio-element' );</code><code class="lang-php">
}</code><code class="greyed">
}
}</code></pre>
<em>Listing 97: Angepasste Loop für alternatives Layout der Portfolio-Kategorie-Seiten</em>
<h3 id="einzelansicht-von-portfolio-elementen">5.21 Einzelansicht von Portfolio-Elementen</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Portfolio-Elemente sind Beiträge und werden mit der <code class="lang-markup">single.php</code> dargestellt. Es soll allerdings auf der Einzelansicht keine Sidebar angezeigt werden und auch keine Navigation zum nächsten und vorherigen Beitrag, wenn die Portfolio-Elemente vom Blog ausgeschlossen sind. Die Datei <code class="lang-mark">single.php</code> muss dafür etwas angepasst werden.
<pre class="lang-php"><code class="greyed">&lt;?php get_header();</code> <code class="lang-php">$portfolio_post = false;
$format = get_post_format( $post_id );
if ( $format == 'gallery' || $format == 'image' ) {
$use_portfolio_category = get_theme_mod(
'portfolio_from_category' );
if ( $use_portfolio_category == 'checked' ) {
$portfolio_category = get_theme_mod( 'portfolio_category' );
if ( has_category( $portfolio_category, $post ) ) {
$portfolio_post = true;
}
} else {
$portfolio_post = true;
}
} ?&gt;</code><code class="greyed">
&lt;main role="main"</code><code class="lang-php">&lt;?php if ( $portfolio_post ) {
echo ' class="portfolio-element"';
} ?&gt;</code><code class="greyed">&gt;
&lt;?php while ( have_posts() ) {
the_post();</code><code class="lang-php">
if ( $portfolio_post ) {
$exclude_portfolio_elements = get_theme_mod(
'exclude_portfolio_elements_from_blog' );
get_template_part(
'template-parts/content-single-portfolio' );
if ( $exclude_portfolio_elements != 'checked' ) {
the_post_navigation();
}
} else {</code><code class="greyed">
get_template_part(
'template-parts/content-single', get_post_format() );
the_post_navigation();</code><code class="lang-php">
}</code><code class="greyed">
if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
} ?&gt;
&lt;/main&gt;</code> <code class="lang-php">&lt;?php if ( ! $portfolio_post ) {</code><code class="greyed">
get_sidebar();</code> <code class="lang-php">}</code> <code class="greyed">get_footer();</code></pre>
<em>Listing 98: Anpassung der single.php für die Einzelansicht von Portfolio-Beiträgen</em>
Zunächst muss in Listing 98 ermittelt werden, ob es sich bei dem angezeigten Beitrag um ein Portfolio-Element handelt. Dafür wird zuerst eine Variable mit dem booleschen Wert <code class="lang-php">false</code> gefüllt, die später – sollte es sich um ein Portfolio-Element handeln – auf <code class="lang-php">true</code> gesetzt wird. Darüber hinaus wird das Post-Format des Beitrags über die <code class="lang-php">get_post_format()</code>-Funktion ermittelt, der das Post-Objekt übergeben wird.<a href="#_ftn214" name="_ftnref214">[214]</a>
Wenn es sich um einen Galerie- oder Bild-Beitrag handelt, wird mit <code class="lang-php">get_theme_mod()</code> der Wert der Portfolio-Kategorie-Checkbox ermittelt – als Wert wird die ID des Settings übergeben.<a href="#_ftn215" name="_ftnref215">[215]</a> Wenn die Checkbox angehakt ist, wird die ID der Kategorie ermittelt und mit der <code class="lang-php">has_category()</code>-Funktion überprüft, ob der aktuelle Beitrag dieser Kategorie zugewiesen ist – dafür wird als erster Parameter die ID und als zweiter das Post-Objekt übergeben.<a href="#_ftn216" name="_ftnref216">[216]</a> Ist die Bedingung wahr, wird der Wert von <code class="lang-php">$portfolio_post</code> auf <code class="lang-php">true</code> geändert.
Wenn das Portfolio nicht anhand einer Kategorie gebildet wird, es sich bei dem Beitrag aber um einen Bild- oder Galerie-Post handelt, wird die Variable ohne weitere Prüfungen auf <code class="lang-php">true</code> gesetzt. Damit die Einzelansicht später per CSS anders angesprochen werden kann, wird dem <code class="lang-markup">main</code>-Element die Klasse <code class="lang-markup">portfolio-element</code> mitgegeben, wenn <code class="lang-php">$portfolio_post</code> den Wert <code class="lang-php">true</code> enthält.
Statt innerhalb der Schleife nun einfach die normale Datei für die Einzelansicht einzubinden, wird überprüft, ob es sich um ein Portfolio-Element handelt und in dem Fall ermittelt, ob die Portfolio-Elemente vom Blog ausgeschlossen werden sollen. Danach wird die <code class="lang-markup">content-single-portfolio.php</code> aus dem <code class="lang-markup">template-parts</code>-Ordner eingebunden. Wenn die Blog-Beiträge <em>nicht</em> von den Portfolio-Elementen getrennt sind, wird mit <code class="lang-php">the_post_navigation()</code> die Navigation zum vorherigen und nächsten Beitrag ausgegeben.<a href="#_ftn217" name="_ftnref217">[217]</a> Wenn der Beitrag kein Portfolio-Element ist, wird die <code class="lang-markup">content-single.php</code> eingebunden.
Die letzte Anpassung ist im Bereich der Sidebar zu finden: Diese wird nur dann eingebunden, wenn es sich bei dem Beitrag nicht um ein Portfolio-Element handelt.
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class(); ?&gt; id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;header class="entry-header"&gt;
&lt;?php hannover_the_title( 'h1', false ); ?&gt;
&lt;span&gt;&lt;?php hannover_the_date(); ?&gt;&lt;/span&gt;
&lt;/header&gt;
&lt;div class="entry-content"&gt;
&lt;?php hannover_the_content();
wp_link_pages(); ?&gt;
&lt;/div&gt;
&lt;/article&gt;</code></pre>
<em>Listing 99: content-single-portfolio.php</em>
Die <code class="lang-markup">content-single-portfolio.php</code> ähnelt der <code class="lang-mark">content-single.php</code> aus Listing 33 auf Seite 48. Der einzige Unterschied ist, dass weder das Beitragsbild noch der Footer eingebunden werden.
<h3 id="portfolio-und-archiv-kategorien-vom-widget-ausschliessen">5.22 Portfolio- und Archiv-Kategorien vom Widget ausschließen</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Eventuell möchten die Nutzer die Kategorien für Archiv und Portfolio nicht in dem Kategorie-Widget angezeigt haben – vor allem dann nicht, wenn sie die Portfolio-Elemente vom Blog ausschließen. Für beide Kategorien wird jeweils eine Option in Form einer Checkbox im Customizer angelegt.
<h4 id="optionen-fuer-ausschluss-der-portfolio-und-archiv-kategorie-im-customizer">5.22.1 Optionen für Ausschluss der Portfolio- und Archiv-Kategorie im Customizer</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_remove_category_from_cat_widget', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
'portfolio_remove_category_from_cat_list', array(
'label' =&gt; __( 'Remove portfolio category from category widget',
'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_elements',
'settings' =&gt; 'portfolio_remove_category_from_cat_widget',
'active_callback' =&gt; 'hannover_use_portfolio_category_callback'
)
);</code> <code class="greyed">$wp_customize-&gt;add_setting(
'exclude_portfolio_elements_from_blog', array(</code></pre>
<em>Listing 100: Option zum Ausschluss der Portfolio-Kategorie</em>
In Listing 100 ist der Code abgebildet, der die Checkbox für den Ausschluss der Portfolio-Kategorie in den Customizer einfügt. Bei Listing 48 auf Seite 57 ist die Nutzung von den Methoden <code class="lang-php">add_setting()</code> und <code class="lang-php">add_control()</code> bereits näher erläutert worden. Die Callback-Funktion, die dafür sorgt, dass die Option nur angezeigt wird, wenn das Portfolio mit einer Kategorie gebildet werden soll, ist in Listing 52 auf Seite 60 näher beschrieben.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'portfolio_archive_remove_category_from_cat_widget', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox'
)
);
$wp_customize-&gt;add_control(
'portfolio_archive_remove_category_from_cat_widget', array(
'label' =&gt; __( 'Remove archive category from category widget',
'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'portfolio_archive',
'settings' =&gt;
'portfolio_archive_remove_category_from_cat_widget',
'active_callback' =&gt; 'hannover_choice_callback'
)
);</code> <code class="greyed">$wp_customize-&gt;add_setting(
'portfolio_archive_elements_per_page', array(</code></pre>
<em>Listing 101: Option zum Ausschluss der Archiv-Kategorie</em>
Der Code aus Listing 101 ist dem aus Listing 100 recht ähnlich. Die Option wird aber in einer anderen Section dargestellt und auch die Callback-Funktion ist nicht dieselbe. Diese in Listing 72 auf Seite 76 erläuterte Funktion muss um einen Teil erweitert werden. Nach dem gleichen Verfahren wie für die andere Option wird in Listing 102 geprüft, ob die Control diejenige zum Ausschluss der Archiv-Kategorie ist und ob der Radio-Button der für die Archiv-Kategorie ist.
<pre class="lang-php"><code class="greyed"> return true;</code> <code class="lang-php">} elseif (
$control_id == 'portfolio_archive_remove_category_from_cat_widget'
&amp;&amp; $radio_setting == 'archive_category' ) {
return true;
}</code> return false;</pre>
<em>Listing 102: Erweiterung der hannover_choice_callback()-Funktion</em>
<h4 id="entfernen-der-kategorien-aus-dem-widget">5.22.2 Entfernen der Kategorien aus dem Widget</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um die Argumente für die Anzeige des Kategorie-Widgets zu filtern, gibt es den Hook <code class="lang-php">widget_categories_args</code>.<a href="#_ftn218" name="_ftnref218">[218]</a> Für das Ausschließend von Kategorien müssen dem Argument-Array, das dieser Filter verändern kann, die ID oder IDs mit dem Schlüssel <code class="lang-php">exclude</code> übergeben werden, der standardmäßig nicht vorhanden ist.
<pre class="lang-php"><code class="lang-php">function hannover_filter_category_widget( $cat_args ) {
$use_portfolio_category = get_theme_mod(
'portfolio_from_category' );
$archive_type = get_theme_mod( 'portfolio_archive' );
$exclude_portfolio_cat_from_widget = get_theme_mod(
'portfolio_remove_category_from_cat_widget' );
$exclude_archive_cat_from_widget = get_theme_mod(
'portfolio_archive_remove_category_from_cat_widget' );
$exclude = '';
if ( $exclude_portfolio_cat_from_widget == 'checked'
&amp;&amp; $use_portfolio_category == 'checked' ) {
$portfolio_category = get_theme_mod( 'portfolio_category' );
$exclude = $portfolio_category;
}
if ( $exclude_archive_cat_from_widget == 'checked'
&amp;&amp; $archive_type == 'archive_category' ) {
$archive_category = get_theme_mod(
'portfolio_archive_category' );
if ( $exclude != '' ) {
$exclude .= ', ' . $archive_category;
} else {
$exclude = $archive_category;
}
}
$cat_args['exclude'] = $exclude;
return $cat_args;
}
add_filter( 'widget_categories_args',
'hannover_filter_category_widget' );</code></pre>
<em>Listing 103: hannover_filter_category_widget() in der functions.php</em>
Listing 103 zeigt den kompletten Code, der für die Filterung verantwortlich ist. Ganz unten ist zu sehen, wie die Funktion an den entsprechenden Filter angehängt wird. Dadurch hat die Funktion <code class="lang-php">hannover_filter_category_widget()</code> über den Parameter <code class="lang-php">$cat_args</code> Zugriff auf die Argumente, die für die Anzeige des Widgets herangezogen werden und kann diese verändern. Zunächst muss in der Funktion der Zustand der Customizer-Einstellungen ermittelt werden – dafür wird, wie bereits häufiger verwendet, <code class="lang-php">get_theme_mod()</code> eingesetzt, an die der Bezeichner des Settings übergeben werden muss.<a href="#_ftn219" name="_ftnref219">[219]</a> Neben den Werten für den Ausschluss der jeweiligen Kategorie wird auch die Einstellung benötigt, ob überhaupt jeweils eine Kategorie genutzt werden soll. Es kann beispielsweise sein, dass zwar noch der Haken gesetzt ist, um die Portfolio-Kategorie auszuschließen, aber nicht der Haken, dass das Portfolio durch eine Kategorie erzeugt werden soll.
Im Anschluss wird die Variable <code class="lang-php">$exclude</code> mit einem leeren String befüllt und geprüft, ob der Haken für das Entfernen der Portfolio-Kategorie vom Widget gesetzt ist und eine Portfolio-Kategorie genutzt werden soll. Ist das der Fall, wird wiederum mit <code class="lang-php">get_theme_mod()</code> die ID der Kategorie ermittelt, die für das Portfolio gewählt ist, und danach der leeren <code class="lang-php">$exclude</code>-Variable zugewiesen.
Danach wird überprüft, ob die Archiv-Kategorie entfernt werden soll und ein Archiv angelegt ist. Auch hier muss die ID der Archiv-Kategorie ermittelt und unterschieden werden, ob <code class="lang-php">$exclude</code> bereits die Kategorie vom Portfolio enthält oder nicht. Wenn <code class="lang-php">$exclude</code> nicht leer ist, also eine Portfolio-Kategorie enthält, dann muss vor der Archiv-Kategorie-ID ein Komma eingefügt werden. Wenn die Variable leer ist, kann einfach die ID zugewiesen werden.
Abschließend wird der Wert von <code class="lang-php">$exclude</code> dem <code class="lang-php">exclude</code>-Schlüssel des Argument-Arrays zugewiesen und dieses zurückgegeben.
<h3 id="seiten-template-ohne-sidebar">5.23 Seiten-Template ohne Sidebar</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
In Kapitel 5.13 wurde die <code class="lang-markup">page.php</code> erstellt, die unter anderem eine Sidebar einbindet. Der Nutzer soll aber auch die Möglichkeit bekommen, eine Seite ohne Sidebar zu erstellen, auf der der Inhaltsbereich dann zentriert ist. Um dieses Verhalten umzusetzen, gleicht das Seiten-Template <code class="lang-markup">no-sidebar-page.php</code> in Listing 104 der <code class="lang-markup">page.php</code> aus Listing 30 auf Seite 46 bis auf den fehlenden Aufruf von <code class="lang-php">get_sidebar()</code>.<a href="#_ftn220" name="_ftnref220">[220]</a>
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template Name: Page without Sidebar
*/
get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', 'page' );
if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
} ?&gt;
&lt;/main&gt;
&lt;?php get_footer();</code></pre>
<em>Listing 104: no-sidebar-page.php</em>
<h3 id="seiten-templates-fuer-die-startseite">5.24 Seiten-Templates für die Startseite</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Auf der Startseite soll es möglich sein, einen Slider oder ein zufälliges Bild anzuzeigen. Am einfachsten ist das mit zwei Seiten-Templates umzusetzen, die jeweils mit einer Galerie arbeiten, welche in die Seite eingefügt wurde. Im Fall des Sliders werden alle Galerie-Bilder zurückgegeben und als Slider dargestellt, im Fall des zufälligen Bildes wird ein Bild aus dem Galerie-Shortcode ausgewählt und angezeigt.
<h4 id="slider-auf-der-startseite">5.24.1 Slider auf der Startseite</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um den Slider umzusetzen, wird das Skript <em>Owl Carousel</em> verwendet, das auf <em>jQuery</em> basiert.<a href="#_ftn221" name="_ftnref221">[221]</a> Da jQuery von WordPress eingebunden wird, wenn ein anderes Skript es voraussetzt, muss nur Owl Carousel nachgerüstet werden. Der Nutzer soll dabei angeben können, ob der Slider automatisch durchläuft und wie lange die Bilder jeweils angezeigt werden sollen.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_section(
'portfolio_elements', array(
'title' =&gt; __( 'Slider settings', 'hannover' ),
'panel' =&gt; 'theme_options'
)
);</code></pre>
<em>Listing 105: Customizer-Section für Slider-Einstellungen</em>
Diese beiden Optionen werden erneut im Customizer umgesetzt, wofür in Listing 105 eine neue Section angelegt wird. Dieser Code kommt ganz ans Ende der Funktion <code class="lang-php">hannover_customize_register()</code> in der <code class="lang-markup">customizer.php</code>.
Für die Option des automatischen Abspielens der eingesetzten Slider wird in Listing 106 eine einfache Checkbox, wie bereits aus Listing 48 auf Seite 57 bekannt, realisiert. Zugewiesen wird die Control der neuen Section <code class="lang-php">slider_settings</code>.
<pre class="lang-php"><code class="lang-php">$wp_customize-&gt;add_setting(
'slider_autoplay', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox',
)
);
$wp_customize-&gt;add_control(
'slider_autoplay', array(
'label' =&gt; __( 'Enable autoplay', 'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'slider_settings',
'settings' =&gt; 'slider_autoplay'
)
);</code> <code class="greyed">$wp_customize-&gt;add_panel(
'theme_options', array(</code></pre>
<em>Listing 106: Option zur Aktivierung des Auoplays für Slider</em>
Damit der Nutzer die Zeitspanne einstellen kann, die ein Bild beim Autoplay eingeblendet sein soll, kommt ein Formularelement von Typ <code class="lang-markup">number</code> zum Einsatz. Als Standard wird in Listing 107 <code class="lang-marku">3000</code> festgelegt, was drei Sekunden entspricht. Ansonsten ähnelt der Code stark dem Listing 54 auf Seite 62.
<pre class="lang-php"><code class="greyed"> 'settings' =&gt; 'slider_autoplay'
)
);</code> <code class="lang-php">$wp_customize-&gt;add_setting(
'slider_autoplay_time', array(
'default' =&gt; 3000,
'sanitize_callback' =&gt; 'absint'
)
);
$wp_customize-&gt;add_control(
'slider_autoplay_time', array(
'label' =&gt; __( 'Time in milliseconds to show each image with
autoplay', 'hannover' ),
'type' =&gt; 'number',
'section' =&gt; 'slider_settings',
'settings' =&gt; 'slider_autoplay_time',
)
);
</code></pre>
<em>Listing 107: Option zur Festlegung der Zeit pro Bild beim Autoplay</em>
Das Seiten-Template sieht fast genauso aus, wie die <code class="lang-markup">no-sidebar-page.php</code> und ist in Listing 108 abgebildet. Ein wichtiger Unterschied ist, dass hier nicht die <code class="lang-mark">content-page.php</code> eingebunden wird, sondern deren Inhalt ohne die Ausgabe des Headers direkt in die Datei eingefügt wird, damit der Seitentitel nicht angezeigt wird.
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template Name: Front page with slider
*/
get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php if ( have_posts() ) {
while ( have_posts() ) {
the_post(); ?&gt;
&lt;article &lt;?php post_class(); ?&gt; id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;div class="entry-content"&gt;
&lt;?php hannover_the_content();
wp_link_pages(); ?&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;?php if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
}
} else {
get_template_part( 'template-parts/content', 'none' );
} ?&gt;
&lt;/main&gt;
&lt;?php get_footer();</code></pre>
<em>Listing 108: slider-front-page.php</em>
Um auf der Seite eine <code>h1</code>-Überschrift anzuzeigen, wie es aus Gründen der Barrierefreiheit geboten ist, müssen die Bedingungen in der <code class="lang-markup">header.php</code> erweitert werden, die in Listing 8 und Listing 9 auf Seite 26 und 27 behandelt worden sind. Dabei wurde der Seitentitel abhängig von der angezeigten Seite entweder als <code class="lang-markup">h1</code>-Überschrift oder als Absatz ausgezeichnet – für das Seiten-Template mit dem Slider soll er als <code class="lang-markup">h1</code> ausgegeben werden. Listing 109 zeigt zwei Ausschnitte aus der <code class="lang-markup">header.php</code>, die diese Änderung umsetzen. Zuerst muss vor der Ausgabe mit der Funktion <code class="lang-php">get_page_template_slug()</code> der Pfad des Seiten-Template ermittelt werden, indem der Funktion die ID der Seite übergeben wird.<a href="#_ftn222" name="_ftnref222">[222]</a> Anschließend wird innerhalb der beiden <code class="lang-php">if</code>-Bedingungen neben der bereits vorhandenen Prüfung noch getestet, ob das Seiten-Template den Slug <code class="lang-markup">page-templates/slider-front-page.php</code> besitzt. Ist das der Fall, wird entweder das Logo oder der Seiten-Titel von einem <code class="lang-markup">h1</code>-Element umschlossen.
<pre class="lang-php"><code class="greyed">&lt;div class="site-branding"&gt;</code><code class="lang-php">
&lt;?php $page_template = get_page_template_slug( $post-&gt;ID );</code><code class="greyed">
if ( get_header_image() ) {
if ( </code><code class="lang-php">(</code><code class="greyed"> is_front_page() &amp;&amp; is_home() </code><code class="lang-php">) ||
$page_template == 'page-templates/slider-front-page.php' ) { ?&gt;</code><code class="greyed">
&lt;h1 class="logo"&gt;
[…]
} else {
if ( </code><code class="lang-php">(</code><code class="greyed"> is_front_page() &amp;&amp; is_home() </code><code class="lang-php">) ||
$page_template == 'page-templates/slider-front-page.php' ) { ?&gt;</code><code class="greyed">
&lt;h1 class="site-title"&gt;&lt;?php bloginfo( 'name' ); ?&gt;&lt;/h1&gt;</code></pre>
<em>Listing 109: Ausgabe des Seitentitels als h1 auf der Startseite mit Slider</em>
Das Owl-Carousel-Skript wird in der Datei <code class="lang-markup">owl-carousel.js</code> innerhalb eines noch anzulegenden <code class="lang-markup">js</code>-Ordners gespeichert, die CSS-Datei als <code class="lang-markup">owl-carousel.css</code> in dem Ordner <code class="lang-markup">css</code>. Um Parameter aus PHP zu JavaScript zu transferieren, damit die Entscheidung des Nutzers aus dem Customizer auch berücksichtigt werden kann, hat Samuel Wood einen hilfreichen Beitrag in seinem Blog verfasst.<a href="#_ftn223" name="_ftnref223">[223]</a> Er nutzt die Funktion <code class="lang-php">wp_localize_script(</code>), die eigentlich für Strings im JavaScript-Code gedacht ist, die übersetzbar sein sollen.<a href="#_ftn224" name="_ftnref224">[224]</a>
<pre class="lang-php"><code class="lang-php">global $post;
$page_template = get_page_template_slug( $post-&gt;ID );
if ( $page_template == 'page-templates/slider-front-page.php' ) {
wp_enqueue_style( 'owl-carousel', get_template_directory_uri()
. '/css/owl-carousel.css' );
wp_enqueue_script( 'owl-carousel', get_template_directory_uri()
. '/js/owl-carousel.js', array( 'jquery' ), false, true );
</code></pre>
<em>Listing 110: Einbinden der CSS- und JS-Datei für Owl Carousel</em>
Das Skript und die CSS-Datei von Owl Carousel werden in der <code class="lang-markup">functions.php</code> in die bereits bestehende <code class="lang-php">hannover_scripts_styles()</code>-Funktion eingebunden, wie Listing 110 zeigt. Zunächst muss allerdings geprüft werden, ob der aktuelle Seitenaufruf das Seiten-Template für den Slider auf der Startseite hat, damit das Skript und die CSS-Datei nur eingebunden werden, wenn es notwendig ist. Dafür wird mit <code class="lang-php">get_page_template_slug()</code> der Slug des Seiten-Templates ermittelt und anschließend geprüft, ob er dem Pfad des Seiten-Template entspricht.<a href="#_ftn225" name="_ftnref225">[225]</a> Ist das der Fall, müssen die Dateien des Slider-Skripts eingebunden werden. Als ersten Parameter wird an <code class="lang-php">wp_enqueue_style()</code> ein Bezeichner übergeben, gefolgt von dem Pfad zur Datei.<a href="#_ftn226" name="_ftnref226">[226]</a> Mit der Funktion <code class="lang-php">get_template_directory_uri()</code> wird der Pfad zum Theme-Ordner ausgegeben.<a href="#_ftn227" name="_ftnref227">[227]</a> Ein wichtiger Unterschied zu <code class="lang-php">get_stylesheet_directory_uri()</code> ist, dass die erste Funktion, wenn sie aus einem Child-Theme aufgerufen wird, den Pfad zum Eltern-Theme ausgibt, statt den Pfad zum Child-Theme.<a href="#_ftn228" name="_ftnref228">[228]</a> So funktioniert diese Referenz auch, wenn ein Child-Theme von Hannover genutzt wird.
An <code class="lang-php">wp_enqueue_script()</code> kann zusätzlich zum Bezeichner und dem Pfad noch ein Array aus Skripten angegeben werden, die vor diesem Skript geladen sein müssen – im Fall vom Owl Carousel ist das jQuery. Danach kann optional eine Version angegeben werden und als letztes ein boolescher Wert, der angibt, ob das Skript mit <code class="lang-php">wp_footer()</code> statt <code class="lang-php">wp_head()</code> ausgegeben werden soll – also im Footer des Themes.
<pre class="lang-php"><code class="greyed"> . '/js/owl-carousel.js', array( 'jquery' ), false, true );</code><code class="lang-php">
$slider_autoplay = get_theme_mod( 'slider_autoplay' );
$slider_autoplay_time = get_theme_mod( 'slider_autoplay_time',
3000 );
$params = array(
'autoplay' =&gt; $slider_autoplay,
'autoplayTimeout' =&gt; $slider_autoplay_time,
'prev' =&gt; __( 'Previous Slide', 'hannover' ),
'next' =&gt; __( 'Next Slide', 'hannover' ),
);
wp_localize_script( 'owl-carousel', 'OwlParams', $params );
}</code></pre>
<em>Listing 111: Parameter aus dem Customizer an das Slider-Skript übergeben</em>
Um die Lösung aus dem Beitrag von Samuel Wood zu nutzen, damit die Werte aus dem Customizer in der JavaScript-Datei verwendet werden können, wird Listing 111 benötigt. Zunächst werden mit <code class="lang-php">get_theme_mod()</code> die Werte aus dem Customizer ermittelt – bei der Zeit wird über den zweiten Parameter der Standard-Wert angegeben.<a href="#_ftn229" name="_ftnref229">[229]</a> Im Anschluss wird ein Array erstellt, in den die Werte eingetragen werden. Für <code class="lang-php">autoplay</code> und <code class="lang-php">autoplayTimeout</code> werden die entsprechenden Werte des Customizers eingesetzt, <code class="lang-php">prev</code> und <code class="lang-php">next</code> enthalten die übersetzbaren Beschriftungen für Screen-Reader-Nutzer, die den Vor- und Zurück-Buttons des Sliders zugewiesen werden.
Im nächsten Schritt muss die <code class="lang-php">wp_localize_script()</code>-Funktion aufgerufen werden. Als ersten Parameter erwartet sie den Bezeichner des Skripts, an den die Parameter übergeben werden sollen. Der zweite Parameter ist der Name des JavaScript-Objekts, über das die Argumente in der JavaScript-Datei zugänglich sind, der dritte Parameter ist der Name des Argument-Arrays.
<pre class="lang-js"><code class="lang-php">jQuery(document).ready(function () {
jQuery('.gallery').wrap("&lt;div class='slider'&gt;&lt;/div&gt;");
jQuery('.gallery').owlCarousel({
items: 1,
animateOut: "fadeOut",
animateIn: "fadeIn",
loop: true,
autoplay: OwlParams.autoplay,
autoplayTimeout: OwlParams.autoplayTimeout,
nav: true,
navText: [
'&lt;span class="screen-reader-text"&gt;' + OwlParams.prev +
'&lt;/span&gt;&lt;span aria-hidden="true"&gt;‹&lt;/span&gt;',
'&lt;span aria-hidden="true"&gt;›&lt;/span&gt;' +
'&lt;span class="screen-reader-text"&gt;'
+ OwlParams.next + '&lt;/span&gt;'],
});
});</code></pre>
<em>Listing 112: Initialisierung des Owl Carousel</em>
Um den Slider zu implementieren, muss nun in die Datei <code class="lang-markup">owl-carousel.js</code> gewechselt werden. Am Ende der Datei wird in Listing 112 zunächst mit der <code class="lang-js">ready()</code>-Funktion von jQuery sichergestellt, dass das Dokument fertig geladen ist.<a href="#_ftn230" name="_ftnref230">[230]</a> Anschließend wird um jedes Element mit der Klasse <code class="lang-markup">gallery</code> ein <code class="lang-markup">div</code> mit der Klasse <code class="lang-markup">slider</code> gelegt – Mittel der Wahl ist hierfür die <code class="lang-js">wrap()</code>-Funktion von jQuery, die als Parameter die HTML-Struktur erwartet, mit der das Element umschlossen werden soll.<a href="#_ftn231" name="_ftnref231">[231]</a> Um den Slider zu initialisieren, wird für die Elemente mit der <code class="lang-markup">gallery</code>-Klasse <code class="lang-js">owlCarousel()</code> ausgeführt, wie auf der Website des Skripts beschrieben.<a href="#_ftn232" name="_ftnref232">[232]</a>
Um die Standard-Optionen anzupassen, werden diese überschrieben.<a href="#_ftn233" name="_ftnref233">[233]</a> So wird mit <code class="lang-js">items</code> angegeben, dass nur ein Element angezeigt werden soll. Als Animation soll ein Ein- und Ausblenden genutzt werden und nach dem letzten Bild soll es wieder mit dem ersten weitergehen. Für den Schlüssel <code class="lang-js">autoplay</code> wird mit <code class="lang-js">OwlParams.autoplay</code> der Wert aus dem Customizer eingetragen, genauso für <code class="lang-js">autoplayTimeout</code>. Für <code class="lang-js">nav</code> wird <code class="lang-js">true</code> übergeben, damit Vor- und Zurück-Links angezeigt werden. Für <code class="lang-js">navText</code> wird ein Array aus den zwei übrigen Optionen gebildet, das über <code class="lang-php">wp_localize_script()</code> übergeben wurde, damit der Text für die Vor- und Zurück-Links übersetzbar ist. Dabei werden die Beschriftungen in HTML verpackt – im Frontend normal angezeigt werden soll jeweils ein Pfeil, der in einem <code class="lang-markup">span</code> durch das Attribut <code class="lang-markup">aria-hidden="true"</code> vor Screen-Readern versteckt wird. Für Screen-Reader-Nutzer hingegen ist das übersetzbare Label, das in einem <code class="lang-markup">span</code> mit der Klasse <code class="lang-markup">screen-reader-text</code> platziert wird, um es via CSS im Frontend zu verstecken.
<h4 id="zufaelliges-bild-auf-der-startseite">5.24.2 Zufälliges Bild auf der Startseite</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Das Seiten-Template für ein zufälliges Bild aus einer Galerie des Beitrags ist schnell erstellt, da alle notwendigen Funktionen bereits im Theme umgesetzt wurden. Für das Template wird die Datei <code class="lang-markup">random-image-front-page.php</code> angelegt und in den Ordner <code class="lang-markup">page-templates</code> gelegt.
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template Name: Front page with random image
*/
get_header(); ?&gt;
&lt;main role="main"&gt;
&lt;?php $images = hannover_get_gallery_images( $post-&gt;ID );
shuffle( $images );
$first_image = array_shift( $images ); ?&gt;
&lt;figure&gt;
&lt;?php if ( ! empty( $first_image ) ) {
echo wp_get_attachment_image( $first_image-&gt;ID, 'large' );
}
if ( ! empty( $first_image-&gt;post_title ) ) { ?&gt;
&lt;figcaption&gt;
&lt;?php echo $first_image-&gt;post_title; ?&gt;
&lt;/figcaption&gt;
&lt;?php } ?&gt;
&lt;/figure&gt;
&lt;/main&gt;
&lt;?php get_footer();</code></pre>
<em>Listing 113: random-image-front-page.php</em>
Die komplette Datei ist in Listing 113 abgebildet. Innerhalb des <code class="lang-marku">main</code>-Elements muss zunächst die <code class="lang-php">hannover_get_gallery_images()</code>-Funktion aufgerufen werden, um die Bilder aus dem oder den Gallery-Shortcodes zu ermitteln – detailliert erläutert wurde diese Funktion in Listing 65 auf Seite 71. Um ein zufälliges Bild aus dem Ergebnis anzuzeigen, muss das Array mit der <code class="lang-php">shuffle()</code>-Funktion gemischt und im Anschluss alles bis auf das erste Element mit <code class="lang-php">array_shift()</code> entfernt werden. <a href="#_ftn234" name="_ftnref234">[234]</a>, <a href="#_ftn235" name="_ftnref235">[235]</a> Innerhalb eines <code class="lang-markup">figure</code>-Elements wird dann durch Aufruf der <code class="lang-php">wp_get_attachment_image()</code>-Funktion und Übergabe der Bild-ID sowie der gewünschten Größe das <code class="lang-markup">img</code>-Tag für das Bild ausgegeben – vorher wird noch überprüft, ob ein Bild vorhanden ist.<a href="#_ftn236" name="_ftnref236">[236]</a>
Wenn im WordPress-Backend für das Bild ein Titel eingetragen ist, dann soll dieser in einem <code class="lang-markup">figcaption</code>-Element angezeigt werden. Zugänglich ist der Wert des Bildtitels über den Array-Schlüssel <code class="lang-php">post_title</code>, der zunächst auf einen Wert geprüft wird. Ist ein Wert vorhanden, wird dieser in dem Element ausgegeben.
<pre class="lang-php"><code class="greyed">if ( get_header_image() ) {
if ( ( is_front_page() &amp;&amp; is_home() ) ||
$page_template == 'page-templates/slider-front-page.php' || </code><code class="lang-php">
$page_template == 'page-templates/random-image-front-page.php' </code><code class="greyed">){?&gt;
&lt;h1 class="logo"&gt;
[…]
} else {
if ( ( is_front_page() &amp;&amp; is_home() ) ||
$page_template == 'page-templates/slider-front-page.php' || </code><code class="lang-php">
$page_template == 'page-templates/random-image-front-page.php' </code><code class="greyed">){?&gt;
&lt;h1 class="site-title"&gt;&lt;?php bloginfo( 'name' ); ?&gt;&lt;/h1&gt;</code></pre>
<em>Listing 114: Ausgabe des Seitentitels als h1 auf der Startseite mit zufälligem Bild</em>
Auch für dieses Seiten-Template muss der Seitentitel als <code class="lang-markup">h1</code>-Überschrift ausgegeben werden – die entsprechende Anpassung in der <code class="lang-markup">header.php</code>, von der Vorgehensweise bereits aus Listing 109 auf Seite 100 bekannt, ist in Listing 114 abgebildet.
<h3 id="galerien-als-slider-oder-einzelne-bilder">5.25 Galerien als Slider oder einzelne Bilder</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Der Nutzer soll entscheiden können, ob sämtliche Galerien auf der Seite als Slider statt als einzelne Bilder dargestellt werden sollen – wie im Seiten-Template mit Slider für die Startseite. Auch diese Option findet ihren Platz wieder im Customizer und wird mit einer Checkbox implementiert.
<pre class="lang-php"><code class="greyed"> 'settings' =&gt; 'slider_autoplay_time',
)
);</code> <code class="lang-php">$wp_customize-&gt;add_setting(
'galleries_as_slider', array(
'sanitize_callback' =&gt; 'hannover_sanitize_checkbox',
)
);
$wp_customize-&gt;add_control(
'galleries_as_slider', array(
'label' =&gt; __( 'Display all galleries as sliders',
'hannover' ),
'type' =&gt; 'checkbox',
'section' =&gt; 'slider_settings',
'settings' =&gt; 'galleries_as_slider'
)
);</code></pre>
<em>Listing 115: Option, alle Galerien als Slider darzustellen</em>
Listing 115 zeigt den im Prinzip bereits bekannten Code, um die Checkbox in den Customizer einzufügen. Als Section wird dieselbe genutzt, in der auch die Optionen für Autoplay und Zeitspanne dargestellt werden.
<pre class="lang-php"><code class="greyed">global $post;</code> <code class="lang-php">$galleries_as_slider = get_theme_mod( 'galleries_as_slider' );</code> <code class="greyed">$page_template = get_page_template_slug( $post-&gt;ID );
if ( $page_template == 'page-templates/slider-front-page.php' </code><code class="lang-php">||
$galleries_as_slider == 'checked'</code> <code class="greyed">) {
wp_enqueue_style( 'owl-carousel', get_template_directory_uri()
. '/css/owl-carousel.css' );</code></pre>
<em>Listing 116: Owl-Carousel-Ressourcen für alle Galerien nutzen, wenn im Customizer gewählt</em>
Um diese Einstellung im Frontend sichtbar zu machen, muss lediglich die Bedingung in der <code class="lang-php">hannover_scripts_styles()</code> erweitert werden, die dafür sorgt, dass das Style-sheet und das Skript von Owl Carousel eingebunden werden. Wie diese Erweiterung aussieht, ist in Listing 116 abgebildet. Mit <code class="lang-php">get_theme_mod()</code> wird die entsprechende Einstellung aus dem Customizer ermittelt und anschließend in der <code class="lang-php">if</code>-Bedingung geprüft, ob diese Option ausgewählt ist und/oder das Seiten-Template mit dem Slider auf der Startseite angezeigt wird.
<h3 id="vorschau-eines-galerie-oder-bild-beitrags">5.26 Vorschau eines Galerie- oder Bild-Beitrags</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
In der Vorschau für einen Beitrag vom Typ <em>Galerie</em> oder <em>Bild</em> soll über dem Titel das erste Bild und statt des <code class="lang-php">the_content()</code>-Aufrufs ein eventuell vorhandener Auszug des Beitrags angezeigt werden. Damit die Ansicht für die beiden Post-Formate richtig ausgegeben wird, müssen die Dateien <code class="lang-markup">content-gallery.php</code> sowie <code class="lang-markup">content-image.php</code> im Ordner <code class="lang-markup">template-parts</code> erstellt werden, die den identischen Inhalt haben.
<pre class="lang-php"><code class="lang-php">&lt;article &lt;?php post_class(); ?&gt; id="post-&lt;?php the_ID(); ?&gt;"&gt;
&lt;header class="entry-header"&gt;
&lt;?php hannover_image_from_gallery_or_image_post( 'large',
$post );
hannover_the_title( 'h2', true ); ?&gt;
&lt;/header&gt;
&lt;div class="entry-content"&gt;
&lt;?php if ( has_excerpt() ) {
the_excerpt();
} ?&gt;
&lt;/div&gt;
&lt;footer&gt;
&lt;p&gt;&lt;a href="&lt;?php the_permalink(); ?&gt;"
class="entry-date"&gt;&lt;?php hannover_the_date(); ?&gt;&lt;/a&gt;
&lt;?php hannover_entry_meta() ?&gt;&lt;/p&gt;
&lt;/footer&gt;
&lt;/article&gt;</code></pre>
<em>Listing 117: Vorschau von Galerie- und Bild-Beiträgen</em>
Der komplette Code für beide Dateien ist in Listing 117 abgebildet. Innerhalb des header-Elements wird mit <code class="lang-php">hannover_image_from_gallery_or_image_post()</code> das erste Bild der Galerie oder des Beitrags angezeigt – genau erläutert wird die Funktion ab Listing 61 auf Seite 67. Anschließend gibt <code class="lang-php">hannover_the_title()</code>, die in Listing 16 auf Seite 36 erklärt wird, den verlinkten Titel auf den Beitrag als <code class="lang-markup">h2</code>-Überschrift aus. Innerhalb des Inhalt-<code class="lang-markup">div</code>s wird mit <code class="lang-php">has_excerpt()</code> geprüft, ob der Nutzer einen Auszug für den Beitrag eingetragen hat und in dem Fall dieser mit <code class="lang-php">the_excerpt()</code> ausgegeben.<a href="#_ftn237" name="_ftnref237">[237]</a>, <a href="#_ftn238" name="_ftnref238">[238]</a>
<h3 id="read-more-sprung-verhindern">5.27 Read-More-Sprung verhindern</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Wenn ein Read-More-Link auf einer Übersichtsseite angezeigt wird, weil der Nutzer ihn in seinem Beitrag eingefügt hat, dann wird standardmäßig eine Sprungmarke eingefügt, sodass auf der Einzelansicht des Beitrags direkt zu dem Teil gesprungen wird, der als nächstes gelesen werden soll. Dieses Verhalten ist etwas verwirrend, da es nicht erwartet wird – daher wird diese Sprungmarke mit dem Code aus Listing 118 von den Read-More-Links entfernt.
<pre class="lang-php"><code class="lang-php">function hannover_remove_more_link_scroll( $link ) {
$link = preg_replace( '/#more-[0-9]+/', '', $link );
return $link;
}
add_filter( 'the_content_more_link',
'hannover_remove_more_link_scroll' );</code></pre>
<em>Listing 118: Entfernen der Sprungmarke beim Read-More-Link</em>
Da die Funktion <code class="lang-php">hannover_remove_more_link_scroll()</code> an den Filter <code class="lang-php">the_content_more_link</code> übergeben wird, ist im Parameter <code class="lang-php">$link</code> der Read-More-Link vorhanden.<a href="#_ftn239" name="_ftnref239">[239]</a> In dieser URL wird mit der <code class="lang-php">preg_replace()</code>-Funktion die Sprungmarke entfernt und die bereinigte URL zurückgegeben.<a href="#_ftn240" name="_ftnref240">[240]</a>
<h3 id="menue">5.28 Menü</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Damit das Menü mit möglichst vielen verschiedenen Methoden genutzt werden kann, muss JavaScript eingesetzt werden – zu diesen Methoden gehört beispielsweise das Öffnen eines DropDown-Menüs mit einem Touchscreen oder die Nutzung des Menüs über eine Tastatur. Auch das Einblenden des Menüs auf kleinen Viewports muss vorbereitet werden.
Da das Rad nicht neu erfunden werden muss, wird die Lösung des diesjährigen WordPress-Standard-Themes <em>Twenty Sixteen</em> genutzt – der notwendige JavaScript-Code ist im GitHub-Repository des Themes zu finden.<a href="#_ftn241" name="_ftnref241">[241]</a> Innerhalb des Codes müssen lediglich einige Zeilen, die nichts mit dem Menü zu tun haben, gelöscht beziehungsweise angepasst werden, damit jQuery die Elemente mit den korrekten Klassen und IDs sucht.
Um zwei Screen-Reader-Texte übersetzbar zu integrieren, kommt die Funktion <code class="lang-php">wp_localize_script()</code> zum Einsatz, wie bereits in Listing 111 erläutert. Wie die Einbindung in <code class="lang-php">hannover_scripts_styles()</code> aussieht, zeigt Listing 119.
<pre class="lang-php"><code class="lang-php">wp_enqueue_script( 'hannover-menu', get_template_directory_uri()
. '/js/menu.js', array( 'jquery' ), false, true );
wp_localize_script( 'hannover-menu', 'screenReaderText', array(
'expand' =&gt; __( 'expand child menu', 'hannover' ),
'collapse' =&gt; __( 'collapse child menu', 'hannover' ),
) );</code></pre>
<em>Listing 119: Einbinden des Menü-Skripts</em>
<h3 id="footer-bereich-erweitern">5.29 Footer-Bereich erweitern</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um Links anzuzeigen, die vielleicht nicht in die Hauptnavigation gehören, wie beispielsweise das Impressum, bekommt das Theme ein Menü im Footer. Darüber hinaus soll der Nutzer ein Menü mit Social-Media-Links anlegen können, die dann automatisch als SVG-Grafiken angezeigt werden. Ganz unten in den Footer kommt ein Hinweis auf den Ersteller des Themes.
<h4 id="social-media-menue">5.29.1 Social-Media-Menü</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Häufig werden zur Anzeige von Icons auf Websites sogenannte Icon Fonts eingesetzt. Das sind Fonts, die statt Buchstaben Icons enthalten und oft durch Einsetzen einer bestimmten Klasse im HTML-Code via CSS eingefügt werden. Das ist nicht besonders semantisch und barrierefrei, im Gegensatz zu SVG, wie Sara Soueidan erläutert.
<blockquote>„SVGs are semantic. An SVG icon is a graphic — an image — so what better way to mark up an image than to use a (scalable vactor) graphic tag? An SVG element (<code class="lang-markup">&lt;svg&gt;</code>) represents an icon simply and semantically, while icon fonts usually require non-semantic markup like pseudo-elements and empty <code class="lang-markup">&lt;span&gt;</code>s to be displayed. For people concerned about semantics and accessibility this introduces a serious issue: these elements don’t accommodate screen readers well, not to mention that the markup generally just doesn’t make much sense — if any — for an image.“<a href="#_ftn242" name="_ftnref242">[242]</a></blockquote>
Um SVG-Icons als Vordergrundbilder zu nutzen, wie es in dem Social-Media-Menü der Fall sein soll, gibt es laut Soueidan die folgende gute Möglichkeit:
<pre class="lang-markup"><code class="lang-markup">&lt;svg version="1.1" xmlns="http://www.w3.org/2000/svg"
style="display: none;"&gt;
&lt;symbol id="icon-twitter" viewBox="0 0 16 16"&gt;
&lt;title&gt;Twitter&lt;/title&gt;
&lt;!-- Twitter-Icon-Markup --&gt;
&lt;/symbol&gt;
&lt;symbol id="icon-facebook" viewBox="0 0 16 16"&gt;
&lt;title&gt;Facebook&lt;/title&gt;
&lt;!-- Twitter-Icon-Markup --&gt;
&lt;/symbol&gt;
&lt;!-- weitere Icons --&gt;
&lt;/svg&gt;</code></pre>
<em>Listing 120: SVG-Markup für die Social-Media-Icons</em>
Der SVG-Code aus Listing 120 wird in eine eigene SVG-Datei <code class="lang-markup">social-media-icons.svg</code> in dem <code class="lang-markup">svg</code>-Ordner eingefügt. Innerhalb des <code class="lang-markup">symbol</code>-Elements kann für die bessere Barrierefreiheit ein <code class="lang-markup">title</code>-Element angegeben werden, gefolgt von dem SVG-Markup für das Icon. Es ließe sich auch noch für jedes Symbol eine Beschreibung einfügen, allerdings gibt es scheinbar keine Möglichkeit, diese übersetzbar zu integrieren. Die Icons stammen zum großen Teil aus dem Genericons-Set von Automattic, abgesehen von dem Xing-Icon, das von <em>Font Awesome</em> ist. <a href="#_ftn243" name="_ftnref243">[243]</a>, <a href="#_ftn244" name="_ftnref244">[244]</a> Die komplette SVG-Datei mit den Icons ist im GitHub-Repository des Hannover-Themes zugänglich.<a href="#_ftn245" name="_ftnref245">[245]</a>
Jedes Icon kann auf der Website mit der Methode aus Listing 121 angezeigt werden. Innerhalb des <code class="lang-markup">svg</code>-Elements wird in dem <code class="lang-markup">use</code>-Tag der Pfad zu der SVG-Datei angegeben, inklusive einem Hash-Wert, der mit der <code class="lang-markup">id</code> des entsprechenden <code class="lang-markup">symbol</code>-Elements übereinstimmt.<a href="#_ftn246" name="_ftnref246">[246]</a>
<pre class="lang-markup"><code class="lang-markup">&lt;svg class="icon-twitter"&gt;
&lt;use xlink:href=
"/pfad-zum-theme/svg/social-media-icons.svg#icon-twitter"/&gt;
&lt;/svg&gt;</code></pre>
<em>Listing 121: SVG auf der Website anzeigen</em>
Diese Ausgabe aus Listing 121 muss statt des normalen Textlinks von der Menü-Funktion ausgegeben werden.
<pre class="lang-php"><code class="greye">'primary' =&gt; __( 'Primary Menu', 'hannover' ),</code> <code class="lang-php">/* translators: Name of menu position for social media icons */
'social' =&gt; __( 'Social Menu', 'hannover' ),</code></pre>
<em>Listing 122: Registrierung des Social-Media-Menüs in der functions.php</em>
Damit die Position für das neue Social-Media-Menü im Backend auswählbar ist, muss die <code class="lang-php">register_nav_menus()</code>-Funktion in der <code class="lang-markup">functions.php</code> um einen Array-Eintrag erweitert werden.<a href="#_ftn247" name="_ftnref247">[247]</a> Um das Menü anzuzeigen, muss in die bereits erstellte <code class="lang-markup">footer.php</code> gewechselt werden.
<pre class="lang-php"><code class="greyed">&lt;footer id="footer"&gt;</code><code class="lang-php">
&lt;?php if ( has_nav_menu( 'social' ) ) {
wp_nav_menu(
array(
'theme_location' =&gt; 'social',
'menu_class' =&gt; 'social-menu',
'container' =&gt; '',
'walker' =&gt; new Hannover_Social_Menu_Walker(),
'depth' =&gt; 1
)
);
}</code></pre>
<em>Listing 123: Ausgabe des Social-Media-Menüs in der footer.php</em>
Zunächst wird in Listing 123 mit <code class="lang-php">has_nav_menu()</code> geprüft, ob die Menüposition <code class="lang-php">social</code> mit einem Menü belegt ist.<a href="#_ftn248" name="_ftnref248">[248]</a> Falls das so ist, gibt <code class="lang-php">wp_nav_menu()</code> das entsprechende Menü von dieser Position aus. Wichtig ist im Vergleich zu dem Menü in der <code class="lang-markup">header.php</code>, dass für <code class="lang-php">walker</code> ein Wert angegeben wird, damit die Ausgabe individuell angepasst werden kann. Die Klasse, die dafür verantwortlich ist, kommt in die Datei <code class="lang-markup" style="word-wrap: break-word; white-space: normal;">class-hannover-social-menu-walker.php</code> in den <code class="lang-markup">inc</code>-Ordner. Um sie in die <code class="lang-markup">functions.php</code> einzubinden, ist Listing 124 zuständig.
<pre class="lang-php"><code class="greyed">require get_template_directory() . '/inc/customizer.php';</code> <code class="lang-php">require get_template_directory()
. '/inc/class-hannover-social-menu-walker.php';</code></pre>
<em>Listing 124: Einbinden der class-hannover-social-menu-walker.php</em>
Die Klasse <code class="lang-php">Hannover_Social_Menu_Walker</code> erweitert <code class="lang-php">Walker_Nav_Menu</code>, die für die Standard-Ausgabe der Menüs zuständig ist.<a href="#_ftn249" name="_ftnref249">[249]</a> Überschrieben werden muss lediglich die <code class="lang-php">start_el()</code>-Methode, die sich um die Ausgabe der Menüelemente kümmert.<a href="#_ftn250" name="_ftnref250">[250]</a> Dabei wird der größte Teil der Methode einfach übernommen und lediglich ein kleiner Teil verändert. Dieser angepasste und selbst programmierte Teil wird hier erläutert, die komplette Klasse ist im Repository auf GitHub zugänglich – der Teil, der aus Gründen der Orientierung aus der übernommenen Klasse abgebildet wird, ist ausgegraut.<a href="#_ftn251" name="_ftnref251">[251]</a>
<pre class="lang-php"><code class="lang-php">&lt;?php
class Hannover_Social_Menu_Walker extends Walker_Nav_Menu {</code><code class="greyed">
[…]
public function start_el( &amp;$output, $item, $depth = 0,
$args = array(), $id = 0 ) {
[…]
$title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );
/**
* Build array to get the class name for the social network in
the SVG
*/</code><code class="lang-php">
$social_media_channels = array(
'plus.google.com' =&gt; 'icon-google-plus',
'wordpress.org' =&gt; 'icon-wordpress',
'wordpress.com' =&gt; 'icon-wordpress',
'facebook.com' =&gt; 'icon-facebook',
'twitter.com' =&gt; 'icon-twitter',
'dribbble.com' =&gt; 'icon-dribbble',
'pinterest.com' =&gt; 'icon-pinterest',
'github.com' =&gt; 'icon-github',
'tumblr.com' =&gt; 'icon-tumblr',
'youtube.com' =&gt; 'icon-youtube',
'flickr.com' =&gt; 'icon-flickr',
'vimeo.com' =&gt; 'icon-vimeo',
'instagram.com' =&gt; 'icon-instagram',
'linkedin.com' =&gt; 'icon-linkedin',
'xing.de' =&gt; 'icon-xing',
'xing.com' =&gt; 'icon-xing',
'/feed' =&gt; 'icon-feed',
);</code></pre>
<em>Listing 125: Erster Ausschnitt aus der Hannover_Social_Menu_Walker()-Klasse</em>
Es muss geprüft werden, zu welchem sozialen Netzwerk die URL des gerade durchlaufenen Menüpunkts gehört und dann die entsprechende SVG-ID genutzt werden. Dafür wird in Listing 125 kurz vor Bearbeitung der Menüpunkte ein Array erstellt, das als Schlüssel immer die URL des sozialen Netzwerks und als entsprechenden Wert die ID aus der SVG-Datei enthält.
<pre class="lang-php"><code class="lang-php">$svg_id = "";
foreach ( $social_media_channels as $key =&gt; $value ) {
$pattern = "|$key|";
preg_match( $pattern, $atts['href'], $matches );
if ( ! empty( $matches[0] ) ) {
$match = $matches[0];
$svg_id = $social_media_channels[ $match ];
break;
}
}</code></pre>
<em>Listing 126: Prüfen der aktuellen Menü-URL und speichern der zugehörenden ID</em>
In Listing 126 wird ein leerer String der Variable <code class="lang-php">$svg_id</code> zugewiesen. Danach wird für das Array aus Social-Media-Kanälen eine Schleife durchlaufen, in der der jeweilige Schlüssel des Arrays in der <code class="lang-php">$key</code>-Variable und der Wert in <code class="lang-php">$value</code> zugänglich ist. In der URL des aktuellen Menüpunkts, die in <code class="lang-php">$atts['href']</code> gespeichert ist, muss nach dem Vorkommen von <code class="lang-php">$key</code> gesucht werden. Dafür wird die Funktion <code class="lang-php">preg_match()</code> eingesetzt, der als erster Parameter der Ausdruck übergeben wird, nach dem gesucht werden soll, als zweiter der String, der durchsucht wird und als dritter eine Variable, in der der Treffer gespeichert wird.
Wenn bei dem Durchlauf des Social-Media-Arrays eine Übereinstimmung gefunden wird, ist <code class="lang-php">$matches[0]</code> nicht mehr leer, sondern enthält den Schlüssel aus dem Array, also die URL des sozialen Netzwerks. In diesem Fall wird der Wert der Variable <code class="lang-php">$match</code> zugewiesen und im nächsten Schritt die ID aus dem Array geholt, indem als Schlüssel der Wert aus <code class="lang-php">$match</code> übergeben wird. Anschließend wird der Schleifendurchlauf abgebrochen, damit die Schleife so selten wie möglich für jeden Menüpunkt durchlaufen werden muss.
<pre class="lang-php"><code class="lang-php">if ( $svg_id != "" ) {
$icon_url = get_template_directory_uri()
. '/svg/social-media-icons.svg#' . $svg_id;</code><code class="greyed">
$item_output = $args-&gt;before;
$item_output .= '&lt;a' . $attributes . '&gt;';</code><code class="lang-php">
$item_output .= '';</code><code class="greyed">
$item_output .= '';
$item_output .= $args-&gt;after;</code> <code class="lang-php">} else {</code><code class="greyed">
$item_output = $args-&gt;before;
$item_output .= '&lt;a' . $attributes . '&gt;';
$item_output .= $args-&gt;link_before . $title . $args-&gt;link_after;
$item_output .= '';
$item_output .= $args-&gt;after;</code> <code class="lang-php">}</code></pre>
<em>Listing 127: Zusammensetzen des Menüpunkts in Hannover_Social_Menu_Walker</em>
Wenn <code class="lang-php">$svg_id</code> nicht leer ist, kann die passende SVG ausgegeben werden. In <code class="lang-php">$icon_url</code> wird die URL gespeichert, die mit <code class="lang-php">get_template_directory_uri()</code>, dem statischen Teil <code class="lang-php">/svg/social-media-icons.svg#</code> und der ID aus <code class="lang-php">$svg_id</code> zusammengesetzt wird. Die <code class="lang-php">$item_output</code>-Anweisungen, die ausgegraut sind, wurden aus der Methode der Oberklasse übernommen. Die Zeile, die eigentlich den Titel ausgibt und das in dem <code class="lang-php">else</code>-Zeig auch tut, ist im <code class="lang-php">if</code>-Zweig durch die Ausgabe des <code class="lang-markup">svg</code>-Elements ersetzt worden.
<strong>Browser-Unterstützung für externe SVGs</strong>
Da Internet Explorer 9 bis 11 keine externen SVGs anzeigen, die mit dem <code class="lang-markup">use</code>-Element eingebunden sind, wird das Skript <code class="lang-markup">svg4everybody</code> eingesetzt.<a href="#_ftn252" name="_ftnref252">[252]</a>, <a href="#_ftn253" name="_ftnref253">[253]</a> Die Datei <code class="lang-markup">svg4everybody.js</code> findet Platz in dem <code class="lang-markup">js</code>-Ordner und wird hier nicht extra abgebildet, da die einzige Anpassung der Datei aus dem GitHub-Repository das Einfügen des <code class="lang-js">svg4everybody()</code>-Aufrufs ist.<a href="#_ftn254" name="_ftnref254">[254]</a>
Damit das Skript nur eingebunden wird, wenn die Menüposition <code class="lang-php">social</code> verwendet wird, wird erneut die <code class="lang-php">has_nav_menu()</code>-Funktion genutzt. In Listing 128 ist der Code abgebildet, der dafür zuständig ist.
<pre class="lang-php"><code class="greyed">wp_enqueue_script( 'hannover-menu', get_template_directory_uri()
. '/js/menu.js', array( 'jquery' ), false, true );</code> <code class="lang-php">if ( has_nav_menu( 'social' ) ) {
wp_enqueue_script( 'hannover-svg4everybody',
get_template_directory_uri() . '/js/svg4everybody.js',
array( 'jquery' ), false, true );
}</code></pre>
<em>Listing 128: Einbinden von svg4everybody.js in der functions.php</em>
<h4 id="footer-menue-und-theme-autor-hinweis">5.29.2 Footer-Menü und Theme-Autor-Hinweis</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<pre class="lang-php"><code class="greyed">'primary' =&gt; __( 'Primary Menu', 'hannover' ),</code> <code class="lang-php">/* translators: Name of menu position in the footer */
'footer' =&gt; __( 'Footer Menu', 'hannover' ),</code> <code class="greyed">/* translators: Name of menu position for social media icons */</code></pre>
<em>Listing 129: Registrieren des Footer-Menüs in der functions.php</em>
Um die Position des Footer-Menüs im Backend einzublenden, muss sie wie beim Social-Media-Menü zunächst registriert werden. Der Teil ist in Listing 129 abgebildet und vom Prinzip her aus Listing 12 von Seite 30 bekannt.
<pre class="lang-php"><code class="lang-php">&lt;?php if ( has_nav_menu( 'footer' ) ) { ?&gt;
&lt;nav&gt;
&lt;h2 class="screen-reader-text"&gt;
&lt;?php /* translators: hidden screen reader headline for the
footer navigation */
_e( 'Footer navigation', 'hannover' ); ?&gt;
&lt;/h2&gt;
&lt;?php wp_nav_menu(
array(
'theme_location' =&gt; 'footer',
'menu_class' =&gt; 'footer-menu',
'container' =&gt; ''
)
); ?&gt;
&lt;/nav&gt;
&lt;?php } ?&gt;</code></pre>
<em>Listing 130: Einfügen der Footer-Navigation in der footer.php</em>
Um das Menü von der Menüposition <code class="lang-php">footer</code> anzuzeigen, kommt erneut die Funktion <code class="lang-php">has_nav_menu()</code> zum Einsatz, damit sichergestellt wird, dass es etwas zum Anzeigen gibt. Innerhalb des <code class="lang-markup">nav</code>-Elements wird für Screen-Reader-Nutzer eine Überschrift eingefügt und anschließend die Navigation mit <code class="lang-php">wp_nav_menu()</code> ausgegeben.
<pre class="lang-php"><code class="lang-php"> &lt;p class="theme-author"&gt;
&lt;?php _e( 'Theme: Hannover by &lt;a rel="nofollow"
href="https://florianbrinkmann.com"&gt;Florian Brinkmann&lt;/a&gt;',
'hannover' ) ?&gt;
&lt;/p&gt;</code> <code class="greyed">&lt;/footer&gt;</code></pre>
<em>Listing 131: Hinweis auf den Theme-Autoren in der footer.php</em>
In Listing 131 ist der abschließende Hinweis auf den Autoren des Themes abgebildet, der ganz ans Ende des sichtbaren Footers kommt.
<h3 id="design">5.30 Design</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Das Design in Form des CSS-Codes wird nicht Teil dieser Bacherlorarbeit sein, da eine detaillierte Besprechung aller CSS-Regeln erstens zu umfangreich wäre und zweitens sich diese Arbeit auf die WordPress-Funktionen konzentrieren soll. Der komplette CSS-Code des Themes wird in die <code class="lang-markup">hannover.css</code> innerhalb des <code class="lang-markup">css</code>-Ordners geschrieben. Theoretisch böte sich dafür auch die <code class="lang-mark">style.css</code> an – das Problem mit dem Code in dieser Datei ist aber, dass er sich nicht komplett minimieren ließe, da der Kommentar mit den Meta-Daten für das Theme nicht minimiert werden darf.
<pre class="lang-php"><code class="lang-php">wp_enqueue_style( 'hannover-style', get_template_directory_uri()
. '/css/hannover.css', array(), null );</code></pre>
<em>Listing 132: Einbinden der CSS-Datei</em>
Wie alle anderen Skripte und Stylesheets wird auch die CSS-Datei des Themes innerhalb der <code class="lang-php">hannover_scripts_styles()</code>-Funktion eingebunden – der dafür notwendige Code ist in Listing 132 abgebildet. Für das Einbinden wird die Funktion <code class="lang-php">wp_enqueue_style()</code> verwendet, deren Parameter bereits erläutert wurden.<a href="#_ftn255" name="_ftnref255">[255]</a>
<h4 id="notwendige-css-selektoren">5.30.1 Notwendige CSS-Selektoren</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Es gibt einige CSS-Selektoren, auf die das Theme-Check-Plugin prüft.<a href="#_ftn256" name="_ftnref256">[256]</a> So müssen in jedem Fall die folgenden Selektoren in der CSS-Datei angesprochen werden: <code class="lang-css">.wp-caption</code> und <code class="lang-css">.wp-caption-text</code>, die bei Bildbeschriftungen zum Einsatz kommen. <code class="lang-css">.sticky</code>, das dem oder den Beiträgen zugewiesen wird, die in der Blog-Übersicht oben gehalten werden sollen und <code class="lang-css">.gallery-caption</code>, das dem Element zugewiesen ist, welches die Bildbeschriftungen in einer Galerie enthält.
<code class="lang-css">.bypostauthor</code> spricht Kommentare an, die vom selben Benutzer geschrieben wurden, der den Beitrag verfasst hat. <code class="lang-css">.alignright</code>, <code class="lang-css">.alignleft</code> und <code class="lang-css">.aligncenter</code> sorgen jeweils für die entsprechende Ausrichtung von Elementen – wenn im WordPress-Editor beispielsweise ein Bild rechts ausgerichtet ist, wird die Klasse <code class="lang-css">.alignright</code> zugewiesen. Der Selektor <code class="lang-css">.screen-reader-text</code> spricht Elemente an, die im Frontend versteckt sind und für Screen-Reader-Nutzer gedacht sind.
<h4 id="lightbox-einbinden">5.30.2 Lightbox einbinden</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Damit Bilder durch einen Klick in einer Lightbox geöffnet werden können und dafür nicht extra ein Plugin installiert werden muss, wird die Lösung von Osvaldas Valutis eingesetzt.<a href="#_ftn257" name="_ftnref257">[257]</a> Standardmäßig bindet sie keine Navigationselemente ein, um nicht vom angezeigten Inhalt abzulenken. Auf der Demo-Seite des Projekts sind die Navigationselemente jedoch umgesetzt, weshalb der entsprechende Code von dort übernommen werden konnte – es waren lediglich leichte Anpassungen notwendig.<a href="#_ftn258" name="_ftnref258">[258]</a>
<pre class="lang-php"><code class="lang-php">wp_enqueue_script( 'hannover-lightbox', get_template_directory_uri()
. '/js/lightbox.js', array( 'jquery' ), false, true );</code></pre>
<em>Listing 133: Einbinden des Lightbox-Skripts</em>
Der komplette Code für die Lightbox kommt in die <code class="lang-markup">lightbox.js</code> im <code class="lang-markup">js</code>-Verzeichnis und wird eingebunden, wie in Listing 133 abgebildet. Die CSS-Angaben werden mit in die <code class="lang-markup">hannover.css</code> geschrieben.
<h4 id="schrift">5.30.3 Schrift</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Als Schrift kommt in dem Theme <em>Noto Sans</em> von Google zum Einsatz. Den Font gibt es im Schrift-Dienst von Google, den <em>Google Web Fonts</em>, und kann deshalb direkt von dort in das Theme eingebunden werden. Um die Schrift zu nutzen, muss lediglich die URL, die nach Wahl der Schriften und Schriftschnitte bereitgestellt wird, wie ein Stylesheet eingebunden werden.
<pre class="lang-php"><code class="lang-php">wp_enqueue_style( 'hannover-fonts', '//fonts.googleapis.com/css
?family=Noto+Sans:400,700,400italic,700italic', array(), null );</code></pre>
<em>Listing 134: Einbinden der Schriftart</em>
Listing 134 zeigt den Code, der dafür notwendig ist. Wie alle anderen Funktionen zum Einbinden von Skripten und Stylesheets kommt auch dieser Teil in die <code class="lang-php">hannover_scripts_styles()</code>-Funktion in der <code class="lang-markup">functions.php</code>. An die Funktion <code class="lang-php">wp_enqueue_style()</code> wird einfach als zweiter Parameter die URL aus den Google Web Fonts übergeben.
<h4 id="inhaltsbreite-definieren-und-grosse-bildgroesse-anpassen">5.30.4 Inhaltsbreite definieren und große Bildgröße anpassen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Nach der groben Umsetzung des Designs stellt sich heraus, dass der Inhaltsbereich maximal 845 Pixel breit ist. Um anzugeben, dass der eingefügte Inhalt höchstens diese Breite haben soll, gibt es in WordPress die Variable <code class="lang-php">$content_width</code>.<a href="#_ftn259" name="_ftnref259">[259]</a> In dieser Breite werden beispielsweise oEmbed-Inhalte wie etwa Tweets eingebunden und auch Plugins können auf diesen Wert zugreifen, um ihre Inhalte bestmöglich an das Theme anzupassen.
Für die Festlegung dieses Wertes reicht es aus, in der <code class="lang-markup">functions.php</code> den Code aus Listing 135 einzufügen.
<pre class="lang-php"><code class="lang-php">if ( ! isset( $content_width ) ) {
$content_width = 845;
}</code></pre>
<em>Listing 135: Definieren der Inhaltsbreite in der functions.php</em>
Um den Standard-Wert der großen Bildgröße dahingehend anzupassen, dass er 845 Pixeln entspricht, gibt es die <code class="lang-php">update_option()</code>-Funktion.<a href="#_ftn260" name="_ftnref260">[260]</a> Als erster Parameter wird der Name der Option übergeben, die aktualisiert werden soll, gefolgt von einem oder mehreren Parametern, die den neuen Wert angeben. Mit dem ersten Parameter <code class="lang-php">large_size_w</code> lässt sich die Breite der großen Bildgröße anpassen. Listing 136 zeigt die Anpassung des Wertes auf eine Breite von 845 Pixeln.
<pre class="lang-php"><code class="lang-php">update_option( 'large_size_w', 845 );</code></pre>
<em>Listing 136: Anapassen der Breite von der großen Bildgröße in der functions.php</em>
<h4 id="screenshot">5.30.5 Screenshot</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Für die Präsentation im Backend, muss eine <code class="lang-marku">screenshot.png</code> im Root-Vereichnis des Themes platziert werden. Laut Theme-Review-Handbook soll dieser Screenshot nicht größer als 1.200 x 900 Pixel sein.<a href="#_ftn261" name="_ftnref261">[261]</a> Auch bei den Bildern auf dem Screenshot muss wie bei allen anderen Ressourcen auf die Lizenz geachtet werden. Bilder mit einer geeigneten Lizenz finden sich beispielsweise auf unsplash.com. Der finale Screenshot des Themes ist in Abbildung 8 zu sehen.
[caption id="attachment_2245" align="alignnone" width="800"]<img class="size-large wp-image-2245" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/screenshot-800x600.png" alt="Abbildung 8: Screenshot des Themes, der im Backend und im Theme-Verzeichnis angezeigt wird" width="800" height="600" /> Abbildung 8: Screenshot des Themes, der im Backend und im Theme-Verzeichnis angezeigt wird[/caption]
<h3 id="readme">5.31 Readme</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
In die Readme-Datei eines Themes sollte idealerweise ein Changelog und in jedem Fall Hinweise zu den Lizenzen verwendeter Ressourcen eingefügt werden. Im Fall des Hannover-Themes sind folgende externe Ressourcen verwendet worden: Der Font <em>Noto Sans</em>, das Skript <em>Owl Carousel</em> für den Slider, das Lightbox-Script von Osvaldas Valutis, das JavaScript von Twenty Sixteen für das Menü, <em>Genericons</em> für die Social-Media-Icons und <em>Font Awesome</em> für das Xing-Icon, <em>svg4everybody</em> für den Browser-Fallback und das Bild im Screenshot.
Listing 137 zeigt die komplette Readme des Themes inklusive Changelog und Copyright-Hinweis ganz am Ende.
<pre class="lang-markup"><code class="lang-markup">== Changelog ==
Version 1.0 – 26.12.2015
---
- initial release
== Copyright ==
Noto Sans
Licence: Apache License, version 2.0
Source: https://www.google.com/fonts/specimen/Noto+Sans
Owl Carousel
Licence: MIT License
Source: http://www.owlcarousel.owlgraphic.com/
Lightbox Script
Licence: MIT License
Source: http://osvaldas.info/image-lightbox-responsive-touch-friendly
Menu JS
Licence: GPLv2 or later
Source: https://github.com/WordPress/twentysixteen/blob/master/js/functions.js
Genericons icon font, Copyright 2013-2015 Automattic.com
License: GNU GPL, Version 2 (or later)
Source: http://www.genericons.com
Xing Icon from Font Awesome 4.5
Licence: SIL OFL 1.1
Source: http://fontastic.me/
svg4everybody
Licence: CC0 1.0 Universal License
Source: https://github.com/jonathantneal/svg4everybody
Image from Screenshot
Licence: CC0 1.0 Universal
Source: https://unsplash.com/photos/a0YaUXLjKaY
---
Hannover WordPress Theme, Copyright 2015 Florian Brinkmann
Hannover is distributed under the terms of the GNU GPL</code></pre>
<em>Listing 137: Readme-Datei</em>
<h3 id="uebersetzung">5.32 Übersetzung</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Durch die konsequente Nutzung der Gettext-Funktionen ist das Theme auf die Übersetzung vorbereitet. Seit einiger Zeit können alle Themes des Theme-Verzeichnisses auf dem <em>GlotPress</em> von WordPress, das unter translate.wordpress.org erreichbar ist, übersetzt werden. Theme-Autoren können jedoch eigene Übersetzungen mitliefern, die die jeweilige Sprache dann überschreiben. Das Hannover-Theme soll von diesen Vorteilen aber profitieren, weshalb keine Übersetzung beigefügt wird.
Um Übersetzungen zu laden, muss die <code class="lang-php">load_theme_textdomain()</code>-Funktion genutzt werden, der als Parameter die Text-Domain des Themes übergeben wird.<a href="#_ftn262" name="_ftnref262">[262]</a> Um die Übersetzungen nur zu laden, wenn es notwendig ist, wird der Aufruf von einigen Bedingungen abhängig gemacht.
<pre class="lang-php"><code class="lang-php">function hannover_load_translation() {
if ( ( ! defined( 'DOING_AJAX' ) &amp;&amp; ! 'DOING_AJAX' ) ||
! hannover_is_login_page() || ! hannover_is_wp_comments_post() ) {
load_theme_textdomain( 'hannover' );
}
}
add_action( 'after_setup_theme', 'hannover_load_translation' );
function hannover_is_login_page() {
return in_array( $GLOBALS['pagenow'], array( 'wp-login.php',
'wp-register.php' ) );
}
function hannover_is_wp_comments_post() {
return in_array( $GLOBALS['pagenow'], array( 'wp-comments-post.php' ) );
}</code></pre>
<em>Listing 138: Laden der Übersetung in der functions.php</em>
Listing 138 zeigt den kompletten Code, der das Laden der Übersetzungen bewerkstelligt. In der Funktion <code class="lang-php">hannover_load_translation()</code> wird mit <code class="lang-php">load_theme_textdomain()</code> die Übersetzung geladen. Vorher wird geprüft, ob ein AJAX-Request ausgeführt wurde – in diesem Fall muss die Übersetzung des Themes nicht neu geladen werden. Dafür gibt es in WordPress die Konstante <code class="lang-php">DOING_AJAX</code>. Ebenfalls nicht geladen werden soll die Übersetzung auf der Backend-Login-Seite und der Seite, die aufgerufen wird, wenn ein Kommentar geschrieben wurde.
Dafür wird jeweils eine Hilfsfunktion erstellt, die einen booleschen Wert zurückgibt. Mit der Funktion <code class="lang-php">hannover_is_login_page()</code> wird überprüft, ob die gerade aufgerufene Seite die <code class="lang-markup">wp-login.php</code> oder <code class="lang-markup">wp-register.php</code> ist. Dabei kommt die <code class="lang-php">in_array()</code>-Funktion zum Einsatz, die überprüft, ob der Wert des ersten Parameters in dem Array vorhanden ist, das als zweiter Parameter übergeben wird – die Globale Variable <code class="lang-php">pagenow</code> liefert die aktuelle Seite.<a href="#_ftn263" name="_ftnref263">[263]</a>
Ähnlich wird in der Funktion <code class="lang-php">hannover_is_wp_comments()</code> verfahren. Hier wird geprüft, ob die aktuelle Seite der <code class="lang-markup">wp-comments-post.php</code> entspricht.
<h3 id="dokumentation">5.33 Dokumentation</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um für andere Nutzer das Theme gut zu dokumentieren, wird über jeder Funktion ein erklärender Kommentar eingefügt, der gegebenenfalls auch die Parameter der Funktion aufführt sowie den Typ des Rückgabewertes. Im Fall der Sanitization-Funktion für die Checkboxen im Customizer sieht das beispielhaft so aus, wie in Listing 139 zu sehen.
<pre class="lang-php"><code class="lang-php">/**
* Sanitizes checkbox input
*
* @param $checked
*
* @return bool
*/
function hannover_sanitize_checkbox( $checked ) {
return ( ( isset( $checked ) &amp;&amp; true == $checked ) ? true : false );
}</code></pre>
<em>Listing 139: Beispiel eines dokumentierenden Kommentars</em>
Zunächst kommt in den PHP-Kommentar eine kurze Beschreibung der Funktion. Hinter <code class="lang-php">@param</code> wird anschließend aufgelistet, welche Parameter die Funktion erwartet und mit <code class="lang-php">@return</code> wird angegeben, welcher Datentyp zurückgegeben wird. Im Fall der obigen Funktion ist das immer ein boolescher Wert.
<h3 id="child-theme-check">5.34 Child-Theme-Check</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Um Anpassungen an einem Theme vorzunehmen, das von jemand anderem entwickelt wurde, werden immer Child-Themes empfohlen, damit die Änderungen bei einem Theme-Update nicht überschrieben werden. Das Problem hierbei ist jedoch, dass eventuelle Sicherheitslücken des Parent-Themes mit in das Child-Theme übernommen und darin konserviert werden. Wenn das Parent-Theme die Lücke schließt, bleibt sie im Child-Theme – und damit auf der Live-Seite – erhalten.
Torsten Landsiedel hat dieses „Dilemma“ in einem Vortrag auf dem WordCamp Cologne 2015 angesprochen und gleich eine Lösung präsentiert: Das Child-Theme-Check-Plugin.<a href="#_ftn264" name="_ftnref264">[264]</a>, <a href="#_ftn265" name="_ftnref265">[265]</a> Damit kann der Nutzer eines Child-Themes nach einem Update die Änderungen im Parent-Theme direkt neben dem Code des Child-Themes anschauen und so entscheiden, ob wichtige Änderungen dabei sind, die übernommen werden sollten, oder nicht.
Um das Plugin als Theme-Autor bestmöglich zu unterstützen, muss in jeder PHP-Datei am Anfang in einem Kommentar eine <code class="lang-php">@version</code>-Angabe eingefügt werden, die dann bei einer Änderung in dieser Datei angepasst wird. Wie das beispielsweise in der <code class="lang-markup">index.php</code> aussieht, ist in Listing 140 abgebildet.
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Main template file
*
* @version 1.0
*/
get_header(); ?&gt;
&lt;main role="main"&gt;</code></pre>
<em>Listing 140: @version-Hinweis in der index.php</em>
<h2 id="upload-und-review-korrekturen-des-themes">6 Upload und Review-Korrekturen des Themes</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Nach dem ersten Upload eines Themes in das Theme-Verzeichnis wird dieses einer Review durch ein Mitglied des Theme-Review-Teams unterzogen. Den wenigen Freiwilligen in dem Team geschuldet, dauert es normalerweise einige Zeit, bis ein neues Theme mit der Review an der Reihe ist – durch die besondere Dringlichkeit im Fall des Hannover-Themes war es aber möglich, schneller einen Theme-Reviewer zu bekommen.
<h3 id="upload-ins-theme-verzeichnis">6.1 Upload ins Theme-Verzeichnis</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Nachdem das Theme ein letztes Mal mit dem Theme-Check-Plugin geprüft und keine Fehler oder Warnungen gemeldet wurden, wird es in ein ZIP-Archiv gepackt und über den Link <em>Upload Your Theme</em> in das Theme-Verzeichnis geladen.<a href="#_ftn266" name="_ftnref266">[266]</a> Bevor das Formular für den Upload aufgerufen wird, gelangt der Theme-Autor auf eine Seite, auf der auf die Richtlinien hingewiesen wird, die ein Theme erfüllen muss.
Nachdem das Theme hochgeladen wurde, wird im Theme-Trac ein neues Ticket erstellt – beim Hannover-Theme die Nummer 29486.<a href="#_ftn267" name="_ftnref267">[267]</a> Hier findet die Kommunikation mit dem Reviewer statt. Wenn eine neue Version des Themes mit Korrekturen hochgeladen wird und bereits ein Ticket für das Theme offen ist, wird die neue Version in dieses Ticket integriert.
<h3 id="korrekturen">6.2 Korrekturen</h3>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Korrekturen sind hier nach den Dringlichkeitsstufen gruppiert, nicht nach den Kommentaren der Reviewer. Aufgeführt werden lediglich die Punkte, die auch angepasst wurden – ein paar konnten nach kurzer Diskussion ausgeräumt werden und erhalten bleiben.
<h4 id="notwendig">6.2.1 Notwendig</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Core-Option zur Änderung der Header-Farbe im Customizer muss von jedem Theme-Autor selbst integriert werden, da der Core das Markup für die CSS-Selektoren nicht kennen kann. Diese Umsetzung wurde bisher nicht getätigt und muss deshalb nun nachgeholt werden. Notwendig ist dafür eine kleine Funktion in der <code class="lang-marku">customizer.php</code>.
<pre class="lang-php"><code class="lang-php">function hannover_header_textcolor() {
if ( get_theme_mod( 'header_textcolor' ) ) { ?&gt;
&lt;style type="text/css"&gt;
#header,
#header a {
color: &lt;?php echo '#' . get_theme_mod('header_textcolor'); ?&gt;;
}
&lt;/style&gt;
&lt;?php }
}
add_action( 'wp_head', 'hannover_header_textcolor' );</code></pre>
<em>Listing 141: hannover_header_textcolor() in der customizer.php</em>
Listing 141 zeigt die Funktion, in der zuerst geprüft wird, ob eine Header-Textfarbe eingetragen wurde – dafür wird <code class="lang-php">get_theme_mod()</code> mit dem Parameter <code class="lang-php">header_textcolor</code> verwendet.<a href="#_ftn268" name="_ftnref268">[268]</a> Im Anschluss wird ein <code class="lang-markup">style</code>-Element geöffnet und darin die Selektoren angegeben, die alle Texte in dem Header ansprechen. Als Wert für <code class="lang-css">color</code> wird der Wert der Customizer-Einstellung übergeben.
Eine weitere notwendige Korrektur ist der Einsatz von <code class="lang-php">if ( have_posts() )</code>, bevor mit <code class="lang-php">while ( have_posts() )</code> die Post-Schleife durchlaufen wird. Diese Anpassung ist in den Dateien <code class="lang-markup">single.php</code>, <code class="lang-markup">page.php</code>, <code class="lang-markup">slider-front-page.php</code> sowie <code class="lang-markup">no-sidebar-page.php</code> umzusetzen – beispielhaft für alle vier zeigt Listing 142 diese Anpassung in der <code class="lang-markup">page.php</code>.
<pre class="lang-php"><code class="greyed">&lt;?php </code><code class="lang-php">if ( have_posts() ) {</code><code class="greyed">
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', 'page' );
if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
}</code> <code class="lang-php">}</code></pre>
<em>Listing 142: Prüfung von have_posts() vor Schleifendurchlauf in der page.php</em>
Zudem ist in diesem Bereich die Bereitstellung einer Nachricht, wenn keine Beiträge gefunden wurden, <code class="lang-php">if ( have_posts() )</code> also zu keinem Ergebnis geführt hat, notwendig. Dafür wird eine neue Datei <code class="lang-markup">content-none.php</code> im <code class="lang-markup">template-parts</code>-Ordner erstellt, die lediglich eine Nachricht für den Nutzer anzeigt – der Inhalt dieser Datei ist in Listing 143 abgebildet.
<pre class="lang-php"><code class="lang-php">&lt;?php
/**
* Template part for no posts found with have_posts()
*
* @version 1.0.6
*/
?&gt;
&lt;article class="post"&gt;
&lt;p&gt;&lt;?php _e( 'Sorry, no posts matched your criteria.',
'hannover' ); ?&gt;&lt;/p&gt;
&lt;/article&gt;</code></pre>
<em>Listing 143: content-none.php</em>
Um die Meldung auszugeben, wenn keine Beiträge gefunden wurden, muss in allen Dateien mit <code class="lang-php">if ( have_posts() )</code> ein <code class="lang-php">else</code>-Zweig eingefügt werden, der beispielhaft erneut an der <code class="lang-markup">page.php</code> gezeigt wird.
<pre class="lang-php"><code class="greyed">&lt;?php if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', 'page' );
if ( comments_open() || get_comments_number() ) {
comments_template( '', true );
}
}
} </code><code class="lang-php">else {
get_template_part( 'template-parts/content', 'none' );
} ?&gt;</code></pre>
<em>Listing 144: Einfügen des content-none-Templates in der page.php</em>
In Listing 144 wird mit <code class="lang-php">get_template_part()</code> die erstellte Datei eingebunden, wenn keine Beiträge gefunden werden.<a href="#_ftn269" name="_ftnref269">[269]</a>
Die letzte notwendige Korrektur aus der ersten Review betrifft die doppelten Anführungszeichen in Text-Strings, die vom Theme-Check-Plugin als spezielle Zeichen gekennzeichnet werden und durch <code class="lang-php">"</code> ersetzt werden sollen.
<strong>Anpassung der Lösung für den Ausschluss der Portfolio-Elemente vom Blog</strong>
Bei der Admin-Review hat Justin Tadlock angemerkt, dass die genutzte Lösung für den Ausschluss der Portfolio-Elemente vom Blog so nicht umgesetzt werden kann, da sie mit Plugins kollidieren wird, die für die Blog-Ausgabe die Main-Query erwarten und keine Custom-Query, die das Hannover-Theme bisher in der <code class="lang-marku">index.php</code> einsetzt. Die richtige Lösung ist hier die Nutzung des <code class="lang-php">pre_get_posts</code>-Hooks, der vor Durchführung der Query ausgeführt wird.<a href="#_ftn270" name="_ftnref270">[270]</a>,<a href="#_ftn271" name="_ftnref271">[271]</a>
Durch diese veränderte Lösung kann die <code class="lang-markup">index.php</code> deutlich schlanker dargestellt werden, wie der abgebildete Ausschnitt in Listing 145 zeigt. Die gesamte Logik für den Ausschluss der Portfolio-Elemente konnte entfernt werden, es verbleibt die normale Durchführung der Loop.
<pre class="lang-php"><code class="lang-php">&lt;?php if ( have_posts() ) {
if ( is_home() &amp;&amp; ! is_front_page() ) { ?&gt;
&lt;header&gt;
&lt;h1 class="page-title screen-reader-text"&gt;
&lt;?php single_post_title(); ?&gt;&lt;/h1&gt;
&lt;/header&gt;
&lt;?php }
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content',
get_post_format() );
}
} else {
get_template_part( 'template-parts/content', 'none' );</code></pre>
<em>Listing 145: Ausschnitt der korrigierten index.php nach Admin-Review</em>
Um die Portfolio-Elemente dennoch ausschließen zu können, kommt wie bereits erwähnt der Hook <code class="lang-php">pre_get_posts</code> zum Einsatz. Die komplette Funktion ist in Listing 146 zu sehen.
<pre class="lang-php"><code class="lang-php">function hannover_exlude_portfolio_elements_from_blog( $query ) {
if ( $query-&gt;is_home() &amp;&amp; $query-&gt;is_main_query() ) {
$exclude_portfolio_elements = get_theme_mod(
'exclude_portfolio_elements_from_blog' );
if ( $exclude_portfolio_elements == 'checked' ) {
$use_portfolio_category = get_theme_mod(
'portfolio_from_category' );
$portfolio_category = get_theme_mod( 'portfolio_category' );
if ( $use_portfolio_category == 'checked'
&amp;&amp; $portfolio_category != '' ) {
$query-&gt;set( 'cat', "-$portfolio_category" );
} else {
$tax_query = array(
array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array( 'post-format-gallery',
'post-format-image' ),
'operator' =&gt; 'NOT IN'
)
);
$query-&gt;set( 'tax_query', $tax_query );
}
}
}
}
add_action( 'pre_get_posts',
'hannover_exlude_portfolio_elements_from_blog' );</code></pre>
<em>Listing 146: hannover_exclude_portfolio_elemente_from_blog() in der functions.php</em>
Über den <code class="lang-php">$query</code>-Parameter ist das Query-Objekt zugänglich, das nach Ausführung des <code class="lang-php">pre_get_posts</code>-Hooks zur Anzeige der Beiträge genutzt wird. Mit <code class="lang-php">$query-&gt;is_home()</code> und <code class="lang-php">$query-&gt;is_main_query()</code> wird zunächst geprüft, ob die Query auf der Blog-Seite ausgeführt wird und die Main-Query ist.<a href="#_ftn272" name="_ftnref272">[272]</a>, <a href="#_ftn273" name="_ftnref273">[273]</a> Anschließend wird mit bekanntem Code aus Listing 67 von Seite 73 ermittelt, ob Portfolio-Elemente vom Blog ausgeschlossen werden sollen. Wenn das der Fall ist und die Elemente durch eine Kategorie gekennzeichnet sind, wird wie im Codex beschrieben mit <code class="lang-php" style="word-wrap: break-word; white-space: normal;">$query-&gt;set( 'cat', "-$portfolio_category" );</code> die Portfolio-Kategorie mit einem vorangestellten <code class="lang-php">-</code> in den <code class="lang-php">cat</code>-Schlüssel des Argument-Arrays für die Query eingefügt.<a href="#_ftn274" name="_ftnref274">[274]</a> Nach demselben Verfahren kann der <code class="lang-php">tax_query</code>-Schlüssel gefüllt werden, wenn alle Bild- und Galerie-Beiträge die Portfolio-Elemente bilden.
<h4 id="stark-empfohlen">6.2.2 Stark Empfohlen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Die Art und Weise, wie das Theme die Portfolio-Funktion integriert, ist ohne kurze Anleitung für einen neuen Nutzer nicht einfach zu erfassen, weshalb der Reviewer empfohlen hat, eine Anleitung in die Readme-Datei einzufügen, um den Einstieg zu erleichtern.
In die Readme wurde daraufhin eine kurze nummerierte Liste eingefügt, die Schritt für Schritt eine mögliche Einrichtung des Themes erläutert, gefolgt von einer ausführlicheren Erklärung und den erweiterten Möglichkeiten durch den Customizer.
<h4 id="empfohlen">6.2.3 Empfohlen</h4>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<strong>Ähnliche Logik aus mehreren Dateien in eine Funktion auslagern</strong>
Die Logik der Argumentvorbereitung für die eigenen Querys in den Page-Template-Dateien <code class="lang-markup">portfolio-page.php</code>, <code class="lang-markup">portfolio-category-page.php</code> und <code class="lang-markup">portfolio-archive-page.php</code> ist sehr ähnlich, weshalb sie sich besser in eine eigene Funktion auslagern lässt, die dann jeweils aus den Template-Dateien aufgerufen wird. Um das richtige Array für jedes der Seiten-Templates in einer Funktion zusammenzusetzen, muss nach den Seiten-Templates unterschieden werden – der Funktionsaufruf gibt neben dem Post-Objekt als String deshalb noch das Seiten-Template als String an.
<pre class="lang-php"><code class="lang-php">function hannover_page_template_query_args( $post,
$template = 'portfolio' ) {
$archive_type = get_theme_mod( 'portfolio_archive' );
$archive_category = get_theme_mod( 'portfolio_archive_category' );
$use_portfolio_category = get_theme_mod( 'portfolio_from_category' );
$portfolio_category = get_theme_mod( 'portfolio_category' );
if ( $template == 'portfolio' ) {
$elements_per_page = get_theme_mod( 'portfolio_elements_per_page',
0 );
} elseif ( $template == 'portfolio-archive' ) {
$elements_per_page = get_theme_mod(
'portfolio_archive_elements_per_page', 0 );
} else {
$elements_per_page = get_theme_mod(
"portfolio_category_page_elements_per_page_$post-&gt;ID", 0 );
$portfolio_category_page_category = get_theme_mod(
"portfolio_category_page_$post-&gt;ID" );
}
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;</code></pre>
<em>Listing 147: Anfang von hannover_page_template_query_args() in functions.php</em>
In Listing 147 sind die ersten Zeilen dieser Funktion abgebildet. Für alle drei Seiten-Templates werden Informationen benötigt, ob und mit welcher Kategorie ein Archiv angelegt ist und ob die Portfolio-Elemente mit einer Kategorie gekennzeichnet wurden und mit welcher – die Informationen aus dem Customizer werden auf dieselbe Art ermittelt, wie bereits aus den verschiedenen Seiten-Template-Dateien bekannt. Die Anzahl der Elemente pro Seite muss für jedes Template anders ermittelt werden, weshalb der Wert von <code class="lang-php">$template</code> überprüft und je nach Wert die richtige Customizer-Einstellung ausgelesen wird – im Fall der Kategorie-Seiten wird für die Bildung der Einstellungs-ID mit <code class="lang-php">$post-&gt;ID</code> auf die Seiten-ID zugegriffen und neben der Anzahl pro Seite noch die Kategorie ermittelt, die angezeigt werden soll. Abschließend wird in dem Code-Block der Wert für den <code class="lang-php">paged</code>-Schlüssel, der bei allen Seiten-Templates gleich ist, in einer Variable gespeichert.
<pre class="lang-php"><code class="lang-php"> $tax_query = array( 'relation' =&gt; 'AND' );
if ( $elements_per_page == 0 ) {
$elements_per_page = - 1;
}
$tax_query[] = array(
'taxonomy' =&gt; 'post_format',
'field' =&gt; 'slug',
'terms' =&gt; array(
'post-format-gallery',
'post-format-image'
),
);
if ( $template != 'portfolio-archive' &amp;&amp;
$archive_type == 'archive_category' ) {
$tax_query[] = array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
'operator' =&gt; 'NOT IN'
);
}
if ( $template == 'portfolio-archive' &amp;&amp;
$archive_category !== '' &amp;&amp; $archive_type == 'archive_category' ) {
$tax_query[] = array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $archive_category ),
);
}
if ( $template == 'portfolio-category-page' ) {
$tax_query[] = array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category_page_category ),
);
}
if ( $use_portfolio_category == 'checked'
&amp;&amp; $portfolio_category !== '' ) {
$tax_query[] = array(
'taxonomy' =&gt; 'category',
'field' =&gt; 'term_id',
'terms' =&gt; array( $portfolio_category ),
);
}
$args = array(
'posts_per_page' =&gt; $elements_per_page,
'paged' =&gt; $paged,
'tax_query' =&gt; $tax_query
);
return $args;
}</code></pre>
<em>Listing 148: Ende der hannover_page_template_query_args()</em>
Listing 148 zeigt den zweiten Teil der Funktion. Die Beziehung zwischen den verschiedenen Unter-Arrays des <code class="lang-php">tax_query</code>-Schlüssels ist bei allen Seiten-Templates <code class="lang-php">AND</code>, weshalb dieser Wert ohne weitere Prüfung in <code class="lang-php">$tax_query</code> gespeichert werden kann. Wenn als Anzahl der Elemente pro Seite eine <code class="lang-php">0</code> ermittelt wurde, wird dieser Wert in <code class="lang-php">-1</code> verändert. Anschließend wird dem <code class="lang-php">tax_query</code>-Array ein weiterer Wert hinzugefügt, der für alle Seiten-Templates gilt: Die Einschränkung auf Galerie- und Bild-Beiträge.
Als Nächstes wird überprüft, ob es sich bei dem Seiten-Template nicht um das Archiv handelt und ob ein Archiv eingesetzt wird – ist das der Fall, wird <code class="lang-php">tax_query</code> ein weiteres Unter-Array hinzugefügt, das die Beiträge aus der Archiv-Kategorie ausschließt. Wenn es sich bei dem Template hingegen um das Archiv handelt und sowohl eine Archiv-Kategorie gesetzt ist als auch ein Archiv erzeugt werden soll, werden die Beiträge mit einer weiteren Bedingung für <code class="lang-php">tax_query</code> auf die Archiv-Kategorie eingeschränkt.
Handelt es sich jedoch um eine Kategorie-Seite, müssen die angezeigten Beiträge auch der Kategorie, die im Customizer für die aktuelle Seite gewählt ist, zugewiesen sein. Wenn das Portfolio anhand einer Kategorie gebildet wird und eine Kategorie gewählt wurde, dann muss unabhängig vom Seiten-Template noch die Bedingung eingefügt werden, dass die Beiträge in der Portfolio-Kategorie sind.
Abschließend wird in <code class="lang-php">$args</code> das Argument-Array aus <code class="lang-php">posts_per_page</code>, <code class="lang-php">paged</code> und dem zusammengesetzten Array für <code class="lang-php">tax_query</code> gebildet und zurückgegeben.
Der Aufruf der Funktion aus den einzelnen Dateien ist in Listing 150, Listing 151 und Listing 152 dargestellt – die jeweils bereits vorhandenen Teile um den Aufruf sind ausgegraut.
<pre class="lang-php"><code class="greyed">&lt;/header&gt;
&lt;?php </code><code class="lang-php">$args = hannover_page_template_query_args( $post, 'portfolio' );</code> <code class="greyed">$portfolio_query = new WP_Query( $args );
$temp_query = $wp_query;</code></pre>
<em>Listing 149: Aufruf von hannover_page_template_query_args() in der portfolio-page.php</em>
<pre class="lang-php"><code class="greyed">&lt;/header&gt;
&lt;?php </code><code class="lang-php">$args = hannover_page_template_query_args( $post,
'portfolio-category-page' );</code> <code class="greyed">$portfolio_query = new WP_Query( $args );
$temp_query = $wp_query;</code></pre>
<em>Listing 150: Aufruf von hannover_page_template_query_args() in der portfolio-category-page.php</em>
<pre class="lang-php"><code class="greyed">&lt;/header&gt;
&lt;?php </code><code class="lang-php">$args = hannover_page_template_query_args( $post,
'portfolio-archive' );</code> <code class="greyed">$archive_query = new WP_Query( $args );
$temp_query = $wp_query;</code></pre>
<em>Listing 151: Aufruf von hannover_page_template_query_args() in der portfolio-archive-page.php</em>
<strong>Weitere kleine Anpassungen</strong>
Die beiden Dateien <code class="lang-markup">customizer.php</code> und <code class="lang-markup" style="word-wrap: break-word; white-space: normal;">class-hannover-social-menu-walker.php</code> werden vom Theme ursprünglich mit der <code class="lang-php">require</code>-Kontrollstruktur eingebunden. Auch wenn es unwahrscheinlich ist, dass diese Dateien zweimal eingebunden werden, kann das mit dem Einsatz von <code class="lang-php">require_once</code> im Vorhinein verhindert werden – die Anpassung ist in Listing 152 abgebildet.<a href="#_ftn275" name="_ftnref275">[275]</a>
<pre class="lang-php"><code class="lang-php">require_once get_template_directory() . '/inc/customizer.php';
require_once get_template_directory()
. '/inc/class-hannover-social-menu-walker.php';</code></pre>
<em>Listing 152: Nutzung von require_once statt require in der functions.php</em>
Zudem wurden bei den Kommentarblöcken über den Funktionen teilweise falsche Werte für <code class="lang-php">@return</code> angegeben. Wenn eine Funktion kein <code class="lang-php">return</code>-Statement enthält, sondern direkt etwas ausgibt, handelt es sich um eine Void-Funktion. In diesem Fall wird <code class="lang-php">@return void</code> angegeben.
Darüber hinaus wurde in die JavaScript-Datei des SVG-Fallbacks die Lizenz eingefügt und drei Einheiten im CSS-Code gelöscht, bei der der Wert <code class="lang-php">0</code> war.
<h2 id="fazit">7 Fazit</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Ergebnis der Bachelorarbeit ist ein WordPress-Theme, das allen WordPress-Nutzern kostenlos über das Theme-Verzeichnis zur Verfügung steht.<a href="#_ftn276" name="_ftnref276">[276]</a> Die eingangs aufgeworfene Frage nach wünschenswerten Funktionen für Fotografen konnte durch die Analyse bestehender Websites beantwortet werden: Wichtig ist die Möglichkeit, eine Trennung der Portfolio-Elemente von der Blog-Funktion vorzunehmen. Die Portfolio-Elemente sollen alle auf einer Seite angezeigt werden, aber mit dem Theme sollte auch eine Aufteilung nach Kategorien möglich sein. Darüber hinaus sollte der Nutzer Portfolio-Elemente für ein Archiv markieren können, sodass sie nicht in der Portfolio-Übersicht auftauchen. Zudem werden Bilder oft als Slider angezeigt, statt einzeln untereinander. Für die Startseite sollte es die Möglichkeiten geben, einen Slider oder ein zufälliges Bild anzuzeigen.
Auch die Frage nach den Voraussetzungen, die für das Theme-Verzeichnis erfüllt werden müssen, konnte mithilfe des Theme-Review-Handbuchs beantwortet werden. So darf der Code keinerlei Fehler auswerfen und muss – wenn vorhanden – statt eigener Funktionen die Core-Funktionen von WordPress nutzen. Änderungen am Inhalt dürfen nicht fest im Code verankert sein, sondern müssen über Hooks oder Funktionsparameter umgesetzt werden. Außerdem muss sich ein Theme auf die Präsentation beschränken und darf keine Funktionen wie Custom-Post-Types oder Shortcodes integrieren, durch die der Nutzer Inhalte erstellen kann. Zudem muss das Theme dokumentiert werden und übersetzungsfähig sein. Der Theme-Code und alle verwendeten Ressourcen müssen unter der GPL oder einer kompatiblen Lizenz stehen, und das Theme darf weder den Begriff <em>WordPress</em> noch <em>Theme</em> im Namen tragen. Ein Theme darf weder Plugin-Code mitliefern noch Plugins für die korrekte Funktionalität voraussetzen. Weitere erforderliche Voraussetzungen sind ein Screenshot sowie die Nutzung von Funktionen für die sichere Ausgabe und Speicherung von Informationen. Bei einem eingebauten Link zum Entwickler dürfen auf seiner Seite nur Themes verkauft werden, die unter der GPL oder einer kompatiblen Lizenz stehen. Stylesheets und Skripte müssen, genau wie Template-Dateien, mit den vorgesehenen Funktionen eingebunden werden. Daneben gibt es noch einige empfohlene Richtlinien, deren Verletzung aber nicht zu einem Ausschluss aus dem Verzeichnis führt.
Alle Funktionen, die aus der Analyse der Fotografen-Websites hervorgegangen sind, konnten mit Bordmitteln umgesetzt werden, ohne die Richtlinien des Theme-Verzeichnisses zu verletzten. Der Code des fertigen Themes kann in einem GitHub-Repository eingesehen werden, wobei das Tag <em>v1.0.8</em> den Stand des Themes nach dieser Arbeit ohne zukünftige Updates festhält.<a href="#_ftn277" name="_ftnref277">[277]</a>, <a href="#_ftn278" name="_ftnref278">[278]</a>
Durch die kleinschrittige Bearbeitung der Theme-Entwicklung ist die Arbeit hilfreich für alle, die sich näher mit der Theme-Programmierung auseinandersetzen möchten oder die sich in das Theme einarbeiten wollen, um Anpassungen vorzunehmen.
Hilfreich für den Verfasser der Arbeit war der Prozess der Theme-Entwicklung, weil er sich intensiv mit der Materie beschäftigen musste, die für seinen späteren Berufsweg wichtig ist. Besonders herausfordernd war die Umsetzung des Social-Media-Menüs mit den SVGs. Zudem hat der Verfasser sich erstmals detailliert mit der Nutzung der Überschriftenebenen nach Aspekten der Barrierefreiheit auseinandergesetzt und einen Weg der getrennten Zählung von Kommentaren und Trackbacks gefunden, der weniger Datenbankabfragen benötigt als die bis dahin genutzte Methode. Durch das Feedback des Reviewers wurde der Verfasser auf wichtige Punkte wie die Auslagerung von Logik aufmerksam gemacht, die an mehreren Stellen fast identisch genutzt wird, um weniger redundanten Code zu schreiben. Durch die Admin-Review wurde er außerdem auf eine praktische Lösung aufmerksam gemacht, um die Main-Query zu verändern, ohne die Funktion von Plugins zu gefährden.
<h2 id="fussnoten">Fußnoten</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<a href="#_ftnref1" name="_ftn1">[1]</a> vgl. WordPress: Code Reference. <a href="https://developer.wordpress.org/reference/">https://developer.wordpress.org/reference/</a> (Zugriff vom 04.01.2016).
<a href="#_ftnref2" name="_ftn2">[2]</a> vgl. WordPress: Theme Review Handbook. <a href="https://make.wordpress.org/themes/handbook/">https://make.wordpress.org/themes/handbook/</a> (Zugriff vom 04.01.2016).
<a href="#_ftnref3" name="_ftn3">[3]</a> vgl. Mozilla: Webtechnologien für Entwickler | MDN. <a href="https://developer.mozilla.org/de/docs/Web">https://developer.mozilla.org/de/docs/Web</a> (Zugriff vom 04.01.2016).
<a href="#_ftnref4" name="_ftn4">[4]</a> vgl. PHP Group: PHP-Handbuch. <a href="http://php.net/manual/de/">http://php.net/manual/de/</a> (Zugriff vom 04.01.2016).
<a href="#_ftnref5" name="_ftn5">[5]</a> vgl. World Press Photo Foundation: 2015 Photo Contest. <a href="http://www.worldpressphoto.org/collection/photo/2015">http://www.worldpressphoto.org/collection/photo/2015</a> (Zugriff vom 30.10.2015).
<a href="#_ftnref6" name="_ftn6">[6]</a> vgl. WordPress: Theme-Verzeichnis. <a href="https://de.wordpress.org/themes/">https://de.wordpress.org/themes/</a> (Zugriff vom 04.01.2016).
<a href="#_ftnref7" name="_ftn7">[7]</a> vgl. World Press Photo Foundation: 2015 Photo Contest. <a href="http://www.worldpressphoto.org/collection/photo/2015">http://www.worldpressphoto.org/collection/photo/2015</a> (Zugriff vom 30.10.2015).
<a href="#_ftnref8" name="_ftn8">[8]</a> vgl. WordPress: Theme Review Handbook › Required. <a href="https://make.wordpress.org/themes/handbook/review/required/">https://make.wordpress.org/themes/handbook/review/required/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref9" name="_ftn9">[9]</a> vgl. WordPress: Theme Review Handbook › Recommended. <a href="https://make.wordpress.org/themes/handbook/review/recommended/">https://make.wordpress.org/themes/handbook/review/recommended/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref10" name="_ftn10">[10]</a> vgl. WordPress: Theme Review Handbook › Required › Code. <a href="https://make.wordpress.org/themes/handbook/review/required/#code">https://make.wordpress.org/themes/handbook/review/required/#code</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref11" name="_ftn11">[11]</a> vgl. WordPress: Theme Review Handbook › Required › Core Functionality and Features. <a href="https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features">https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref12" name="_ftn12">[12]</a> vgl. WordPress: Theme Review Handbook › Required › Presentation vs Functionality. <a href="https://make.wordpress.org/themes/handbook/review/required/#presentation-vs-functionality">https://make.wordpress.org/themes/handbook/review/required/#presentation-vs-functionality</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref13" name="_ftn13">[13]</a> vgl. Tadlock, Justin (2015): Meeting Minutes 06/11/15 › Kommentar. <a href="https://make.wordpress.org/themes/2015/06/13/meeting-minutes-061115/#comment-42032">https://make.wordpress.org/themes/2015/06/13/meeting-minutes-061115/#comment-42032</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref14" name="_ftn14">[14]</a> vgl. WordPress: Theme Review Handbook › Required › Documentation. <a href="https://make.wordpress.org/themes/handbook/review/required/#documentation">https://make.wordpress.org/themes/handbook/review/required/#documentation</a> (Zugriff vom 25. November).
<a href="#_ftnref15" name="_ftn15">[15]</a> vgl. WordPress: Theme Review Handbook › Required › Language. <a href="https://make.wordpress.org/themes/handbook/review/required/#language">https://make.wordpress.org/themes/handbook/review/required/#language</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref16" name="_ftn16">[16]</a> vgl. Schilling, Dominik (2014): Language chooser in 4.0. <a href="https://make.wordpress.org/core/2014/09/05/language-chooser-in-4-0/">https://make.wordpress.org/core/2014/09/05/language-chooser-in-4-0/</a> (Zugriff vom 17.01.2016).
<a href="#_ftnref17" name="_ftn17">[17]</a> vgl. WordPress: Codex › L10n. <a href="https://codex.wordpress.org/L10n">https://codex.wordpress.org/L10n</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref18" name="_ftn18">[18]</a> vgl. WordPress: Plugin Handbook › Internationalization › How to Internationalize Your Plugin › Disambiguation by context. <a href="https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#disambiguation-by-context">https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#disambiguation-by-context</a> (Zugriff vom 17.01.2016).
<a href="#_ftnref19" name="_ftn19">[19]</a> vgl. WordPress: Plugin Handbook › Internationalization › How to Internationalize Your Plugin › Descriptions. <a href="https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#descriptions">https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#descriptions</a> (Zugriff vom 17.01.2016).
<a href="#_ftnref20" name="_ftn20">[20]</a> vgl. WordPress: Theme Review Handbook › Required › Licensing. <a href="https://make.wordpress.org/themes/handbook/review/required/#licensing">https://make.wordpress.org/themes/handbook/review/required/#licensing</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref21" name="_ftn21">[21]</a> vgl. WordPress: Theme Review Handbook › Required › Naming. <a href="https://make.wordpress.org/themes/handbook/review/required/#naming">https://make.wordpress.org/themes/handbook/review/required/#naming</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref22" name="_ftn22">[22]</a> vgl. Bennett, Chip: Using Sane Defaults in Themes. <a href="https://make.wordpress.org/themes/2014/07/09/using-sane-defaults-in-themes/">https://make.wordpress.org/themes/2014/07/09/using-sane-defaults-in-themes/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref23" name="_ftn23">[23]</a> vgl. WordPress: Theme Review Handbook › Required › Options and Settings. <a href="https://make.wordpress.org/themes/handbook/review/required/#options-and-settings">https://make.wordpress.org/themes/handbook/review/required/#options-and-settings</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref24" name="_ftn24">[24]</a> vgl. WordPress: Theme Review Handbook › Required › Plugins. <a href="https://make.wordpress.org/themes/handbook/review/required/#plugins">https://make.wordpress.org/themes/handbook/review/required/#plugins</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref25" name="_ftn25">[25]</a> vgl. WordPress: Theme Review Handbook › Required › Screenshot. <a href="https://make.wordpress.org/themes/handbook/review/required/#screenshot">https://make.wordpress.org/themes/handbook/review/required/#screenshot</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref26" name="_ftn26">[26]</a> vgl. WordPress: Theme Review Handbook › Required › Security and Privacy. <a href="https://make.wordpress.org/themes/handbook/review/required/#security-and-privacy">https://make.wordpress.org/themes/handbook/review/required/#security-and-privacy</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref27" name="_ftn27">[27]</a> vgl. WordPress: Theme Review Handbook › Required › Selling, credits and links. <a href="https://make.wordpress.org/themes/handbook/review/required/#selling-credits-and-links">https://make.wordpress.org/themes/handbook/review/required/#selling-credits-and-links</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref28" name="_ftn28">[28]</a> Tadlock, Justin (2015): Themes should be 100% GPL. <a href="https://make.wordpress.org/themes/2015/08/15/themes-should-be-100-gpl/">https://make.wordpress.org/themes/2015/08/15/themes-should-be-100-gpl/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref29" name="_ftn29">[29]</a> vgl. WordPress: Theme Review Handbook › Required › Templates. <a href="https://make.wordpress.org/themes/handbook/review/required/#templates">https://make.wordpress.org/themes/handbook/review/required/#templates</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref30" name="_ftn30">[30]</a> vgl. WordPress: Theme Review Handbook › Required › Core Functionality and Features. <a href="https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features">https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref31" name="_ftn31">[31]</a> vgl. WordPress: Theme Review Handbook › Design. <a href="https://make.wordpress.org/themes/handbook/review/recommended/design/">https://make.wordpress.org/themes/handbook/review/recommended/design/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref32" name="_ftn32">[32]</a> vgl. WordPress: Theme Review Handbook › Documentation. <a href="https://make.wordpress.org/themes/handbook/review/recommended/documentation/">https://make.wordpress.org/themes/handbook/review/recommended/documentation/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref33" name="_ftn33">[33]</a> vgl. WordPress: Theme Review Handbook › Selling, Themes and Links. <a href="https://make.wordpress.org/themes/handbook/review/recommended/selling-themes-and-links/">https://make.wordpress.org/themes/handbook/review/recommended/selling-themes-and-links/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref34" name="_ftn34">[34]</a> vgl. WordPress: Theme Review Handbook › Templates. <a href="https://make.wordpress.org/themes/handbook/review/recommended/templates/">https://make.wordpress.org/themes/handbook/review/recommended/templates/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref35" name="_ftn35">[35]</a> vgl. Koster, James (2015): Explore WordPress’ free theme options. In: net, H. 274, S. 108-112.
<a href="#_ftnref36" name="_ftn36">[36]</a> vgl. WordPress: Theme Directory › photoblogging-Tag. <a href="https://wordpress.org/themes/tags/photoblogging/">https://wordpress.org/themes/tags/photoblogging/</a> (Zugriff vom 02.11.2015).
<a href="#_ftnref37" name="_ftn37">[37]</a> vgl. ThemeForest: Premium WordPress Themes &amp; WordPress Templates. <a href="http://themeforest.net/category/wordpress">http://themeforest.net/category/wordpress</a> (Zugriff vom 09.11.2015).
<a href="#_ftnref38" name="_ftn38">[38]</a> vgl. ThemeForest: Meistverkaufte WordPress-Themes mit Tags „photography“ und „portfolio“. <a href="http://themeforest.net/search?utf8=%E2%9C%93&amp;term=&amp;view=list&amp;sort=sales&amp;date=&amp;category=wordpress&amp;tags=photography&amp;tags=portfolio&amp;price_min=&amp;price_max=&amp;sales=&amp;rating_min=">http://themeforest.net/search?utf8=%E2%9C%93&amp;term=&amp;view=list&amp;sort=sales&amp;date=&amp;category=wordpress&amp;tags=photography&amp;tags=portfolio&amp;price_min=&amp;price_max=&amp;sales=&amp;rating_min=</a> (Zugriff vom 09.11.2015).
<a href="#_ftnref39" name="_ftn39">[39]</a> vgl. ThemeForest: ANAN – For Photography Creative Portfolio. <a href="http://themeforest.net/item/anan-for-photography-creative-portfolio/174507">http://themeforest.net/item/anan-for-photography-creative-portfolio/174507</a> (Zugriff vom 09.11.2015).
<a href="#_ftnref40" name="_ftn40">[40]</a> vgl. inTheme: Alerts – Fluxus. <a href="http://inthe.me/demo/fluxus/features/alerts/">http://inthe.me/demo/fluxus/features/alerts/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref41" name="_ftn41">[41]</a> vgl. do.media: Help Document – Invictus › III. Adding Photos to your gallery. <a href="http://help.doitmax.de/invictus/#galleryIII">http://help.doitmax.de/invictus/#galleryIII</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref42" name="_ftn42">[42]</a> vgl. Tadlock, Justin (2015): The theme review team’s content creation discussion. <a href="http://justintadlock.com/archives/2015/05/28/the-theme-review-teams-content-creation-discussion">http://justintadlock.com/archives/2015/05/28/the-theme-review-teams-content-creation-discussion</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref43" name="_ftn43">[43]</a> vgl. WordPress: Debugging in WordPress. <a href="https://codex.wordpress.org/Debugging_in_WordPress">https://codex.wordpress.org/Debugging_in_WordPress</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref44" name="_ftn44">[44]</a> vgl. Castaneda, Jose (2015): Theme Review Tools. <a href="https://make.wordpress.org/themes/2015/07/23/theme-review-tools/">https://make.wordpress.org/themes/2015/07/23/theme-review-tools/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref45" name="_ftn45">[45]</a> vgl. automattic; Jangda, Mohammad; Mills, Alex; Bachiyski, Nikolay; Ott, Thorsten; Bachhuber, Daniel; Betz, Josh; Nadarajah, Prasath; Daugherty, Dick: „Developer“-Plugin. <a href="https://wordpress.org/plugins/developer/">https://wordpress.org/plugins/developer/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref46" name="_ftn46">[46]</a> vgl. Wood, Samuel; Prosser, Simon: „Theme Check“-Plugin. <a href="https://wordpress.org/plugins/theme-check/">https://wordpress.org/plugins/theme-check/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref47" name="_ftn47">[47]</a> vgl. WordPress; Boren, Ryan; Westwood, Peter; Koopersmith, Daryl; Cave, Jon; Yoshitaka Erlewine, Michael: „Debug Bar“-Plugin. <a href="https://wordpress.org/plugins/debug-bar/">https://wordpress.org/plugins/debug-bar/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref48" name="_ftn48">[48]</a> vgl. Nacin, Andrew: „Log Deprecated Notices“-Plugin. <a href="https://wordpress.org/plugins/log-deprecated-notices/">https://wordpress.org/plugins/log-deprecated-notices/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref49" name="_ftn49">[49]</a> vgl. automattic; Fields, Michael; Willett, Lance: „Monster Widget“-Plugin. <a href="https://wordpress.org/plugins/monster-widget/">https://wordpress.org/plugins/monster-widget/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref50" name="_ftn50">[50]</a> vgl. Westwood, Peter: „WordPress Beta Tester“-Plugin. <a href="https://wordpress.org/plugins/wordpress-beta-tester/">https://wordpress.org/plugins/wordpress-beta-tester/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref51" name="_ftn51">[51]</a> vgl. Mills, Alex: „Regenerate Thumbnails“-Plugin. <a href="https://wordpress.org/plugins/regenerate-thumbnails/">https://wordpress.org/plugins/regenerate-thumbnails/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref52" name="_ftn52">[52]</a> vgl. WordPress: Codex › Theme Unit Test. <a href="http://codex.wordpress.org/Theme_Unit_Test">http://codex.wordpress.org/Theme_Unit_Test</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref53" name="_ftn53">[53]</a> vgl. Novotny, Michael: WP Test. <a href="http://wptest.io/">http://wptest.io/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref54" name="_ftn54">[54]</a> Williams, Brad; Damstra, David; Stern, Hal (2015): <em>Professional WordPress. Design and development. </em>Third edition. Indianapolis, Indiana: Wrox. S. 166-171.
<a href="#_ftnref55" name="_ftn55">[55]</a> vgl. WordPress: Code Reference › Hooks › comment_post. <a href="https://developer.wordpress.org/reference/hooks/comment_post/">https://developer.wordpress.org/reference/hooks/comment_post/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref56" name="_ftn56">[56]</a> Williams, Brad; Damstra, David; Stern, Hal (2015): <em>Professional WordPress. Design and development. </em>Third edition. Indianapolis, Indiana: Wrox. S. 167.
<a href="#_ftnref57" name="_ftn57">[57]</a> vgl. WordPress: Code Reference › Functions › add_action. <a href="https://developer.wordpress.org/reference/functions/add_action/">https://developer.wordpress.org/reference/functions/add_action/</a> (Zugriff vom 17.12.2015).
<a href="#_ftnref58" name="_ftn58">[58]</a> Williams, Brad; Damstra, David; Stern, Hal (2015): <em>Professional WordPress. Design and development. </em>Third edition. Indianapolis, Indiana: Wrox. S. 166-167.
<a href="#_ftnref59" name="_ftn59">[59]</a> vgl. WordPress: Code Reference › Functions › add_filter. <a href="https://developer.wordpress.org/reference/functions/add_filter/">https://developer.wordpress.org/reference/functions/add_filter/</a> (Zugriff vom 17.12.2015).
<a href="#_ftnref60" name="_ftn60">[60]</a> vgl. WordPress: Code Reference › Hooks › the_content. <a href="https://developer.wordpress.org/reference/hooks/the_content/">https://developer.wordpress.org/reference/hooks/the_content/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref61" name="_ftn61">[61]</a> vgl. Tadlock, Justin (2015): Details on the new theme settings (customizer) guideline. <a href="https://make.wordpress.org/themes/2015/04/22/details-on-the-new-theme-settings-customizer-guideline/">https://make.wordpress.org/themes/2015/04/22/details-on-the-new-theme-settings-customizer-guideline/</a> (Zugriff vom 19.12.2015).
<a href="#_ftnref62" name="_ftn62">[62]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_setting. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/add_setting/">https://developer.wordpress.org/reference/classes/wp_customize_manager/add_setting/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref63" name="_ftn63">[63]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_control. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/add_control/">https://developer.wordpress.org/reference/classes/wp_customize_manager/add_control/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref64" name="_ftn64">[64]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/">https://developer.wordpress.org/reference/classes/wp_customize_manager/</a> (Zugriff vom 17.12.2015).
<a href="#_ftnref65" name="_ftn65">[65]</a> vgl. WordPress: Code Reference › Hooks › customize_register. <a href="https://developer.wordpress.org/reference/hooks/customize_register/">https://developer.wordpress.org/reference/hooks/customize_register/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref66" name="_ftn66">[66]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_section. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/add_section/">https://developer.wordpress.org/reference/classes/wp_customize_manager/add_section/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref67" name="_ftn67">[67]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_panel. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/add_panel/">https://developer.wordpress.org/reference/classes/wp_customize_manager/add_panel/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref68" name="_ftn68">[68]</a> vgl. WordPress: Theme Handbook › Theme Basics › Template Files › Common WordPress template files. <a href="https://developer.wordpress.org/themes/basics/template-files/#common-wordpress-template-files">https://developer.wordpress.org/themes/basics/template-files/#common-wordpress-template-files</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref69" name="_ftn69">[69]</a> vgl. WordPress: Codex › Theme Development › Theme Stylesheet. <a href="https://codex.wordpress.org/Theme_Development#Theme_Stylesheet">https://codex.wordpress.org/Theme_Development#Theme_Stylesheet</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref70" name="_ftn70">[70]</a> vgl. Wood, Samuel; Obenland, Konstantin (2015): theme-check/checks/style_needed.php. <a href="https://github.com/Otto42/theme-check/blob/542e2b520c94f5455cbf86f8d59d3bc6555aac1e/checks/style_needed.php#L11-L16">https://github.com/Otto42/theme-check/blob/542e2b520c94f5455cbf86f8d59d3bc6555aac1e/checks/style_needed.php#L11-L16</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref71" name="_ftn71">[71]</a> vgl. WordPress: Theme Handbook › Internationalization › Text Domains. <a href="https://developer.wordpress.org/themes/functionality/internationalization/#text-domains">https://developer.wordpress.org/themes/functionality/internationalization/#text-domains</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref72" name="_ftn72">[72]</a> vgl. WordPress: Theme Handbook › Theme Basics › Template Files › Template Partials. <a href="https://developer.wordpress.org/themes/basics/template-files/#template-partials">https://developer.wordpress.org/themes/basics/template-files/#template-partials</a> (Zugriff vom 22.12.2015).
<a href="#_ftnref73" name="_ftn73">[73]</a> vgl. WordPress: Code Reference › Functions › language_attributes. <a href="https://developer.wordpress.org/reference/functions/language_attributes/">https://developer.wordpress.org/reference/functions/language_attributes/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref74" name="_ftn74">[74]</a> vgl. vlastuin: Code Reference › Functions › bloginfo › Show Character Set. <a href="https://developer.wordpress.org/reference/functions/bloginfo/#comment-515">https://developer.wordpress.org/reference/functions/bloginfo/#comment-515</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref75" name="_ftn75">[75]</a> vgl. xrds; Shepherd, Eric; thehaverchuck; hasAngel; Dursun, Resul; Hobson, Stephanie; Rebert, Chris; Taylor, Mike; wesj; zigomir; martind1; ddsgdfgidshvbeivbosdlvbdfvdsv; Dutton, Sam; Brubeck, Matt; Vukicevic, Vlad: Using the viewport meta tag to control layout on mobile browsers. <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag">https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref76" name="_ftn76">[76]</a> vgl. WordPress: Code Reference › Functions › is_singular. <a href="https://developer.wordpress.org/reference/functions/is_singular/">https://developer.wordpress.org/reference/functions/is_singular/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref77" name="_ftn77">[77]</a> vgl. WordPress: Code Reference › Functions › pings_open. <a href="https://developer.wordpress.org/reference/functions/pings_open/">https://developer.wordpress.org/reference/functions/pings_open/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref78" name="_ftn78">[78]</a> vgl. WordPress: Codex › Function Reference › bloginfo › Parameters. <a href="https://codex.wordpress.org/Function_Reference/bloginfo#Parameters">https://codex.wordpress.org/Function_Reference/bloginfo#Parameters</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref79" name="_ftn79">[79]</a> vgl. WordPress: Codex › Introducion to Blogging › Pingbacks. <a href="http://codex.wordpress.org/Introduction_to_Blogging#Pingbacks">http://codex.wordpress.org/Introduction_to_Blogging#Pingbacks</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref80" name="_ftn80">[80]</a> vgl. WordPress: Code Reference › Functions › wp_head. <a href="https://developer.wordpress.org/reference/functions/wp_head/">https://developer.wordpress.org/reference/functions/wp_head/</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref81" name="_ftn81">[81]</a> vgl. WordPress: Code Reference › Hooks › wp_head. <a href="https://developer.wordpress.org/reference/hooks/wp_head/">https://developer.wordpress.org/reference/hooks/wp_head/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref82" name="_ftn82">[82]</a> vgl. WordPress: Code Reference › Functions › body_class. <a href="https://developer.wordpress.org/reference/functions/body_class/">https://developer.wordpress.org/reference/functions/body_class/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref83" name="_ftn83">[83]</a> vgl. WordPress: Core-Trac › tags/4.3.1/src/wp-includes/post-template.php › Zeile 544. <a href="https://core.trac.wordpress.org/browser/tags/4.3.1/src/wp-includes/post-template.php#L544">https://core.trac.wordpress.org/browser/tags/4.3.1/src/wp-includes/post-template.php#L544</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref84" name="_ftn84">[84]</a> vgl. WordPress: Code Reference › Functions › _e. <a href="https://developer.wordpress.org/reference/functions/_e/">https://developer.wordpress.org/reference/functions/_e/</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref85" name="_ftn85">[85]</a> vgl. WordPress: Code Reference › Functions › get_header_image. <a href="https://developer.wordpress.org/reference/functions/get_header_image/">https://developer.wordpress.org/reference/functions/get_header_image/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref86" name="_ftn86">[86]</a> vgl. Rietveld, Rian (2014): HTML5 Headings in WordPress: A11y versus SEO? <a href="http://blog.rrwd.nl/2014/11/21/html5-headings-in-wordpress-lets-fight/">http://blog.rrwd.nl/2014/11/21/html5-headings-in-wordpress-lets-fight/</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref87" name="_ftn87">[87]</a> vgl. WordPress: Code Reference › Functions › is_front_page. <a href="https://developer.wordpress.org/reference/functions/is_front_page/">https://developer.wordpress.org/reference/functions/is_front_page/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref88" name="_ftn88">[88]</a> vgl. WordPress: Code Reference › Functions › is_home. <a href="https://developer.wordpress.org/reference/functions/is_home/">https://developer.wordpress.org/reference/functions/is_home/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref89" name="_ftn89">[89]</a> vgl. WordPress: Code Reference › Functions › get_header_image. <a href="https://developer.wordpress.org/reference/functions/get_header_image/">https://developer.wordpress.org/reference/functions/get_header_image/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref90" name="_ftn90">[90]</a> vgl. WordPress: Codex › Function Reference › bloginfo › Parameters. <a href="https://codex.wordpress.org/Function_Reference/bloginfo#Parameters">https://codex.wordpress.org/Function_Reference/bloginfo#Parameters</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref91" name="_ftn91">[91]</a> vgl. WordPress: Code Reference › Functions › home_url. <a href="https://developer.wordpress.org/reference/functions/home_url/">https://developer.wordpress.org/reference/functions/home_url/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref92" name="_ftn92">[92]</a> vgl. WordPress: Code Reference › Functions › esc_url. <a href="https://developer.wordpress.org/reference/functions/esc_url/">https://developer.wordpress.org/reference/functions/esc_url/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref93" name="_ftn93">[93]</a> vgl. WordPress: Codex › Function Reference › bloginfo › Parameters. <a href="https://codex.wordpress.org/Function_Reference/bloginfo#Parameters">https://codex.wordpress.org/Function_Reference/bloginfo#Parameters</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref94" name="_ftn94">[94]</a> vgl. WordPress: Code Reference › Functions › bloginfo › Source. <a href="https://developer.wordpress.org/reference/functions/bloginfo/#source-code">https://developer.wordpress.org/reference/functions/bloginfo/#source-code</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref95" name="_ftn95">[95]</a> vgl. WordPress: Code Reference › Functions › get_bloginfo. <a href="https://developer.wordpress.org/reference/functions/get_bloginfo/">https://developer.wordpress.org/reference/functions/get_bloginfo/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref96" name="_ftn96">[96]</a> vgl. WordPress: Code Reference › Functions › has_nav_menu. <a href="https://developer.wordpress.org/reference/functions/has_nav_menu/">https://developer.wordpress.org/reference/functions/has_nav_menu/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref97" name="_ftn97">[97]</a> vgl. Perrier, Jean-Yves; Zartner, Sebastian; Scarfone, Karen; Stone-Thompson, Peter; Shepherd, Eric; medicdude; ethertank; Sonne, Christian; dhodder; Scholz, Florian; Wilsson, Jonathan; Hobson, Trevor; Swisher, Janet: MDN › HTML › &lt;nav&gt;. <a href="https://developer.mozilla.org/de/docs/Web/HTML/Element/nav">https://developer.mozilla.org/de/docs/Web/HTML/Element/nav</a> (Zugriff vom 28.11.2015).
<a href="#_ftnref98" name="_ftn98">[98]</a> vgl. WordPress: Plugin Handbook › Internationalization › How to Internationalize Your Plugin › Descriptions.
<a href="#_ftnref99" name="_ftn99">[99]</a> vgl. WordPress: Code Reference › Functions › wp_nav_menu. <a href="https://developer.wordpress.org/reference/functions/wp_nav_menu/">https://developer.wordpress.org/reference/functions/wp_nav_menu/</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref100" name="_ftn100">[100]</a> vgl. WordPress: Code Reference › Functions › register_nav_menu. <a href="https://developer.wordpress.org/reference/functions/register_nav_menu/">https://developer.wordpress.org/reference/functions/register_nav_menu/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref101" name="_ftn101">[101]</a> vgl. WordPress: Code Reference › Functions › register-nav_menus. <a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">https://developer.wordpress.org/reference/functions/register_nav_menus/</a> (Zugriff vom 01.12.2015).
<a href="#_ftnref102" name="_ftn102">[102]</a> vgl. WordPress: Code Reference › Functions › __. <a href="https://developer.wordpress.org/reference/functions/__/">https://developer.wordpress.org/reference/functions/__/</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref103" name="_ftn103">[103]</a> vgl. WordPress: Code Reference › Hooks › init. <a href="https://developer.wordpress.org/reference/hooks/init/">https://developer.wordpress.org/reference/hooks/init/</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref104" name="_ftn104">[104]</a> vgl. WordPress: Code Reference › Functions › add_theme_support. <a href="https://developer.wordpress.org/reference/functions/add_theme_support/">https://developer.wordpress.org/reference/functions/add_theme_support/</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref105" name="_ftn105">[105]</a> vgl. WordPress: Codex › add_theme_support › Custom Header. <a href="https://codex.wordpress.org/Function_Reference/add_theme_support#Custom_Header">https://codex.wordpress.org/Function_Reference/add_theme_support#Custom_Header</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref106" name="_ftn106">[106]</a> vgl. WordPress: Codex › add_theme_support › Feed Links. <a href="https://codex.wordpress.org/Function_Reference/add_theme_support#Feed_Links">https://codex.wordpress.org/Function_Reference/add_theme_support#Feed_Links</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref107" name="_ftn107">[107]</a> vgl. Obenland, Konstantin (2015): Title Tags in 4.1. <a href="https://make.wordpress.org/core/2014/10/29/title-tags-in-4-1/">https://make.wordpress.org/core/2014/10/29/title-tags-in-4-1/</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref108" name="_ftn108">[108]</a> vgl. WordPress: Codex › Post Formats › Supported Formats. <a href="https://codex.wordpress.org/Post_Formats#Supported_Formats">https://codex.wordpress.org/Post_Formats#Supported_Formats</a> (Zugriff vom 28.11.2015).
<a href="#_ftnref109" name="_ftn109">[109]</a> vgl. WordPress: Codex › add_theme_support › HTML5. <a href="https://codex.wordpress.org/Function_Reference/add_theme_support#HTML5">https://codex.wordpress.org/Function_Reference/add_theme_support#HTML5</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref110" name="_ftn110">[110]</a> vgl. WordPress: Codex › add_theme_support › Post Thumbnails. <a href="https://codex.wordpress.org/Function_Reference/add_theme_support#Post_Thumbnails">https://codex.wordpress.org/Function_Reference/add_theme_support#Post_Thumbnails</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref111" name="_ftn111">[111]</a> vgl. WordPress: Theme Handbook › Template Files Section › Post Template Files › index.php. <a href="https://developer.wordpress.org/themes/template-files-section/post-template-files/#index-php">https://developer.wordpress.org/themes/template-files-section/post-template-files/#index-php</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref112" name="_ftn112">[112]</a> vgl. WordPress: Code Reference › Functions › get_header. <a href="https://developer.wordpress.org/reference/functions/get_header/">https://developer.wordpress.org/reference/functions/get_header/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref113" name="_ftn113">[113]</a> vgl. WordPress: Code Reference › Functions › is_home. <a href="https://developer.wordpress.org/reference/functions/is_home/">https://developer.wordpress.org/reference/functions/is_home/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref114" name="_ftn114">[114]</a> vgl. WordPress: Code Reference › Functions › is_front_page. <a href="https://developer.wordpress.org/reference/functions/is_front_page/">https://developer.wordpress.org/reference/functions/is_front_page/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref115" name="_ftn115">[115]</a> vgl. WordPress: Code Reference › Functions › single_post_title. <a href="https://developer.wordpress.org/reference/functions/single_post_title/">https://developer.wordpress.org/reference/functions/single_post_title/</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref116" name="_ftn116">[116]</a> vgl. WordPress: Code Reference › Functions › have_posts. <a href="https://developer.wordpress.org/reference/functions/have_posts/">https://developer.wordpress.org/reference/functions/have_posts/</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref117" name="_ftn117">[117]</a> vgl. WordPress: Code Reference › Functions › the_post. <a href="https://developer.wordpress.org/reference/functions/the_post/">https://developer.wordpress.org/reference/functions/the_post/</a> (Zugriff vom 02.12.2015).
<a href="#_ftnref118" name="_ftn118">[118]</a> vgl. WordPress: Code Reference › Functions › get_template_part. <a href="https://developer.wordpress.org/reference/functions/get_template_part/">https://developer.wordpress.org/reference/functions/get_template_part/</a> (Zugriff vom 01.12.2015).
<a href="#_ftnref119" name="_ftn119">[119]</a> vgl. WordPress: Code Reference › Functions › get_post_format. <a href="https://developer.wordpress.org/reference/functions/get_post_format/">https://developer.wordpress.org/reference/functions/get_post_format/</a> (Zugriff vom 02.12.2015).
<a href="#_ftnref120" name="_ftn120">[120]</a> vgl. WordPress: Code Reference › Functions › the_posts_pagination. <a href="https://developer.wordpress.org/reference/functions/the_posts_pagination/">https://developer.wordpress.org/reference/functions/the_posts_pagination/</a> (Zugriff vom 07.12.2015).
<a href="#_ftnref121" name="_ftn121">[121]</a> vgl. WordPress: Code Reference › Functions › get_footer. <a href="https://developer.wordpress.org/reference/functions/get_footer/">https://developer.wordpress.org/reference/functions/get_footer/</a> (Zugriff vom 10.12.2015).
<a href="#_ftnref122" name="_ftn122">[122]</a> vgl. WordPress: Code Reference › Functions › get_sidebar. <a href="https://developer.wordpress.org/reference/functions/get_sidebar/">https://developer.wordpress.org/reference/functions/get_sidebar/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref123" name="_ftn123">[123]</a> vgl. WordPress: Code Reference › Functions › post_class. <a href="https://developer.wordpress.org/reference/functions/post_class/">https://developer.wordpress.org/reference/functions/post_class/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref124" name="_ftn124">[124]</a> vgl. WordPress: Code Reference › Functions › the_post_thumbnail. <a href="https://developer.wordpress.org/reference/functions/the_post_thumbnail/">https://developer.wordpress.org/reference/functions/the_post_thumbnail/</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref125" name="_ftn125">[125]</a> vgl. WordPress: Code Reference › Functions › the_title. <a href="https://developer.wordpress.org/reference/functions/the_title/">https://developer.wordpress.org/reference/functions/the_title/</a> (Zugriff vom 07.12.2015).
<a href="#_ftnref126" name="_ftn126">[126]</a> vgl. PHP Group: sprintf. <a href="http://php.net/manual/de/function.sprintf.php">http://php.net/manual/de/function.sprintf.php</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref127" name="_ftn127">[127]</a> vgl. PHP Group: printf. <a href="http://php.net/manual/de/function.printf.php">http://php.net/manual/de/function.printf.php</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref128" name="_ftn128">[128]</a> vgl. WordPress: Code Reference › Functions › get_the_date. <a href="https://developer.wordpress.org/reference/functions/get_the_date/">https://developer.wordpress.org/reference/functions/get_the_date/</a> (Zugriff vom 29.11.2015).
<a href="#_ftnref129" name="_ftn129">[129]</a> vgl. WordPress: Code Reference › Functions › get_the_time. <a href="https://developer.wordpress.org/reference/functions/get_the_time/">https://developer.wordpress.org/reference/functions/get_the_time/</a> (Zugriff vom 02.12.2015).
<a href="#_ftnref130" name="_ftn130">[130]</a> vgl. WordPress: Code Reference › Functions › the_content. <a href="https://developer.wordpress.org/reference/functions/the_content/">https://developer.wordpress.org/reference/functions/the_content/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref131" name="_ftn131">[131]</a> vgl. WordPress: Theme Review Handbook › Accessibility › Required › Link Text. <a href="https://make.wordpress.org/themes/handbook/review/accessibility/required/#link-text">https://make.wordpress.org/themes/handbook/review/accessibility/required/#link-text</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref132" name="_ftn132">[132]</a> vgl. WordPress: Code Reference › Functions › get_the_title. <a href="https://developer.wordpress.org/reference/functions/get_the_title/">https://developer.wordpress.org/reference/functions/get_the_title/</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref133" name="_ftn133">[133]</a> vgl. WordPress: Code Reference › Functions › get_the_author. <a href="https://developer.wordpress.org/reference/functions/get_the_author/">https://developer.wordpress.org/reference/functions/get_the_author/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref134" name="_ftn134">[134]</a> vgl. WordPress: Code Reference › Functions › get_the_category. <a href="https://developer.wordpress.org/reference/functions/get_the_category/">https://developer.wordpress.org/reference/functions/get_the_category/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref135" name="_ftn135">[135]</a> vgl. WordPress: Code Reference › Functions › _n. <a href="https://developer.wordpress.org/reference/functions/_n/">https://developer.wordpress.org/reference/functions/_n/</a> (Zugriff vom 17.01.2016).
<a href="#_ftnref136" name="_ftn136">[136]</a> vgl. PHP Group: count. <a href="http://php.net/manual/de/function.count.php">http://php.net/manual/de/function.count.php</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref137" name="_ftn137">[137]</a> vgl. WordPress: Code Reference › Functions › get_the_category_list. <a href="https://developer.wordpress.org/reference/functions/get_the_category_list/">https://developer.wordpress.org/reference/functions/get_the_category_list/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref138" name="_ftn138">[138]</a> vgl. WordPress: Code Reference › Functions › get_the_tags. <a href="https://developer.wordpress.org/reference/functions/get_the_tags/">https://developer.wordpress.org/reference/functions/get_the_tags/</a> (Zugriff vom 02.12.2015).
<a href="#_ftnref139" name="_ftn139">[139]</a> vgl. WordPress: Code Reference › Functions › get_the_tag_list. <a href="https://developer.wordpress.org/reference/functions/get_the_tag_list/">https://developer.wordpress.org/reference/functions/get_the_tag_list/</a> (Zugriff vom 02.12.2015).
<a href="#_ftnref140" name="_ftn140">[140]</a> vgl. WordPress: Code Reference › Functions › separate_comments. <a href="https://developer.wordpress.org/reference/functions/separate_comments/">https://developer.wordpress.org/reference/functions/separate_comments/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref141" name="_ftn141">[141]</a> vgl. WordPress: Code Reference › Functions › comments_template. <a href="https://developer.wordpress.org/reference/functions/comments_template/">https://developer.wordpress.org/reference/functions/comments_template/</a> (Zugriff vom 20.12.2015).
<a href="#_ftnref142" name="_ftn142">[142]</a> vgl. WordPress: Code Reference › Functions › get_comments. <a href="https://developer.wordpress.org/reference/functions/get_comments/">https://developer.wordpress.org/reference/functions/get_comments/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref143" name="_ftn143">[143]</a> vgl. WordPress: Code Reference › Functions › number_format_i18n. <a href="https://developer.wordpress.org/reference/functions/number_format_i18n/">https://developer.wordpress.org/reference/functions/number_format_i18n/</a> (Zugriff vom 01.12.2015).
<a href="#_ftnref144" name="_ftn144">[144]</a> vgl. WordPress: Function Reference › Functions › is_active_sidebar. <a href="https://developer.wordpress.org/reference/functions/is_active_sidebar/">https://developer.wordpress.org/reference/functions/is_active_sidebar/</a> (Zugriff vom 27.11.2015).
<a href="#_ftnref145" name="_ftn145">[145]</a> vgl. WordPress: Code Reference › Functions › register_sidebar. <a href="https://developer.wordpress.org/reference/functions/register_sidebar/">https://developer.wordpress.org/reference/functions/register_sidebar/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref146" name="_ftn146">[146]</a> vgl. WordPress: Code Reference › Functions › __. <a href="https://developer.wordpress.org/reference/functions/__/">https://developer.wordpress.org/reference/functions/__/</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref147" name="_ftn147">[147]</a> vgl. WordPress: Code Reference › Functions › wp_footer. <a href="https://developer.wordpress.org/reference/functions/wp_footer/">https://developer.wordpress.org/reference/functions/wp_footer/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref148" name="_ftn148">[148]</a> vgl. WordPress: Code Reference › Functions › the_archive_title. <a href="https://developer.wordpress.org/reference/functions/the_archive_title/">https://developer.wordpress.org/reference/functions/the_archive_title/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref149" name="_ftn149">[149]</a> vgl. WordPress: Code Reference › Functions › the_archive_description. <a href="https://developer.wordpress.org/reference/functions/the_archive_description/">https://developer.wordpress.org/reference/functions/the_archive_description/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref150" name="_ftn150">[150]</a> vgl. WordPress: Code Reference › Functions › get_search_query. <a href="https://developer.wordpress.org/reference/functions/get_search_query/">https://developer.wordpress.org/reference/functions/get_search_query/</a> (Zugriff vom 27.12.2015).
<a href="#_ftnref151" name="_ftn151">[151]</a> vgl. WordPress: Code Reference › Functions › get_search_form. <a href="https://developer.wordpress.org/reference/functions/get_search_form/">https://developer.wordpress.org/reference/functions/get_search_form/</a> (Zugriff vom 27.12.2015).
<a href="#_ftnref152" name="_ftn152">[152]</a> vgl. WordPress: Code Reference › Functions › get_header. <a href="https://developer.wordpress.org/reference/functions/get_header/">https://developer.wordpress.org/reference/functions/get_header/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref153" name="_ftn153">[153]</a> vgl. WordPress: Code Reference › Functions › get_comments_number. <a href="https://developer.wordpress.org/reference/functions/get_comments_number/">https://developer.wordpress.org/reference/functions/get_comments_number/</a> (Zugriff vom 12.12.2015).
<p style="text-align: left;"><a href="#_ftnref154" name="_ftn154">[154]</a> vgl. WordPress: Code Reference › Functions › comments_open. <a href="https://developer.wordpress.org/reference/functions/comments_open/">https://developer.wordpress.org/reference/functions/comments_open/</a> (Zugriff vom 19.12.2015).</p>
<a href="#_ftnref155" name="_ftn155">[155]</a> vgl. WordPress: Code Reference › Functions › comments_template. <a href="https://developer.wordpress.org/reference/functions/comments_template/">https://developer.wordpress.org/reference/functions/comments_template/</a> (Zugriff vom 20.12.2015).
<a href="#_ftnref156" name="_ftn156">[156]</a> vgl. WordPress: Code Reference › Functions › wp_link_pages. <a href="https://developer.wordpress.org/reference/functions/wp_link_pages/">https://developer.wordpress.org/reference/functions/wp_link_pages/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref157" name="_ftn157">[157]</a> vgl. WordPress: Code Reference › Functions › the_post_navigation. <a href="https://developer.wordpress.org/reference/functions/the_post_navigation/">https://developer.wordpress.org/reference/functions/the_post_navigation/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref158" name="_ftn158">[158]</a> vgl. WordPress: Code Reference › Functions › post_password_required. <a href="https://developer.wordpress.org/reference/functions/post_password_required/">https://developer.wordpress.org/reference/functions/post_password_required/</a> (Zugriff vom 30.12.2015).
<a href="#_ftnref159" name="_ftn159">[159]</a> vgl. WordPress: Code Reference › Functions › have_comments. <a href="https://developer.wordpress.org/reference/functions/have_comments/">https://developer.wordpress.org/reference/functions/have_comments/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref160" name="_ftn160">[160]</a> vgl. WordPress: Code Reference › Functions › wp_list_comments. <a href="https://developer.wordpress.org/reference/functions/wp_list_comments/">https://developer.wordpress.org/reference/functions/wp_list_comments/</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref161" name="_ftn161">[161]</a> vgl. Obenland, Konstantin: Core-Trac › Ticket #30589 – Comments navigation template tags. <a href="https://core.trac.wordpress.org/ticket/30589">https://core.trac.wordpress.org/ticket/30589</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref162" name="_ftn162">[162]</a> vgl. WordPress: Code Reference › Functions › comment_form. <a href="https://developer.wordpress.org/reference/functions/comment_form/">https://developer.wordpress.org/reference/functions/comment_form/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref163" name="_ftn163">[163]</a> vgl. WordPress: Code Reference › Functions › comment_class. <a href="https://developer.wordpress.org/reference/functions/comment_class/">https://developer.wordpress.org/reference/functions/comment_class/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref164" name="_ftn164">[164]</a> vgl. WordPress: Code Reference › Functions › comment_ID. <a href="https://developer.wordpress.org/reference/functions/comment_id/">https://developer.wordpress.org/reference/functions/comment_id/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref165" name="_ftn165">[165]</a> vgl. WordPress: Code Reference › Functions › get_avatar. <a href="https://developer.wordpress.org/reference/functions/get_avatar/">https://developer.wordpress.org/reference/functions/get_avatar/</a> (Zugriff vom 19.12.2015).
<a href="#_ftnref166" name="_ftn166">[166]</a> vgl. WordPress: Code Reference › Functions › comment_author_link. <a href="https://developer.wordpress.org/reference/functions/comment_author_link/">https://developer.wordpress.org/reference/functions/comment_author_link/</a> (Zugriff vom 20.12.2015).
<a href="#_ftnref167" name="_ftn167">[167]</a> vgl. Sari, Dennis; Zartner, Sebastian; Perrier, Jean-Yves; Kraut, Tim: MDN › HTML › &lt;time&gt;. <a href="https://developer.mozilla.org/de/docs/Web/HTML/Element/time">https://developer.mozilla.org/de/docs/Web/HTML/Element/time</a> (Zugriff vom 08.12.2015).
<a href="#_ftnref168" name="_ftn168">[168]</a> vgl. WordPress: Code Reference › Functions › get_comment_link. <a href="https://developer.wordpress.org/reference/functions/get_comment_link/">https://developer.wordpress.org/reference/functions/get_comment_link/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref169" name="_ftn169">[169]</a> vgl. WordPress: Code Reference › Functions › get_comment_time. <a href="https://developer.wordpress.org/reference/functions/get_comment_time/">https://developer.wordpress.org/reference/functions/get_comment_time/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref170" name="_ftn170">[170]</a> vgl. PHP Group: date. <a href="http://php.net/manual/de/function.date.php">http://php.net/manual/de/function.date.php</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref171" name="_ftn171">[171]</a> vgl. WordPress: Code Reference › Functions › get_comment_date. <a href="https://developer.wordpress.org/reference/functions/get_comment_date/">https://developer.wordpress.org/reference/functions/get_comment_date/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref172" name="_ftn172">[172]</a> vgl. WordPress: Code Reference › Functions › comment_text. <a href="https://developer.wordpress.org/reference/functions/comment_text/">https://developer.wordpress.org/reference/functions/comment_text/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref173" name="_ftn173">[173]</a> vgl. WordPress: Code Reference › Functions › edit_comment_link. <a href="https://developer.wordpress.org/reference/functions/edit_comment_link/">https://developer.wordpress.org/reference/functions/edit_comment_link/</a> (Zugriff vom 20.12.2015).
<a href="#_ftnref174" name="_ftn174">[174]</a> vgl. WordPress: Code Reference › Functions › comment_reply_link. <a href="https://developer.wordpress.org/reference/functions/comment_reply_link/">https://developer.wordpress.org/reference/functions/comment_reply_link/</a> (Zugriff vom 19.12.2015).
<a href="#_ftnref175" name="_ftn175">[175]</a> vgl. WordPress: Code Reference › Functions › wp_enqueue_script. <a href="https://developer.wordpress.org/reference/functions/wp_enqueue_script/">https://developer.wordpress.org/reference/functions/wp_enqueue_script/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref176" name="_ftn176">[176]</a> vgl. WordPress: Code Reference › Functions › wp_enqueue_style. <a href="https://developer.wordpress.org/reference/functions/wp_enqueue_style/">https://developer.wordpress.org/reference/functions/wp_enqueue_style/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref177" name="_ftn177">[177]</a> vgl. WordPress: Code Reference › Functions › get_search_form. <a href="https://developer.wordpress.org/reference/functions/get_search_form/">https://developer.wordpress.org/reference/functions/get_search_form/</a> (Zugriff vom 27.12.2015).
<a href="#_ftnref178" name="_ftn178">[178]</a> vgl. PHP Group: Kontrollstrukturen › require. <a href="http://php.net/manual/de/function.require.php">http://php.net/manual/de/function.require.php</a> (Zugriff vom 05.12.2015).
<a href="#_ftnref179" name="_ftn179">[179]</a> vgl. WordPress: Code Reference › Functions › get_template_directory. <a href="https://developer.wordpress.org/reference/functions/get_template_directory/">https://developer.wordpress.org/reference/functions/get_template_directory/</a> (Zugriff vom 10.12.2015).
<a href="#_ftnref180" name="_ftn180">[180]</a> vgl. WordPress: Theme Handbook › Advanced Theme Topics › Theme Options – The Customizer API › Settings. <a href="https://developer.wordpress.org/themes/advanced-topics/customizer-api/#settings">https://developer.wordpress.org/themes/advanced-topics/customizer-api/#settings</a> (Zugriff vom 17.12.2015).
<a href="#_ftnref181" name="_ftn181">[181]</a> vgl. WordPress: Theme Handbook › Advanced Theme Topics › Theme Options – The Customizer API › Controls. <a href="https://developer.wordpress.org/themes/advanced-topics/customizer-api/#controls">https://developer.wordpress.org/themes/advanced-topics/customizer-api/#controls</a> (Zugriff vom 17.12.2015).
<a href="#_ftnref182" name="_ftn182">[182]</a> vgl. Bennett, Chip: WPTRT/code-examples/customizer/sanitization-callbacks.php. <a href="https://github.com/WPTRT/code-examples/blob/master/customizer/sanitization-callbacks.php">https://github.com/WPTRT/code-examples/blob/master/customizer/sanitization-callbacks.php</a> (Zugriff vom 20.12.2015).
<a href="#_ftnref183" name="_ftn183">[183]</a> vgl. WordPress: Code Reference › Functions › get_categories. <a href="https://developer.wordpress.org/reference/functions/get_categories/">https://developer.wordpress.org/reference/functions/get_categories/</a> (Zugriff vom 31.12.2015).
<a href="#_ftnref184" name="_ftn184">[184]</a> vgl. Bennett, Chip: WPTRT/code-examples/customizer/sanitization-callbacks.php. <a href="https://github.com/WPTRT/code-examples/blob/master/customizer/sanitization-callbacks.php">https://github.com/WPTRT/code-examples/blob/master/customizer/sanitization-callbacks.php</a> (Zugriff vom 20.12.2015).
<a href="#_ftnref185" name="_ftn185">[185]</a> vgl. WordPress: Code Reference › Functions › sanitize_key. <a href="https://developer.wordpress.org/reference/functions/sanitize_key/">https://developer.wordpress.org/reference/functions/sanitize_key/</a> (Zugriff vom 17.12.2015).
<a href="#_ftnref186" name="_ftn186">[186]</a> vgl. WordPress: Code Reference › Functions › absint. <a href="https://developer.wordpress.org/reference/functions/absint/">https://developer.wordpress.org/reference/functions/absint/</a> (Zugriff vom 18.12.2015).
<a href="#_ftnref187" name="_ftn187">[187]</a> vgl. WordPress: Theme Handbook › Template Files Section › Page Template Files › Page Templates › File Organization of Page Templates. <a href="https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/#file-organization-of-page-templates">https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/#file-organization-of-page-templates</a> (Zugriff vom 12.12.2015).
<a href="#_ftnref188" name="_ftn188">[188]</a> vgl. WordPress: Theme Handbook › Template Files Section › Page Template Files › Page Templates › Creating Custom Page Templates for Global Use. <a href="https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/#creating-custom-page-templates-for-global-use">https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/#creating-custom-page-templates-for-global-use</a> (Zugriff vom 12.12.2015).
<a href="#_ftnref189" name="_ftn189">[189]</a> vgl. WordPress: Code Reference › Functions › get_theme_mod. <a href="https://developer.wordpress.org/reference/functions/get_theme_mod/">https://developer.wordpress.org/reference/functions/get_theme_mod/</a> (Zugriff vom 21.12.2015).
<a href="#_ftnref190" name="_ftn190">[190]</a> vgl. Bennett, Chip (2013): How to fix pagination for custom loops? <a href="http://wordpress.stackexchange.com/a/120408">http://wordpress.stackexchange.com/a/120408</a> (Zugriff vom 23.12.2015).
<a href="#_ftnref191" name="_ftn191">[191]</a> vgl. WordPress: Codex › Class Reference › WP_Query › Taxonomy Parameters. <a href="https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters">https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref192" name="_ftn192">[192]</a> vgl. WordPress: Codex › Class Reference › WP_Query › Taxonomy Parameters. <a href="https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters">https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref193" name="_ftn193">[193]</a> vgl. WordPress: Code Reference › Functions › wp_reset_postdata. <a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">https://developer.wordpress.org/reference/functions/wp_reset_postdata/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref194" name="_ftn194">[194]</a> vgl. WordPress: Code Reference › Functions › the_posts_pagination. <a href="https://developer.wordpress.org/reference/functions/the_posts_pagination/">https://developer.wordpress.org/reference/functions/the_posts_pagination/</a> (Zugriff vom 07.12.2015).
<a href="#_ftnref195" name="_ftn195">[195]</a> vgl. Bennett, Chip (2013): How to fix pagination for custom loops? <a href="http://wordpress.stackexchange.com/a/120408">http://wordpress.stackexchange.com/a/120408</a> (Zugriff vom 23.12.2015).
<a href="#_ftnref196" name="_ftn196">[196]</a> vgl. WordPress: Code Reference › Functions › post_class. <a href="https://developer.wordpress.org/reference/functions/post_class/">https://developer.wordpress.org/reference/functions/post_class/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref197" name="_ftn197">[197]</a> vgl. WordPress: Code Reference › Functions › has_post_thumbnail. <a href="https://developer.wordpress.org/reference/functions/has_post_thumbnail/">https://developer.wordpress.org/reference/functions/has_post_thumbnail/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref198" name="_ftn198">[198]</a> vgl. PHP Group: array_shift. <a href="http://php.net/manual/de/function.array-shift.php">http://php.net/manual/de/function.array-shift.php</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref199" name="_ftn199">[199]</a> vgl. WordPress: Code Reference › Functions › wp_get_attachment_image. <a href="https://developer.wordpress.org/reference/functions/wp_get_attachment_image/">https://developer.wordpress.org/reference/functions/wp_get_attachment_image/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref200" name="_ftn200">[200]</a> vgl. WordPress: Code Reference › Functions › attachment_url_to_postid. <a href="https://developer.wordpress.org/reference/functions/attachment_url_to_postid/">https://developer.wordpress.org/reference/functions/attachment_url_to_postid/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref201" name="_ftn201">[201]</a> vgl. WordPress: Code Reference › Functions › get_post. <a href="https://developer.wordpress.org/reference/functions/get_post/">https://developer.wordpress.org/reference/functions/get_post/</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref202" name="_ftn202">[202]</a> vgl. WordPress: Code Reference › Functions › get_post_galleries. <a href="https://developer.wordpress.org/reference/functions/get_post_galleries/">https://developer.wordpress.org/reference/functions/get_post_galleries/</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref203" name="_ftn203">[203]</a> vgl. PHP Group: explode. <a href="http://php.net/manual/de/function.explode.php">http://php.net/manual/de/function.explode.php</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref204" name="_ftn204">[204]</a> vgl. WordPress: Code Reference › Functions › array_merge. <a href="http://php.net/manual/de/function.array-merge.php">http://php.net/manual/de/function.array-merge.php</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref205" name="_ftn205">[205]</a> vgl. WordPress: array_unique. <a href="http://php.net/manual/de/function.array-unique.php">http://php.net/manual/de/function.array-unique.php</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref206" name="_ftn206">[206]</a> vgl. WordPress: Code Reference › Functions › get_posts. <a href="https://developer.wordpress.org/reference/functions/get_posts/">https://developer.wordpress.org/reference/functions/get_posts/</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref207" name="_ftn207">[207]</a> vgl. PHP Group: preg_match. <a href="http://php.net/manual/de/function.preg-match.php">http://php.net/manual/de/function.preg-match.php</a> (Zugriff vom 08.12.2015).
<a href="#_ftnref208" name="_ftn208">[208]</a> vgl. WordPress: Code Reference › Functions › get_posts. <a href="https://developer.wordpress.org/reference/functions/get_posts/">https://developer.wordpress.org/reference/functions/get_posts/</a> (Zugriff vom 06.12.2015).
<a href="#_ftnref209" name="_ftn209">[209]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_setting. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/add_setting/">https://developer.wordpress.org/reference/classes/wp_customize_manager/add_setting/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref210" name="_ftn210">[210]</a> vgl. WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_control. <a href="https://developer.wordpress.org/reference/classes/wp_customize_manager/add_control/">https://developer.wordpress.org/reference/classes/wp_customize_manager/add_control/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref211" name="_ftn211">[211]</a> vgl. WordPress: Code Reference › Functions › get_theme_mod. <a href="https://developer.wordpress.org/reference/functions/get_theme_mod/">https://developer.wordpress.org/reference/functions/get_theme_mod/</a> (Zugriff vom 21.12.2015).
<a href="#_ftnref212" name="_ftn212">[212]</a> vgl. WordPress: Code Reference › Functions › has_excerpt. <a href="https://developer.wordpress.org/reference/functions/has_excerpt/">https://developer.wordpress.org/reference/functions/has_excerpt/</a> (Zugriff vom 29.12.2015).
<a href="#_ftnref213" name="_ftn213">[213]</a> vgl. WordPress: Code Reference › Functions › the_excerpt. <a href="https://developer.wordpress.org/reference/functions/the_excerpt/">https://developer.wordpress.org/reference/functions/the_excerpt/</a> (Zugriff vom 11.12.2015).
<a href="#_ftnref214" name="_ftn214">[214]</a> vgl. WordPress: Code Reference › Functions › get_post_format. <a href="https://developer.wordpress.org/reference/functions/get_post_format/">https://developer.wordpress.org/reference/functions/get_post_format/</a> (Zugriff vom 02.12.2015).
<a href="#_ftnref215" name="_ftn215">[215]</a> vgl. WordPress: Code Reference › Functions › get_theme_mod. <a href="https://developer.wordpress.org/reference/functions/get_theme_mod/">https://developer.wordpress.org/reference/functions/get_theme_mod/</a> (Zugriff vom 21.12.2015).
<a href="#_ftnref216" name="_ftn216">[216]</a> vgl. WordPress: Code Reference › Functions › has_category. <a href="https://developer.wordpress.org/reference/functions/has_category/">https://developer.wordpress.org/reference/functions/has_category/</a> (Zugriff vom 23.12.2015).
<a href="#_ftnref217" name="_ftn217">[217]</a> vgl. WordPress: Code Reference › Functions › the_post_navigation. <a href="https://developer.wordpress.org/reference/functions/the_post_navigation/">https://developer.wordpress.org/reference/functions/the_post_navigation/</a> (Zugriff vom 03.12.2015).
<a href="#_ftnref218" name="_ftn218">[218]</a> vgl. WordPress: Code Reference › Hooks › widget_categories_args. <a href="https://developer.wordpress.org/reference/hooks/widget_categories_args/">https://developer.wordpress.org/reference/hooks/widget_categories_args/</a> (Zugriff vom 23.12.2015).
<a href="#_ftnref219" name="_ftn219">[219]</a> vgl. WordPress: Code Reference › Functions › get_theme_mod. <a href="https://developer.wordpress.org/reference/functions/get_theme_mod/">https://developer.wordpress.org/reference/functions/get_theme_mod/</a> (Zugriff vom 21.12.2015).
<a href="#_ftnref220" name="_ftn220">[220]</a> vgl. WordPress: Code Reference › Functions › get_sidebar. <a href="https://developer.wordpress.org/reference/functions/get_sidebar/">https://developer.wordpress.org/reference/functions/get_sidebar/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref221" name="_ftn221">[221]</a> vgl. Wojciechowski, Bartosz: Owl Carousel. <a href="http://www.owlcarousel.owlgraphic.com">http://www.owlcarousel.owlgraphic.com</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref222" name="_ftn222">[222]</a> vgl. WordPress: Code Reference › Functions › get_page_template_slug. <a href="https://developer.wordpress.org/reference/functions/get_page_template_slug/">https://developer.wordpress.org/reference/functions/get_page_template_slug/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref223" name="_ftn223">[223]</a> vgl. Wood, Samuel: Passing parameters from PHP to Javascripts in plugins. <a href="http://ottopress.com/2010/passing-parameters-from-php-to-javascripts-in-plugins/">http://ottopress.com/2010/passing-parameters-from-php-to-javascripts-in-plugins/</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref224" name="_ftn224">[224]</a> vgl. WordPress: Code Reference › Functions › wp_localize_script. <a href="https://developer.wordpress.org/reference/functions/wp_localize_script/">https://developer.wordpress.org/reference/functions/wp_localize_script/</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref225" name="_ftn225">[225]</a> vgl. WordPress: Code Reference › Functions › get_page_template_slug. <a href="https://developer.wordpress.org/reference/functions/get_page_template_slug/">https://developer.wordpress.org/reference/functions/get_page_template_slug/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref226" name="_ftn226">[226]</a> vgl. WordPress: Code Reference › Functions › wp_enqueue_style. <a href="https://developer.wordpress.org/reference/functions/wp_enqueue_style/">https://developer.wordpress.org/reference/functions/wp_enqueue_style/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref227" name="_ftn227">[227]</a> vgl. WordPress: Code Reference › Functions › get_template_part_directory. <a href="https://developer.wordpress.org/reference/functions/get_template_directory_uri/">https://developer.wordpress.org/reference/functions/get_template_directory_uri/</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref228" name="_ftn228">[228]</a> vgl. WordPress: Code Reference › Functions › get_stylesheet_directory_uri. <a href="https://developer.wordpress.org/reference/functions/get_stylesheet_directory_uri/">https://developer.wordpress.org/reference/functions/get_stylesheet_directory_uri/</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref229" name="_ftn229">[229]</a> vgl. WordPress: Code Reference › Functions › get_theme_mod. <a href="https://developer.wordpress.org/reference/functions/get_theme_mod/">https://developer.wordpress.org/reference/functions/get_theme_mod/</a> (Zugriff vom 21.12.2015).
<a href="#_ftnref230" name="_ftn230">[230]</a> vgl. jQuery: .ready. <a href="http://api.jquery.com/ready/">http://api.jquery.com/ready/</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref231" name="_ftn231">[231]</a> vgl. jQuery: .wrap. <a href="http://api.jquery.com/wrap/">http://api.jquery.com/wrap/</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref232" name="_ftn232">[232]</a> vgl. Wojciechowski, Bartosz: Owl Carousel › Installation. <a href="http://www.owlcarousel.owlgraphic.com/docs/started-installation.html">http://www.owlcarousel.owlgraphic.com/docs/started-installation.html</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref233" name="_ftn233">[233]</a> vgl. Wojciechowski, Bartosz: Owl Carousel › Options. <a href="http://www.owlcarousel.owlgraphic.com/docs/api-options.html">http://www.owlcarousel.owlgraphic.com/docs/api-options.html</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref234" name="_ftn234">[234]</a> vgl. PHP Group: shuffle. <a href="http://php.net/manual/de/function.shuffle.php">http://php.net/manual/de/function.shuffle.php</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref235" name="_ftn235">[235]</a> vgl. PHP Group: array_shift. <a href="http://php.net/manual/de/function.array-shift.php">http://php.net/manual/de/function.array-shift.php</a> (Zugriff vom 14.12.2015).
<a href="#_ftnref236" name="_ftn236">[236]</a> vgl. WordPress: Code Reference › Functions › wp_get_attachment_image. <a href="https://developer.wordpress.org/reference/functions/wp_get_attachment_image/">https://developer.wordpress.org/reference/functions/wp_get_attachment_image/</a> (Zugriff vom 04.12.2015).
<a href="#_ftnref237" name="_ftn237">[237]</a> vgl. WordPress: Code Reference › Functions › the_excerpt. <a href="https://developer.wordpress.org/reference/functions/the_excerpt/">https://developer.wordpress.org/reference/functions/the_excerpt/</a> (Zugriff vom 11.12.2015).
<a href="#_ftnref238" name="_ftn238">[238]</a> vgl. WordPress: Code Reference › Functions › has_excerpt. <a href="https://developer.wordpress.org/reference/functions/has_excerpt/">https://developer.wordpress.org/reference/functions/has_excerpt/</a> (Zugriff vom 29.12.2015).
<a href="#_ftnref239" name="_ftn239">[239]</a> vgl. WordPress: Code Reference › Hooks › the_content_more_link. <a href="https://developer.wordpress.org/reference/hooks/the_content_more_link/">https://developer.wordpress.org/reference/hooks/the_content_more_link/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref240" name="_ftn240">[240]</a> vgl. PHP Group: preg_replace. <a href="http://php.net/manual/de/function.preg-replace.php">http://php.net/manual/de/function.preg-replace.php</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref241" name="_ftn241">[241]</a> vgl. Carlson, Ty; trenzterra; Irie, Takashi; Maharzan, Chandra; Vorotnov, Ihor; Klein, Fränk; Moore, Philip A.: twentysixteen/js/functions.js. <a href="https://github.com/WordPress/twentysixteen/blob/4c56411d81155e696ee57723c6d5a911ba4cb45f/js/functions.js">https://github.com/WordPress/twentysixteen/blob/4c56411d81155e696ee57723c6d5a911ba4cb45f/js/functions.js</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref242" name="_ftn242">[242]</a> Soueidan, Sara (2015): Mastering SVG for Responsive Web Design, in <em>The smashing book #5. Real-life responsive web design</em>, hrsg. v. Friedman, Vitaly, S. 127-208. Freiburg: Smashing Media GmbH. S. 161.
<a href="#_ftnref243" name="_ftn243">[243]</a> vgl. automattic: Genericons. <a href="http://genericons.com/">http://genericons.com/</a> (Zugriff vom 22.12.2015).
<a href="#_ftnref244" name="_ftn244">[244]</a> vgl. Gandy, Dave: Font Awesome. <a href="http://fontawesome.io/">http://fontawesome.io/</a> (Zugriff vom 22.12.2015).
<a href="#_ftnref245" name="_ftn245">[245]</a> vgl. Brinkmann, Florian: Tag „v1.0.8“ – hannover/svg/social-media-icons.svg. <a href="https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/svg/social-media-icons.svg">https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/svg/social-media-icons.svg</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref246" name="_ftn246">[246]</a> vgl. Soueidan, Sara (2015): Mastering SVG for Responsive Web Design, in <em>The smashing book #5. Real-life responsive web design</em>, hrsg. v. Friedman, Vitaly, S. 127-208. Freiburg: Smashing Media GmbH. S. 175-176.
<a href="#_ftnref247" name="_ftn247">[247]</a> vgl. WordPress: Code Reference › Functions › register-nav_menus. <a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">https://developer.wordpress.org/reference/functions/register_nav_menus/</a> (Zugriff vom 01.12.2015).
<a href="#_ftnref248" name="_ftn248">[248]</a> vgl. WordPress: Code Reference › Functions › has_nav_menu. <a href="https://developer.wordpress.org/reference/functions/has_nav_menu/">https://developer.wordpress.org/reference/functions/has_nav_menu/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref249" name="_ftn249">[249]</a> vgl. WordPress: Code Reference › Classes › Walker_Nav_Menu. <a href="https://developer.wordpress.org/reference/classes/walker_nav_menu/">https://developer.wordpress.org/reference/classes/walker_nav_menu/</a> (Zugriff vom 22.12.2015).
<a href="#_ftnref250" name="_ftn250">[250]</a> vgl. WordPress: Code Reference › Classes › Walker_Nav_Menu › Walker_Nav_Menu::start_el. <a href="https://developer.wordpress.org/reference/classes/walker_nav_menu/start_el/">https://developer.wordpress.org/reference/classes/walker_nav_menu/start_el/</a> (Zugriff vom 22.12.2015).
<a href="#_ftnref251" name="_ftn251">[251]</a> vgl. Brinkmann, Florian: Tag „v1.0.8“ – hannover/inc/class-hannover-social-walker.php. <a href="https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/inc/class-hannover-social-menu-walker.php">https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/inc/class-hannover-social-menu-walker.php</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref252" name="_ftn252">[252]</a> vgl. Can I use: SVG (basic support). <a href="http://caniuse.com/#feat=svg">http://caniuse.com/#feat=svg</a> (Zugriff vom 31.12.2015).
<a href="#_ftnref253" name="_ftn253">[253]</a> vgl. Neal, Jonathan: svg4everybody. <a href="https://github.com/jonathantneal/svg4everybody">https://github.com/jonathantneal/svg4everybody</a> (Zugriff vom 22.12.2015).
<a href="#_ftnref254" name="_ftn254">[254]</a> vgl. Brinkmann, Florian: Tag „v1.0.8“ – hannover/js/svg4everybody.js. <a href="https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/js/svg4everybody.js">https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/js/svg4everybody.js</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref255" name="_ftn255">[255]</a> vgl. WordPress: Code Reference › Functions › wp_enqueue_style. <a href="https://developer.wordpress.org/reference/functions/wp_enqueue_style/">https://developer.wordpress.org/reference/functions/wp_enqueue_style/</a> (Zugriff vom 30.11.2015).
<a href="#_ftnref256" name="_ftn256">[256]</a> Wood, Samuel; Obenland, Konstantin (2015): theme-check/checks/style_needed.php. <a href="https://github.com/Otto42/theme-check/blob/542e2b520c94f5455cbf86f8d59d3bc6555aac1e/checks/style_needed.php#L11-L16">https://github.com/Otto42/theme-check/blob/542e2b520c94f5455cbf86f8d59d3bc6555aac1e/checks/style_needed.php#L11-L16</a> (Zugriff vom 26.11.2015).
<a href="#_ftnref257" name="_ftn257">[257]</a> vgl. Valutis, Osvaldas: Image Lightbox, Responsive and Touch‑friendly. <a href="http://osvaldas.info/image-lightbox-responsive-touch-friendly">http://osvaldas.info/image-lightbox-responsive-touch-friendly</a> (Zugriff vom 15.12.2015).
<a href="#_ftnref258" name="_ftn258">[258]</a> vgl. Valutis, Osvaldas: Image Lightbox › Demo. <a href="http://osvaldas.info/examples/image-lightbox-responsive-touch-friendly/">http://osvaldas.info/examples/image-lightbox-responsive-touch-friendly/</a> (Zugriff vom 16.12.2015).
<a href="#_ftnref259" name="_ftn259">[259]</a> vgl. WordPress: Codex › Content Width. <a href="https://codex.wordpress.org/Content_Width">https://codex.wordpress.org/Content_Width</a> (Zugriff vom 26.12.2015).
<a href="#_ftnref260" name="_ftn260">[260]</a> vgl. WordPress: Code Reference › Functions › update_option. <a href="https://developer.wordpress.org/reference/functions/update_option/">https://developer.wordpress.org/reference/functions/update_option/</a> (Zugriff vom 26.12.2015).
<a href="#_ftnref261" name="_ftn261">[261]</a> vgl. WordPress: Theme Review Handbook › Required › Screenshot. <a href="https://make.wordpress.org/themes/handbook/review/required/#screenshot">https://make.wordpress.org/themes/handbook/review/required/#screenshot</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref262" name="_ftn262">[262]</a> vgl. WordPress: Code Reference › Functions › load_theme_textdomain. <a href="https://developer.wordpress.org/reference/functions/load_theme_textdomain/">https://developer.wordpress.org/reference/functions/load_theme_textdomain/</a> (Zugriff vom 26.12.2015).
<a href="#_ftnref263" name="_ftn263">[263]</a> vgl. PHP Group: in_array. <a href="http://php.net/manual/de/function.in-array.php">http://php.net/manual/de/function.in-array.php</a> (Zugriff vom 26.12.2015).
<a href="#_ftnref264" name="_ftn264">[264]</a> vgl. Landsiedel, Torsten (2015): Torsten Landsiedel: Das Child Theme Dilemma. <a href="http://wordpress.tv/2015/07/15/torsten-landsiedel-das-child-theme-dilemma/">http://wordpress.tv/2015/07/15/torsten-landsiedel-das-child-theme-dilemma/</a> (Zugriff vom 27.12.2015).
<a href="#_ftnref265" name="_ftn265">[265]</a> vgl. Landsiedel, Torsten; Wiechers, Ralf; Staude, Frank; Hübinger, Caspar; Altenburg, Hinnerk: Child Theme Check. <a href="https://wordpress.org/plugins/child-theme-check/">https://wordpress.org/plugins/child-theme-check/</a> (Zugriff vom 27.12.2015).
<a href="#_ftnref266" name="_ftn266">[266]</a> vgl. WordPress: Theme Directory › Getting Started. <a href="https://wordpress.org/themes/getting-started/">https://wordpress.org/themes/getting-started/</a> (Zugriff vom 03.01.2016).
<a href="#_ftnref267" name="_ftn267">[267]</a> vgl. WordPress: Make WordPress Themes › Theme: Hannover. <a href="https://themes.trac.wordpress.org/ticket/29486">https://themes.trac.wordpress.org/ticket/29486</a> (Zugriff vom 03.01.2016).
<a href="#_ftnref268" name="_ftn268">[268]</a> vgl. WordPress: Code Reference › Functions › get_theme_mod. <a href="https://developer.wordpress.org/reference/functions/get_theme_mod/">https://developer.wordpress.org/reference/functions/get_theme_mod/</a> (Zugriff vom 21.12.2015).
<a href="#_ftnref269" name="_ftn269">[269]</a> vgl. WordPress: Code Reference › Functions › get_template_part. <a href="https://developer.wordpress.org/reference/functions/get_template_part/">https://developer.wordpress.org/reference/functions/get_template_part/</a> (Zugriff vom 01.12.2015).
<a href="#_ftnref270" name="_ftn270">[270]</a> vgl. Tadlock, Justin: Make WordPress Themes › Theme: Hannover › Comment 29. <a href="https://themes.trac.wordpress.org/ticket/29486#comment:29">https://themes.trac.wordpress.org/ticket/29486#comment:29</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref271" name="_ftn271">[271]</a> vgl. WordPress: Code Reference › Hooks › pre_get_posts. <a href="https://developer.wordpress.org/reference/hooks/pre_get_posts/">https://developer.wordpress.org/reference/hooks/pre_get_posts/</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref272" name="_ftn272">[272]</a> vgl. WordPress: Code Reference › Functions › is_home. <a href="https://developer.wordpress.org/reference/functions/is_home/">https://developer.wordpress.org/reference/functions/is_home/</a> (Zugriff vom 25.11.2015).
<a href="#_ftnref273" name="_ftn273">[273]</a> vgl. WordPress: Code Reference › Functions › is_main_query. <a href="https://developer.wordpress.org/reference/functions/is_main_query/">https://developer.wordpress.org/reference/functions/is_main_query/</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref274" name="_ftn274">[274]</a> vgl. WordPress: Codex › Plugin API › Action Reference › pre_get_posts › Exclude categories on your main page. <a href="https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts#Exclude_categories_on_your_main_page">https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts#Exclude_categories_on_your_main_page</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref275" name="_ftn275">[275]</a> vgl. PHP Group: Kontrollstrukturen › require_once. <a href="http://php.net/manual/de/function.require-once.php">http://php.net/manual/de/function.require-once.php</a> (Zugriff vom 03.01.2016).
<a href="#_ftnref276" name="_ftn276">[276]</a> vgl. Brinkmann, Florian: Theme-Verzeichnis › Hannover. <a href="https://de.wordpress.org/themes/hannover/">https://de.wordpress.org/themes/hannover/</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref277" name="_ftn277">[277]</a> vgl. Brinkmann, Florian: hannover. <a href="https://github.com/FlorianBrinkmann/hannover/">https://github.com/FlorianBrinkmann/hannover/</a> (Zugriff vom 05.01.2016).
<a href="#_ftnref278" name="_ftn278">[278]</a> vgl. Brinkmann: Brinkmann, Florian: hannover „v1.0.8“. <a href="https://github.com/FlorianBrinkmann/hannover/tree/v1.0.8">https://github.com/FlorianBrinkmann/hannover/tree/v1.0.8</a> (Zugriff vom 14.01.2016).
<a href="#_ftnref279" name="_ftn279">[279]</a> vgl. Schulp, Michelle: Template Hierarchy › Visual Overview. <a href="https://developer.wordpress.org/themes/basics/template-hierarchy/#visual-overview">https://developer.wordpress.org/themes/basics/template-hierarchy/#visual-overview</a> (Zugriff vom 29.11.2015).
<h2 id="literaturverzeichnis">Literaturverzeichnis</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
automattic: Genericons. http://genericons.com/ (Zugriff vom 22.12.2015).
automattic; Fields, Michael; Willett, Lance: „Monster Widget“-Plugin. https://wordpress.org/plugins/monster-widget/ (Zugriff vom 25.11.2015).
automattic; Jangda, Mohammad; Mills, Alex; Bachiyski, Nikolay; Ott, Thorsten; Bachhuber, Daniel; Betz, Josh; Nadarajah, Prasath; Daugherty, Dick: „Developer“-Plugin. https://wordpress.org/plugins/developer/ (Zugriff vom 25.11.2015).
Bennett, Chip: Using Sane Defaults in Themes. https://make.wordpress.org/themes/2014/07/09/using-sane-defaults-in-themes/
(Zugriff vom 26.11.2015).
Bennett, Chip: WPTRT/code-examples/customizer/sanitization-callbacks.php. https://github.com/WPTRT/code-examples/blob/master/customizer/sanitization-callbacks.php (Zugriff vom 20.12.2015).
Bennett, Chip (2013): How to fix pagination for custom loops? http://wordpress.stackexchange.com/a/120408 (Zugriff vom 23.12.2015).
Brinkmann, Florian: hannover. https://github.com/FlorianBrinkmann/hannover/
(Zugriff vom 05.01.2016).
Brinkmann, Florian: hannover „v1.0.8“. https://github.com/FlorianBrinkmann/hannover/tree/v1.0.8 (Zugriff vom 14.01.2016).
Brinkmann, Florian: Tag „v1.0.8“ – hannover/inc/class-hannover-social-walker.php. https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/inc/class-hannover-social-menu-walker.php (Zugriff vom 14.01.2016).
Brinkmann, Florian: Tag „v1.0.8“ – hannover/js/svg4everybody.js. https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/js/svg4everybody.js
(Zugriff vom 14.01.2016).
Brinkmann, Florian: Tag „v1.0.8“ – hannover/svg/social-media-icons.svg. https://github.com/FlorianBrinkmann/hannover/blob/v1.0.8/svg/social-media-icons.svg (Zugriff vom 14.01.2016).
Brinkmann, Florian: Theme-Verzeichnis › Hannover. https://de.wordpress.org/themes/hannover/ (Zugriff vom 14.01.2016).
Can I use: SVG (basic support). http://caniuse.com/#feat=svg (Zugriff vom 31.12.2015).
Carlson, Ty; trenzterra; Irie, Takashi; Maharzan, Chandra; Vorotnov, Ihor; Klein, Fränk; Moore, Philip A.: twentysixteen/js/functions.js. https://github.com/WordPress/twentysixteen/blob/4c56411d81155e696ee57723c6d5a911ba4cb45f/js/functions.js (Zugriff vom 16.12.2015).
Castaneda, Jose (2015): Theme Review Tools. https://make.wordpress.org/themes/2015/07/23/theme-review-tools/
(Zugriff vom 25.11.2015).
do.media: Help Document – Invictus › III. Adding Photos to your gallery. http://help.doitmax.de/invictus/#galleryIII (Zugriff vom 25.11.2015).
Friedman, Vitaly (Hrsg.), 2015: <em>The smashing book #5. Real-life responsive web design. </em>Freiburg: Smashing Media GmbH.
Gandy, Dave: Font Awesome. http://fontawesome.io/ (Zugriff vom 22.12.2015).
inTheme: Alerts – Fluxus. http://inthe.me/demo/fluxus/features/alerts/
(Zugriff vom 25.11.2015).
jQuery: .append. http://api.jquery.com/append/ (Zugriff vom 15.12.2015).
jQuery: .click. http://api.jquery.com/click/ (Zugriff vom 15.12.2015).
jQuery: .ready. http://api.jquery.com/ready/ (Zugriff vom 15.12.2015).
jQuery: .wrap. http://api.jquery.com/wrap/ (Zugriff vom 14.12.2015).
Koster, James (2015): Explore WordPress’ free theme options. In: net, H. 274, S. 108-112.
Landsiedel, Torsten (2015): Torsten Landsiedel: Das Child Theme Dilemma. http://wordpress.tv/2015/07/15/torsten-landsiedel-das-child-theme-dilemma/
(Zugriff vom 27.12.2015).
Landsiedel, Torsten; Wiechers, Ralf; Staude, Frank; Hübinger, Caspar; Altenburg, Hinnerk: Child Theme Check. https://wordpress.org/plugins/child-theme-check/
(Zugriff vom 27.12.2015).
Mills, Alex: „Regenerate Thumbnails“-Plugin. https://wordpress.org/plugins/regenerate-thumbnails/ (Zugriff vom 25.11.2015).
Mozilla: Webtechnologien für Entwickler | MDN. https://developer.mozilla.org/de/docs/Web (Zugriff vom 04.01.2016).
Nacin, Andrew: „Log Deprecated Notices“-Plugin. https://wordpress.org/plugins/log-deprecated-notices/ (Zugriff vom 25.11.2015).
Neal, Jonathan: svg4everybody. https://github.com/jonathantneal/svg4everybody
(Zugriff vom 22.12.2015).
Novotny, Michael: WP Test. http://wptest.io/ (Zugriff vom 26.11.2015).
Obenland, Konstantin: Core-Trac › Ticket #30589 – Comments navigation template tags. https://core.trac.wordpress.org/ticket/30589 (Zugriff vom 06.12.2015).
Obenland, Konstantin (2015): Title Tags in 4.1. https://make.wordpress.org/core/2014/10/29/title-tags-in-4-1/
(Zugriff vom 29.11.2015).
Perrier, Jean-Yves; Zartner, Sebastian; Scarfone, Karen; Stone-Thompson, Peter; Shepherd, Eric; medicdude; ethertank; Sonne, Christian; dhodder; Scholz, Florian; Wilsson, Jonathan; Hobson, Trevor; Swisher, Janet: MDN › HTML › &lt;nav&gt;. https://developer.mozilla.org/de/docs/Web/HTML/Element/nav
(Zugriff vom 28.11.2015).
PHP Group: array_shift. http://php.net/manual/de/function.array-shift.php
(Zugriff vom 14.12.2015).
PHP Group: count. http://php.net/manual/de/function.count.php (Zugriff vom 30.12.2015).
PHP Group: date. http://php.net/manual/de/function.date.php (Zugriff vom 30.11.2015).
PHP Group: explode. http://php.net/manual/de/function.explode.php
(Zugriff vom 06.12.2015).
PHP Group: in_array. http://php.net/manual/de/function.in-array.php
(Zugriff vom 26.12.2015).
PHP Group: Kontrollstrukturen › require. http://php.net/manual/de/function.require.php (Zugriff vom 05.12.2015).
PHP Group: Kontrollstrukturen › require_once. http://php.net/manual/de/function.require-once.php (Zugriff vom 03.01.2016).
PHP Group: PHP-Handbuch. http://php.net/manual/de/ (Zugriff vom 04.01.2016).
PHP Group: preg_match. http://php.net/manual/de/function.preg-match.php
(Zugriff vom 08.12.2015).
PHP Group: preg_replace. http://php.net/manual/de/function.preg-replace.php
(Zugriff vom 16.12.2015).
PHP Group: printf. http://php.net/manual/de/function.printf.php (Zugriff vom 30.11.2015).
PHP Group: shuffle. http://php.net/manual/de/function.shuffle.php
(Zugriff vom 15.12.2015).
PHP Group: sprintf. http://php.net/manual/de/function.sprintf.php
(Zugriff vom 30.11.2015).
Rietveld, Rian (2014): HTML5 Headings in WordPress: A11y versus SEO? http://blog.rrwd.nl/2014/11/21/html5-headings-in-wordpress-lets-fight/
(Zugriff vom 27.11.2015).
Sari, Dennis; Zartner, Sebastian; Perrier, Jean-Yves; Kraut, Tim: MDN › HTML › &lt;time&gt;. https://developer.mozilla.org/de/docs/Web/HTML/Element/time
(Zugriff vom 08.12.2015).
Schilling, Dominik (2014): Language chooser in 4.0. https://make.wordpress.org/core/2014/09/05/language-chooser-in-4-0/ (Zugriff vom 17.01.2016).
Schulp, Michelle: Template Hierarchy › Visual Overview. https://developer.wordpress.org/themes/basics/template-hierarchy/#visual-overview (Zugriff vom 29.11.2015).
Soueidan, Sara (2015): Mastering SVG for Responsive Web Design, in <em>The smashing book #5. Real-life responsive web design</em>, hrsg. v. Friedman, Vitaly, S. 127-208. Freiburg: Smashing Media GmbH.
Tadlock, Justin (2015): Details on the new theme settings (customizer) guideline. https://make.wordpress.org/themes/2015/04/22/details-on-the-new-theme-settings-customizer-guideline/ (Zugriff vom 19.12.2015).
Tadlock, Justin: Make WordPress Themes › Theme: Hannover › Comment 29. https://themes.trac.wordpress.org/ticket/29486#comment:29 (Zugriff vom 14.01.2016).
Tadlock, Justin (2015): The theme review team’s content creation discussion. http://justintadlock.com/archives/2015/05/28/the-theme-review-teams-content-creation-discussion (Zugriff vom 27.11.2015).
Tadlock, Justin (2015): Meeting Minutes 06/11/15 › Kommentar. https://make.wordpress.org/themes/2015/06/13/meeting-minutes-061115/#comment-42032 (Zugriff vom 25.11.2015).
Tadlock, Justin (2015): Themes should be 100% GPL. https://make.wordpress.org/themes/2015/08/15/themes-should-be-100-gpl/
(Zugriff vom 25.11.2015).
ThemeForest: ANAN – For Photography Creative Portfolio. http://themeforest.net/item/anan-for-photography-creative-portfolio/174507
(Zugriff vom 09.11.2015).
ThemeForest: Meistverkaufte WordPress-Themes mit Tags „photography“ und „portfolio“. http://themeforest.net/search?utf8=%E2%9C%93&amp;term=&amp;view=list&amp;sort=sales&amp;date=&amp;category=wordpress&amp;tags=photography&amp;tags=portfolio&amp;price_min=&amp;price_max=&amp;sales=&amp;rating_min= (Zugriff vom 09.11.2015).
ThemeForest: Premium WordPress Themes &amp; WordPress Templates. http://themeforest.net/category/wordpress (Zugriff vom 09.11.2015).
Valutis, Osvaldas: Image Lightbox › Demo. http://osvaldas.info/examples/image-lightbox-responsive-touch-friendly/ (Zugriff vom 16.12.2015).
Valutis, Osvaldas: Image Lightbox, Responsive and Touch‑friendly. http://osvaldas.info/image-lightbox-responsive-touch-friendly
(Zugriff vom 15.12.2015).
vlastuin: Code Reference › Functions › bloginfo › Show Character Set. https://developer.wordpress.org/reference/functions/bloginfo/#comment-515
(Zugriff vom 26.11.2015).
Westwood, Peter: „WordPress Beta Tester“-Plugin. https://wordpress.org/plugins/wordpress-beta-tester/ (Zugriff vom 25.11.2015).
Williams, Brad; Damstra, David; Stern, Hal (2015): <em>Professional WordPress. Design and development. </em>Third edition. Indianapolis, Indiana: Wrox.
Wojciechowski, Bartosz: Owl Carousel. http://www.owlcarousel.owlgraphic.com
(Zugriff vom 14.12.2015).
Wojciechowski, Bartosz: Owl Carousel › Events. http://www.owlcarousel.owlgraphic.com/docs/api-events.html
(Zugriff vom 15.12.2015).
Wojciechowski, Bartosz: Owl Carousel › Installation. http://www.owlcarousel.owlgraphic.com/docs/started-installation.html
(Zugriff vom 14.12.2015).
Wojciechowski, Bartosz: Owl Carousel › Options. http://www.owlcarousel.owlgraphic.com/docs/api-options.html
(Zugriff vom 14.12.2015).
Wood, Samuel: Passing parameters from PHP to Javascripts in plugins. http://ottopress.com/2010/passing-parameters-from-php-to-javascripts-in-plugins/
(Zugriff vom 14.12.2015).
Wood, Samuel; Obenland, Konstantin (2015): theme-check/checks/style_needed.php. https://github.com/Otto42/theme-check/blob/542e2b520c94f5455cbf86f8d59d3bc6555aac1e/checks/style_needed.php#L11-L16 (Zugriff vom 26.11.2015).
Wood, Samuel; Prosser, Simon: „Theme Check“-Plugin. https://wordpress.org/plugins/theme-check/ (Zugriff vom 25.11.2015).
WordPress: array_unique. http://php.net/manual/de/function.array-unique.php
(Zugriff vom 06.12.2015).
WordPress: Code Reference. https://developer.wordpress.org/reference/
(Zugriff vom 04.01.2016).
WordPress: Code Reference › Classes › Walker_Nav_Menu. https://developer.wordpress.org/reference/classes/walker_nav_menu/
(Zugriff vom 22.12.2015).
WordPress: Code Reference › Classes › Walker_Nav_Menu › Walker_Nav_Menu::start_el. https://developer.wordpress.org/reference/classes/walker_nav_menu/start_el/
(Zugriff vom 22.12.2015).
WordPress: Code Reference › Classes › WP_Customize_Manager. https://developer.wordpress.org/reference/classes/wp_customize_manager/
(Zugriff vom 17.12.2015).
WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_control. https://developer.wordpress.org/reference/classes/wp_customize_manager/add_control/ (Zugriff vom 15.12.2015).
WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_panel. https://developer.wordpress.org/reference/classes/wp_customize_manager/add_panel/ (Zugriff vom 16.12.2015).
WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_section. https://developer.wordpress.org/reference/classes/wp_customize_manager/add_section/ (Zugriff vom 16.12.2015).
WordPress: Code Reference › Classes › WP_Customize_Manager › WP_Customize_Manager::add_setting. https://developer.wordpress.org/reference/classes/wp_customize_manager/add_setting/ (Zugriff vom 16.12.2015).
WordPress: Code Reference › Classes › wpdb. https://developer.wordpress.org/reference/classes/wpdb/ (Zugriff vom 14.12.2015).
WordPress: Code Reference › Classes › wpdb › wpdb::get_var. https://developer.wordpress.org/reference/classes/wpdb/get_var/
(Zugriff vom 15.12.2015).
WordPress: Code Reference › Functions › __. https://developer.wordpress.org/reference/functions/__/ (Zugriff vom 30.12.2015).
WordPress: Code Reference › Functions › _e. https://developer.wordpress.org/reference/functions/_e/ (Zugriff vom 30.12.2015).
WordPress: Code Reference › Functions › _n. https://developer.wordpress.org/reference/functions/_n/ (Zugriff vom 17.01.2016).
WordPress: Code Reference › Functions › absint. https://developer.wordpress.org/reference/functions/absint/ (Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › add_action. https://developer.wordpress.org/reference/functions/add_action/
(Zugriff vom 17.12.2015).
WordPress: Code Reference › Functions › add_filter. https://developer.wordpress.org/reference/functions/add_filter/
(Zugriff vom 17.12.2015).
WordPress: Code Reference › Functions › add_theme_support. https://developer.wordpress.org/reference/functions/add_theme_support/
(Zugriff vom 29.11.2015).
WordPress: Code Reference › Functions › array_merge. http://php.net/manual/de/function.array-merge.php (Zugriff vom 06.12.2015).
WordPress: Code Reference › Functions › attachment_url_to_postid. https://developer.wordpress.org/reference/functions/attachment_url_to_postid/
(Zugriff vom 04.12.2015).
WordPress: Code Reference › Functions › bloginfo › Source. https://developer.wordpress.org/reference/functions/bloginfo/#source-code
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › body_class. https://developer.wordpress.org/reference/functions/body_class/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › comment_author_link. https://developer.wordpress.org/reference/functions/comment_author_link/
(Zugriff vom 20.12.2015).
WordPress: Code Reference › Functions › comment_class. https://developer.wordpress.org/reference/functions/comment_class/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › comment_form. https://developer.wordpress.org/reference/functions/comment_form/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › comment_ID. https://developer.wordpress.org/reference/functions/comment_id/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › comment_reply_link. https://developer.wordpress.org/reference/functions/comment_reply_link/
(Zugriff vom 19.12.2015).
WordPress: Code Reference › Functions › comment_text. https://developer.wordpress.org/reference/functions/comment_text/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › comments_open. https://developer.wordpress.org/reference/functions/comments_open/
(Zugriff vom 19.12.2015).
WordPress: Code Reference › Functions › comments_template. https://developer.wordpress.org/reference/functions/comments_template/
(Zugriff vom 20.12.2015).
WordPress: Code Reference › Functions › edit_comment_link. https://developer.wordpress.org/reference/functions/edit_comment_link/
(Zugriff vom 20.12.2015).
WordPress: Code Reference › Functions › esc_url. https://developer.wordpress.org/reference/functions/esc_url/ (Zugriff vom 26.11.2015).
WordPress: Code Reference › Functions › get_avatar. https://developer.wordpress.org/reference/functions/get_avatar/
(Zugriff vom 19.12.2015).
WordPress: Code Reference › Functions › get_bloginfo. https://developer.wordpress.org/reference/functions/get_bloginfo/
(Zugriff vom 26.11.2015).
WordPress: Code Reference › Functions › get_categories. https://developer.wordpress.org/reference/functions/get_categories/
(Zugriff vom 31.12.2015).
WordPress: Code Reference › Functions › get_comment_date. https://developer.wordpress.org/reference/functions/get_comment_date/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › get_comment_link. https://developer.wordpress.org/reference/functions/get_comment_link/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › get_comment_time. https://developer.wordpress.org/reference/functions/get_comment_time/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › get_comments. https://developer.wordpress.org/reference/functions/get_comments/
(Zugriff vom 15.12.2015).
WordPress: Code Reference › Functions › get_comments_number. https://developer.wordpress.org/reference/functions/get_comments_number/
(Zugriff vom 12.12.2015).
WordPress: Code Reference › Functions › get_footer. https://developer.wordpress.org/reference/functions/get_footer/
(Zugriff vom 10.12.2015).
WordPress: Code Reference › Functions › get_header. https://developer.wordpress.org/reference/functions/get_header/
(Zugriff vom 30.11.2015).
WordPress: Code Reference › Functions › get_header_image. https://developer.wordpress.org/reference/functions/get_header_image/
(Zugriff vom 26.11.2015).
WordPress: Code Reference › Functions › get_page_template_slug. https://developer.wordpress.org/reference/functions/get_page_template_slug/
(Zugriff vom 15.12.2015).
WordPress: Code Reference › Functions › get_post. https://developer.wordpress.org/reference/functions/get_post/
(Zugriff vom 06.12.2015).
WordPress: Code Reference › Functions › get_post_format. https://developer.wordpress.org/reference/functions/get_post_format/
(Zugriff vom 02.12.2015).
WordPress: Code Reference › Functions › get_post_galleries. https://developer.wordpress.org/reference/functions/get_post_galleries/
(Zugriff vom 06.12.2015).
WordPress: Code Reference › Functions › get_posts. https://developer.wordpress.org/reference/functions/get_posts/
(Zugriff vom 06.12.2015).
WordPress: Code Reference › Functions › get_search_form. https://developer.wordpress.org/reference/functions/get_search_form/
(Zugriff vom 27.12.2015).
WordPress: Code Reference › Functions › get_search_query. https://developer.wordpress.org/reference/functions/get_search_query/
(Zugriff vom 27.12.2015).
WordPress: Code Reference › Functions › get_sidebar. https://developer.wordpress.org/reference/functions/get_sidebar/
(Zugriff vom 30.11.2015).
WordPress: Code Reference › Functions › get_stylesheet_directory_uri. https://developer.wordpress.org/reference/functions/get_stylesheet_directory_uri/
(Zugriff vom 14.12.2015).
WordPress: Code Reference › Functions › get_template_directory. https://developer.wordpress.org/reference/functions/get_template_directory/
(Zugriff vom 10.12.2015).
WordPress: Code Reference › Functions › get_template_part. https://developer.wordpress.org/reference/functions/get_template_part/
(Zugriff vom 01.12.2015).
WordPress: Code Reference › Functions › get_template_part_directory. https://developer.wordpress.org/reference/functions/get_template_directory_uri/
(Zugriff vom 14.12.2015).
WordPress: Code Reference › Functions › get_the_author. https://developer.wordpress.org/reference/functions/get_the_author/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Functions › get_the_category. https://developer.wordpress.org/reference/functions/get_the_category/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Functions › get_the_category_list. https://developer.wordpress.org/reference/functions/get_the_category_list/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Functions › get_the_date. https://developer.wordpress.org/reference/functions/get_the_date/
(Zugriff vom 29.11.2015).
WordPress: Code Reference › Functions › get_the_tag_list. https://developer.wordpress.org/reference/functions/get_the_tag_list/
(Zugriff vom 02.12.2015).
WordPress: Code Reference › Functions › get_the_tags. https://developer.wordpress.org/reference/functions/get_the_tags/
(Zugriff vom 02.12.2015).
WordPress: Code Reference › Functions › get_the_time. https://developer.wordpress.org/reference/functions/get_the_time/
(Zugriff vom 02.12.2015).
WordPress: Code Reference › Functions › get_the_title. https://developer.wordpress.org/reference/functions/get_the_title/
(Zugriff vom 30.12.2015).
WordPress: Code Reference › Functions › get_theme_mod. https://developer.wordpress.org/reference/functions/get_theme_mod/
(Zugriff vom 21.12.2015).
WordPress: Code Reference › Functions › has_category. https://developer.wordpress.org/reference/functions/has_category/
(Zugriff vom 23.12.2015).
WordPress: Code Reference › Functions › has_excerpt. https://developer.wordpress.org/reference/functions/has_excerpt/
(Zugriff vom 29.12.2015).
WordPress: Code Reference › Functions › has_nav_menu. https://developer.wordpress.org/reference/functions/has_nav_menu/
(Zugriff vom 16.12.2015).
WordPress: Code Reference › Functions › has_post_thumbnail. https://developer.wordpress.org/reference/functions/has_post_thumbnail/
(Zugriff vom 04.12.2015).
WordPress: Code Reference › Functions › have_comments. https://developer.wordpress.org/reference/functions/have_comments/
(Zugriff vom 18.12.2015).
WordPress: Code Reference › Functions › have_posts. https://developer.wordpress.org/reference/functions/have_posts/
(Zugriff vom 29.11.2015).
WordPress: Code Reference › Functions › header_image. https://developer.wordpress.org/reference/functions/header_image/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › home_url. https://developer.wordpress.org/reference/functions/home_url/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › is_front_page. https://developer.wordpress.org/reference/functions/is_front_page/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › is_home. https://developer.wordpress.org/reference/functions/is_home/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › is_main_query. https://developer.wordpress.org/reference/functions/is_main_query/
(Zugriff vom 14.01.2016).
WordPress: Code Reference › Functions › is_singular. https://developer.wordpress.org/reference/functions/is_singular/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › language_attributes. https://developer.wordpress.org/reference/functions/language_attributes/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › load_theme_textdomain. https://developer.wordpress.org/reference/functions/load_theme_textdomain/
(Zugriff vom 26.12.2015).
WordPress: Code Reference › Functions › number_format_i18n. https://developer.wordpress.org/reference/functions/number_format_i18n/
(Zugriff vom 01.12.2015).
WordPress: Code Reference › Functions › pings_open. https://developer.wordpress.org/reference/functions/pings_open/
(Zugriff vom 25.11.2015).
WordPress: Code Reference › Functions › post_class. https://developer.wordpress.org/reference/functions/post_class/
(Zugriff vom 30.11.2015).
WordPress: Code Reference › Functions › post_password_required. https://developer.wordpress.org/reference/functions/post_password_required/
(Zugriff vom 30.12.2015).
WordPress: Code Reference › Functions › register_nav_menu. https://developer.wordpress.org/reference/functions/register_nav_menu/
(Zugriff vom 26.11.2015).
WordPress: Code Reference › Functions › register_sidebar. https://developer.wordpress.org/reference/functions/register_sidebar/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Functions › register-nav_menus. https://developer.wordpress.org/reference/functions/register_nav_menus/
(Zugriff vom 01.12.2015).
WordPress: Code Reference › Functions › sanitize_key. https://developer.wordpress.org/reference/functions/sanitize_key/
(Zugriff vom 17.12.2015).
WordPress: Code Reference › Functions › separate_comments. https://developer.wordpress.org/reference/functions/separate_comments/
(Zugriff vom 16.12.2015).
WordPress: Code Reference › Functions › single_post_title. https://developer.wordpress.org/reference/functions/single_post_title/
(Zugriff vom 30.12.2015).
WordPress: Code Reference › Functions › the_archive_description. https://developer.wordpress.org/reference/functions/the_archive_description/
(Zugriff vom 04.12.2015).
WordPress: Code Reference › Functions › the_archive_title. https://developer.wordpress.org/reference/functions/the_archive_title/
(Zugriff vom 16.12.2015).
WordPress: Code Reference › Functions › the_content. https://developer.wordpress.org/reference/functions/the_content/
(Zugriff vom 15.12.2015).
WordPress: Code Reference › Functions › the_excerpt. https://developer.wordpress.org/reference/functions/the_excerpt/
(Zugriff vom 11.12.2015).
WordPress: Code Reference › Functions › the_post. https://developer.wordpress.org/reference/functions/the_post/
(Zugriff vom 02.12.2015).
WordPress: Code Reference › Functions › the_post_navigation. https://developer.wordpress.org/reference/functions/the_post_navigation/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Functions › the_post_thumbnail. https://developer.wordpress.org/reference/functions/the_post_thumbnail/
(Zugriff vom 29.11.2015).
WordPress: Code Reference › Functions › the_posts_pagination. https://developer.wordpress.org/reference/functions/the_posts_pagination/
(Zugriff vom 07.12.2015).
WordPress: Code Reference › Functions › the_title. https://developer.wordpress.org/reference/functions/the_title/
(Zugriff vom 07.12.2015).
WordPress: Code Reference › Functions › update_option. https://developer.wordpress.org/reference/functions/update_option/
(Zugriff vom 26.12.2015).
WordPress: Code Reference › Functions › wp_enqueue_script. https://developer.wordpress.org/reference/functions/wp_enqueue_script/
(Zugriff vom 30.11.2015).
WordPress: Code Reference › Functions › wp_enqueue_style. https://developer.wordpress.org/reference/functions/wp_enqueue_style/
(Zugriff vom 30.11.2015).
WordPress: Code Reference › Functions › wp_footer. https://developer.wordpress.org/reference/functions/wp_footer/
(Zugriff vom 30.11.2015).
WordPress: Code Reference › Functions › wp_get_attachment_image. https://developer.wordpress.org/reference/functions/wp_get_attachment_image/
(Zugriff vom 04.12.2015).
WordPress: Code Reference › Functions › wp_head. https://developer.wordpress.org/reference/functions/wp_head/
(Zugriff vom 27.11.2015).
WordPress: Code Reference › Functions › wp_link_pages. https://developer.wordpress.org/reference/functions/wp_link_pages/
(Zugriff vom 15.12.2015).
WordPress: Code Reference › Functions › wp_list_comments. https://developer.wordpress.org/reference/functions/wp_list_comments/
(Zugriff vom 26.11.2015).
WordPress: Code Reference › Functions › wp_localize_script. https://developer.wordpress.org/reference/functions/wp_localize_script/
(Zugriff vom 14.12.2015).
WordPress: Code Reference › Functions › wp_nav_menu. https://developer.wordpress.org/reference/functions/wp_nav_menu/
(Zugriff vom 27.11.2015).
WordPress: Code Reference › Functions › wp_reset_postdata. https://developer.wordpress.org/reference/functions/wp_reset_postdata/
(Zugriff vom 04.12.2015).
WordPress: Code Reference › Hooks › comment_post. https://developer.wordpress.org/reference/hooks/comment_post/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Hooks › customize_register. https://developer.wordpress.org/reference/hooks/customize_register/
(Zugriff vom 03.12.2015).
WordPress: Code Reference › Hooks › init. https://developer.wordpress.org/reference/hooks/init/ (Zugriff vom 27.11.2015).
WordPress: Code Reference › Hooks › pre_get_posts. https://developer.wordpress.org/reference/hooks/pre_get_posts/
(Zugriff vom 14.01.2016).
WordPress: Code Reference › Hooks › the_content. https://developer.wordpress.org/reference/hooks/the_content/
(Zugriff vom 04.12.2015).
WordPress: Code Reference › Hooks › the_content_more_link. https://developer.wordpress.org/reference/hooks/the_content_more_link/
(Zugriff vom 16.12.2015).
WordPress: Code Reference › Hooks › widget_categories_args. https://developer.wordpress.org/reference/hooks/widget_categories_args/
(Zugriff vom 23.12.2015).
WordPress: Code Reference › Hooks › wp_head. https://developer.wordpress.org/reference/hooks/wp_head/ (Zugriff vom 26.11.2015).
WordPress: Codex › add_theme_support › Custom Header. https://codex.wordpress.org/Function_Reference/add_theme_support#Custom_Header (Zugriff vom 29.11.2015).
WordPress: Codex › add_theme_support › Feed Links. https://codex.wordpress.org/Function_Reference/add_theme_support#Feed_Links
(Zugriff vom 29.11.2015).
WordPress: Codex › add_theme_support › HTML5. https://codex.wordpress.org/Function_Reference/add_theme_support#HTML5
(Zugriff vom 29.11.2015).
WordPress: Codex › add_theme_support › Post Thumbnails. https://codex.wordpress.org/Function_Reference/add_theme_support#Post_Thumbnails (Zugriff vom 30.11.2015).
WordPress: Codex › Class Reference › WP_Query › Taxonomy Parameters. https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
(Zugriff vom 03.12.2015).
WordPress: Codex › Content Width. https://codex.wordpress.org/Content_Width
(Zugriff vom 26.12.2015).
WordPress: Codex › Function Reference › bloginfo › Parameters. https://codex.wordpress.org/Function_Reference/bloginfo#Parameters
(Zugriff vom 26.11.2015).
WordPress: Codex › Function Reference › get_bloginfo › Parameters. https://codex.wordpress.org/Function_Reference/get_bloginfo#Parameters
(Zugriff vom 26.11.2015).
WordPress: Codex › Introducion to Blogging › Pingbacks. http://codex.wordpress.org/Introduction_to_Blogging#Pingbacks
(Zugriff vom 26.11.2015).
WordPress: Codex › L10n. https://codex.wordpress.org/L10n (Zugriff vom 26.11.2015).
WordPress: Codex › Plugin API › Action Reference › pre_get_posts › Exclude categories on your main page. https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts#Exclude_categories_on_your_main_page (Zugriff vom 14.01.2016).
WordPress: Codex › Post Formats › Supported Formats. https://codex.wordpress.org/Post_Formats#Supported_Formats
(Zugriff vom 28.11.2015).
WordPress: Codex › Theme Development › Theme Stylesheet. https://codex.wordpress.org/Theme_Development#Theme_Stylesheet
(Zugriff vom 26.11.2015).
WordPress: Codex › Theme Unit Test. http://codex.wordpress.org/Theme_Unit_Test
(Zugriff vom 25.11.2015).
WordPress: Core-Trac › tags/4.3.1/src/wp-includes/post-template.php › Zeile 544. https://core.trac.wordpress.org/browser/tags/4.3.1/src/wp-includes/post-template.php#L544 (Zugriff vom 26.11.2015).
WordPress: Debugging in WordPress. https://codex.wordpress.org/Debugging_in_WordPress (Zugriff vom 25.11.2015).
WordPress: Function Reference › Functions › is_active_sidebar. https://developer.wordpress.org/reference/functions/is_active_sidebar/
(Zugriff vom 27.11.2015).
WordPress: Make WordPress Themes › Theme: Hannover. https://themes.trac.wordpress.org/ticket/29486 (Zugriff vom 03.01.2016).
WordPress: Plugin Handbook › Internationalization › How to Internationalize Your Plugin › Descriptions. https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#descriptions (Zugriff vom 17.01.2016).
WordPress: Plugin Handbook › Internationalization › How to Internationalize Your Plugin › Disambiguation by context. https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#disambiguation-by-context (Zugriff vom 17.01.2016).
WordPress: Theme Directory › Getting Started. https://wordpress.org/themes/getting-started/ (Zugriff vom 03.01.2016).
WordPress: Theme Directory › photoblogging-Tag. https://wordpress.org/themes/tags/photoblogging/ (Zugriff vom 02.11.2015).
WordPress: Theme Handbook › Advanced Theme Topics › Theme Options – The Customizer API › Controls. https://developer.wordpress.org/themes/advanced-topics/customizer-api/#controls (Zugriff vom 17.12.2015).
WordPress: Theme Handbook › Advanced Theme Topics › Theme Options – The Customizer API › Settings. https://developer.wordpress.org/themes/advanced-topics/customizer-api/#settings (Zugriff vom 17.12.2015).
WordPress: Theme Handbook › Internationalization › Text Domains. https://developer.wordpress.org/themes/functionality/internationalization/#text-domains (Zugriff vom 27.11.2015).
WordPress: Theme Handbook › Template Files Section › Page Template Files › Page Templates › Creating Custom Page Templates for Global Use. https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/#creating-custom-page-templates-for-global-use
(Zugriff vom 12.12.2015).
WordPress: Theme Handbook › Template Files Section › Page Template Files › Page Templates › File Organization of Page Templates. https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/#file-organization-of-page-templates (Zugriff vom 12.12.2015).
WordPress: Theme Handbook › Template Files Section › Post Template Files › index.php. https://developer.wordpress.org/themes/template-files-section/post-template-files/#index-php (Zugriff vom 30.11.2015).
WordPress: Theme Handbook › Theme Basics › Template Files › Common WordPress template files. https://developer.wordpress.org/themes/basics/template-files/#common-wordpress-template-files (Zugriff vom 29.11.2015).
WordPress: Theme Handbook › Theme Basics › Template Files › Template Partials. https://developer.wordpress.org/themes/basics/template-files/#template-partials
(Zugriff vom 22.12.2015).
WordPress: Theme Review Handbook. https://make.wordpress.org/themes/handbook/
(Zugriff vom 04.01.2016).
WordPress: Theme Review Handbook › Accessibility › Required › Link Text. https://make.wordpress.org/themes/handbook/review/accessibility/required/#link-text (Zugriff vom 03.12.2015).
WordPress: Theme Review Handbook › Core Functionality and Features. https://make.wordpress.org/themes/handbook/review/recommended/core-functionality-and-features/ (Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Design. https://make.wordpress.org/themes/handbook/review/recommended/design/
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Documentation. https://make.wordpress.org/themes/handbook/review/recommended/documentation/ (Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Recommended. https://make.wordpress.org/themes/handbook/review/recommended/
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required. https://make.wordpress.org/themes/handbook/review/required/
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Code. https://make.wordpress.org/themes/handbook/review/required/#code
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Core Functionality and Features. https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features (Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Documentation. https://make.wordpress.org/themes/handbook/review/required/#documentation
(Zugriff vom 25. November).
WordPress: Theme Review Handbook › Required › Language. https://make.wordpress.org/themes/handbook/review/required/#language
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Licensing. https://make.wordpress.org/themes/handbook/review/required/#licensing
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Naming. https://make.wordpress.org/themes/handbook/review/required/#naming
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Options and Settings. https://make.wordpress.org/themes/handbook/review/required/#options-and-settings (Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Plugins. https://make.wordpress.org/themes/handbook/review/required/#plugins
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Presentation vs Functionality. https://make.wordpress.org/themes/handbook/review/required/#presentation-vs-functionality (Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Screenshot. https://make.wordpress.org/themes/handbook/review/required/#screenshot
(Zugriff vom 25.11.2015).
WordPress: Theme Review Handbook › Required › Security and Privacy. https://make.wordpress.org/themes/handbook/review/required/#security-and-privacy (Zugriff vom 26.11.2015).
WordPress: Theme Review Handbook › Required › Selling, credits and links. https://make.wordpress.org/themes/handbook/review/required/#selling-credits-and-links (Zugriff vom 26.11.2015).
WordPress: Theme Review Handbook › Required › Templates. https://make.wordpress.org/themes/handbook/review/required/#templates
(Zugriff vom 26.11.2015).
WordPress: Theme Review Handbook › Selling, Themes and Links. https://make.wordpress.org/themes/handbook/review/recommended/selling-themes-and-links/ (Zugriff vom 26.11.2015).
WordPress: Theme Review Handbook › Templates. https://make.wordpress.org/themes/handbook/review/recommended/templates/
(Zugriff vom 26.11.2015).
WordPress: Theme-Verzeichnis. https://de.wordpress.org/themes/
(Zugriff vom 04.01.2016).
WordPress; Boren, Ryan; Westwood, Peter; Koopersmith, Daryl; Cave, Jon; Yoshitaka Erlewine, Michael: „Debug Bar“-Plugin. https://wordpress.org/plugins/debug-bar/
(Zugriff vom 26.11.2015).
World Press Photo Foundation: 2015 Photo Contest. http://www.worldpressphoto.org/collection/photo/2015 (Zugriff vom 30.10.2015).
xrds; Shepherd, Eric; thehaverchuck; hasAngel; Dursun, Resul; Hobson, Stephanie; Rebert, Chris; Taylor, Mike; wesj; zigomir; martind1; ddsgdfgidshvbeivbosdlvbdfvdsv; Dutton, Sam; Brubeck, Matt; Vukicevic, Vlad: Using the viewport meta tag to control layout on mobile browsers. https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag (Zugriff vom 27.11.2015).
<h2 id="anhang-a">Anhang A:
Preisträger-Websites des Photo Contest von der World Press Photo Foundation</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Datum der Untersuchung war der 28. Oktober 2015
<strong>jeromesessiniukraine.com</strong>
<ul>
<li>Übersicht von Referenzen auf Startseite</li>
<li>Übersicht der drei Reportagen auf Startseite</li>
<li>Bilder auf Detailseite als Thumbnails lassen sich in Lightbox öffnen</li>
</ul>
<strong>kierandoherty.com</strong>
<ul>
<li>Slideshow auf Startseite und Detailseiten</li>
<li>Gibt die Möglichkeit, auf Thumbnails umzuschalten</li>
</ul>
<strong>sofiavaliente.com</strong>
<ul>
<li>Bilder einer Reportage nebeneinander in einem scrollbaren Bereich</li>
</ul>
<strong>raphaelarosella.com</strong>
<ul>
<li>Bilder auf Startseite und Detail-Ansicht in Slideshow</li>
<li>Wieder die Möglichkeit, auf Thumbs umzuschalten</li>
</ul>
<strong>varmaphoto.com</strong>
<ul>
<li>Vollbild-Slider auf Startseite</li>
<li>Bilder einer Galerie einfach in groß untereinander. Beschreibung in Lightbox nach Klick</li>
</ul>
<strong>darcypadilla.com</strong>
<ul>
<li>Fast alle Infos direkt auf der Startseite</li>
<li>Verlinkt mehr auf Seiten, als direkt ihre Arbeiten auf der eigenen Seite zu zeigen</li>
</ul>
<strong>petemullerphotography.com</strong>
<ul>
<li>Slideshow auf der Startseite</li>
<li>In Detailansicht große, bildschirmfüllende Bilder in einem scrollbaren Bereich</li>
<li>Andere Variante Detail: große Bilder mit kleinen Thumbnails darunter – Slider</li>
</ul>
<strong>www.ilnitsky-photography.com</strong>
<ul>
<li>Großes Titelbild auf der Startseite</li>
<li>Wird zufällig angezeigt</li>
<li>Übersicht aller Arbeiten in einer Portfolio-Ansicht</li>
<li>Archiv-Ansicht</li>
<li>Auf Einzelseite eines Portfolio-Elements ein Slider</li>
</ul>
<strong>michelepalazziphotographer.com</strong>
<ul>
<li>Slider auf der Startseite</li>
<li>Portfolio-Übersicht
<ul>
<li>Im Menü lassen sich die einzelnen Kategorien auswählen</li>
</ul>
</li>
<li>In Einzelansicht ein Slider</li>
<li>WordPress-Theme <em>Evolution</em> in Nutzung: http://www.elegantthemes.com/gallery/evolution/</li>
</ul>
<strong>madsnissen.com</strong>
<ul>
<li>Viewportfüllender Slider auf Startseite</li>
<li>Auf Einzelansicht Text und Bild-Grid – Lightbox zeigt große Versionen</li>
<li>Gibt die Möglichkeit, mehrere Galerien auf einer Seite anzuzeigen (nach Kategorie?) http://www.madsnissen.com/category/stories/</li>
<li>WordPress-Theme <em>Widescreen</em>: https://graphpaperpress.com/themes/widescreen/</li>
</ul>
<strong>giuliodisturco.com</strong>
<ul>
<li>Slideshow auf Startseite</li>
<li>Auf Detailseite entweder große Bilder im scrollbaren Bereich oder in einem Slider</li>
</ul>
<strong>massimosestini.it</strong>
<ul>
<li>Einfach alle Bilder einer Kategorie auf einer Seite, vergrößerbar in einer Lightbox</li>
</ul>
<strong>gianfrancotripodo.com</strong>
<ul>
<li>Auf Startseite eine Übersicht der Kategorien. Jeweils ein Bild für eine Kategorie</li>
<li>Auf Einzelansicht der Kategorien ein Bild pro Bilderstrecke</li>
<li>Auf Einzelansicht einer Bilderstrecke eine Slideshow</li>
</ul>
<strong>sergeyponomarev.com</strong>
<ul>
<li>Slideshow mit Infos zum jeweiligen Bild auf der Startseite</li>
<li>Auf Einzelansicht ein Slider</li>
<li>Text zu der jeweiligen Serie wird mit in der Sidebar angezeigt</li>
</ul>
<strong>glennagordon.com</strong>
<ul>
<li>Großes Bild auf der Startseite</li>
<li>Auf der Einzelansicht große Bilder in scrollbarem Bereich</li>
</ul>
<strong>kacperkowalski.pl</strong>
<ul>
<li>Slider auf Startseite</li>
<li>Auf Galerie-Seite sieht man jeweils in einer Art Slider die Vorschau auf eine Galerie. Da kann man draufklicken und dann die Galerie anschauen.</li>
</ul>
<strong>sandrahoyn.de</strong>
<ul>
<li>Slider auf der Startseite</li>
<li>Übersicht der Galerien auf einer Seite:
<ul>
<li>Vorschaubild, Titel, Beschreibung</li>
<li>Zeigt immer nur Galerien einer Kategorie an</li>
</ul>
</li>
</ul>
<strong>christianziegler.photography</strong>
<ul>
<li>Slider auf der Startseite und auf den Detailseiten</li>
</ul>
<strong>paolomarchetti.org</strong>
<ul>
<li>Großes Bild auf der Startseite</li>
<li>Übersicht der <em>Stories</em> mit Titel und Datum auf einer Seite</li>
<li>Auf der Einzelansicht Text mit Thumb-Grid.</li>
</ul>
<strong>lisakrantz.com</strong>
<ul>
<li>Video auf der Startseite</li>
<li>Große Bilder im Slider auf Einzelansicht</li>
</ul>
<strong>paoloverzone.com</strong>
<ul>
<li>Startseite zeigt gleich die erste Übersicht einer Kategorie</li>
<li>Auf Kategorie-Seite werden die Bilder in klein dargestellt, können durch Klick vergrößert werden</li>
</ul>
<strong>markmetcalfe.com.au</strong>
<ul>
<li>Bilder werden auf jeder Seite groß dargestellt, in einem scrollbaren Bereich</li>
<li>Als System wird <em>Format</em> genutzt: http://format.com/l/your_new_portfolio#horizon-left</li>
</ul>
<strong>albello.com</strong>
<ul>
<li>Slideshow auf der Startseite</li>
<li>Ebenso auf allen anderen Seiten</li>
</ul>
<strong>asasjostrom.com</strong>
<ul>
<li>Gleich auf der Startseite Grid der Arbeiten</li>
<li>Einzelansicht zeigt Slider mit Text, darunter immer weiter das Grid von der Startseite</li>
</ul>
<strong>malinfezehai.net</strong>
<ul>
<li>Vollflächiges Hintergrundbild auf Startseite</li>
<li>Slider auf der eigentlichen Home-Seite</li>
<li>Die übrigen Einzelansichten öffnen sich mit einem großen Bild. Man kann aber auf die Thumbnails umschalten</li>
</ul>
<strong>sarkerprotick.com</strong>
<ul>
<li>Einzelnes Bild auf der Startseite</li>
<li>Auf den Einzelseiten jeweils große Bilder im scrollbaren Bereich</li>
<li>COLr-WordPress-Theme von http://minimalistwp.com/</li>
</ul>
<strong>turicalafato.com</strong>
<ul>
<li>Slideshow auf der Startseite</li>
<li>Portfolio-Ansicht zeigt die verschiedenen Galerien in einer Übersicht</li>
<li>In Einzelansicht eine Slideshow mit Auswahl-Thumbs</li>
</ul>
<strong>tomasvh.com</strong>
<ul>
<li>Slider auf der Startseite</li>
<li>Unter <em>Works</em> die Vorschau zu drei Serien, und ein Link zum <em>Archiv</em></li>
<li>Auf Einzelseite Slider</li>
</ul>
<h2 id="anhang-b">Anhang B:
Untersuchung der kostenlosen WordPress-Themes</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Untersuchung der 126 kostenlosen WordPress-Themes mit dem Tag <em>Fotoblog</em> von WordPress.org. Untersuchungszeitraum ist der 3. und 4. November 2015
Die Funktionen, auf die untersucht wird:
<ul>
<li>Trennung von Portfolio-Elementen und Blogbeiträgen</li>
<li>Galerie als Slider oder einzelne Bilder anzeigen</li>
<li>Slider oder zufälliges Bild auf der Startseite</li>
<li>Übersicht aller Arbeiten auf einer Seite und Archiv</li>
<li>Kategorie-Seiten für Arbeiten</li>
<li>Verschiedene Darstellungsmöglichkeiten für Portfolio und Kategorie-Übersicht</li>
</ul>
Da die Funktion, Bilder einer Galerie als einzelne Bilder anzuzeigen, eine Standard-Funktion von WordPress ist, wird diese Funktion hier nicht weiter untersucht
<strong>de.wordpress.org/themes/omega/</strong>
<ul>
<li>Keine der besonderen Funktionen</li>
<li>Mehr ein Theme-Framework, das als Ausgangslage für ein eigenes Theme gedacht ist</li>
</ul>
<strong>de.wordpress.org/themes/x2/</strong>
<ul>
<li>Bietet die Möglichkeit, einen Slider einzubinden</li>
</ul>
<strong>de.wordpress.org/themes/make/</strong>
<ul>
<li>Bietet die Möglichkeit, eine Galerie als Slider darzustellen</li>
</ul>
<strong>de.wordpress.org/themes/sans-serif/</strong>
<ul>
<li>Keine der besonderen Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/veal/</strong>
<ul>
<li>Slider-Möglichkeit für Startseite</li>
</ul>
<strong>de.wordpress.org/themes/cubic/</strong>
<ul>
<li>Keine der besonderen Funktionen</li>
<li>Vorschau von Galerien auf der Homepage sieht gut aus</li>
</ul>
<strong>de.wordpress.org/themes/tari/</strong>
<ul>
<li>Keine der besonderen Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/treeson/</strong>
<ul>
<li>Keine der besonderen Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/precious-lite/</strong>
<ul>
<li>Gibt Feature, dass man Galerie mit Shortcode einbinden und dann die Bilder filtern kann</li>
<li>Keine der Funktionen, die aus der Fotografen-Analyse hervorgingen</li>
</ul>
<strong>de.wordpress.org/themes/pinboard/</strong>
<ul>
<li>Möglichkeit, Portfolio-Elemente vom Blog auszuschließen</li>
<li>Möglichkeit, alle Beiträge aus dieser Kategorie auf einer Seite anzuzeigen</li>
</ul>
<strong>de.wordpress.org/themes/origami-evergreen/</strong>
<ul>
<li>Bestimmte Elemente können auf einer Seite angezeigt werden</li>
</ul>
<strong>de.wordpress.org/themes/nova-lite/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/realm/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/white/</strong>
<ul>
<li>Möglichkeit, Slider einzufügen</li>
</ul>
<strong>de.wordpress.org/themes/foliogine-lite/</strong>
<ul>
<li>Möglichkeit, Slider einzubauen</li>
</ul>
<strong>de.wordpress.org/themes/skt-white/</strong>
<ul>
<li>Slider-Möglichkeit</li>
</ul>
<strong>de.wordpress.org/themes/yuuta/</strong>
<ul>
<li>Keine der Funktionen, aber Design gefällt</li>
</ul>
<strong>de.wordpress.org/themes/alum/</strong>
<ul>
<li>Slider auf Startseite</li>
</ul>
<strong>de.wordpress.org/themes/snapshot/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/virtue/</strong>
<ul>
<li>Können Portfolio-Elemente angelegt werden</li>
<li>Slider auf den Einzel-Seiten</li>
<li>Nutzt für die Portfolio-Funktion aber ein Plugin</li>
</ul>
<strong>de.wordpress.org/themes/family/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/diarjo-lite/</strong>
<ul>
<li>In der Free-Version keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/skt-parallaxme/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/paraxe/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/boardwalk/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/rara-clean/</strong>
<ul>
<li>Beitrags-Slider</li>
</ul>
<strong>de.wordpress.org/themes/lens/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/semper-fi-lite/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/marla/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/kwikload/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/editor/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/verbo/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/inovate/</strong>
<ul>
<li>Slider-Möglichkeit</li>
</ul>
<strong>de.wordpress.org/themes/skt-black/</strong>
<ul>
<li>Slider-Möglichkeit</li>
</ul>
<strong>de.wordpress.org/themes/coherent/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/sylvia/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/willingness/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/bushwick/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/photostory/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/verge/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/nerocity/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/seiryuu/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/sg-window/</strong>
<ul>
<li>Keine der Möglichkeiten</li>
</ul>
<strong>de.wordpress.org/themes/snaps/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/dazzling/</strong>
<ul>
<li>Beitrags-Slider</li>
</ul>
<strong>de.wordpress.org/themes/adventurous/</strong>
&nbsp;
<ul>
<li>Featured-Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/seller/</strong>
<ul>
<li>Featured-Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/writ/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/jehanne/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/quest/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/tography-lite/</strong>
<ul>
<li>Portfolio-Elemente lassen sich auf einer Seite anzeigen</li>
<li>Können auch gefiltert werden</li>
</ul>
<strong>de.wordpress.org/themes/quickpic/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/sidekick/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/dms/</strong>
<ul>
<li>Portfolio-Übersicht möglich</li>
<li>Kann auch gefiltert werden</li>
</ul>
<strong>de.wordpress.org/themes/kelly/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/fukasawa/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/ariwoo/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/panaroma/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/patio/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/aladdin/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/birdsite/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/aspen/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/landline/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/invisible-assassin/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/bose/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/pinnacle/</strong>
<ul>
<li>Portfolio-Übersicht in zwei verschiedenen Varianten</li>
<li>Auf einzelnem Objekt ist Slider möglich</li>
<li>Portfolio-Funktion kann nur mit einem Plugin erreicht werden</li>
</ul>
<strong>de.wordpress.org/themes/protopress/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/sg-grid/</strong>
<ul>
<li>Portfolio-Übersicht</li>
<li>Lässt sich filtern</li>
</ul>
<strong>de.wordpress.org/themes/the-j-a-mortram/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/pagelines/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/aron/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/alhena-lite/</strong>
<ul>
<li>Content-Slider</li>
<li>Bilder können als Projekte angelegt und gefiltert werden</li>
</ul>
<strong>de.wordpress.org/themes/sparkling/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/professional/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/i-max/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/gridsby/</strong>
<ul>
<li>Fotos lassen sich auf einer Seite anzeigen, interessante Ansicht beim Vergrößern (mit Beschreibung)</li>
</ul>
<strong>de.wordpress.org/themes/skt-photo-session/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/sg-double/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/horas/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/weaver-ii/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/xclusive/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/aldehyde/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/follet/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/swell-lite/</strong>
<ul>
<li>Lassen sich Portfolio-Elemente festlegen</li>
</ul>
<strong>de.wordpress.org/themes/skt-photo-world/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/museum/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/freak/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/dream-way/</strong>
<ul>
<li>Portfolio-Übersicht</li>
<li>Lässt sich auch filtern</li>
</ul>
<strong>de.wordpress.org/themes/aperture/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/colorsnap/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
de.wordpress.org/themes/sliding-door/
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/market/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/fifteen/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/harmonic/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/biancaa/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/divina/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/emphaino/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/jolene/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/hoffman/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/phogra/</strong>
<ul>
<li>Slider</li>
<li>Portfolio-Übersicht</li>
<li>Slider auf Einzelseite</li>
</ul>
<strong>de.wordpress.org/themes/biker/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/stained-glass/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/jax-lite/</strong>
<ul>
<li>Portfolio-Übersicht</li>
<li>Kann gefiltert werden</li>
</ul>
<strong>de.wordpress.org/themes/undiscovered/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/satu/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/water-lily/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/times/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/weaver-xtreme/</strong>
<ul>
<li>Slider</li>
</ul>
<strong>de.wordpress.org/themes/great/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/times-square/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/eryn/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/visual/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
de.wordpress.org/themes/suevafree/
<ul>
<li>Galerie-Bilder als Slider</li>
</ul>
<strong>de.wordpress.org/themes/catch-kathmandu/</strong>
<ul>
<li>Content-Slider</li>
</ul>
<strong>de.wordpress.org/themes/adaption/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/skt-full-width/</strong>
<ul>
<li>Slider</li>
<li>Portfolio nur in Pro-Version</li>
</ul>
<strong>de.wordpress.org/themes/careta/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/enlightenment/</strong>
<ul>
<li>Content-Slider</li>
<li>Portfolio-Übersicht (mit Plugin)</li>
</ul>
<strong>de.wordpress.org/themes/photolab/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/avnii/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/blaskan/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/azeria/</strong>
<ul>
<li>Content-Slider</li>
<li>Portfolio-Übersicht, aber mit Plugin</li>
</ul>
<strong>de.wordpress.org/themes/sg-simple/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/fluxipress/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<strong>de.wordpress.org/themes/bouquet/</strong>
<ul>
<li>Keine der Funktionen</li>
</ul>
<h2 id="anhang-c">Anhang C:
Untersuchung der kostenpflichtigen Themes</h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
Untersuchung von 10 kostenpflichtigen Premium-Themes von ThemeForest. Untersuchungszeitraum ist der 9. November 2015
Die Funktionen, auf die untersucht wird:
<ul>
<li>Trennung von Portfolio-Elementen und Blogbeiträgen</li>
<li>Galerie als Slider oder einzelne Bilder anzeigen</li>
<li>Slider oder zufälliges Bild auf der Startseite</li>
<li>Übersicht aller Arbeiten auf einer Seite und Archiv</li>
<li>Kategorie-Seiten für Arbeiten</li>
<li>Verschiedene Darstellungsmöglichkeiten für Portfolio und Kategorie-Übersicht</li>
</ul>
Da die Funktion, Bilder einer Galerie als einzelne Bilder anzuzeigen, eine Standard-Funktion von WordPress ist, wird diese Funktion hier nicht weiter untersucht
<strong>themeforest.net/item/core-minimalist-photography-portfolio/240185</strong>
<ul>
<li>Bietet verschiedene Möglichkeiten, eine Galerie darzustellen (mit Shortcodes)</li>
<li>Kann eine Art Slider auf der Startseite darstellen</li>
<li>Arbeitet viel mit Shortcodes (Buttons, Lightbox-Funktion, Slider …)</li>
</ul>
<strong>themeforest.net/item/invictus-a-fullscreen-photography-wordpress-theme/180096</strong>
<ul>
<li>Möglichkeit, einen Vollbild-Slider für die Startseite zu nutzen – optional mit Video-Hintergrund</li>
<li>Verschiedene Templates für die Darstellung einer Portfolio-Übersicht</li>
<li>Portfolio-Elemente scheinen mit Custom-Post-Types angelegt zu werden</li>
<li>Einige Shortcodes</li>
</ul>
<strong>themeforest.net/item/photolux-photography-portfolio-wordpress-theme/894193</strong>
<ul>
<li>Portfolio-Elemente lassen sich auf einer Seite darstellen</li>
<li>Können gefiltert werden</li>
<li>Kann Slider eingebaut werden</li>
<li>Portfolio-Elemente sind keine Beiträge</li>
</ul>
<strong>themeforest.net/item/fluxus-portfolio-theme-for-photographers/3854385</strong>
<ul>
<li>Homepage-Slider</li>
<li>verschiedene Portfolio-Ansichten, die sich auch filtern lassen</li>
<li>Portfolio-Elemente keine Beiträge</li>
<li>Setzt auf Shortcodes für Accordion, Meldungen, Service-Ansicht und mehr</li>
</ul>
<strong>themeforest.net/item/expression-photography-responsive-wordpress-theme/2855595</strong>
<ul>
<li>Slider</li>
<li>Filterbare Portfolio-Ansicht, nur eine Variante</li>
<li>Shortcodes für Tabs</li>
</ul>
<strong>themeforest.net/item/dk-for-photography-creative-portfolio/631383</strong>
<ul>
<li>Slider auf Homepage</li>
<li>Auch einzelnes Bild möglich</li>
<li>Keine Portfolio-Ansicht</li>
</ul>
<strong>themeforest.net/item/skylab-portfolio-photography-wordpress-theme/4740718</strong>
<ul>
<li>Slider auf Homepage</li>
<li>Verschiedene Portfolio-Layouts</li>
<li>Portfolio-Elemente sind keine Beiträge</li>
<li>Möglichkeit, Einzelansicht eines Portfolio-Elements als einzelne Bilder oder in einem Slider anzuzeigen</li>
</ul>
<strong>themeforest.net/item/border-a-delightful-photography-wordpress-theme/6920241</strong>
<ul>
<li>Homepage-Slider</li>
<li>Portfolio-Ansicht in verschiedenen Varianten</li>
<li>Setzt auf Shortcodes</li>
</ul>
<strong>themeforest.net/item/epix-fullscreen-photography-wordpress-theme/5783556</strong>
<ul>
<li>Slider auf Homepage</li>
<li>Portfolio-Ansicht, lässt sich auch filtern</li>
<li>Portfolio-Items keine Beiträge</li>
<li>Verschiedene Möglichkeiten, Bilder anzuzeigen</li>
</ul>
<strong>themeforest.net/item/titan-responsive-portfolio-photography-theme/5072056</strong>
<ul>
<li>Homepage-Slider</li>
<li>Verschiedene Möglichkeiten, Galerien darzustellen</li>
<li>Portfolio-Funktion mit verschiedenen Varianten</li>
<li>Arbeitet auch mit Shortcodes</li>
</ul>
<h2 id="anhang-d">Anhang D:
Template-Hierarchie in WordPress-Themes<a href="#_ftn279" name="_ftnref279">[279]</a></h2>
<em><a href="#inhaltsverzeichnis">Zum Inhaltsverzeichnis</a></em>
<a href="https://florianbrinkmann.com/wp-content/uploads/2016/02/template-hierarchy.png" rel="attachment wp-att-2249"><img class="alignnone size-large wp-image-2249" src="https://florianbrinkmann.com/wp-content/uploads/2016/02/template-hierarchy-800x500.png" alt="template-hierarchy" width="800" height="500" /></a>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment