Zend Framework : placeholders et layout

A quoi ça sert ?

Dans le Zend Framework, une vue, au sens MVC du terme, peut être composée de plusieurs scripts. Le plus souvent on en aura au moins deux : le script de layout et le script de vue correspondant à l'action du contrôleur.

Dans le layout, on va placer les éléments qui sont communs à plusieurs pages : l'entête HTML, l'entête visible de la page (avec le logo, la boite de recherche, le titre de la page) et le pied de page.

Le layout enveloppe le script de vue

Le problème avec cette disposition, c'est qu'on a des éléments comme le titre de la page qui font partie du layout, mais dont le contenu varie pour chaque page.

Il faut donc pouvoir définir le titre de la page à partir du script de vue.

Variable de Layout

La façon la plus simple d'y parvenir, c'est d'utiliser l'aide de vue Layout pour accéder à l'instance du Layout et de lui ajouter une variable :

<?php
// Dans le script de vue
$this->layout()->title 'Mon titre';
?>

Cette variable peut alors être récupérée dans le script de layout :

<?php
// Dans le script de layout
echo '<h1>' $this->layout()->title '</h1>';
?>

L'aide de vue Placeholder

Les placeholders fonctionnent un peu de la même façon, mais ils offrent des fonctionnalités supplémentaires. On peut reprendre le même exemple avec l'aide de vue Placeholder :

<?php
// Dans le script de vue
$this->placeholder('title')->set('Mon titre');
?>
<?php
// Dans le script de layout
echo '<h1>' $this->placeholder('title') . '</h1>';
?>

Les préfixes et suffixes

On peut définir des préfixes et des suffixes. Dans notre exemple, on pourrait s'en servir pour la balise h1 qui enveloppe notre titre :

<?php
// Dans le script de layout
$title $this->placeholder('title');
if (!
$title->getPrefix()) {
  
$title->setPrefix('<h1>');
}
if (!
$title->getPostfix()) {
  
$title->setPostfix('</h1>');
}
echo 
$title;
?>

L'avantage, c'est qu'on peut alors les modifier à partir du script de vue :

<?php
// Dans le script de vue
$title $this->placeholder('title');
$title->set('Mon titre');

// Affiche le titre en rouge
$title->setPrefix('<h1 style="color:red">');
?>

Les tableaux

On peut placer un tableau dans un placeholder et utiliser la méthode setSeparator pour spécifier le texte qui sera utilisé pour joindre les différents éléments (un peu à la manière de la commande PHP implode) :

<?php
// Dans le script de vue
$this->placeholder('title')->exchangeArray(array('Mon site''Ma page'));
?>
<?php
// Dans le script de layout
$title $this->placeholder('title');
$title->setSeparator(' | ');
echo 
$title// Affiche 'Mon site | Ma page'
?>

L'identation

On peut également spécifier une indentation avec la méthode setIndent :

<?php
// Dans le script de layout
$title $this->placeholder('title');
$title->setIndent(4);
$title->setSeparator("\n");
// Affiche 'Mon site' suivi de 'Ma page' sur la ligne suivante 
// avec une indentation de 4 espaces
echo $title
?>

La capture du contenu

Le contenu du placeholder peut être capturé, ce qui est pratique pour les longs blocs de texte :


<?php 
$this
->placeholder('texte')->captureStart();
?>
Un texte<br>
sur plusieurs<br>
lignes
<?php 
$this
->placeholder('texte')->captureEnd();
?>

La classe Placeholder utilise l'output_buffering pour réaliser ce prodige.

Implémentations concrètes des placeholders

Les placeholders ont surtout un intérêt pour leurs implémentations concrètes :

  • Doctype permet de définir la déclaration DOCTYPE des pages
  • HeadTitle permet de définir la balise TITLE de votre page
  • HeadLink permets de créer des balises LINK pour lier des feuilles de style CSS à vos pages
  • HeadMeta permet de définir les balises META (description, keywords, http-equiv)
  • HeadScript permet de définir les balises SCRIPT pour charger des fichiers javascript
  • HeadStyle permet de d'inclure des styles CSS dans l'entête de votre page
  • InlineScript permet de d'inclure du code javascript dans le corps de votre page

A l'aide de ces différents outils, on peut créer des mises en page très flexible :


<?php echo $this->doctype() . PHP_EOL ?>
<html>
    <head>
<?php
$meta 
$this->headMeta();
$meta->setIndent(8);
echo 
$meta PHP_EOL;

$title $this->headTitle();
$title->setIndent(8);
echo 
$title PHP_EOL;

$headLink $this->headLink();
$headLink->setIndent(8);
$headLink->prependStylesheet('screen.css');
echo 
$headLink PHP_EOL;

$headStyle $this->headStyle();
$headStyle->setIndent(8);
echo 
$headStyle PHP_EOL;
?>
    </head>
    <body>
        <?php echo $this->layout()->content ?>
    </body>
</html>
?>

Exemple de code HTML produit par ce layout :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
        <title>Titre de la page</title>        
        <link href="screen.css" media="screen" rel="stylesheet" type="text/css" >
        <style type="text/css" media="screen">
                <!--
                .error { color: red }
                -->
        </style>
    </head>
    <body>
        <!-- Contenu de la page -->
    </body>
</html>
Placez les balises META en première position pour que le navigateur puisse détecter le type de contenu et le jeu de caractères utilisé par la page.

Spécifier le DOCTYPE dans le bootstrap

Généralement, le DOCTYPE sera le même pour toutes les pages de l'application. On peut donc le spécifier dans la phase d'amorçage de l'application (bootstrap). Si vous utilisez Zend_Application, vous pouvez ajouter une méthode _initDoctype à votre classe Bootstrap.

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function 
_initHTMLView()
    {
        
$this->bootstrap('view');
        
$view $this->getResource('view');
        
$view->doctype('HTML4_STRICT');
    }
}
?>
Le DOCTYPE affecte le comportement des aides de vues. Si on choisit d'utiliser du XHTML, les balises seront systématiquement fermées (on aura <input /> au lieu de <input&gt).

Spécifier le titre de la page

Les bonnes pratiques veulent qu'on ait un titre différent par page. On le spécifiera donc dans le script de vue :

<?php
// Dans le script de vue
$this->headTitle('Titre de la page');
?>

Généralement, on ajoute également le nom du site au titre. Il y a deux écoles : on peut mettre le titre du site en premier ou en dernier. La première méthode est la plus évidente, mais la deuxième est plus maligne : lorsqu'on visualise un titre, il est souvent tronqué car l'espace manque sur un onglet ou sur une page de résultats de recherche. En tous cas, ce titre doit être spécifié au moment du démarrage, comme pour le DOCTYPE :

<?php
// Titre du site en première position, séparé du titre de la page par un tiret
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function 
_initHTMLView()
    {
        
$this->bootstrap('view');
        
$view $this->getResource('view');
        
$headTitle $view->headTitle();
        
$headTitle->setSeparator(' - ');
        
$headTitle->append('Titre du site');
    }
}
?>

ou

<?php
// Titre du site en dernière position, séparé du titre de la page par un tiret
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function 
_initHTMLView()
    {
        
$this->bootstrap('view');
        
$view $this->getResource('view');
        
$headTitle $view->headTitle();
        
$headTitle->setPostfix(' - Titre du site');
    }
}
?>
Dans un précédent article, je vous expliquai comment récupérer le titre placé dans la balise TITLE pour l'afficher dans une balise H1 par exemple.

Balises Méta

Comme pour la balise TITLE, on a des balises META globale pour tout le site (Content-Type par exemple) et des balises spécifiques pour chaque page (description, keywords).

<?php
// Spécification du Content-Type dans le bootstrap
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function 
_initHTMLView()
    {
        
$this->bootstrap('view');
        
$view $this->getResource('view');
        
$view->headMeta()->appendHttpEquiv('Content-Type''text/html; charset=UTF-8');
    }
}
?>
<?php
// Définition de la description de la page et des mots clés dans le script de vue
$this->headMeta(
    
'La description de la page',
    
'description'
);
$this->headMeta(
    
'1er mot clé, 2ème mot clé',
    
'keywords'
);
?>

Feuilles de style CSS

<?php
// Ajout d'une feuille de style CSS dans le bootstrap
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function 
_initHTMLView()
    {
        
$this->bootstrap('view');
        
$view $this->getResource('view');
        
$view->headLink()->appendStylesheet('screen.css');
    }
}
?>
<?php
// Dans le script de vue
$this->headLink()->appendStylesheet('page.css');
// On peut également définir des styles spécifique à la page avec headStyle
?>

<?php
// Ajout d'un style à l'entête de la page
$this->headStyle()->appendStyle('.red { color: #FF0000 }');

// Par capture, plus pratique si on a plusieurs règles CSS à ajouter
$this->headStyle()->captureStart();
?>
.blue {
    color: #0000FF;
}
.red {
    color: #FF0000;
}
<?php
$this
->headStyle()->captureEnd();
?>

Conclusion

Les placeholders et les layouts permettent d'éviter de répéter du code et garantissent que le code HTML sera correctement formé. Alors utilisez les si ce n'est pas déjà le cas.

Commentaires

Très très bon article sur le sujet !
Je suis en train de parcourir les autres qui sont sympa aussi. Je suis, moi aussi, en train de faire des tutos sur le Zend Framework ;), n'hesite pas a venir faire un tour :d
LyRiX's blog
PS : c'est pas de la pub ..., mais si un pseudo partenariat peut s'installer ...

Je t'ai installé avec d'autre dans un petit bloc dans la barre latérale. Ton logiciel de gestion de compte à l'air sympa. T'as utilisé quelle bibliothèque pour tes graphiques ?

Ah merci beaucoup, je n'avais pas vu que tu avais mis un liens. Je vais faire de meme sur mon blog.
Sinon pour la librairie j'ai utiliser Pchart, je ne sais pas si tu connais, c'est assez simple après 1 heure de test. Sinon c'est assez complet. N'hésites pas a m'envoyer un mail :)

Ajouter un commentaire