<?php print $content; ?>
Hallo zusammen,
ich hätte da eine kleine Frage bezüglich des <head> Bereichs auf meiner Website. Damals als ich mir PHP angelernt hab (ist schon ein Weilchen her...) schien es gängiger Standart zu sein das man den kompletten Bereich in eine php-Datei (z.B.: layout/header.inc.php) auslagert ud einfach in alle Seiten dann einbindet.
Nun beschäftige ich mich in dieser Woche zum ersten Mal vermehrt mit SEO und allem was so dazu gehört.
Die Kernaussage vieler Grundlagen-Artikel ist, dass man eben diesen <head> Bereich für jede Seite individuell gestalten sollte (meta-description, keywords <title> etc.). Ergibt ja irgendwie auch Sinn <i class="far fa-smile-wink"></i> <br />Wie habt ihr das Ganze denn gelöst? Lasst ihr euch per selbstdefinierter Funktion einen Kopfbereich generieren oder arbeitet ihr mit dem altbewährten Mittel copy-paste und ändert dann einfach die entsprechenden Attribute ab ? <br /> <br />Mit freundlichen Grüßen <br />Euer Pohl</p></title>
Hallo Johannes,
Es stellt sich die Frage, wie Du Deinen Content abrufst. Die wohl aktuellste Methode ist den Content aus einer Datenbank zu holen. Das denke ich, ist dann am einfachsten.
Die Eingabe für einen Artikel in etwa so, wenn kein CMS verwandt wird
$article->setContent(\'der Inhalt\');
$article->setMeta(\'description\',\'hier meine Beschreibung\');
Ausgabe
$article->renderHead();// Alle Meta an den Head-Tag übergeben
$article->renderContent();
So geht es fix, Artikel und Metas liegen beieinander.
Geht es um Deine Seite, wie in der Signatur?
Denke da kann man besser ein CMS nehmen.
Wenn alles so gut wie statisch ist auf jeden Fall eine TemplateEngine benutzen. Die vlibTemplate hat sich bei mir über die Jahre bewehrt.
Hallo Roman,
vielen Dank für deine Antwort. Ich denke ich werde es jetzt ähnlich wie von dir vorgeschlagen lösen und alle <head> - Daten in eine DB-Tabelle auslagern. Am Beginn jeder Seite lege ich dann die Rubrik fest und rufe die dementsprechenden Daten ab.
Das vlib-Template werde ich mir anschauen, danke für den Tip!
Viele Grüße
Johnny
P.S.: Mir fällt gerade erst auf, dass der Vorname ja angezeigt wird
Template-Engines wie z.B. Smarty sind so eine Sache für sich, die einen schwören auf sie, die anderen verteufeln sie. Ich gehöre eher zur zweiten Gruppe. Das heißt nicht, dass man die Ausgabe nicht vom Rest trennen sollte, aber die meisten Template-Engines sind unnötig aufgebläht und letztendlich bringt PHP alles von Haus aus mit, was man für eine gute Template-Engine benötigt.
Das ist aber ein Thema für sich, ich lass einfach mal drei Links zur Ansicht da, wer will kann ja ein wenig schmökern und sich seine eigene Meinung bilden:
http://php-coding-standard.de/php_template_engine.php
http://michaelbertsch.eu/blog/minimalistische-template-engine-fuer-php
http://mylittlehomepage.net/de/sonstiges/ueber-den-sinn-von-php-template-engines
Kommen wir zum eigentlichen Thema, dem Seitenlayout:
romacron schrieb:
Ausgabe
$article->renderHead();// Alle Meta an den Head-Tag übergeben
$article->renderContent();
So geht es fix, Artikel und Metas liegen beieinander.
Genau dort liegt das Probem, Artikel und Seitenlayout sollten schlicht und einfach nicht beieinander liegen. Klar, es funktioniert, aber es macht Probleme. Was wenn du mal keinen Artikel auf der Seite hast, und trotzdem einen Meta-Tag setzen möchtest? Klar könnte man dann eine weitere Klasse schreiben, aber das führt letztendlich zu Duplikationen, die man so gut es geht vermeiden sollte. (Vielleicht war deine Namensgebung auch einfach falsch gewählt.)
Um das ganze möglichst wiederverwendbar zu machen, sollte man versuchen, das ganze zu abstrahieren.
Ich nutze in diesem Beispiel eine erdachte Template-Engine mit nachfolgendem Interface. Die meisten Template-Engines nutzen ein ähnliches Interface, darum gehe ich hier nicht auf die genauere Implementierung ein, jeder kann hier gerne seine favorisierte Template-Engine nutzen. Man sollte allerdings darauf achten, das Seitenlayout und die Template-Engine voneinander getrennt zu halten, um einen eventuellen späteren Wechsel der Template-Engine möglichst einfach vornehmen zu können. <?php
/**
* Template-Engine, damit wir keinen Spaghetti-Code bekommen
*/
interface TemplateEngine
{
/**
* Setzt den Pfad zur einzubindenen Template-Datei.
*
* @param string $sScript
* @return TemplateEngine
*/
public function setScript($sScript);
/**
* Setzt die Variablen, die in der Template-Datei zur Verfügung stehen sollen.
*
* @param array $aVars
* @return TemplateEngine
*/
public function setVars(array $aVars);
/**
* Parst die aktuelle Template-Datei mit den aktuell gesetzten Variablen
* und gibt ihren Inhalt zurück.
*
* @return string
*/
public function render();
}
Wir haben eine Seite, die verschiedene Eigenschaften hat. Dementsprechend benötigen wir eine Klasse, die das widerspiegelt und deren Aufgabe es ist, aus den verschiedenen Eigenschaften das Layout zu erstellen. <?php
/**
* Eine Klasse zum Verwalten des Seitenlayouts.
*/
class Layout
{
/**
* Die Template-Engine, die das Layout nutzen soll
*
* @var TemplateEngine
*/
protected $_oTemplateEngine;
/**
* Die einzelnen Variablen, die in unserem Layout nachher zur Verfügung
* stehen
*
* @var array
*/
protected $_aVars = array();
/**
* Setzt die Template-Engine für das Layout.
*
* @param TemplateEngine $oTemplateEngine
* @return Layout
*/
public function __construct(TemplateEngine $oTemplateEngine)
{
$this->_oTemplateEngine = $oTemplateEngine;
$this->_aVars[\'css\'] = array();
$this->_aVars[\'js\'] = array();
}
/**
* Setzt den eigentlichen Inhalt der Seite.
*
* @param string $sContent
* @return Layout
*/
public function setContent($sContent)
{
$this->_aVars[\'content\'] = $sContent;
return $this;
}
/**
* Setzt den Inhalt der linken Sidebar.
*
* @param string $sContent
* @return Layout
*/
public function setLeftSidebar($sContent)
{
$this->_aVars[\'leftSidebar\'] = $sContent;
return $this;
}
/**
* Setzt den Inhalt der rechten Sidebar.
*
* @param string $sContent
* @return Layout
*/
public function setRightSidebar($sContent)
{
$this->_aVars[\'rightSidebar\'] = $sContent;
return $this;
}
/**
* Setzt den Titel der Seite.
*
* @param string $sTitle
* @return Layout
*/
public function setTitle($sTitle)
{
$this->_aVars[\'title\'] = $sTitle;
return $this;
}
/**
* Setzt die Meta-Beschreibung der Seite.
*
* @param string $sMetaDescription
* @return Layout
*/
public function setMetaDescription($sMetaDescription)
{
$this->_aVars[\'metaDescription\'] = $sMetaDescription;
return $this;
}
/**
* Fügt eine externe CSS-Datei hinzu.
*
* @param string $sPath
* @return Layout
*/
public function addCssFile($sPath)
{
$this->_aVars[\'css\'][] = $sPath;
return $this;
}
/**
* Fügt eine externe JavaScript-Datei hinzu.
*
* @param string $sPath
* @return Layout
*/
public function addJsFile($sPath)
{
$this->_aVars[\'js\'][] = $sPath;
return $this;
}
/**
* Setzt den Pfad zur Template-Datei.
*
* @param string $sPath
* @return Layout
*/
public function setLayoutScript($sPath)
{
$this->_sLayoutScript = $sPath;
return $this;
}
/**
* Fügt die gegebenen Daten zusammen und gibt sie zurück.
*
* @return string
*/
public function render()
{
return $this->_oTemplateEngine
->setScript($this->_sLayoutScript)
->setVars($this->_aVars)
->render();
}
}
Die Layout Klasse besitzt nun eine Reihe von Eigenschaften, die wir an jeder Stelle in unserem Script ändern können. Es gibt natürlich eine längere Liste von Eigenschaften und verschiedene Möglichkeiten, diese in die Klasse einzufügen. Im Grunde müsste zumindest viele Eigenschaften wieder abstrahieren oder einige zu Unterklassen zusammenfassen und es fehlen auch noch viele Funktionalitäten, aber ich denke zum Nachvollziehen ist diese Klasse erstmal geeigneter.
So, wie wird das ganze jetzt verwendet? Nun, in der Regel haben wir ja für die meisten Seiten ein Standart-Layout und verschiedene CSS-Dateien, die wir auf jeder Seite einbinden. Für können also z.B. am Anfang unseres Scripts folgendes machen: <?php
$oLayout = new Layout($oTemplateEngine);
$oLayout->addCssFile(\'base.css\');
$oLayout->setLayoutScript(\'layout.phtml\');
Die layout.phtml sieht dann z.B. so aus: <html>
<head>
<title><?= $title; ?></title>
<meta name="description" content="<?= $metaDescription; ?>" />
<?php foreach ($css AS $file): ?>
<link rel="stylesheet" type="text/css" href="<?= $file; ?>" />
<?php endforeach ?>;
</head>
<body>
<?php print $leftSidebar; ?>
<?php print $content; ?>
<?php print $rightSidebar; ?>
<?php foreach ($js AS $file): ?>
<script src="<?= $file; ?>"></script>
<?php endforeach ?>;
</body>
</html>
Irgendwann im Laufe des Scripts setzen wir dann z.B. den Inhalt der linken und rechten Sidebar, des Footers oder vergleichbarer Dinge (Letzte Beiträge, Navigation, neuste Artikel etc.): <?php
$oLayout->setLeftSidebar(\'irgendein inhalt für die linke seite\');
$oLayout->setRightSidebar(\'irgendein inhalt für die rechte seite\');
Je nach URL geht die Arbeit dann in irgendeiner include-Datei weiter und erst hier kennen wir dann oft den Titel: <?php
$oLayout->setTitle($sTitle);
$oLayout->setMetaDescription($sDescription);
$oLayout->setContent($sContent);
Der Vorteil liegt auf der Hand: Wir können den Titel (und sämtliche anderen Eigenschaften) dynamisch setzen, ohne dass wir uns in irgendeine Abhängigkeit begeben. Der Titel kann aus der Datenbank kommen, er kann statisch gesetzt werden, aus XML-Dateien erzeugt werden oder was es sonst so gibt.
Irgendwann am Ende müssen wir das Layout natürlich noch ausgeben: <?php
print $oLayout->render();
Ich hoffe ich habe mich relativ verständlich ausgedrückt. Es ist ein recht komplexes Thema, das schon sehr in im Bereich Software-Design geht. Hier ist viel möglich, was die Arbeit sehr erleichtern kann, weit mehr als das, was eine Template-Engine bieten kann und wenn man einmal mit solchen Systemen gearbeitet hat, will man sie nicht mehr vermissen, die Einarbeitung kann dafür allerdings auch schon mal ein wenig dauern.
Hallo Oskar,
Vielen Dank für Deinen klasse Artikel. Strikte Trennung untereinander ist bei mir oberstes Gebot. Ich glaube auch das es missverstanden wurde. Mein Beispiel soll genau das aussagen, was Du beschrieben hattest.
Zum anderen fängt objekt/subjekt Orientierung bereits bei der zu beantwortenden Frage an.
cite:
Damals als ich mir PHP angelernt hab (ist schon ein Weilchen her...) schien es gängiger Standart zu sein das man den kompletten Bereich in eine php-Datei (z.B.: layout/header.inc.php) auslagert und einfach in alle Seiten dann einbindet.
Vermutlich liegen die Kenntnisse 4-5 Jahre zurück. So ist es mir ein Greul mit Abstraction und Interfaces zu antworten.
Softwaredesign ist Glaubenskrieg, der eine verteufelt der andere liebt bestimmte Skills. Somit ist das eine weder falsch noch besser.
Nehmen wir als Basis: Logische Trennung Code-Layout. Da werden wir uns einig sein. Wie aber der einzelne das umsetzt ist Geschmackssache.
Warum das Rad neu erfinden, wenn man eine fixe-und Könnens-orientierte Lösung braucht.
Im Ãœbrigen hat vlibT auch eine TemplateCache in dem die Replaces aufgelöst werden.
Warum soll sich ein nicht täglich programmierender mit Klassen auseinander setzen. Schwer vorstellbar. Es würde zwar Wissen und Können bringen, dauert aber 5mal solange bis Ergebnisse vorhanden sind.
Wie gesagt, ich würde es ähnlich schreiben und vieles Glaubenskrieg. Ob es ein getuntes Mofa ist "mein Vergaser ist besser" oder SEO Voodoo.
Für wichtiger halte ich objekt/subjekt bezogene Ergebnisse.
cite: Qualität orientiert sich an den Anforderungen.
Guten Morgen zusammen,
Zitat:
Vermutlich liegen die Kenntnisse 4-5 Jahre zurück. So ist es mir ein Greul mit Abstraction und Interfaces zu antworten.
Das stimmt, wie gesagt es ist schon etwas her, dass ich das letzte mal mit PHP gearbeitet habe, allerdings bin ich relativ fit in Java und Begriffe wie Abstraktion und Interfaces sind daher keine Fremdwörter für mich.
Primär geht es mir darum meine Kenntnisse wieder aufzufrischen und auf einen etwas aktuelleren Stand zu bringen.
Ob man allerdings kleineren Problemen mit der geballten Kraft der OOP zu Leibe rücken sollte, halte ich für fragwürdig, denn man sollte auch immer im Hinterkopf behalten, dass vll eines Tages einmal die Notwendigkeit bestehen könnte das jemand Anderes sich in dem Code zurechtfinden muss (um kleinere Anpassungen vorzunehmen o.Ä.).
Ob dieser fiktive Jemand sich dann in polymorphen Klassen zurechtfinden kann, deren Methoden von Subklassen redefiniert werden steht dann auf einem ganz anderen Blatt geschrieben
Trotzdem bin ich sehr dankbar für die vielen hilfreichen Links und Tips von euch, ich hatte zwar noch nicht die Zeit alle durchzulesen, aber heute Abend ist ja dann Wochenende!
So long
Euer Johnny
romacron schrieb:
Nehmen wir als Basis: Logische Trennung Code-Layout. Da werden wir uns einig sein. Wie aber der einzelne das umsetzt ist Geschmackssache.
Ich denke darauf können wir uns gut einigen
Solange der Code überhaupt irgendwie zwischen Layout und dem ganzen Rest trennt, kann man schon sehr zufrieden sein, es erleichtert das spätere betrachten des Codes einfach ungemein.
Pohl schrieb:
Ob man allerdings kleineren Problemen mit der geballten Kraft der OOP zu Leibe rücken sollte, halte ich für fragwürdig, denn man sollte auch immer im Hinterkopf behalten, dass vll eines Tages einmal die Notwendigkeit bestehen könnte das jemand Anderes sich in dem Code zurechtfinden muss (um kleinere Anpassungen vorzunehmen o.Ä.).
Ob dieser fiktive Jemand sich dann in polymorphen Klassen zurechtfinden kann, deren Methoden von Subklassen redefiniert werden steht dann auf einem ganz anderen Blatt geschrieben
Letztendlich ist es halt immer eine Frage der eigenen Vorzüge und auch der jeweiligen Seite. Wenn ich im Vorhinein schon weiß, dass ich meinen kleinen Enkel ein wenig an der Seite rumbasteln lassen möchte, wäre OOP natürlich irgendwo ein Killer für den armen Jungen - oder der kleine Junge ist sauer, weil man OOP nicht genutzt hat; die Jugend ist heute doch manchmal erstaunlich pfiffig bei solchen Dingen
Ich für meinen Teil würde z.B. eine nicht objektorientiert programmierte Seite eher komplett neu schreiben als Änderungen daran vorzunehmen. Meiner Erfahrung nach ist es meistens einfacher, gut objektorientiert programmierte (und dokumentiere) Scripte nachzuvollziehen und vor Allem auch zu ändern. Klar, es gibt auch gut programmierte und dokumentierte Scripte, die nicht objektorientiert programmiert wurden, aber die Chance ist hier wesentlich kleiner und der Arbeitsaufwand bei Änderungen oft wesentlich größer.
Aber ich will hier keine Diskussion auslösen, jeder hat seine Art zu programmieren und solange er damit gut zurecht kommt und das Ergebnis stimmt, ist sowieso alles in Butter
Vielleicht kannst du uns, wenn es soweit ist, noch berichten, wie du das ganze umgesetzt hast, es gibt bestimmt noch öfter mal den ein oder anderen, der vor diesem Problem stehen wird.
Beitrag erstellen
EinloggenKostenlos registrieren