Erstellen einer Webseite
Diese Seite beinhaltet veraltete Komponenten, die nicht mehr im
Release 1.11 enthalten sind. Die Seite
befindet sich deshalb bis zum Entfernen dieser Meldung in einem Bearbeitungszustand. Sollten
Fragen auftauchen, können diese gerne im
Forum gestellt werden.
Das vorliegende Tutorial soll aufbauend auf den Ausführungen in den
Grundlagen
zeigen, wie auf einfache Weise eine Webseite mit den Mitteln des Adventure PHP Frameworks erstellt
werden kann. Um die Anleitung einfach zu gestalten wird von einem aufwändigen Design Abstand
genommen.
Die zu erstellende Webseite soll Platz für ein Key-Visual, einen Header-Bereich, ein Menü
und einen Bereich für den Inhalt und einen Footer bieten. Im Content-Bereich soll dynamischer
Inhalt abhängig von einem URL-Parameter angezeigt werden. Grafisch betrachtet soll die Seite
dann folgendes Aussehen haben:
An dieser Stelle geht der Autor davon aus, dass der Leser lediglich ein
Code-Pack (Pakete mit
dem Namen
apf-codepack-*.[zip | tar.gz | tar.bz2]) auf der
Download-Seite bezogen hat. Diese Pakete beinhalten
den Quellcode des Frameworks, die Strukturen einer Webseite bzw. die Konfigurationen werden nicht
mitgeliefert. Nun muss das Paket in einen beliebigen Ordner unterhalb des DocumentRoot des lokalen
Webservers entpackt werden. Um eine einheitliche Sprechweise zu haben, soll dieser Ordner
apps/ genannt werden. Aus Gründen der Übersichtlichkeit wird der Ordner
apps/ in einen Ordner
testwebsite/, der unter dem DocumentRoot des
Webservers erstellt wurde verschoben werden. Als weitere Schritte müssen nun die Strukturen
für die Webseite generiert und die nach
Grundlagen
notwenigen Konfigurationsdateien erstellt werden. Dazu ist folgende Vorgehensweise ratsam:
Hierzu soll unter
testwebsite/apps/ die Struktur
Code
sites/
testwebsite/
pres/
templates/
documentcontroller/
erstellt werden. Diese dient später zur strukturierten Aufnahme der Template- und Controller-
Dateien der Webseite.
Da das Framework für die Verwendung einer zentralen Bootstrap-Datei konzipiert wurde, über
die alle Requests der Besucher abgehandelt werden, muss diese nun im Ordner
testwebsite/
angelegt werden. Der Inhalt der Datei kann aus der aktuellen
index.php der
Dokumentationswebseite kopiert und wie folgt angepasst werden. Der Einfachheit wegen wird auf die
Verwendung des FrontControllers verzichtet, da auch dies die Handhabung für den Einsteiger
erleichtert.
PHP-Code
// Fehlermeldung konfigurieren (Es treten sonst Fehler wie unter
// http://forum.adventure-php-framework.org/de/viewtopic.php?f=7&t=32
// beschrieben auf!)
ini_set('html_errors','off');
// PageController einbinden
require_once('./apps/core/pagecontroller/pagecontroller.php');
// Seite erzeugen
$page = new Page();
// Template laden
$page->loadDesign('sites::testwebsite::pres::templates','website');
// Seite transformieren und ausgeben
echo $page->transform();
In der Code-Darstellung sind bereits implizit weitere Vereinbarungen über die Struktur des
Codes enthalten, die die weiteren Schritte beeinflussen.
Wie im Code-Ausschnitt der
index.php bereits festgelegt wurde, soll das zentrale Template
der Webseite unter dem Ordner
testwebsite/apps/sites/testwebsite/pres/templates
liegen und
website.html heißen. In dieser Datei legen wir nun das unter
Kapitel 2 beschriebene HTML-Gerüst an und sehen die einzelnen Bereichen darin vor. Die Datei
hat damit - gekürzt dargestellt - folgenden Inhalt:
APF-Template
<html>
<head>
<title>TestWebSite</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
[..]
</style>
</head>
<body>
<center>
<table width="800" border="0" cellpadding="0" cellspacing="0" class="table_layout">
<tr>
<td class="table_keyvisual">
K e y
<br />
V i s
<br />
u a l
</td>
<td class="table_header">
Header
</td>
</tr>
<tr>
<td class="table_menu">
<br />
Startseite
<br />
Impressum
</td>
<td class="table_content">
Content
</td>
</tr>
</table>
</center>
</body>
</html>
Damit kann nach Starten des Webservers (z.B. XAMPP, oder eine lokale Apache- oder IIS-Installation
mit PHP 4 oder 5 als Modul) durch Aufruf der URL
Code
http://localhost/testwebsite/
die Test-Webseite bereits betrachtet werden.
Damit die zentralen Bereiche wie Header, Menü und Inhalt nicht auf jeder Inhaltsseite gepflegt
werden müssen, werden diese in eigene Templates ausgelagert und an den entsprechenden Stellen
eingebunden. Dazu werden drei weitere Template-Dateien unter
testwebsite/apps/sites/testwebsite/pres/templates
angelegt:
-
header.html: Inhalte des Headers
-
menu.html: Inhalte des Menüs
-
content.html: Inhalte der Webseite
Die Template-Datei
website.html wird wie folgt geändert/ergänzt:
Html-Code
<html>
<head>
<title>TestWebSite</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
[..]
</style>
</head>
<body>
<center>
<table width="800" border="0" cellpadding="0" cellspacing="0" class="table_layout">
<tr>
<td class="table_keyvisual">
K e y
<br />
V i s
<br />
u a l
</td>
<td class="table_header">
<core:importdesign
namespace="sites::testwebsite::pres::templates"
template="header"
/>
</td>
</tr>
<tr>
<td class="table_menu">
<core:importdesign
namespace="sites::testwebsite::pres::templates"
template="menu"
/>
</td>
<td class="table_content">
<core:importdesign
namespace="sites::testwebsite::pres::templates"
template="content"
/>
</td>
</tr>
</table>
</center>
</body>
</html>
Die Beschreibung des
<core:importdesign />-Tags findet sich auf der Seite
Standard TagLibs. Die drei genannten
Dateien haben dabei folgenden Inhalt:
header.html:
menu.html:
APF-Template
<br />
Startseite
<br />
Impressum
content.html:
Damit sind die Vorkehrungen getroffen, zentrale Elemente und den Inhalte der Webseite unabhängig
vom Design derselben pflegen zu können. Der Aufruf der URL
APF-Template
http://localhost/testwebsite/
sollte nun eine zu Kapitel 3.4. identische Ausgabe im Browser zeigen.
Aufbauend auf der unter Kapitel 4 skizzierten Trennung der Webseite in einzelne Views, soll nun in
einem weiteren Schritt aufgezeigt werden, wie es möglich ist, die Webseite mit dynamischen
Inhalten zu bestücken. Dabei sollen die Inhalte abhängig vom URL-Parameter
Page ausgegeben werden. Dazu muss zunächst das Menü angepasst werden,
damit bei Klick auf die Menü-Punkte auch die gewünschte Seite angefragt wird. Das
funktioniert nun wie folgt:
menu.html:
APF-Template
<br />
<a href="./?Seite=Startseite">Startseite</a>
<br />
<a href="./?Seite=Impressum">Impressum</a>
Beim Klick auf die beiden Menüpunkte wird die Seite selbst (Datei
index.php) aufgerufen
und mit dem Parameter
Page ausgestattet. Um nun abhängig der Request-Variable
Page Inhalte im Inhaltsbereich anzeigen zu können bedarf es einer dynamischen
Komponente. Hier stehen dem Entwickler zwei Möglichkeiten zur Verfügung, die das Framework
out-of-the-box bietet.
Eine sehr einfache Möglichkeit ist es, dynamische Inhalte aus Text-Dateien im Inhaltsbereich
darzustellen. Zu diesem Zweck bietet das Framework die unter
Standard-Taglibs, Kapitel 3.1,
dokumentierte TagLib
<doc:createobject />. Diese muss gemäß den
oben festgelegten Anforderungen entsprechend konfiguriert werden. Die Bibliothek erwartet, dass die
sprachabhängigen Inhaltsdateien unter dem Ordner
./frontend/content/ liegen,
der parallel zur Bootstrap-Datei existieren muss. Vorrausgesetzt, die Inhalte sollen in deutscher
Sprache angezeigt werden, ist es notwendig für die beiden Beispiele die Dateien
- ./frontend/content/c_de_startseite.html
- ./frontend/content/c_de_impressum.html
mit den gewünschten Inhalten anzulegen. Da der Content im Inhaltsbereich angezeigt werden soll
muss die dafür verantwortliche Template-Datei wie folgt abgeändert werden:
content.html
APF-Template
<core:addtaglib namespace="tools::html::taglib" prefix="doc" class="createobject" />
<doc:createobject requestparam="Seite" defaultvalue="Startseite" />
Hinweis:
Die TagLib erwartet, dass die Dateinamen nur Kleinbuchstaben enthalten. Auf Windows-Maschinen ist
dies zwar zunächst unerheblich, überträgt man die Applikation jedoch auf einen
LINUX-Rechner, wird die angesprochene Datei nicht gefunden!
Eine weitere Möglichkeit bietet die Variante, die Inhalte aus einer Datenbank zu lesen und in
den Inhaltsbereich der Seite einzubetten. Hierzu kann der Entwickler Gebrauch von einem
DocumentController machen, der dazu gedacht ist, dynamischen Inhalt zu erzeugen.
Zunächst muss dazu eine Tabelle in der Datenbank freier Wahl erzeugt werden, die den Inhalt
aufnimmt. Diese kann mit folgendem SQL-Statement erzeugt werden:
APF-Template
CREATE TABLE demopage_content (
PageID tinyint(5) NOT NULL auto_increment,
PageURLName varchar(50) NOT NULL default '',
PageTitle varchar(50) NOT NULL default '',
PageContent text NOT NULL,
PRIMARY KEY (PageID),
UNIQUE KEY PageURLName (PageURLName),
KEY PageTitle (PageTitle)
) ENGINE=MyISAM;
Ähnlich der unter 5.1. gezeigten Änderung muss nun die Datei
content.html
angepasst werden:
APF-Template
<@controller
namespace="sites::testwebsite::pres::documentcontroller"
file="content_v1_controller"
class="content_v1_controller"
@>
Mit diesem XML-Tag wird dem PageController bekannt gemacht, dass zur Verarbeitung des aktuellen
Templates einen Controller im Sinne des MVC-Patterns zu verwenden ist. Wie unter
Controller beschrieben wird, ist ein
DocumentController eine von der Klasse
baseController abgeleitete
PHP-Klasse, die mit Hilfe standardisierter Methoden und Tools bei der Transformation des DOM-Baumes
dynamischen Inhalt generiert.
Da die Inhalte aus der Datenbank gelesen werden wird zur Konnektierung der Datenbank die Komponente
MySQLHandler verwendet. Deren Instanz kann über die private Methode
__getServiceObject() des DocumentControllers bezogen werden. Die Logik des
Controllers wird, wie im Manual beschrieben, in die Funktion
transformContent()
eingebettet. Die Controller-Datei
testwebsite/apps/sites/testwebsite/pres/documentcontroller/content_v1_controller.php
soll mit folgendem Inhalt gefüllt werden:
PHP-Code
import('core::database','MySQLHandler');
class content_v1_controller extends baseController {
function content_v1_controller(){
}
function transformContent(){
// Instanz der Datenbank-Abstraktionsklasse holen
$SQL = $this->__getServiceObject('core::database','MySQLHandler');
// URL-Parameter beziehen
$page = RequestHandler::getValue('Seite','Startseite');
// Parameter gegen SQL-Injections absichern
$page = $SQL->escapeValue($Page);
// Inhalt der Seite auslesen
$select = 'SELECT PageContent
FROM demopage_content
WHERE PageURLName = \''.$page.'\'
LIMIT 1';
$result = $SQL->executeTextStatement($select);
$data = $SQL->fetchData($result);
// Inhalt der Seite ausgeben
$this->__Content = $data['PageContent'];
}
}
Der Quelltext des Controllers sollte selbstredend sein. Im Groben beschrieben wird hier nichts anderes
in PHP-Code abgebildet, wie in einem herkömmlichen Script auch stehen würde.
Um auf die Datenbank zugreifen zu können erwartet die MySQL-Komponente eine Konfigurationsdatei
unter dem Pfad
Code
testwebsite/apps/config/core/database/sites/testwebsite/DEFAULT_connections.ini
Der Dateiname setzt sich aus dem Pfad
Code
testwebsite/apps/config/core/database/{CONTEXT}/
und dem Namen
Code
{ENVIRONMENT}_connections.ini
zusammen. Dabei entspricht
{CONTEXT} dem Context der aktuellen Applikation,
der in der
index.php bereits implizit beim Laden des Templates gesetzt wurde und
sites::testwebsite lautet. Implementierungsdetails können in der
API-Dokumentation der Klasse
Page nachgelesen werden. Im obigen Code war hier die Zeile
PHP-Code
$page->loadDesign('sites::testwebsite::pres::templates','website');
, genauer, der erste Parameter der Methode
loadDesign() ausschlaggebend. Der Wert für
ENVIRONMENT wird aus der Registry bezogen und ist standardmäßig auf
DEFAULT gesetzt. Der Inhalt der Konfiguration muss an die lokale Datenbank-Installation
angepasst werden, genügt jedoch folgendem Schema:
APF-Konfiguration
[MySQL]
DB.Host = "" ; Servername oder IP-Adresse der Datenbank
DB.User = "" ; Benutzer
DB.Pass = "" ; Passwort
DB.Name = "" ; Name der Datenbank
Die vorliegende Webseite zeigt nun aus einer Textdatei oder Datenbank stammende dynamische Inhalten
an. Ein Manko der Implementierung liegt noch darin, dass nicht abgefangen wird, ob ein Inhalt
tatsächlich in der Datenbank existiert. Im Fall eines nicht vorhandenen Datenbank-Inhalts wird
keine Fehlerseite ausgegeben, bei Verwendung der Datei-Variante ist dies bereits in der TagLib
vorgesehen.
Darüber hinaus fehlt bei der in Kapitel 5.2 beschriebenen Vorgehensweise die Möglichkeit,
eine Seite zu erstellen, zu pflegen und zu löschen. Diese Aufgabe kann im Moment lediglich mit
einem Datenbank-Administrationstool wie
PHPMyAdmin
oder einem dafür erstelltes Tool erledigt werden.
Der Einfachheit wegen wurde in diesem Tutorial darauf verzichtet eine korrekte 3-Schicht-Implementierung
aufzuzeigen, da dies den Schwierigkeitsgrad erheblich erhöht hätte. Fortgeschrittene
Benutzer sollten jedoch die Datenbank-Kommunikation nicht direkt in einem DocumentController vornehmen,
sondern eine Business-Komponente eingeführen, die dem Controller ein "Inhalts-Domain-Objekt" liefert,
das dieser dann anzeigt. Diese kümmert sich dann um die Bereitstellung einer Fehlerseite, sollte
die vom Benutzer gewünschte Seite nicht existieren. Konsequenterweise greift die Business-Komponente
auf eine Service-Komponente der Daten-Schicht zurück, die schließlich die Daten physikalisch
aus der Datenbank bezieht. Innerhalb der Datenschicht kann dann Gebrauch vom
MySQLHandler
gemacht werden um die relevanten Daten aus der MySQL-Datenbank zu laden. Weitere Anregungen bieten
hier die Tutorials
Die in diesem Tutorial erstellten Dateien können unter
tutorial_testwebsite.zip
heruntergeladen werden. Nicht im Archiv enthalten sind die Quellcodes des Frameworks, da diese,
wie bereits erwähnt, auf der
Download-Seite
bezogen werden können.
Kommentare
Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese
hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
1
Marc Dannemann
31.05.2009, 11:24:42
In der APF-Version, die ich im Moment verwende (1.9) ist der Pfad für die MySQL-Konfiguration nicht mehr so, wie im Tutorial beschrieben. Statt "/config/core/sites/testwebsite/DEFAULT_connections.ini" muss dieser Pfad nun um die Komponente "Database" erweitert werden. Der vollständige Pfad lautet demnach "/config/core/database/sites/testwebsite/DEFAULT_connections.ini"
Mfg Marc
2
Christian
08.06.2009, 23:39:14
Hallo Marc,
richtig, im Pfad fehlt ein "database". Ich habe das nun nachgetragen.
Vielen Dank,
Christian