Projekte mit dem CMS ProcessWire

ProcessWire (https://processwire.com) ist ein schlankes, flexibles, leicht zu erlernendes und gut erweiterbares Content Management System.
Es ist kostenfrei, open-source und basiert auf PHP und MySQL (bzw. MariaDB).
Für Redakteur/innen ist der Umgang damit leicht zu erlernen, das Backend (Administrations-Oberfläche) ist an Einfachheit kaum zu überbieten.
Für Programmierer/innen ist es dank guter Online-Dokumentation und einer durchdachten API schnell zu durchschauen.
Es gibt eine lebendige Community und diverse Erweiterungen.

Es wurde von Ryan Cramer entwickelt, der es in diesem Video vorstellt: https://www.youtube.com/watch?v=Wl4XiYadV_k

 

Grundprinzipien
Für Anwender/innen und Redakteur/innen
Für Programmierer
Dateiverwaltung
Projekte mit webdecker

 

Grundprinzipien

Prflegbare "Objekte" wie Seiten, News-Artikel, Veranstaltungen, Produkte oder sonstige Datensätze werden einheitlich in einer hierarchischen Baum- oder Ordner-Struktur gepflegt. All diese "Objekte" heißen dort "Seiten", auch wenn es sich nicht zwingend um Web-Seiten handeln muss.

Die Anzeige und Verwendung dieser Objekte regelt der Programmierer in den Darstellungs-Templates.

Ein Administrator erstellt im Backend "Templates" alias "Datentypen" durch Zuordnung von beliebigen Eingabe-Feldern. Damit ist die Pflegemaske für Objekte diesen Typs definiert.

Dazu wird ein passendes PHP-Template erstellt, das die Anzeige steuert. Über die Programmier-Schnittstelle (API) kann dabei auf alle Seiten bzw. Objekte und ihre Felder zugegriffen werden. Dabei werden Abfragen nicht in SQL programmiert, sondern durch "Selektoren" definiert, was ein bisschen an JQuery erinnert. (Wobei ein SQL-Zugriff auch möglich ist.)

Durch eine ProcessWire-Installation werden bereits erste Templates angelegt, so dass man sofort mit einer einfachen Website starten kann. Als Programmierer/in genießt man dabei sämtliche Freiheiten, da die Templates und damit auch der HTML-, CSS- und JavaScript-Code beliebig angepasst oder überschrieben werden können.

Man könnte ProcessWire beinahe auch als eine Art "Headless CMS" bezeichnen, denn im Grunde stellt es nur ein Backend zur Pflege von beliebigen Objekten und eine PHP-API für den Zugriff auf die Daten zur Verfügung. Dazu dann quasi Vorschläge für die Darstellung als Website.

(Würde man eine PHP-Seite bzw. ein PHP-Template programmieren, das einen "Selektor" entgegen nimmt und die gefundenen Daten JSON-codiert zurück liefern, könnte man dadurch die Basis für ein Headless CMS schaffen...)

 

Für Anwender/innen bzw. Redakteur/innen

Das Backend ist an Schlichtheit kaum zu überbieten. Nach Login sieht man den Seitenbaum. Durch Klick auf ein Element in diesem Baum werden die Unter-Elemente angezeigt und es öffnet sich ein Kontextmenü für das Element.
Dort kann eine Aktion ausgewählt werden, z.B. zum Bearbeiten des Elements, zum Verschieben, Löschen, Offline-Schalten oder zum Erstellen eines neuen Elements unterhalb des aktiven Elements.

Seitenbaum ProcessWire


Die Bearbeitungsmasken folgen alle dem gleichen Schema und durch einen WYSIWYG-Editor ist auch die Eingabe von formatierem Text möglich.

Eingabemaske ProcessWire


Je nach Typ können Bilder oder andere Dateien hoch geladen und damit dem Element zugeordnet werden.
Der Menüpunkt "Seiten -> Finden" lässt eine hoch differenzierte Suche nach Elementen zu. Durch Hinzufügen von Abfragen zu einzelnen Feldern lassen sich sehr spezielle Suchanfragen erzeugen.
Unter dem Menüpunkt "Verwaltung" finden sich projek-spezifische Funktionalitäten.
Durch Zuordnung von Usern zu User-Gruppen mit definierbaren Rechten lassen sich Zugriffe auf bestimmte Bereiche oder Funktionalitäten definieren.

 

Für Programmierer/innen

Als Administrator/in oder Programmierer/in lege ich im Backend zuerst Eingabe-Felder an. Hier stehen diverse Feld-Typen zur Verfügung (Text, WYSIWIG-Text, Zahl, Datum, Seiten-Referenz, Datei, Select, Checkbox, ...).
Habe ich neben der Default-Sprache Englisch auch das deutsche Sprachpaket installiert, kann ich die Labels der Felder entsprechend übersetzen (und auch mehrsprachige Website aufsetzen).
Danach erstelle ich ein "Template" alias "Datentyp" durch Auswahl von Feldern. Felder sind somit in mehreren Templates / Datentypen nutzbar.

Dies deutet auch auf die Datenhaltung hin: Datensätze eines Typs werden nicht in einer eigenen Tabelle gespeichert, sondern die (nicht-leeren) Feld-Inhalte in jeweils eigenen Tabellen.
Das ergibt eine ausgesprochen schlanke Datenhaltung, führt aber auch dazu, dass ich nicht mal eben alle Datensätze eines Typs aus der Datenbank exportieren kann. Dies müsste mit Hilfe der API programmiert werden oder eine Seiten-Export-Erweiterung wird genutzt.

Templates müssen kein Darstellungs-PHP-Template haben. Sie können schlicht zur Pflege von Datensätzen da sein. Templates, die für Web-Seiten oder anzuzeigende Objekte stehen, werden um ein PHP-Template ergänzt. Es wird angelegt als DOCROOT/site/templates/[Template-Name].php.
Hier setze ich den HTML-Code ein und die Ausgaben der Feld-Werte der gerade anzuzeigenden Instanz. Ein Beispiel:

<?php
include('./_head.php'); // include header markup 
// In Templates stehen diverse Variablen "global" zur Verfügung.
// Z.B. 
// $page (anzuzeigende Instanz), 
// $pages (Zugriff auf alle Seiten), 
// $user (aktiver User, im Zweifel "guest")
?>
<h1><?= $page->title ?></h1>
<div><?= $page->text ?></div>
<div><strong>Aktiver User:</strong> <?= $user->name ?></div>
<div>
	<strong>Unterseiten:</strong><br>
	<?php foreach ($page->children() as $p): ?>
		<a href="<?= $p->url() ?>" title="<?= htmlspecialchars($p->title) ?>">
			<?= $p->title ?>
		</a><br>
	<?phl endforeach ?>
</div>
<div>
	<strong>Unterseiten direkt unter Home:</strong><br>
	<?php foreach ($pages->get(1)->children() as $p): ?>
		<a href="<?= $p->url() ?>" title="<?= htmlspecialchars($p->title) ?>">
			<?= $p->title ?>
		</a><br>
	<?phl endforeach ?>
</div>
<div>
	<strong>Alle Seiten vom Typ 'page_standard' unter Seite 3:</strong><br>
	<?php foreach ($pages->find('template=page_standard,parent=3') as $p): ?>
		<a href="<?= $p->url() ?>" title="<?= htmlspecialchars($p->title) ?>">
			<?= $p->title ?>
		</a><br>
	<?phl endforeach ?>
</div>
<?php
include('./_foot.php'); // include footer markup
?>


Diverse Funktionalitäten des Core sind durch Hooks anpasspar. ProcessWire bietet hier ein interessantes Modell an. Sobald (in einer von Wire abgeleiteten Klasse) der Name einer Methode mit drei Unterstrichen beginnt, ist sie "hookable". Nun kann ich voher oder nachher mit einem Hook eingreifen oder diese Methode sogar ersetzen.
Solche Hooks kann ich heinfach in DOCUMENTROOT/site/ready.php einsetzen. Ein einfaches Beispiel:

<?php
/** Hook to page render process to add some code. */
$wire->addHookAfter('Page::render', function(HookEvent $event) {
	$html = $event->return;
	$page = $event->object;
	if (preg_match('~page~', $page->template->name)) {
		$html = str_replace('</body>', 'TEST</body>', $html);
	}
	$event->return = $html;
});
?>

 

Dateiverwaltung

Es gibt keine zentrale Dateiverwaltung, wie man sie von anderen CMS kennt. Bilder oder andere Datein werden - sofern es entsprechende Datei-Felder im Template gibt - direkt an einer Seite hoch geladen und in einem entsprechenden Seiten-Verzeichnis auf der Platte gespeichert.
Es gibt Erweiterungen, die eine Übersicht ermöglichen sowie Referenzen zu Dateien von anderen Seiten.

 

Projekte mit webdecker

Ich nutze ProcessWire inzwischen ein paar Jahre und habe immer noch Spaß daran. Inzwischen habe ich ein Set aus Konzepten und Erweiterungen aus dem Repository oder selbst programmiert zusammengestellt, das das Aufsetzten von einfachen bis hin zu komplexen Websites mit Shop-Funktionen erleichtert.

Dabei mache ich eine Sache etwas anders als es vermutlich in vielen anderen Projekten mit ProcessWire gemacht wird.
Ich hatte bereits mit vielen Projekten zu tun, wo Redakteure sehr lange Seiten erstellen wollten mit beliebigen Inhaltsblöcken. Erst soll ein Text erscheinen, dann eine Slideshow, dann eine Bildergalerie, dann wieder Text in einem grauen Kasten, dann x Downloads, dann wieder Text. Auf der nächsten Seite aber Text in grauem Block, Slideshow, Text in schwarzem Block, ...

ProcessWire bietet die Möglichkeit, beliebige Templates mit beliebigen Feldern zu definieren und damit diverse verschiedene und spezialisierte Seitentypen anzubieten. Zudem gibt es durch "Repeater"-Funktionen die Möglichkeit, Felder oder Fieldsets mehrfach einzusetzen. Wenn man das alles auf einer Pflegemaske abbilden möchte, entstehen aus meiner Erfahrung sehr lange Masken, wo Redakteure schon mal den Überblick verlieren. Zudem wären sehr viele verschiedene, sehr spezielle Seiten-Templates zu erstellen.

Ich verfolge in meinen Projekten daher den Weg, eigentlich nur ein Seiten-Template anzubieten ("page_standard"). Dazu kommt eine Reihe von ca. 20 Templates für "Inhaltselemente" oder "Content Elements". "Inhaltselemente" sind Blöcke wie z.B. Text/Bild, Video-Player, Audio-Player, Bilder-Galerie, Container für Inhaltselemente, Download oder auch HTML und PHP-Include-Code.
Inhaltselemente sind "Seiten", die unterhalb einer Web-Seite angelegt und auf dieser Web-Seite dargestellt werden.
Somit ist es möglich, Seiten mit beliebigen und beliebig vielen Inhaltselementen oder Blöcken zu erstellen - aber sowohl die Masken für die Seiten als auch für die Inhaltselemente bleiben übersichtlich.


Redakteure haben durch Eingabe von "CSS-Klassen" ("Stil-Attribute" oder "Befehle") die Möglichkeit, das Aussehen dieser Blöcke zu beeinflussen (z.B. soll ein Text-Block in einem grauen Kasten erscheinen).
Dafür wird entsprechende Dokumentation bereit gestellt.
Und natürlich erfolgt bei jedem Projekt eine CMS-Schulung.
Und dann stehe ich natürlich für Rückfragen zur Verfügung!