Section: Générer une page HTML5
^ Générer du contenu avec les vues | Générer du texte brut » |
− Table des matières
Pour générer du xhtml/html, vous indiquez l'alias "html" ou "basichtml" à la
méthode getResponse()
. Vous récupérez alors respectivement une instance de
l'objet jResponseHtml
ou jResponseBasicHtml
. Voici un exemple :
$rep = $this->getResponse('html');
HTML5 ou HTML4 ¶
Depuis Jelix 1.5, jResponseHtml
génère un entête HTML5 plutôt que HTML4.
Vous pourriez vouloir avoir du HTML4/XHTML1 comme dans les versions précédentes.
Pour cela, vous devez utiliser la classe jResponseHtml4
.
Aussi, si vous avez une classe de réponse personnalisée
(ce qui est le cas par défaut dans les nouvelles applications), vous devez hériter
de la classe jResponseHtml4
plutôt que jResponseHtml
:
require_once (JELIX_LIB_CORE_PATH.'response/jResponseHtml4.class.php');
class myHtmlResponse extends jResponseHtml4 {
}
Note: jResponseHtml4
hérite de jResponseHtml
, donc dans la suite
du manuel, toutes les fonctionnalités décrites pour jResponseHtml
sont
valables pour jResponseHtml4
, sauf mention contraire.
XHTML ou HTML ¶
Les classes jResponseHtml
et jResponseHtml4
ont un mode XHTML.
D'ailleurs, jResponseHtml4
génère du XHTML par défaut, comme le fait
depuis longtemps Jelix ( <= 1.4).
La méthode setXhtmlOutput()
de ces deux classes permettent de basculer
en mode XHTML ou HTML :
// jResponseHtml
$rep->setXhtmlOutput(true); // Réponse au format XHTML 5
$rep->setXhtmlOutput(false); // Réponse au format HTML 5 (par défaut)
// jResponseHtml4
$rep->setXhtmlOutput(true); // Réponse au format XHTML 1.0 (par défaut)
$rep->setXhtmlOutput(false); // Réponse au format HTML 4
// connaitre le mode :
$outputXhtml = $this->isXhtml();
Avec jResponseHtml
et jResponseHtml4
, vous pouvez aussi changer le
doctype, en surchargeant la méthode outputDoctype()
, qui doit faire un
echo du doctype souhaité.
Le mode XHTML est utilisable également avec jResponseBasicHtml
. Mais cela
n'influencera que les entêtes HTTP, pas le contenu de la page web. Il faut
que le template utilisé indique lui-même le DOCTYPE etc.
Renvoyer le contenu d'une page statique ¶
jResponseBasicHtml
permet de renvoyer simplement une page HTML complète
stockée dans un fichier. Ce fichier doit être un simple fichier PHP, cela ne
doit pas être un template pour jTpl. Il doit contenir tout le code HTML de la
page, et trois instructions qui affichent les variables suivantes :
- $HEADTOP : après la balise d'ouverture
<head>
- $HEADBOTTOM : avant la balise de fin
</head>
- $BODYTOP : aprés la balise d'ouverture
<body>
- $BODYBOTTOM : avant la balise de fin
</body>
Ces variables contiennent du code HTML qui a été indiqué lors des appels des
méthodes addHeadContent()
et addContent()
de l'objet
jResponseBasicHtml
. Elles ont pu être appelée par des contrôleurs, des
classes techniques, des plugins. C'est pourquoi il faut indiquer ces variables.
Il y a une quatrième variable, $BASEPATH qui contient le chemin de base de l'application, ce qui peut être utile pour vos feuilles de styles et autres ressources statiques.
Voici un exemple de fichier statique :
<!DOCTYPE html>
<html lang="en_US">
<head>
<?php echo $HEADTOP; ?>
<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
<title>Hello From Jelix !</title>
<link type="text/css" href="<?php echo $BASEPATH; ?>mystyles.css" rel="stylesheet" />
<?php echo $HEADBOTTOM; ?>
</head>
<body>
<?php echo $BODYTOP; ?>
<h1>Hello YOU !</h1>
<p>This is a sample html page generated by Jelix</p>
<?php echo $BODYBOTTOM; ?>
</body>
</html>
Dans votre contrôleur, vous devez indiquer où jResponseBasicHtml
peut
trouver ce fichier, en donnant son chemin complet dans la propriété
$htmlFile
. Notez que l'objet jCoordinator
possède une méthode
permettant de récupérer le chemin d'un module. Il est ainsi aisée de récupérer
un fichier d'un module, par exemple se trouvant dans un sous-répertoire
static/
du module :
$rep = $this->getResponse('basichtml');
$rep->htmlFile = jApp::coord()->getModulePath('unModule'). 'static/hello.php';
Générer du contenu dynamique ¶
Pour renvoyer du contenu dynamique, il est préférable d'utiliser la classe
jResponseHtml
, donc de récupérer la réponse de type "html". Cette classe
implémente des méthodes et propriétés supplémentaires par rapport à la réponse
"basichtml", pour manipuler le contenu (X)HTML. Elle est de ce fait bien plus
facilement utilisable par les divers composants (zones, templates, classes
techniques, contrôleurs..) voulant agir sur la réponse.
Le source HTML d'une page est découpé en deux parties : la partie <head>
,
et la partie <body>
:
jResponseHTML s'occupe de générer le contenu de la balise <head>
, à partir
des informations données au travers de ses méthodes. Par contre la génération du
contenu de la partie <body>
est de votre ressort, avec l'aide
éventuellement d'un template. Voyons tout ça en détails.
Modification de l'entête HTML ¶
Pour modifier le contenu de la balise <head>
, vous avez plusieurs méthodes
et propriétés. Vous pouvez ainsi modifier le titre du document, le "favicon",
les urls des feuilles de styles et des scripts javascripts à lier au document,
du CSS ou du javascript à inclure directement dans le <head>
, ou encore
les mots clés associés, la description de la page, et autres metas. Voyons un
exemple qui montre l'ensemble de ces possibilités :
$rep->title = "Le titre de mon document";
// génère une balise <script src="/lib.js"....>
$rep->addJSLink('/lib.js');
// génère une balise <script>alert....</script> qui sera incluse dans <head>
$rep->addJSCode('alert("essai");');
// génère une balise <link>
$rep->addCSSLink('/maFeuille.css');
// génère une balise <style>
$rep->addStyle('span', 'font-weight:bold;');
// ajoute une balise meta pour la description
$rep->addMetaDescription('description');
// ajoute une balise meta pour les mots clés
$rep->addMetaKeywords('motclé motclé motclé');
// Ajoute un auteur
$resp->addMetaAuthor('Laurent');
// modifie le nom du generateur
$resp->addMetaGenerator('My Super App 1.0');
// indique le mode de compatibilité pour IE (depuis 1.6.17)
$resp->IECompatibilityMode = 'IE=Edge'; // valeur par défaut dans Jelix 1.7
// spécifie le viewport (depuis 1.6.17)
$resp->metaViewport = 'width=device-width, initial-scale=1.0';
// ajoute une balise meta (depuis 1.6.17)
$resp->addMeta(array('name'=>'apple-touch-fullscreen', 'content'=>'yes'));
Si vous voulez injecter du contenu spécifique dans la balise <head>
, vous
pouvez le faire via la méthode addHeadContent()
$rep->addHeadContent('<link rel="alternate" type="application/rss+xml" title="Recent Changes" href="/feed.php" />')
Si à un moment ou à un autre, vous voulez annuler les modifications faites dans
le head (par exemple, vous êtes dans une zone qui est appelée par un module
tiers que vous ne voulez pas/pouvez pas modifier), vous pouvez appeler la
méthode clearHtmlHeader()
. Cette fonction vous permet d'effacer une partie
du header de votre document html, en indiquant quoi effacer : CSSLink
,
Styles
, JSLink
, JSCode
et/ou Others
.
$rep->clearHtmlHeader(array('CSSLink', 'Styles'));
Cet exemple effacera les liens CSS (addCSSLink
) et les balises
<style>
(addStyle
).
Générer le contenu principal de la page HTML ¶
jResponseHtml génère la balise <body>
, mais c'est vous qui en contrôlez
ses attributs et son contenu.
Pour définir les attributs de la balise <body>
, vous pouvez utiliser la
propriété bodyTagAttributes
.
$rep->bodyTagAttributes = array('onload'=>'bodyonload()',
'class'=>'maincontent');
Pour générer le contenu même de la balise body, vous avez deux choix : soit
utiliser un template, soit utiliser la méthode addContent()
.
Générer avec un template ¶
Pour utiliser un template, jResponseHtml propose deux propriétés :
bodyTpl
, qui doit contenir le sélecteur du template à utiliserbody
qui contient un objet jTpl permettant de "paramétrer" le template.
Exemple :
$rep->bodyTpl = 'myapp~main';
$rep->body->assign('person','Laurent');
Le contenu généré par le moteur de template sera intégré entre les balises
<body>
et </body>
.
Pour en savoir plus sur l'utilisation des templates, consultez le chapitre sur les templates.
Il se peut que vous ayez besoin d'ajouter du contenu en plus de celui produit
par le template. Pour cela vous utiliserez la méthode addContent()
. Elle
prend en paramètre une chaîne pour le contenu, et un booléen (facultatif) pour
indiquer si on veut que le contenu soit ajouté avant (true) ou après (false,
valeur par défaut) le contenu du template.
$rep->addContent('Mon contenu HTML après le template');
$rep->addContent('Mon contenu HTML avant le template', true);
Notez que le contenu à ajouter peut être aussi le contenu de zones
$rep->addContent(jZone::get('monmodule~uneZone'));
Générer avec un template principal et des "sous-templates" ¶
Bien souvent, les pages d'un site ont un gabarit commun, et seules certaines zones changent (notamment le contenu principal) en fonction de l'action. Il y aura donc un template principal , défini comme on l'a vu précédemment, qui ne contiendra que le contenu commun à toutes les pages, et dans chaque action on utilisera un autre template (un "sous-template") pour générer le contenu spécifique, dont on injectera le résultat dans le template principal. Ce travail peut être fait avec un template directement, ou au moyen d'une zone.
Et pour éviter que dans chaque action on définisse à chaque fois le template principal, les élements communs (feuilles de style etc), on créera un objet réponse HTML qui héritera de jResponseHtml.
Pour savoir comment faire, lire la section sur la personnalisation de réponse commune.
Générer sans template ¶
Si vous ne voulez pas utiliser de template pour le body, alors il faut laisser
la propriété $bodyTpl
à vide, et utiliser seulement la méthode
addContent()
:
$rep->addContent('contenu pour mon body');
Ajouter des feuilles de styles, fichiers javascript, images... ¶
Vous avez probablement remarqué l'exemple sur l'utilisation de addJSLink()
et
addCSSLink()
. Ces méthodes permettent de lier des feuilles de styles CSS et
des fichiers javascript à votre page HTML.
addJSLink()
et addCSSLink()
acceptent en premier argument une URL d'un
fichier Javascript ou d'un fichier CSS. Faites attention cependant à l'URL que vous
indiquez. À moins que ce soit vraiment ce que vous voulez, n'utilisez pas d'URL relative
(dependante de l'URL de la page). Car la plupart des URLs des pages de votre
application étant vituelles (ne pointant pas vers des fichiers physiques), l'URL
résultante risque de ne pas être la bonne. Par exemple, 'css/styles.css'
donne http://exemple.com/foo/bar/css/styles.css
avec la page
http://exemple.com/foo/bar/
, mais donne
http://exemple.com/foo/css/styles.css
avec la page
http://exemple.com/foo/bar
ou http://exemple.com/foo/
. Alors que si vous
donnez une URL absolue (avec ou sans le nom de domaine), vous obtiendrez
toujours le bon chemin. '/css/styles.css'
(notez le /
au début) donne
toujours http://exemple.com/css/styles.css
quelle que soit l'URL de la page.
Aussi il est recommandé d'indiquer une URL absolue, dont le chemin débute à la racine du site.
Les fichiers CSS/JS peuvent être stockées dans le répertoire www/
de votre application
ou le répertoire www/
d'un module.
Si c'est stocké dans le répertoire www/
de l'application, et si ce répertoire
est le "documentRoot" de l'application, vous pouvez indiquer simplement son chemin
absolue. Par exemple, si vous voulez le lien vers le fichier yourapp/www/css/mystyles.css
,
alors vous feriez :
$resp->addCSSLink('/css/mystyles.css');
Cependant, si www/
n'est pas le "document root", ou si votre module est déstiné
à être utilisé par d'autres application, ou encore que l'application peut être installée
avec une configuration différente, il est préférable d'ajoute le "basePath" du
site web :
$resp->addCSSLink(jApp::config()->urlengine['basepath'].'css/mystyles.css');
Si vous voulez lier un fichier CSS/JS du répertoire lib/jelix-www/
, vous
pouvez utiliser la propriété jelixWWWPath
:
$resp->addJSLink(jApp::config()->urlengine['jelixWWWPath'].'js/tooltip.js');
Si le fichier CSS/JS se trouve dans un module, alors vous ne pouvez pas indiquer
le chemin direct, les fichiers d'un module n'étant pas accessibles directement
à partir d'un navigateur, en temps normal. Vous devez passer par deux méthodes spécifiques
addJSLinkModule()
et addCSSLinkModule()
.
Vous devez donner deux paramètres, le nom du module et le chemin du fichier dans le répertoire www/
du module. Par exemple, si vous voulez lier le fichier
mymodule/www/css/mystyles.css
:
$resp->addCSSLinkModule('mymodule', 'css/mystyles.css');
Notez que pour les méthodes addCSSLink
, addJSLink
, addJSLinkModule()
et addCSSLinkModule()
vous pouvez indiquer un paramètre supplémentaire qui doit être un tableau associatif,
décrivant les attributs supplémentaires à mettre dans la balise HTML générée.
$rep->addCSSLink('maFeuille.css',
array('title'=>'design bleu',
'rel'=>'alternate stylesheet',
'media'=>'all'));
Tous les exemples précédent sur la récupération des URL des fichiers CSS,
fonctionnent aussi bien pour les fichiers JS, les images et autres fichiers
de ressources, stockés dans le répertoire www/
d'une application, d'un module
ou dans le répertoire jelix-www
.
Et vous pouvez appliquer les mêmes principes dans un template :
{* dans le www/ d'une application *}
{meta_html css '/css/mystyles.css'}
{meta_html css $j_basepath.'css/mystyles.css'}
{* dans le jelix-www/ *}
{meta_html js $j_jelixwww.'js/tooltip.js'}
{* dans le www/ d'un module *}
{meta_htmlmodule css 'mymodule', 'css/mystyles.css'}
{* lien vers une image mymodule/www/img/mypicture.png *}
<img src="{jurl 'jelix~www:getfile', array('targetmodule=>'mymodule', 'file'=>'img/mypicture.png')}" />
Voyez le chapitre sur les templates pour en savoir plus.
Autres paramètres pour les réponses html et basichtml ¶
Comme jResponseHtml
et jResponseBasicHtml
sont dérivés de
jReponse
, vous pouvez influer sur les entêtes HTTP, comme le code
"status", et bien sûr ajouter d'autres en-têtes.
$rep->setHttpStatus ("404", "Not Found");
$rep->addHttpHeader ("Date-modified", "....");
Il y a aussi une autre propriété : $xhtmlContentType
. Cette propriété
définit si le contenu xHTML doit être envoyé avec un en-tête HTTP
Content-Type
spécifique : application/xhtml+xml
. Bien sûr, une
vérification des capacités du navigateur à recevoir du xhtml est faite, et si le
navigateur ne peut pas recevoir du xHTML, la réponse sera envoyée avec le
Content-Type text/html
comme pour le HTML classique.
$rep->xhtmlContentType = true ;
Activer des plugins ¶
Les classes jResponseHtml
, jResponseHtml4
et jResponseBasicHtml
ont un système de plugin. Ces plugins permettent d'enrichir ou agir
automatiquement sur le contenu de toutes les pages HTML du site. C'est ainsi
qu'il existe par exemple un plugin pour afficher une barre de debug, ou encore
un autre pour "minifier" les fichiers CSS et Javascript.
Ces plugins sont des plugins de type "htmlresponse", ils doivent se trouver dans
un répertoire htmlresponse/
d'un dépot de plugin. Et pour les activer, il
faut indiquer les noms des plugins utilisé dans l'option plugins
de la
section jResponseHtml
de la configuration générale. Exemple :
[jResponseHtml]
plugins = debugbar, minify
Compression des fichiers css et javascript ¶
Jelix est fourni avec Minify, qui permet de compresser et concaténer automatiquement les fichiers CSS et Javascript d'une page HTML.
Pour activer le plugin minify, il faut indiquer son nom dans l'option
plugins
comme indiqué précédemment. Et vous avez une série d'options qui
vous permet de contrôler le comportement de Minify. Ce plugin ne fonctionne pas
avec jResponseBasicHtml.
[jResponseHtml]
;concatene et compress les fichier CSS
minifyCSS = on
;concatene et compress les fichier JS
minifyJS = on
; liste des fichiers CSS qui ne doivent pas être compressé
minifyExcludeCSS = "file1.css,file2.css"
; liste des fichiers JS qui ne doivent pas être compressé
minifyExcludeJS = "jelix/wymeditor/jquery.wymeditor.js"
; chemin du point d'entrée de Minify, relatif au basePath
minifyEntryPoint = minify.php
Tout d'abord, vous devez activer la compression en mettant minifyCSS
et/ou
minifyJS
à "on". Vous pouvez indiquer de ne pas compresser certains fichiers
en les listant dans minifyExcludeCSS
et/ou minifyExcludeJS
. Gardez
"jelix/wymeditor/jquery.wymeditor.js" dans minifyExcludeJS
, car Wymeditor n'aime pas être
concaténé avec d'autres fichiers js.
Les chemins des fichiers indiqués doivent être
- soit relatifs au basePath (sans / au début)
- soit des chemins absolus par rapport au domaine (démarrant donc par /)
N'indiquez pas d'URLs complètes, elles sont automatiquement exclues.
La dernière chose à faire est d'installer un script minify.php
dans
www/
. Copiez simplement le fichier
lib/jelix-scripts/templates/www/minify.php.tpl
en
votre_appli/www/minify.php
. Il y a quelques options supplémentaires pour
Minify que vous pouvez changer dans ce fichier (voyez la documentation de
Minify), et c'est tout. Si vous voulez nommer ce fichier autrement, indiquez son
nom dans l'option minifyEntryPoint
.