Lors de la réalisation de vos projets, l’étape de la construction du backend est devenue un passage obligatoire. Que cela soit un souhait initial du client ou une envie de pouvoir proposer une prise en main du site via une interface, le backoffice justifie pleinement sa présence et son importance. Cette philosophie est très largement soutenue par Symfony avec son générateur CRUD d’admin, ses filters, l’extensibilité de ses templates, l’internationalisation… Le but de cet article est de chercher plus loin dans les fonctionnalités de base proposées par Symfony pour l’élaboration de notre backend.
La Homepage
Proposer à l’administrateur l’affichage d’une page de listing d’un modèle, dès le login effectué, est bien sûr une mauvaise idée. Une page d’accueil doit être présente et peut présenter les différentes informations pertinentes et vitales pour l’administrateur : Dans cette capture, l’accueil permet dès l’authentification, de connaitre les différentes statistiques du site et d’avoir un accés direct aux actions redondantes mais nécessaires : Utilisateurs en attente de validation, Visualisation de messages suspects etc… Pour aller plus loin, vous pouvez afficher certaines indications propres à la fréquentation sur votre site. Si vous possédez un compte Google Analytics, c’est l’occasion d’en profiter ! En effet, une API pour accéder à ses statistiques est disponible depuis peu, et devinez quoi ? Il existe un plugin Symfony pour l’utiliser : sfGoogleAnalyticsPlugin. Alors plus d’excuses pour ne plus proposer une page d’accueil efficace à votre client.
Un listing précis et concis
Par défault, Symfony propose un listing complet des différents champs de votre modèle. Cela est souvent beaucoup trop confus et non adapté pour les besoins d’un client : Il apparait comme essentiel de sélectionner et de renommer les différentes colonnes de votre modèle que vous souhaitez afficher. De même, selon la complexité de votre objet, il peut être intéressant de fournir des informations “associées” : Pour un objet Article de Blog, il est pertinent d’afficher le nombre de Commentaires associés. Dans mon cas, j’affiche le nombre d’utilisateurs associés à un projet : Concernant les valeurs, il est déconseillé d’utiliser des IDs. Ils apportent aucune information quantitative ou qualitative pour l’administrateur. De plus, il est préférable de créer une action pour les tâches répétitives. Cela simplifie grandement l’administration pour un client et on évite ainsi de l’envoyer directement sur les pages d’éditions. La documentation de Symfony étant très complète sur ce sujet, nous allons continuer notre tour d’horizon avec les filters.
Les filtres au service de la navigation
Symfony permet à l’aide du générateur d’administration, de trier vos modèles en fonction de filtres spécifiques. Mais comme pour la partie précédente, les problèmes sont similaires : Trop de champs renseignables, souvent complexes et non traduits. Outre la documentation de Symfony qui vient encore une fois à notre aide, il faudra faire un tour sur cet article pour compléter la traduction des filtres sur le backend. Mais la véritable force des filtres, c’est leur utilisation de manière transparente par le client. En effet, si on reprend l’exemple de notre page d’accueil, on propose un lien “3 projets en attente” sensé rediriger sur les projets concernés.
Comment cela est-il possible ?
Tout simplement en créant le filtre qui nous permet de trier nos projets, dès le chargement de la page. La manière la plus simple est de passer nos filtres dans l’URL.
Mise en place
Il faut d’abord surcharger notre action index du module concerné :
public function executeIndex(sfWebRequest $request) { if($request->getParameter('filter')) { $this->setFilters($request->getParameter('filter')); } parent::executeIndex($request); }
On vérifie si l’on passe un paramètre “filter” lors du chargement de la page. Le cas échéant, on applique les filtres renseignés. Mon lien permettant de voir seulement les utilisateurs en attente de validation aura le routing :
@user_user?filter[is_active]=0
Pour mes projets en attente de validation, c’est la pratiquement la même chose, on indique en plus le type de l’argument.
@project_project?filter[state][text]=1
Pensez à bien regarder la structure de vos filtres en cas d’erreur.
Allez plus loin
Maintenant que vous savez filtrer directement à partir d’un lien, vous allez pouvoir vous servir de cette astuce autre part que sur la page d’accueil. Revenons sur nos listing. Nous avons vu qu’il était pratique pour le client d’afficher par exemple le nombre d’objet Commentaire associés à un objet Article. Nous sommes maintenant capables de rediriger directement vers les objets associés. On ajoute une méthode d’affichage sur notre objet Article :
public function getCountPositioning() { return link_to($this->getComments()->count(),'@comment_comment?filter[article_id]='.$this->Id()); }
On retourne ainsi le lien contenant le filtre permettant de trier les commentaires en fonction de l’ID de l’article. Il suffit de modifer notre action index afin de correctement afficher notre entité HTML :
public function executeIndex(sfWebRequest $request) { sfConfig::set('sf_escaping_strategy', false); if($request->getParameter('filter')) { $this->setFilters($request->getParameter('filter')); } parent::executeIndex($request); }
Voilà pour nos petites idées pour vous aider à parfaire votre back office. N’hésitez pas à parlez de vos astuces dans les commentaires.
Mise à jour
La désactivation de la stratégie d’échappement des caractères (sfConfig::set(‘sf_escaping_strategy’, false)) est utilisée pour éviter l’affichage des balises <a> obtenues depuis notre modèle. Cette méthode à deux limites : D’une part, elle est inhérente à certaines failles de sécurité provoquées par une injection de code malicieux (cf commentaire de @Niko) ; D’autre part, on perd l’avantage lié à notre MVC en faisant parvenir le lien directement depuis le modèle.
Il est alors conseillé de déclarer dans notre generator.yml l’utilisation des partials pour afficher nos liens filtrants :
display: [_countComments]
Il suffit alors de créer notre partial _countComments.php dans le dossier templates/ de notre module :
<?php echo link_to($article->getComments()->count(), '@comments_comments?filter[article_id]='.$article->getId());?>