Mise en ligne de Stick’innov et framework Typolight
Stick’innov est une société de vente de stickers muraux, vous proposant les classiques stickers adhésifs et pochoirs, ainsi qu’un produit nouveau : le sticker magnétique. Celui-ci peut être choisi avec un support en laize magnétique ou en peinture aimantée. Un large catalogue vous permet de rajouter une touche personnelle corespondant aux différentes ambiences de votre logement, pour adoucir votre salon, ajouter une note exotique ou créer la surprise au détour d’une fantaisie.
J’ai réalisé ce site avec Telly Delalande, pour le compte de la société Stick’Innov. Telly s’est occupé de la charte graphique et de l’intégration et j’ai pris en charge le développement moteur et la couche javascript. Pour distinguer le site de ses concurents et lui offrir une avance en référencement, nous avons fait le choix de réaliser l’application sans utiliser flash, au profit d’une interface javascript non obstrusive et dégradable.
Le site est realisé entièrement sous Typolight, autant pour les pages statiques, que pour les fonctions motrices et que pour la partie boutique. Il constitue une première démonstration publique de ce qui est faisable avec Typolight et mon extension framework. Cette application étant commerciale et réalisée pour un tiers, je ne peux en montrer le code, mais je peux démontrer certaines particularités du framework.
Les routes
Ce qui est peut-être le plus flagrant pour un utilisateur de Typolight est l’usage des routes. Prenons par exemple l’adresse : http://www.stick-innov.fr/adhesif/Abstrait-35/modele/105.html . Ceci est rendu possible en utilisant une “route”. Une route est caractérisée par une définition, reflétant l’url, qui lorsqu’elle correspond renvoie à une page donnée avec des paramètres donnés. Ces routes peuvent être configurées soit dans le config/config.php de votre module, soit en backend. Ici, je l’ai mise dans le config.php, ce qui donne :
array_insert( $GLOBALS[ 'TL_ROUTES' ], 0, array( "fr_adhesif" => array( 'route' => 'adhesif/:theme/modele/:modele_id', 'staticParams' => array( 'action' => 'index', 'type' => 'adhesif', ), 'method' => 'GET', 'resolveTo' => 'adhesif', ), ) );
La définition de la route est donc ici : ‘adhesif/:theme/modele/:modele_id’. :theme et :modele_id sont des variables. N’importe quelle valeur peut y être introduite et sera injectée dans les paramètres GET, récupérable avec $this->Input->get( ‘nom_du_param’ ).
L’option ’staticParams’ permet de rajouter arbitrairement des paramètres supplémentaires. Ici, ‘action’ est utilisé pour déterminer quelle action le contrôleur devra executer et ‘type’ est un paramètre que j’ai ajouté pour pouvoir ne faire qu’un contrôleur pour les trois types de produits.
L’option ‘method’ détermine quel verbe http accepte la route. En utilisant GET, nous interdisons l’usage de POST. Si nous utilisons un POST sur cette url, l’application répondra par une 404. Cela permet de router vers des actions ou pages différentes le GET et le POST sur une même url. Les options de ‘method’ sont : ‘GET’, ‘POST’ ou ‘GET/POST’. Ce dernier accepte les deux verbes.
Enfin, l’option ‘resolveTo’ indique la page vers laquelle la route redirige.
Cette route a un nom : ‘fr_adhesif’. Ce nom est utilisé pour générer une url à partir d’un nom, grâce à Route::compose(). Ainsi, si nous avons :
array_insert( $GLOBALS[ 'TL_ROUTES' ], 0, array( "product_list" => array( 'route' => 'voir/les/produits', 'staticParams' => array( 'action' => 'list', ), 'method' => 'GET', 'resolveTo' => 'produits', ), ) );
et que nous voulons faire un lien en utilisant cette route dans une vue, nous pouvons faire :
<a href="<?php echo Route::compose( 'product_list' ) ?>">Voir les produits</a>
ou, avec un insert tag :
<a href="{{Route::product_list}}">Voir les produits</a>
Il est ensuite possible de modifier la définition de la route sans avoir à modifier ce code.
Dans le cas de la première route que j’ai montrée, il y a également deux paramètres dynamiques, :theme et :modele_id. Ces paramètres sont ajoutés en passant un array associatif :
<a href="<?php echo Route::compose( 'fr_adhesif', array( 'theme' => $theme->urlName, 'modele_id' => $modele->id ) ) ?>">Voir les produits</a>
Enfin, les routes supportent l’internationalisation. Si nous avons :
array_insert( $GLOBALS[ 'TL_ROUTES' ], 0, array( "fr_adhesif" => array( 'route' => 'adhesif/:theme/modele/:modele_id', 'staticParams' => array( 'action' => 'index', 'type' => 'adhesif', ), 'method' => 'GET', 'resolveTo' => 'adhesif', ), "en_adhesif" => array( 'route' => 'adhesive/:theme/model/:modele_id', 'staticParams' => array( 'action' => 'index', 'type' => 'adhesif', ), 'method' => 'GET', 'resolveTo' => 'adhesif', ), ) );
nous pouvons utiliser :
<a href="<?php echo Route::composeI18n( 'adhesif', array( 'theme' => $theme->urlName, 'modele_id' => $modele->id ) ) ?>">Voir les produits</a>
La langue courante sera utilisée pour déterminer quelle route il faut suivre.
Un dernier point : l’ordre des routes importe. Il est possible d’avoir des urls auxquelles plusieurs routes correspondent, comme par exemple si on a “voir/produits/tous” et “voir/produits/:produit_id”. Si cela arrive, la première route rencontrée l’emportera.
Les contrôleurs
Les contrôleurs de Typolight ( ModuleQuelqueChose, héritant de FrontendModule ) sont pensés pour n’executer qu’une seule action, bien qu’il soit possible de les forcer. Il y a la méthode generate() qui sert à initialiser le module, et la méthode compile() qui passe les variables à la vue ( template, dans le vocabulaire Typolight ). L’extension framework rajoute une nouvelle classe : RoutedModule.
RoutedModule est pensé pour permettre de gérer facilement des actions multiples. Quand un RoutedModule est généré, il regarde s’il existe un paramètre GET ‘action’. S’il y en a un et qu’une méthode du même nom existe dans le module, celle-ci est appelée et la vue est automatiquement déclarée selon le schémas : ‘fe’ + nom du contrôleur + ‘_’ + nom de l’action. Sinon, la méthode index() est utilisée. Prenons l’exemple d’un contrôleur simple :
< ?php class ControllerProduct extends RoutedModule { protected $controller = 'products'; /* List products */ protected function index() { $product = new Product(); $this->Template->products = $product->all; } /* Show a product */ protected function show() { $product = new Product( $this->Input->get( 'product_id' ) ); $this->Template->product = $product; } /* Create a new product */ protected function create() { $product = new Product(); $success = false; if ( $posted = $this->Input->post( 'product' ) ) { $product->data = $posted; if ( $product->save() ) { $success = true; } else { $this->Template->errors = $product->errors; } } $this->Template->product = $product; $this->Template->success = $success; } /* Update a product */ protected function update() { $product = new Product( $this->Input->get( 'product_id' ) ); $success = false; if ( $posted = $this->Input->post( 'product' ) ) { if ( $product->update_attributes( $posted ) ) { $success = true; } else { $this->Template->errors = $product->errors; } } $this->Template->product = $product; $this->Template->success = $success; } /* Delete a product */ protected function delete() { $product = new Product( $this->Input->get( 'product_id' ) ); if ( $product->delete() ) { $this->redirect( Route::compose( 'product_list' ) ); } } }
Ceux qui se sont déjà servi de Ruby on Rails trouveront ici une note familière. Un utilisateur de Typolight pourra s’interroger sur les méthodes de Product. Product hérite en fait d’une autre classe du framework, EModel, que je traiterai une autre fois.
La première chose à faire est de donner un nom au contrôleur :
protected $controller = 'products';
Ensuite, on définit les différentes actions, et le paramètre GET ‘action’ déterminera lequel utiliser. La vue est automatiquement retrouvée d’après le nom du contrôleur et de l’action, comme je l’ai expliqué plus haut. Ici, on aura donc les vues : fe_products_index.tpl, fe_products_show.tpl, fe_products_create.tpl, fe_products_update.tpl et fe_products_delete.tpl .
RoutedModule offre de nombreuses autres fonctionalités, comme la possibilité de forcer l’action sans prendre en compte le paramètre d’action ( utile lorsqu’on a plusieurs RoutedModule dans une même page ), les getters et les setters, le cache, la gestion de json, et autres.
Si vous désirez essayer l’extension framework, vous pouvez la télécharger sur github. Je suis sur le point de publier mon troisième site l’utilisant et je le considère donc comme stable. La version 1.0 devrait sortir sous peu, après un cleanup de l’API et l’écriture de documentation.
10 octobre, 2009 à 21:50
Bonjour,
Bravo pour ce superbe et fonctionnel site “Stick’Innov” que vous avez réalisé. Votre article m’a donné l’occasion de constater qu’il était possible d’utiliser Typolight pour des fonctions et présentations sophistiquées ou complexes.
Par contre, j’ai eu énormément de mal à comprendre votre article, c’est sans doute parce que je ne suis pas programmeur.
N’auriez-vous pas la possibilité au travers d’un nouvel article de présenter de manière simple de créer un nouveau template sous Typolight avec l’interaction entre les différents éléments (page de présentation, feuille de style, modèles, modules, articles). Il semble que tout soit lié mais difficile de savoir dans quel ordre il faut utiliser ces concepts pour modifier correctement les choses.
13 octobre, 2009 à 16:04
Bonjour,
Et merci pour ce commentaire :)
Oui, effectivement, j’ai oublié de préciser que l’audience de cet article est les développeurs. Il s’agit en fait ici de la présentation d’une extension que j’ai réalisée pour rendre la tâche des développeurs plus simple.
Pour obtenir de l’aide sur l’utilisation générale de Typolight, vous pouvez vous rendre sur la documentation française ( http://www.typolight.fr/introduction.html ) ou sur le forum ( http://www.typolight.fr/forums/ ).
Pour répondre brièvement à votre question, les présentations de page sont le “squelette” des pages. Elles servent à définir une structure commune, comme par exemple un menu de navigation, une image d’en-tête, etc. Le contenu de la page sera placé à l’endroit où le module “article” apparaît.
Les modèles sont les fichiers HTML squelettes utilisés par une présentation de page (le plus courant étant fe_page). Il est nécessaire d’avoir des base en HTML pour les modifier (mais leur modification n’est pas indispensable).
Les feuilles de styles permettent de définir des règles CSS (il est nécessaire d’avoir des base en CSS pour comprendre leur fonctionnement). Elles s’attachent à une présentation de page pour définir comment le contenu de toutes les pages qui l’utilisent seront stylées.
Les modules sont des fonctionnalités isolées, pouvant être insérés dans une présentation de page ou un article, comme par exemple un menu de navigation ou un formulaire de connexion.
Les pages représentent une page classique d’un site, se caractérisant par une adresse unique. Une page peut comporter plusieurs articles, bien que la plupart du temps il n’y ait qu’un article par page.
Enfin, les articles sont le coeur du contenu, l’endroit où vous ajoutez votre texte.
En règle générale, le processus de création d’un site avec Typolight suit l’ordre que je viens d’utiliser pour présenter ces éléments. Je vous invite à consulter la documentation pour mieux saisir tout cela.