Raccourcis : Contenu - rubriques - sous rubriques
EN FR

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 à utiliser
  • body 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.