===== Un peu de théorie =====
Une action est un élément fondamental du framework. Tout affichage, tout traitement
de formulaire, tout appel de service web est une action.
Une action est appelée dans le cadre d'une requête d'un type précis et génère
une réponse spécifique dans un format spécifique, qui peut être lié au type de
requête en question.
Il existe plusieurs types de requêtes, notament le type que l'on nomme dans
Jelix, "classic", pour lequel une action peut fournir une réponse dans un
format quelconque : HTML, XML, etc. C'est pour ce type de requête que vous
définirez le plus souvent des actions. En général, ce type de requête fournit
ses paramètres dans l'url ou dans le corps de la requête HTTP (méthode POST).
Vous avez aussi des types de requêtes plus spécifiques, comme par exemple le
type xmlrpc (utilisée dans le cadre d'un service web). En XML-RPC, les données
en entrée ne sont pas des paramètres dans une url, mais sont stockées dans un
contenu XML. Comme le veut le protocole XML-RPC, une action définie pour ce
type de requête doit fournir obligatoirement une réponse au format XML-RPC.
En connaissant le type de requête traitée et l'action, Jelix connaît ainsi le
type de la réponse à générer, et donc contrôle plus ou moins la génération de
la réponse. Ainsi, même en cas d'erreur (une exception ou autre) survenant
pendant le traitement de l'action, le format de sortie sera toujours celui
attendu. Un client qui appelle un service web en XML-RPC, aura donc quoi qu'il
arrive une réponse au format XML-RPC. Cela apporte une certaine robustesse à
l'application.
Voici un schéma simplifié du déroulement d'une action :
{{http://jelix.org/images/schema_logic.png}}
- Jelix reçoit une requête HTTP. Il instancie un objet jRequest qui contient les données de la requête, et instancie le contrôleur qui correspond à l'action.
- La méthode du contrôleur correspondante à l'action est exécutée. La méthode récupère les paramètres de requête pour déterminer les traitements à suivre.
- Le contrôleur exécute les traitements métiers et récupère éventuellement des résultats qui seront utilisés pour l'affichage
- Le contrôleur instancie un objet de type jResponse auquel il assignera les données à afficher, initialisera les templates etc.
- Jelix récupère cet objet jResponse, invoque la génération du document en sortie et envoi ce dernier au navigateur.
===== Implémentation d'une action =====
Les actions sont implémentées dans ce qu'on appelle des contrôleurs. Les
contrôleurs sont des classes contenant des méthodes pour chaque action.
Les contrôleurs sont stockés dans des fichiers @@F@controllers/nom_controleur.type_requete.php@@.
En général il y a une méthode @@M@index()@@ pour l'action par défaut.
Modifions donc cette action par défaut. Pour cela ouvrons le fichier
@@F@module/news/controllers/default.classic.php@@. Vous devez avoir ce contenu :
class defaultCtrl extends jController {
function index () {
$rep = $this->getResponse('html');
return $rep;
}
}
Vous remarquerez qu'il y a certaines conventions de nommage. Les classes
contrôleurs ont un nom suffixé par "Ctrl". Ce qui précède le suffixe,
"default", est le nom du contrôleur, que vous indiquerez dans le paramètre
action, et c'est aussi le préfixe du nom du fichier *.classic.php.
==== Objet réponse ====
Dans la méthode @@M@index()@@ du contrôleur, on récupère dans la variable
@@V@$rep@@ une réponse de type "html". Vous obtenez en fait un objet de
classe @@C@jResponseHtml@@, dérivant de la classe @@C@jResponse@@.
Vous verrez plus tard qu'il existe d'autres types de réponses et que vous
pouvez développer vos propres objets réponse.
L'objet @@C@jResponseHtml@@ s'occupe de générer une réponse en HTML
(donc une page en HTML). Il génère automatiquement la partie
$rep->title = 'Dernières actualités';
Et le navigateur recevra :
Dernières actualités
Tout le corps de la page, c'est à dire le contenu de la balise html @@E@@@,
doit être généré par vous même, via éventuellement le moteur de template de
Jelix : [[https://docs.jelix.org/fr/manuel-1.7/composants/templates|jTpl]].
@@C@jResponseHtml@@ instancie en standard un moteur de template placé dans la
propriété @@P@body@@. Le nom du fichier template est à placer dans la propriété
@@P@bodyTpl@@.
==== Un objet réponse personnalisé ====
En théorie donc, dans chaque action, vous devez indiquer à l'objet réponse HTML
le titre, les feuilles de styles, le template principal etc. Si c'est la même
chose à faire dans chaque action (ce qui est bien souvent le cas puisqu'en
général les pages d'un même sites ont le même aspect, le même bandeau, menu etc),
ça risque bien de devenir rébarbatif.
Pourquoi donc n'aurions nous pas un objet réponse html qui définit lui même
ces propriétés, et qu'on récupérerait dans chaque action et en lui indiquant
juste ce qui est spécifique à la page affichée ?
C'est en fait ce qui se passe dans une application créée avec @@c@create-jelix-app@@.
Dans le répertoire @@F@app/responses/@@, vous avez une classe @@C@myHtmlResponse@@
déjà créée, qui hérite de @@C@jResponseHtml@@. Et qui défini certaines choses
par défaut:
class myHtmlResponse extends jResponseHtml {
public $bodyTpl = 'jelix~defaultmain';
function __construct() {
parent::__construct();
// Include your common CSS and JS files here
}
protected function doAfterActions() {
// Include all process in common for all actions, like the settings of the
// main template, the settings of the response etc..
$this->body->assignIfNone('MAIN','no content
');
}
}
On voit que le template par défaut des pages est le template "jelix~defaultmain"
(qui correspond au fichier @@F@lib/jelix/core-modules/jelix/templates/defaultmain.tpl@@).
Cette classe @@C@myHtmlResponse@@ est déclarée dans la configuration comme
correspondant au type de réponse "html". Ceci est spécifié dans @@F@app/system/mainconfig.ini.php@@ :
[responses]
html=myHtmlResponse
Quand on fait donc @@$this->getResponse('html')@@ dans un contrôleur, nous
obtenons alors un objet @@C@myHtmlResponse@@ au lieu de @@C@jResponseHtml@@
(comme c'est le cas par défaut si on ne passe pas par createapp).
À propos de "jelix~defaultmain", il n'est pas besoin de mettre le suffixe ".tpl"
du nom du fichier, car il s'agit en fait d'un [[https://docs.jelix.org/fr/manuel-1.7/concepts/selecteurs|sélecteur Jelix]].
Un [[https://docs.jelix.org/fr/manuel-1.7/concepts/selecteurs|sélecteur]] est une
chaîne, permettant de désigner facilement une ressource du projet, indépendement de son emplacement physique.
Un sélecteur comporte un nom de module et un nom de ressource séparés par le
caractère "~", comme ceci : @@nom_module~nom_ressource@@. La partie "nom_module~"
est facultative quand il s'agit du module courant. Le nom de la ressource n'est
pas forcément un nom de fichier, même si la plupart du temps elle désigne un
fichier. L'objet qui utilise le sélecteur
(ici [[https://docs.jelix.org/fr/manuel-1.7/composants/templates|jTpl]]) sait comment
récupérer le fichier correspondant au sélecteur. Vous verrez que les sélecteurs
sont abondamment utilisés, et permettent une certaine souplesse et une
indépendance vis à vis des chemins de fichiers physiques.
==== Premier affichage ====
Voyons maintenant ce que génère cette réponse avec le template "jelix~defaultmain",
avant même que l'on ait à coder quoique ce soit.
Nous n'allons pas configurer un serveur web nginx ou apache, mais utiliser, pour la démonstration, le serveur web de php.
cd actu.org
php -S localhost:8080 -t www
Tapons l'adresse suivante dans le navigateur : http://localhost:8080/index.php/news/default/index
"news" est le nom du module, "default" le nom du contrôleur, et "index" le
nom de la méthode dans le contrôleur. "default" et "index" étant des noms par
défaut pour Jelix, vous pouvez, pour cette action, taper http://localhost:8080/index.php/news/.
Ou encore, comme nous avons indiqué @@--default-module@@ à la création de l'application,
vous pouvez même juste indiquer http://localhost:8080.
Si il n'y a pas d'erreur, vous avez cette page :
Welcome in your new jelix application
no content
==== Créer un template général ====
Nous avons donc un template principal ("jelix~defaultmain") pour toutes les pages.
Comme vous le voyez à l'affichage, ce n'est pas forcément ce que vous voulez.
Créer donc un nouveau template général, que vous mettrez dans
@@F@modules/news/templates/main.tpl@@ par exemple:
Actu.org: toute l'actu
{$MAIN}
Comme il a été dit auparavant, le contenu du template sera le contenu de la
balise @@E@@@. C'est pourquoi vous n'avez pas à mettre les balises
standard @@E@@@, @@E@@@, etc... Juste le contenu de la page.
@@{$MAIN}@@ affiche une variable de template nommée @@V@$MAIN@@. Dans chaque action,
vous devrez indiquer le contenu de cette variable, qui sera dans le cadre de
notre application, le contenu spécifique de la page que l'on veut afficher.
Spécifions maintenant ce template à notre réponse personnalisée dans
@@F@responses/myhtmlresponse.class.php@@:
class myHtmlResponse extends jResponseHtml {
public $bodyTpl = 'news~main';
....
Si vous rafraîchissez http://localhost:8080/news/, vous devriez voir votre nouveau template.
==== Template de contenu spécifique ====
Pour notre action principale, nous allons définir un template, dont le contenu
sera assigné à la variable @@V@$MAIN@@ du template principal (ce qui vous fera
donc deux templates).
Créez un fichier listenews.tpl dans le répertoire //templates// du module.
Et mettez y ce contenu :
Dernières actualités
Ouverture prochaine de cette rubrique.
==== Utilisation du template dans l'action ====
Voyons maintenant comment cela se concrétise dans le contrôleur :
class defaultCtrl extends jController {
function index () {
$rep = $this->getResponse('html');
// on définit un titre de page
$rep->title = 'Dernières actualités';
// creation d'un objet template pour le contenu spécifique
$tpl = new jTpl();
// assignation du resultat du template listenews à la variable $MAIN
$rep->body->assign('MAIN', $tpl->fetch('listenews'));
return $rep;
}
}
Rafraichissez la page dans votre navigateur. Vous devriez avoir:
Actu.org: toute l'actu
Dernières actualités
Ouverture prochaine de cette rubrique.
ou plus exactement le code HTML suivant :
Actu.org: toute l'actu
Dernières actualités
Ouverture prochaine de cette rubrique.
==== Problème d'affichage des caractères accentués ====
Si les caractères accentués s'affichent mal dans votre navigateur, c'est que
l'édition de vos fichiers ne s'est pas faite avec le même encodage
que celui indiqué dans la configuration de Jelix (qui est par défaut UTF-8). Donc :
* soit vous modifiez la configuration de votre éditeur préféré pour qu'il édite en UTF-8, et il faut alors convertir vos scripts/templates existants pour UTF-8 (ou les réécrire)
* soit vous modifiez le fichier @@F@app/system/mainconfig.ini.php@@ en changeant la propriété charset (en mettant ISO-8859-1 par exemple). Toutefois, nous vous recommandons de rester en UTF-8, ceci étant le charset universel et le plus adopté sur le web aujourd'hui.