5.8 Content Management System (CMS)

Da oftmals von Content Management Systemen die Rede ist, möchte ich Ihnen in diesem Unterkapitel zeigen wie Sie sich kurzerhand eines selbst entwickeln können. Prinzipiell ist Content Management, also das Verarbeiten von Inhalten ja nichts anderes als das Hinzufügen, Bearbeiten und Entfernen von Daten. Ein System dafür zu haben bedeutet für mich, die Webseiteninhalte über einen gesonderten Bereich pflegen zu können ohne dafür eine Entwicklungsumgebung zu öffnen oder die Daten über eine gesonderte Webanwendung wie phpMyAdmin verwalten zu müssen. Den ersten Schritt in diese Richtung haben Sie bereits mit dem letzten Kapitel getan, indem Sie dem Nutzer die Möglichkeit gegeben haben, Daten über ein Formular abzuschicken und in der Datenbank zu speichern. Was nun letztendlich fehlt ist die Ausgabe der Daten und die Möglichkeiten, diese zu editieren oder sogar zu löschen. Ziel dieses Unterkapitels ist es, Ihnen diese fehlenden Schritte zu vermitteln, so dass Sie darauf aufbauend ein eigenes CMS entwickeln könnten. Sicherlich gehört dazu im großen Stil auch noch eine Nutzerverwaltung mit Berechtigungen und einiges mehr, aber ich bin mir sicher, dass dies mit genügend Übung auch keinerlei Problem für Sie darstellt.

Daten ausgeben

Erstellen Sie sich zunächst einen neuen Ordner namens cms in Ihrem Projektverzeichnis unterhalb des htdocs-Ordners. Darin legen Sie die Dateien reports.php und reports.tpl an.

PHP

Bereits mit minimalem Quellcode ist es möglich, die Inhalte aus der Datenbank zu laden. Quellcode 1 zeigt die Datei reports.php.

Quellcode 1 - PHP Über die Methode MergeBlock werden die Daten in der reports.php für das Template geladen.
  1. <?php
  2.   include('../overall_header.php');
  3.  
  4.   $title = 'Feedback - CMS';
  5.   $note = '';
  6.    
  7.   // Datenbankverbindung herstellen
  8.   $db = mysql_connect('localhost', 'root', '') or die ('Keine Verbindung moeglich');
  9.   mysql_select_db('webdesign-tutorial', $db) or die ('Die Datenbank existiert nicht');
  10.  
  11.   include('../overall_footer.php');
  12.   $TBS->LoadTemplate('reports.tpl', FALSE);
  13.   $TBS->MergeBlock('report', $db, 'SELECT id, email, content FROM reports');
  14.   $TBS->Show();
  15. ?>

In Zeile 8 und 9 wird wie bereits beim Einfügen der Daten eine Verbindung zur Datenbank hergestellt. Wenn Sie die Datenbank oft benötigen lohnt es sich, die Verbindung bereits in der overall_header.php herzustellen oder den Quellcode in eine separate PHP-Datei auszulagern, so dass Sie diese lediglich mit dem include-Befehl einbinden müssen.
Neu in diesem Skript ist Zeile 13. Dort wird die Methode MergeBlock aufgerufen, die in Ihrem Template nach den entsprechenden Templatevariablen sucht und diese durch die Werte ersetzt, die aus der Datenbank kommen. Eine Zeile wird dabei als Block bezeichnet, der so oft wiederholt wird bis alle Daten aus der Tabelle ausgelesen wurden. Die Templatevariable habe ich in diesem Beispiel report genannt. Anschließend übergebe ich der MergeBlock-Methode eine Datenquelle und den entsprechenden Query.
Wichtig: Da die Inhalte im Template ersetzt werden, muss dieses zuvor angegeben worden sein. Die Methode MergeBlock muss daher immer nach dem Laden des Templates und vor der Darstellung durch die Show-Methode aufgerufen werden.

Template

Die Ausgabe der Inhalte in der Templatedatei reports.tpl ist bereits durch wenige Zeilen Quellcode möglich, wie dies Quellcode 2 zeigt. Auch wenn für die Datenausgabe vorerst kein Hinweis an den Nutzer notwendig ist, binde ich das bereits bekannte Konstrukt für die note-Variable unter der h1-Überschrift ein.

Quellcode 2 - HTML In der Templatedatei reports.tpl werden die einzelnen Einsendungen der Nutzer dargestellt.
  1. [onload;file=../overall_header.tpl]
  2.  
  3. <h1>Feedback</h1>
  4.  
  5. <p>
  6.   <b>[var.note;magnet=p]</b>
  7. </p>
  8.  
  9. <div>
  10.   E-Mail von <b>[report.email;block=div]</b>:<br />
  11.   [report.content]
  12.   <p>
  13.     <a href="[var.domain]/cms/reports.php?a=edit&id=[report.id]">Feedback editieren</a> |
  14.     <a href="[var.domain]/cms/reports.php?a=delete&id=[report.id]">Feedback löschen</a>
  15.   </p>
  16.   <hr/>
  17. </div>
  18.  
  19. [onload;file=../overall_footer.tpl]

Die zuvor im PHP-Teil definierte Templatevariable wird im Template wie in Zeile 10 angesprochen. Vor dem Punkt steht der Blockname, dahinter der Feldname in der MySQL-Tabelle, aus der Sie die Daten auslesen. Zusätzlich können Sie die den Block für die Templatevariable definieren, indem Sie bei einem beliebigen report-Element das Konstrukt block=div hinzufügen. In diesem Beispiel ist der äußere div-Container das Blockelement, so dass dieser solange wiederholt wird, bis alle Zeilen aus der Datenbank ausgelesen wurden. Setzen Sie die Block-Eigenschaft nicht, so wird lediglich ein Datensatz ausgegeben.
Selbstverständlich können Sie auch andere HTML-Elemente als Blockelement definieren.
In Zeile 13 und 14 definiere ich zudem zwei Links, an welche die Id aus der Datenbank übergeben wird. Dabei handelt es sich um GET-Parameter, die Sie einer PHP-Datei übergeben können, indem Sie diese mit einem Fragezeichen anhängen. Vor dem Gleichheitszeichen steht der Variablenname, dahinter der Wert. Weitere GET-Parameter werden über das kaufmännische Und angehangen.

Zusammenfassung

Ein mögliches Vorgehen zur Verwaltung der Daten ist es also, die Inhalte aus der Datenbank auszulesen und dabei die Id dazu zu verwenden, die jeweiligen Datensätze eindeutig zu markieren. Ein zum Datensatz definierter Link erhält diese Id und übergibt diese beim Klick darauf an das Skript, so dass dieses weiß, welcher Datensatz editiert bzw. gelöscht werden soll. Die Ausgabe der Daten sieht in meinem Beispiel wie in Abbildung 1 aus.

Abbildung 1Im CMS werden alle durch den Nutzer eingegebenen Daten angezeigt.
Abbildung 1

Daten bearbeiten und löschen

Um das Content Management System in den wesentlichen Teilen fertigzustellen fehlen noch die Möglichkeiten, die Datensätze bearbeiten bzw. löschen zu können. Dazu verwende ich einfach die beiden bereits existierenden Dateien reports.php und reports.tpl, wobei Letztere bereits zwei Links zum Bearbeiten bzw. Löschen enthält und somit nicht mehr angepasst werden muss.
Zusätzlich lege ich der Einfachheit halber eine Datei reports_edit.tpl an über die der Datensatz editiert werden kann. Dafür könnten Sie auch die Datei report.tpl vom Einfügen verwenden, aber um das Beispiel übersichtlich zu halten verwende ich dafür eine leicht modifizierte neue Datei.

PHP

Auch wenn Ihnen Quellcode 3 zunächst recht viel erscheinen mag, so sind die Änderungen dennoch leicht zu verstehen. Die Grundidee dabei ist es, zusätzliche Parameter über die URL zu übergeben und dementsprechend eine Editier- oder Löschaktion auszuführen. Zudem soll zum Editieren ein anderes Template geladen werden, in dem die Daten in ein Formular geladen und gespeichert werden können.

Quellcode 3 - PHP Die Datei reports.php wurde um die Möglichkeiten erweitert, einen Datensatz bearbeiten und löschen zu können.
  1. <?php
  2.   include('../overall_header.php');
  3.  
  4.   $title = 'Feedback - CMS';
  5.   $note = '';
  6.   $template = 'reports.tpl';
  7.   $report_query = 'SELECT id, email, content FROM reports';
  8.    
  9.   // Datenbankverbindung herstellen
  10.   $db = mysql_connect('localhost', 'root', '') or die ('Keine Verbindung moeglich');
  11.   mysql_select_db('webdesign-tutorial', $db) or die ('Die Datenbank existiert nicht');
  12.  
  13.   if(isset($_GET['a']))
  14.   {
  15.     $action = $_GET['a'];
  16.     $report_id = $_GET['id'];
  17.    
  18.     switch($action)
  19.     {
  20.       case 'edit':
  21.         $template = 'reports_edit.tpl';
  22.         $report_query = "SELECT * FROM reports WHERE id=$report_id LIMIT 1";
  23.       break;
  24.  
  25.       case 'saveedit':
  26.         $new_email = $_POST['email'];
  27.         $new_content = $_POST['content'];
  28.         $update_query = mysql_query("UPDATE reports SET email='$new_email', content='$new_content' WHERE id=$report_id LIMIT 1", $db);
  29.         if($update_query)
  30.           $note = 'Der Eintrag wurde erfolgreich editiert.';
  31.         else
  32.           $note = 'Der Eintrag konnte nicht editiert werden.';
  33.       break;
  34.  
  35.       case 'delete':
  36.         $delete_query = mysql_query("DELETE FROM reports WHERE id=$report_id LIMIT 1", $db);
  37.         if($delete_query)
  38.           $note = 'Der Eintrag wurde erfolgreich gelöscht.';
  39.         else
  40.           $note = 'Der Eintrag konnte nicht gelöscht werden.';
  41.       break;
  42.     }
  43.   }
  44.  
  45.   include('../overall_footer.php');
  46.   $TBS->LoadTemplate($template, FALSE);
  47.   $TBS->MergeBlock('report', $db, $report_query);
  48.   $TBS->Show();
  49. ?>

In Zeile 6 und 7 definiere ich zunächst das Standard-Template und die Standard-Query, die für das Laden der Datensätze zuständig ist.
Ab Zeile 13 wird zwischen verschiedenen Fällen unterschieden, indem zunächst die GET-Parameter in Zeile 15 und 16 ausgelesen werden. Anschließend entscheidet die Variable $action darüber, welche Aktion ausgeführt werden soll. Der erste Fall in Zeile 20 ist das Editieren eines Datensatzes. Dazu soll ein anderes Template geladen und eine andere Query ausgeführt werden. Der Unterschied dabei ist es, dass lediglich ein Datensatz geladen werden soll, nämlich der, dessen Id übergeben wurde.
Der nächste Fall tritt in Zeile 25 auf, wenn das Formular zum Editieren des Datensatzes abgeschickt wurde. Der Nutzer hat die Daten bearbeitet und möchte diese nun speichern. Dazu werden wie bereits beim Erstellen eines neuen Datensatzes die POST-Parameter der Felder des Formulars ausgelesen. Anschließend wird in Zeile 28 ein Update auf die Tabelle ausgeführt, über welches der Datensatz aktualisiert wird. Wurde die Anfrage an die Datenbank ausgeführt, so wird ein entsprechender Hinweis ausgegeben.
Der letzte Fall ab Zeile 35 sorgt für die Funktionalität, einen Datensatz löschen zu können. Dazu wird einfach eine Anfrage an die Datenbank gestellt, bei der die Zeile mit der übergebenen Id gelöscht wird.
Wichtig: Um das Beispiel möglichst einfach zu halten, habe ich keine Sicherheitsmaßnahmen eingebaut. Sie sollten beispielsweise immer überprüfen, ob das was da als GET-Parameter übergeben wurde überhaupt stimmen kann. Zudem empfiehlt es sich oftmals, einen Datensatz nicht zu löschen, sondern lediglich zu flaggen. Das bedeutet, dass Sie in der Tabelle eine zusätzliche Spalte haben, in der entweder eine 1 oder eine 0 steht. Wenn der Wert 0 ist, können Sie so tun als würde dieser nicht existieren, indem Sie eine Anfrage an die Datenbank stellen, die lediglich Zeilen mit dem Wert 1 zurück gibt. Dies hat den Vorteil, dass Sie einen Datensatz nicht unbeabsichtigt löschen, denn einmal gelöscht kann dieser nicht wieder hergestellt werden.

Template

Um das Beispiel zu komplettieren fehlt die Templatedatei reports_edit.tpl, die in Quellcode 4 dargestellt wird. Dieses Template soll geladen werden, wenn ein Datensatz editiert wird.

Quellcode 4 - HTML Die Templatedatei reports_edit.tpl ähnelt der bereits definierten Datei zur Erfassung der Daten.
  1. [onload;file=../overall_header.tpl]
  2.  
  3. <h1>Feedback bearbeiten</h1>
  4.  
  5. <form name="report_form" method="post" action="[var.domain]/cms/reports.php?a=saveedit&id=[report.id]">
  6.   <p>
  7.     E-Mail-Adresse:<br />
  8.     <input type="text" name="email" value="[report.email]" size="50" />
  9.   </p>
  10.  
  11.   <p>
  12.     Feedback:<br />
  13.     <textarea cols="60" rows="5" name="content">[report.content]</textarea>
  14.   </p>
  15.   <p>
  16.     <input type="submit" name="submit" value="Absenden" />
  17.   </p>
  18. </form>
  19.  
  20. [onload;file=../overall_footer.tpl]

Das Formular dürfte Ihnen bekannt vorkommen. Es ähnelt wie bereits beschrieben dem Formular, das beim Hinzufügen eines Datensatzes Verwendung findet. Was geändert werden musste ist das Ziel der action, also die Seite, die nach dem Absenden des Formulars aufgerufen wird. An diese Datei übergibt das Formular neben den POST-Parametern (email, content, submit) zusätzlich zwei GET-Parameter (a, id) die dafür sorgen, dass die Editieren-Aktion gespeichert wird.
Um die Inhalte in das Formular zu laden, müssen Sie zudem die beiden Parameter als Initialwerte der Textfelder angeben. Bei einem input-Feld müssen Sie dazu lediglich die value-Eigenschaft setzen und bei einer textarea genügt das setzen des Wertes zwischen den Tags, wie in Zeile 13 gezeigt.

Zusammenfassung

In diesem Unterkapitel habe ich Ihnen gezeigt, wie Sie Inhalte aus einer Datenbank auslesen und darstellen können. Zusätzlich haben Sie gesehen, wie Sie diese Inhalte über Ihre Webseite pflegen können, indem Sie die Möglichkeit schaffen, diese editieren bzw. löschen zu können. Wenn Sie dieses Prinzip verstanden haben, können Sie bereits große Teile eines Content Mangement Systems abbilden, denn letztendlich sind es immer ähnliche Aktionen, die durch den Nutzer ausgeführt werden.
< 5.7 Formulare verarbeiten 6 Optimierung >