Solide Grundlagen für den CakePHP View

Nach dem wir in der Ape Unit GmbH zwei große Projekte mit CakePHP aufgebaut haben und ich größtenteils für die Views zuständig war, gibt es eine Reihe von Grundlagen auf die ich in einem Cake Projekt nicht mehr verzichten möchte. Welche das sind, wie sie eingebaut und verwendet werden, ist das Thema dieses Artikels.

Ein Artikel von Paul Lunow, erschienen 2010 auf Interaktionsdesigner.de.

Zuletzt überarbeitet am von : .

Denkst Du darüber nach zu gründen? Eine Familie oder ein Startup oder beides? In der zweiten Staffel meines Podcasts spreche ich mit tollen Menschen genau darüber. Lass Dich inspirieren und abonniere meinen Podcast: Auf Apple Podcast, Spotify und auf www.gründerväter.net.

Im App Controller

Alles fängt im Controller an. Meine erste Tat ist jetzt stets einen App Controller anzulegen. Der liegt im Verzeichnis /app/ und definiert eine Reihe von Grundlagen.

class AppController extends Controller {
    var $components = array('Auth', 'Session', 'RequestHandler');
    var $helpers = array('Form', 'Html', 'Javascript', 'Time', 'Text', 'Layout');
}

Die Components Auth und Session sind wahrscheinlich schon hinreichend bekannt. Der RequestHandler ist mein bester Freund, denn er beinhaltet alle Informationen über den aktuellen Aufruf. Mit seiner Hilfe ist es zum Beispiel möglich zu erkennen ob es sich um einen asynchronen Aufruf handelt oder um ein mobiles Endgerät. Die Helper sollten auch soweit klar sein, bis auf Layout. Der ist nicht im Core enthalten sondern in der Bakery verfügbar. Mit diesem Helper im Projekt ist Template Inheritance möglich. Das heißt man definiert im Layout (/app/views/layouts/default.ctp) einen Block, zum Beispiel den Footer.

<div id="footer">
    <? $this->Layout->output($footer_for_layout, $this->element('default_footer')); ?>
</div>

Im Element default_footer (/app/views/elements/default_footer.ctp) befindet sich der Standardfooter. Und den überschreibt man im Bedarf einfach in einem View:

<?=$layout->blockStart('footer');?>
Ein <strong>neuer</strong> Footer!
<?=$layout->blockEnd();?>

Grandios oder? Der im View definierte Inhalt wird dann im entsprechenden Block im Layout ausgegeben. Das Prinzip habe ich bei Django gesehen und jetzt zum Glück auch in Cake zur Verfügung. Noch ein Wort zum RequestHandler. In der Funktion AppController::beforeFilter() benutze ich folgende Abfrage um auf einen asynchronen Aufruf zu reagieren:

if($this->RequestHandler->isAjax()) {
    Configure::write('debug', 0);
    if($this->RequestHandler->prefers() == 'json') {
       die(json_encode($this->viewVars));
    }
    else {
       $this->layout = 'ajax';
    }
}

Wenn es sich um einen Ajaxaufruf handelt$this->RequestHandler->isAjax() dann wird als erstes eine Debugausgabe verhindert Configure::write(‘debug’, 0); (das sollte man sich merken!!) und dann überprüft, was für ein Datentyp zurück erwartet wird. Wenn JSON Code angefordert wird, werden alle Variablen für den View in einem JSON Objekt zurück gegeben, andernfalls wird das Ajax Layout verwendet, welches einfach den View zurück gibt ohne das ganze HTML Gerüst. Wichtig ist bei der Verwendung dieser Abfrage daran zu denken keine sensiblen Daten an den View zu übergeben und dort zu prüfen ob der Nutzer die Daten sehen darf oder nicht. Aber da wir ja alle strikt dem MVC Pattern folgen, ist das ja auch gar nicht möglich.

Das Layout

Okay, jQuery keine Frage:

echo $this->Javascript->link(array(
    'jquery.min'
));

Die Endung .js kann man sich sparen, Cake sucht die angegebenen Dateien automatisch im Ordner /app/webroot/js/. Zur angenehmen Verteilung des Inhalts benutze ich jetzt immer das 960.gs CSS Framework. Es gibt einen grandiosen Konfigurator mit dessen Hilfe man sich sehr schnell ein passendes Grid zusammenstellt. Die erzeugte CSS Datei legt man im Ordner /app/webroot/css/ ab und bindet sie mit Hilfe des HTML Helpers ein. Außerdem benutze ich den CSS Reset von Eric Meyer um eine einheitliche Ausgangslage in allen Browsern zu erreichen. In der Datei layout.css binde ich dann je nach Komplexibilität weitere CSS Dateien über import url() ein.

echo $this->Html->link(array(
    '960',
    'reset',
    'layout'
));

Um in jQuery immer die richtige Baseurl für Ajaxanfragen zur Verfügung zu haben, nutze ich das Base Tag:

<base href="http://<?=env('HTTP_HOST').$this->base?>/" />

HTML Gerüst

Das960.gs verlangt einen umfassenden Container mit der Klasse container_XX, wobei das XX für die Anzahl der Spalten steht. Was sich außerdem bewäht hat ist, Controller und Action als Klasse auszugeben um per CSS einzelne Ansichten individuell gestallten zu können. In meinem Layout führt das zur folgenden Monsterzeile:

<div id="wrap" class="container_16 <?=$this->params['controller']?> <?=$this->params['action']?> <?=$this->params['controller']?><?=ucfirst($this->params['action'])?>">

Alle Views des Controllers Blogs haben jetzt die Klasse #wrap.blogs. Und jede einzelne View lässt sich mit #wrap.blogsAdd gezielt ansprechen. Außerdem können auch alle Formular zum hinzufügen von neuen Einträgen angesprochen werden: #wrap.add form. Damit ist man schon sehr flexibel. Noch ein Satz zu 960.gs: die Aufteilung des Inhalts in Spalten erfolgt über das verteilen von Klassen. Diese haben immer das Format grid_XX, darauf folgt immer ein Container mit der Klasse clear.

<div class="grid_8">Linke Hälfte</div>
<div class="grid_8">Rechte Hälfte</div>
<div class="clear"></div>

Das teilt den Inhalt in zwei gleiche Teile. Es ist über die Klassen pull_XX und push_XX auch möglich Abstände einzufügen. Einfach ein bisschen rumspielen.

Hilfe und Informationen

Alle Core Components und Helper liegen bestens dokumentiert in eurem Projekt! Um schnell zu erfahren wie die verdammte Funktion im RequestHandler heißt, öffnet man einfach die entsprechende Datei in /cake/libs/controller/components/. Im Verzeichnis /cake/libs/ ist Cake genau so aufgebaut wie im eigenen Ordner /app/. Daran muss man unbedingt denken und diese wertvolle Quelle **nutzen. Aber: **niemals Änderungen vornehmen!!! NIEMALS. Absolut verboten, denn damit verliert man die Updatefähigkeit. Alle Dateien die man anpacken darf liegen im /app/ _Ordner. Wenn man jetzt wirklich nicht drum rum kommt und zum Beispiel im Time Helper etwas ändern muss, dann kopiert man die komplette Datei und legt sie in den Ordner _/app/views/helpers/. Jetzt darf man sie verändern wenn es unbedingt sein muss. Unter http://www.cakephp.org findet man eine ganze Reihe nützlicher Links und Ressourcen, dass ist ja klar. Für deutschsprachige Cake Entwickler bietet sich außerdem noch das CakeForum an, da bin ich auch ab und zu unterwegs.

Fazit

CakePHP ist ein grandioses Framework, die aktuelle Version 1.3 macht großen Spaß und ich kann es kaum erwarten das unsere Projekte endlich das digitale Licht des Internets erblicken. Infohäppchen gibt es in meinem Twitter Account, richtig gute Hilfe und Unterstüztung leistet die Ape Unit GmbH gegen Bares oder Mitarbeit und wenn du einen Job suchst, dann freue ich mich auf einen Besuch auf unserer Seite der offenen Stellen! Frohes backen!


Deine Meinung

Sind wir einer Meinung? Sind noch Fragen offen geblieben?

Mehr zum Thema