Raccourcis : Contenu - rubriques - sous rubriques
EN FR

Il est possible que Jelix ne fournisse pas le moyen de générer du contenu dans un format spécifique voulu. Aussi, il vous faut dans ce cas créer votre propre réponse.

Cela consiste à :

  1. créer une classe héritant de jResponse (ou d'une autre réponse existante), et qui doit implémenter les méthodes adéquates pour manipuler le format en question
  2. stocker cette classe dans le répertoire app/responses/ de votre application ou responses/ de vos modules, ou un autre répertoire de votre module si la classe a un namespace et est autochargée.
  3. déclarer ce type de réponse dans le fichier de configuration

Créer la classe

Une classe doit posséder au moins deux méthodes : output() et outputErrors(). Et redéfinir la propriété $_type avec un identifiant propre à votre type de réponse. output() doit générer le contenu formaté correctement (en faisant des print ou echo). outputErrors() est appelé quand des erreurs bloquantes sont survenues pendant le traitement d'une action. Il génère alors une réponse différente, voire spécifique au format dans ce contexte-là. Il ne faut pas oublier non plus d'envoyer un en-tête HTTP correspondant au type de format.

Exemple d'un format (bidon :-) ):



class myFooResponse extends jResponse {
    protected $_type = 'foo';

    public $content = '';

    /**
     * génère le contenu et l'envoi au navigateur.
     * @return boolean    true si la génération est ok, false sinon
     */
    public function output() {
        $this->_httpHeaders['Content-Type'] = 'text/foo;charset='.jApp::config()->charset;
        $this->sendHttpHeaders();
        echo "content:\n".$this->content."/content;";
        return true;
    }

    public function outputErrors() {
        header('Content-Type: text/foo;charset='.jApp::config()->charset);
        echo "errors\n";
        foreach (jApp::coord()->errorMessages  as $e) {
            echo '['.$e[0].' '.$e[1].'] '.$e[2]." \t".$e[3]." \t".$e[4]."\n";
        }
        echo "/errors;";
    }
}

Comme dans l'exemple ci-dessus avec la propriété $content, vous pouvez rajouter toutes les propriétés et méthodes nécessaires à une manipulation aisée de l'objet dans les actions. Par exemple, l'objet jResponseHtml instancie d'office un template, contient une propriété pour spécifier le titre d'une page html, des méthodes pour ajouter des choses dans le <head> etc..

N'hésitez pas à regarder le code source des fichiers dans lib/jelix/core/response/. Peut-être d'ailleurs que votre format s'apparente à un de ceux fournis par Jelix. Dans ce cas, votre objet response peut hériter de cet objet, ajouter des méthodes, en redéfinir etc.

Stockage de la classe

Le nom de la classe importe peu, mais il doit être utilisé dans le nom du fichier, et précéder le suffixe .class.php. Dans notre exemple, la classe sera alors stockée dans le fichier myFooResponse.class.php.

Le fichier doit être enregistré dans le répertoire app/responses/ de votre application ou responses/ d'un module.

Il est aussi possible d'utiliser un nom de classe avec un namespace, stockée dans un fichier dont le nom permet de l'auto-charger (par une déclaration dans module.xml ou composer.json) à partir de n'importe quel répertoire de votre module.

Déclarer la réponse

Pour que la réponse soit utilisable par les actions, il faut la déclarer avec un code. Et c'est ce code que vous indiquerez à la méthode getResponse dans les contrôleurs. Pour cela, vous ajouterez dans la section responses du fichier de configuration, une ligne <alias>=<classe>.

Voici un exemple de réponse fournie par votre application :


[responses]
foo=myFooResponse

Voici un exemple de réponse fournie par votre module :


[responses]
foo="mymodule~myFooResponse"

Ou encore, si la classe est auto-chargeable grâce à son namespace :


[responses]
foo="\My\Foo\Response\Class"

Ensuite vous sera à même d'utiliser votre réponse dans les actions de votre contrôleur.

Et dans un contrôleur, cela donne :



function index(){
   $rep = this->getResponse('foo');
   $rep->content='hello world';
   return $rep;
}

Pourquoi ne pas indiquer directement le nom de la classe à getResponse ? Parce que cela permet de redéfinir un même type de réponse de façon transparente pour les actions et modules.

À propos des templates

Les plugins de templates sont, pour un certain nombre, attribués à un type de réponse particulier. Aussi, si vous créez un nouveau type de réponse spécifique, il vous faudra adapter et aussi dupliquer/copier/recréer les plugins de templates existants pour les autres types de réponses.

Si vous héritez par contre d'un objet response existant (de jResponseHtml par exemple), ne changez pas la propriété type de la classe mère, sinon vous ne pourrez pas réutiliser les plugins de templates existants (à moins de les redéfinir).

Voir la doc pour faire des plugins de templates.