Création d'un composant MVC - Hello World
-
Document typeTutoriel PHP
-
NiveauDébutant
-
Version Joomla1.5.x
-
Dernière modification17.12.11
-
Version PHP4.x, 5.x, 5.3.x
-
Créé parGarstud
-
Version MySQL4.x, 5.x
-
Introduction
Ce tutoriel a pour but de montrer comment créer un composant simple de type HelloWorld en utilisant l’architecture MVC proposée par Joomla! Son but n’est pas de vous montrer toutes les subtilités de la création d’un composant, mais bien de voir étape par étape, comment créer un composant simple utilisant le modèle MVC.
Ce tutoriel est axé sur le développement de la partie Site (Frontend) d’un composant. La partie Administration (Backend) étant plus élaborée tout en étant basée sur la même architecture, son développement sera détaillé lors d’un prochain tutoriel.
> tutoriel Admin à venir prochainement !
Pré-requis
Si le niveau de connaissances nécessaire pour appréhender le développement sous Joomla ! est standard, il est toutefois conseillé de posséder des bases en Programmation Orienté Objet (POO), ainsi que des bases du framework Joomla!
Pour ce dernier point, la lecture de l'article suivant devrait vous éclairer :
> Appréhender les bases du développement avec le framework Joomla !
Composant Frontend
Objectif : créer un composant simple qui affiche la liste des articles publiés dans votre Joomla

A) MVC d'un composant
Le MVC correspond au decoupage d'un script en 3 scripts spécialisés : le Controlleur, la Vue et le Modèle de données. Seule particularité de Joomla, la vue de son MVC est découpé en une Vue (JView) et en 1 ou plusieurs Layout (« calque » ou « couche » d' écran) selon ce que vous souhaitez afficher comme rendu (Liste, table, blog …).

une requête HTTP (url) est chargée par un internaute
1) Votre classe contrôleur qui hérite de Jcontroller (la classe fournit par le framework) va traiter la demande afin de contrôler
- si toutes les conditions sont requises
- qualifier le chargement de la vue et/ou du modèle demandé
2) la vue charge les données nécessaires en appelant le modèle
3) le modèle accède aux données demandées et les fournis à l'appelant (la vue)
4) la vue renvoie vers le Layout demandé. Le layout s'exécute en formatant le rendu des données au format HTML
puis le résultat HTML est renvoyé à l'appelant (l'internaute)
Note : notez que la notion de Layout pour le rendu de votre vue va notamment permettre de :
- typer votre affichage, ainsi vous pouvez avoir un layout Blog ou Table selon le rendu attendu de la page
- introduire la notion de surcharge ("override" en anglais) qui permet a quiconque de personnaliser le rendu de votre layout sans "hacker" votre code source. Il lui suffira de copier votre layout dans un dossier spécifique de son template Joomla, pour que ce "clone " de votre écran soit utilisé à la place du votre !
B) Structure du composant
La construction du composant va permettre de concevoir les 3 briques (Controleur, Modele et Vue).
Les scripts seront regroupés dans un ZIP selon une arborescence spécifique :
manifest.xml
/admin
/site
simplecontent.php
controller.php
/models
ecran1.php
/views
/ecran1
view.html.php
metadata.xml
/tmpl
list.php
list.xml
Afin de décrire à joomla!, le processus d'installation a respecter pour votre composant, un fichier XML appelé le « manifest » va décrire les informations d'installation.
Il contient une entête déclarative, la liste des fichiers a installer et des informations d'administration
|
... <files folder="site"> <filename>index.html</filename> <filename>simplecontent.php</filename> <filename>controller.php</filename> <folder>models</folder> <folder>views</folder> </files> <administration> <menu link="option=com_simplecontent" img="templates/khepri/images/menu/icon-16-user.png">Simple Content</menu> <files folder="admin"> <filename>index.html</filename> </files> </administration> ... |
La balise <files folder="site"> décrit les fichiers a copier (ici pour la partie site frontend)
La balise <administration> contient des informations comme le lien du menu avec le nom de votre composant "com_simplecontent"
C) le script d'entrée
Le script “simplecontent.php” a une structure toujours identique dans 95% des composants.
Il ne fait qu’orienter l’appel du composant vers le contrôleur principal.
<?php
defined('_JEXEC') or die('Acces interdit'); require_once (JPATH_COMPONENT.DS.'controller.php'); if($controller = JRequest::getWord('controller')) { $path = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php'; if (file_exists($path)) { require_once $path; } else { $controller = ''; } } $classname = 'SimplecontentController'.ucfirst($controller); $controller = new $classname( ); $controller->execute(JRequest::getCmd('task')); $controller->redirect();
?>
|
Seul le $classname est à personnaliser pour préciser le nom de votre classe de controleur !
Note : la présence de _JEXEC dans tous les scripts PHP est la 1ere règle de sécurité pour vérifier que ce script PHP est bien appelé par le framework Joomla et pas par un script pirate !
D) le controleur principal
le “controller.php” va gérer l’aiguillage des appels vers les bons modèles et vues.
il implémente toujours la méthode display() pour gérer les appels par défaut
il peut implémenter autant de fonctions de type « task »que l’on souhaite dans le composant
-
Définir un nom de classe standard : <nom du compo>Controller
<?php
defined('_JEXEC') or die('Accès interdit'); jimport('joomla.application.component.controller'); class SimplecontentController extends JController { function __construct() { parent::__construct(); } function display() { // forcer la vue par défaut si aucun paramétre renseignés dans l'url if ( ! JRequest::getCmd( 'view' ) ) { JRequest::setVar('view', 'ecran1' ); JRequest::setVar('layout', 'list' ); } parent::display(); } /* * Task : mon écran de liste */ function list_contents() { JRequest::setVar('view', 'ecran1' ); JRequest::setVar('layout', 'list' ); parent::display(); } } ?>
|
Ici, la fonction « list_contents() » correspond à une task qui sera appelé pour afficher la vue correspondante. Elle chargera la Vue 'ecran1' et choisir le layout 'list.
E) la Vue
La Vue hérite de JView. Cette classe du framework Joomla fournit tout ce dont nous aurons besoin dans le cadre de la construction et de l'affichage de la vue.
Elle est constituée de :
- un nom normalisé de classe : <bnom du compo>View< nom de la vue>
- une fonction display() correspondant a l’appel du parent::display() du controller.php
- le chargement de l'application en appelant la fabrique JFactory
- du code pour récupérer les paramètres (de l'url et du menu)
- des test de JDEBUG pour utiliser le debuggeur de Joomla!
- des manipulations d’objet comme JDocument …
plus d’infos, voir Wiki joomla : http://docs.joomla.org/Platform/11.1
- l’appel du modele et son interrogation pour nos données et les informations de pagination
- l’envoi de variables au Tmpl en utilisant la méthode assignRef()
<?php
jimport( 'joomla.application.component.view'); class SimplecontentViewEcran1 extends JView { function display($tpl = null) { $mainframe = JFactory::getApplication(); //recuperation du parametre contextuel dans l'url $ pParam1 = JRequest::getVar("param1"); //recuperation du parametre defini dans le menu $params =& $mainframe->getParams('com_simplecontent'); $pParam2 = $params->get('param2'); // affichage de debug, si 'debug systeme' activé dans la configuration de votre Joomla! if (JDEBUG) echo "<br />DEBUG : test de Debug systeme Joomla : param1=".$pParam1 .", param2=".$pParam2; // personnaliser votre page (votre JDocument) $document =& JFactory::getDocument(); $document->setTitle( "titre de cet écran dans la barre du navigateur" ); // recuperation de la liste des données du modele $rowsList = $this->get('DataContents'); // recuperation de l'objet de navigation dans la pagination $pagination =& $this->get('Pagination'); // transmet les données au layout $this->assignRef('contentsList', $rowsList); $this->assignRef('pagination', $pagination); parent::display($tpl); } } ?>
|
Note : Le mot clé « parent » désigne en POO la classe dont on hérite, ici notre classe "extends" JView
donc, parent::display($tpl) permet de demander a la classe JView du framework de prendre la main pour lancer la méthode display() de JView (méthode procédant au chargement du layout et au rendu HTML de celui-ci)
F) le Modèle
le fichier /models/ecran1.php doit permettre de gérer toutes les requêtes SQL et accès BD pour la vue du même nom : ecran1
Le modèle est constitué de :
- un nom de classe standard : <compo>Model<vue>
- des variables et un constructeur standard qui récupere notamment les informations de pagination
- une fonction privée _buildQuery pour construire la requete principal
- autant de fonctions que souhaitées pour récupérer les données dans la vue : getDataContents() … etc
- puis des fonctions standards pour gérer la pagination … etc (voir le zip du composant)
<?php
defined( '_JEXEC' ) or die( 'Acces interdit' ); jimport( 'joomla.application.component.model' ); class SimplecontentModelEcran1 extends JModel { function __construct() { parent::__construct(); $mainframe = JFactory::getApplication(); // recupere les parametres de pagination de la session utilisateur $limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', 20, 'int'); $limitstart = JRequest::getVar('limitstart', 0, '', 'int'); // si limit a changé, on ajuste la nouvelle limitstart pour notre liste $limitstart = ($limit != 0 ? (floor($limitstart/$limit)*$limit) : 0); // on mémorise les nouvelles valeurs dans la session utilisateur $this->setState('limitstart', $limitstart); $this->setState('limit', $limit); } /** * Methode pour construire la requete SQL * @return string de la requete SQL */ function _buildQuery() { $query = null; $query = "SELECT id, title, modified, hits FROM #__content WHERE state=1"; if (JDEBUG) echo "<br />DEBUG : query SQL=".$query; return $query; } /** * Ma Methode pour recuperer mes données * @return object with data */ function &getDataContents() { $this->_data = null; // construction de la requete SQL $query = $this->_buildQuery(); // recuperation des données selon la page 'Pagination' ou l'on se trouve if ($query) $this->_data = $this->_getList( $query, $this->getState('limitstart'), $this->getState('limit') ); return $this->_data; } … etc ?> |
G) le layout (calque) de l'écran
Le rendu HTML est déporté dans le fichier de /tmpl/list.php de la vue.
Ce script affiche les données qui vont construire l’écran au format HTML.
Le layout peut être notamment constitué de :
- un formulaire <form> qui défini une « action » correspondant à l'url du composant
- une boucle pour afficher les données en provenance de la vue (préfixées par « $this-> »
- l'affichage du bloc de navigation de la pagination
<?php
defined('_JEXEC') or die('Accès interdit'); ?> <div class="component_simplethu"> <h1 class="componentheading">Liste des données Contents</h1> <form action="index.php?option=com_simplecontent" method="post"> <div> <ul> <?php // boucle d'affichage de toutes les données foreach($this->contentsList as $dataContent) { ?> <li class="result_item"> <span class="result_item_desc"> <?php echo $dataContent->title ?> - (<?php echo $dataContent->modified ?>) : <?php echo $dataContent->hits ?> visites </span> </li> <?php } ?> </ul> <div id="map_pagination"><?php echo $this->pagination->getListFooter(); ?></div> </div> </form> </div> |
H) déclaration des menus
Pour permettre d'accéder facilement à votre composant, il peut être intéressant de proposer la création d'un menu Frontend en passant par la gestion des menus du Backend.
Pour ce faire vous devez créer 2 fichiers XML :
Un fichier nommé “metadata.xml” pour présenter l'entrée de menu qui correspond a votre dossier de Vue.
Il faut alors renseigné un title et un message :
|
<?xml version="1.0" encoding="utf-8"?> <metadata> <view title="ecran1 de Simple Content"> <message> <![CDATA[Ecran qui affiche la liste des contenus]]> </message> </view> </metadata> |
Le fichier “list.xml” pour qualifier le lien de menu vers l’écran « list.php ».
Dans notre exemple, le fichier déclare un « title » et un « message » dans la balise « layout ». Puis dans la balise « state », un « name » et une « description » seront affichés sur l'écran de création du menu et 2 paramètres seront personnalisable dans ce même écran.
Le paramètre inclut dans la balise <url> à la spécificité d’être transmis dans l'url et donc de pouvoir être modifié de façon contextuelle !
|
<?xml version="1.0" encoding="utf-8"?> <metadata> <layout title="Liste des contenus"> <message> <![CDATA[La liste d'affichage avec les titres des articles]]> </message> </layout> <state> <name>Liste Simple Content</name> <description>La liste d'affichage avec les titres des articles</description> <url> <param type="text" name="param1" label="Mon param1" description="le 1er param (inclu dans l'url)" default="" /> </url> <params> <param type="text" name="param2" label="Mon param2" description="le 2nd param" default="" /> </params> </state> </metadata> |
ces 2 fichiers permettront d'avoir ce rendu dans le backend, dans la gestion des menus :


Composant complet
Pour vous permettre de tester et personnaliser cet exemple, vous trouverez ci-dessous, le composant complet
Note : ce tutoriel a été complètement refondu en décembre 2011 pour fiabiliser et améliorer sa compréhension, merci de vos retours dans les commentaires ci-dessous.
-
fichier
-
-
Catégories
-





2.5
12.x
Commentaires
Y-a-t-il quelque chose à faire en plus quand on développe un composant dans la partie administration ? Merci
Cordialement cédric
serait-il possible svp d'avoir le même tuto mais avec la version 1.7 avec les subtilités suivantes :
- l'url de l'action du formulaire ait en plus un id, se comporter différemment en fonction de la valeur de l'id
exemple :
-que dans le modèle il y ait une méthode de contruction de la requête sql avec un paramètre ( function _buildQuery($pa ram)) du coup ça change tout pour le getDataContents non ????
- un exemple où le contrôleur fait appel au model
je trouve qu'il y a trop de tuto sur les anciennes versions et pas assez sur la v7 c'est juste une remarque de débutant
Aidez moi svp je bloque sur ces points et je n'arrive plus à avancer
S'il s'agit de surcharge, il s'agit d'overload ; s'il s'agit de redéfinition/réécriture, il s'agit alors d'override. Que ça soit en traduction ou informatique, le fait de surcharger est de l'overload.
mon site tourne bien avec Joomla1.6 (sur localhost)mais mais lorsque j'ai fait hébergement la parti client marche bien mais j'ai un problème dans le panneau d'administration j'explique
je sais ouvrir les menus sans problème ( modules - composents - plugin-s .... ) mais quand je click sur mon composant de menu et je clique sur un élément je tombe sur ce message
Le site Web a rencontré une erreur lors de l'extraction de http://xxxxxxxxxxxxxxx.be/administra...&task=edit&cid[]=21. Cela peut être dû à une opération de maintenance ou à une configuration incorrecte.
avez vous une solution
Merci d'avance
Un très grand Merci pour Ce tutoriel,
Merci encore et bon travail
HelloWorld
Tuto - Hello The World
helloworld.php
models/simple.php
views/simple/tmpl/default.php
views/simple/view.html.php
Pour les codes PHP, vous devez impérativement écrire, par exemple :
au lieu de :
defined('_JEXEC') or die ('Restricted access');
echo("Hello the world");
PHP-->
Pour le xml, en lisant la doc on s'en sort : http://goo.gl/2JfVP
Voici ma version qui fonctionne avec ce tuto :
HelloWorld
Tuto - Hello The World
helloworld.php
models/simple.php
views/simple/tmpl/default.php
views/simple/view.html.php
je suis bloqué au point 3.1 : erreur 404 composant non trouvé. J'ai cherché un peu sur le web, mais là je suis bloqué...
S’abonner au flux RSS pour les commentaires de cet article.
Ajouter un Commentaire