Développement du CMS Ocari avec Symfony Sébastien ANGELE Jérôme MACIAS Titre présentation Conférencier
Les besoins
Un CMS pour faire quoi? Gérer des contenus Gérer des médias Gérer des homes
Gérer des contenus des articles
Gérer des contenus des diaporamas
Gérer des contenus des dossiers
Gérer des contenus des infographies
Gérer des contenus des quiz, des sondages, des vidéos, des palmarès, des blogs, des tests
Gérer des médias
Gérer des homes Développement du CMS Ocari avec Symfony Sébas/en ANGELE Jérôme MACIAS
Un CMS pour qui? Pour des journalistes
Un CMS pour qui? Pour plusieurs sites web Lexpress.fr Lexpress Styles Cotemaison.fr Lexpansion.com Lentreprise.fr Votreargent.fr
Le contenu
Un contenu est standard Un titre Une image de Une Un chapo
mais aussi spécifique Du texte pour les articles Des flash pour les infographies Des images pour les diaporamas
Un contenu = x éléments 1 article = Home Texte Sommaire
Un contenu = x éléments 1 diaporama = Home Diapositives Sommaire
Un contenu = x éléments 1 article 1 diaporama Home Home Texte Diapositives Sommaire Sommaire
L élément de contenu Un fragment de contenu indépendant Une interface de saisie associée Un CRUD autonome
Le generator
Un type de contenu = un module
Un générator pour les modules
Un élément = un niveau virtuel supplémentaire Home Texte Sommaire
Un élément = un niveau virtuel supplémentaire Home actions lib templates
Un générator pour les éléments
Principe de la génération 1. Une tâche qui déploie le module dans l application 2. Un générator qui : 1. Crée les squelettes de chaque élément dans le module de l application 2. Crée le module en cache en construisant le contenu en fonction de ses éléments
Le module Article généré
Le generator.yml generator: class: ocaricontentgenerator param: model_class: Content primary_key: id type: theme: config: elements: home: article default label: À la une texte: label: Article sommaire: label: Suppléments
Le module Article généré
Un exemple de code généré class autoarticleactions extends sfactions { protected function init(ocaricontent $object) { } $this->content = new ocaricontentarticle($object); $this->content->addelements(array('home', 'texte', 'sommaire')); } public function save() { foreach ($this->content->getelements() as $element) { } $element->save();
Un exemple de code généré class BaseOcariContentArticleElementHome extends ocaricontentelementhome { public function configure() { $this->setname('home'); $this->setlabel('à la une'); } } class ocaricontentelementhome { public function save() { $this->form->save(); } }
Le générator pour un contenu Ocari dispose d éléments de contenu génériques et configurables Chaque contenu est construit en choisissant des éléments et en les configurants Chaque site peut construire et configurer ses contenus à partir des éléments standards Le contenu est standard... mais aussi spécifique
Les sfforms
Les sfforms au cœur des éléments
Les sfforms au cœur des éléments class BaseOcariContentDiaporamaElementDiaporama extends ocaricontentelement { public function getform() { $this->form = new sfform(); } } // fields $this->form->setwidget( surtitre', new sfwidgetforminput()); $this->form->setwidget('titre', new sfwidgetforminput()); $this->form->setwidget('chapo', new sfwidgetformtextarea()); $this->form->setwidget('diapos_media_list', new sfwidgetforminputhidden()); $this->form->setvalidator( surtitre', new sfvalidatorstring(array('max_length' => 128, 'required' => false))); $this->form->setvalidator('titre', new sfvalidatorstring(array('max_length' => 256, 'required' => false))); $this->form->setvalidator('chapo', new sfvalidatorstring(array('max_length' => 2048, 'required' => false))); $this->form->setvalidator('diapos_media_list', new sfvalidatorpass(); $this->form->getwidgetschema()->setnameformat( element_diaporama[%s]');
Des images pour les contenus Développement du CMS Ocari avec Symfony Sébas/en ANGELE Jérôme MACIAS
Les FormFilters pour la recherche class OcariMediaSearchFormFilter extends BaseFormFilterDoctrine { public function setup() { $this->setwidgets(array( source => new sfwidgetforminput(array('label => source')))); } $this->setwidgets(array('keywords => new sfwidgetforminput(array('label => 'Mots-clés')))); $this->setvalidators(array('keywords => new sfvalidatorstring(array('required' => false)))); $this->getwidgetschema()->setnameformat('media_search[%s]'); public function getmodelname() { } return 'OcariMedia'; } public function addkeywordscolumnquery($query, $field, $value) { $query->addwhere('titre LIKE? OR legende LIKE?', array('%'.$value.'%', '%'.$value.'%')); }
Doctrine
Et le workflow? Gestion des utilisateurs et de leurs droits Chaîne de production des contenus, de l édition à la publication Gestion de version de travail / version en ligne / historique
La puissance de Doctrine Création d une version de travail $object = $object->copy(); $object->online_content_id = null; $object->settransitionto(ocaricontent::workflow_state_draft); $object->save(); Gestion de l historique if ($objectonline = $this->object->getonlineobject()) { } $objectonline->fromarray(array( )); online_content_id' => null, history_content_id' => $objectonline->online_content_id, state' $objectonline->save(); => OcariContent::WORKFLOW_STATE_HISTORY,
Les sfevents
La publication avec des agents Publication d un contenu Prégénération Du HTML Indexation dans le moteur de recherche Indexation des Images liées (droits) Mise à jour Des homes Agents
Les événements au cœur des agents Le contenu envoie un événement lors d un changement d état Chaque agent connait les événements auxquels il doit répondre Chaque action connait les agents qui peuvent potentiellement répondre Génération en cache des agents chaque agent peut être configuré et surchargé pour chaque type de contenu
Le MVC
Gestion des homes : les zones
Gestion des homes : les modules
Gestion des homes Interface entièrement en Ajax avec prévisualisation
Le rendering du MVC de Symfony rendercomponent pour appel Ajax et non Ajax renderpartial pour centraliser les parties de templates récurrentes rendertext pour accélerer les temps de réponse
Filter pour conversion ISO / UTF8 public function execute($filterchain) { $request = $this->getcontext()->getrequest(); // Ajax request if ($request->isxmlhttprequest() && $this->isfirstcall()) { } $this->decodeparameters($request->getparameterholder()->getall()); } // execute next filter $filterchain->execute(); * Code inspiré d un snippet
Le sftask
Génération des homes: sftask Prégénération systématique du HTML de tous les blocs de homes en lançant une tâche : sur un événement (publication) à la demande (Gestion des homes) planifiée (contenus automatiques) Unification du code, facilité d appel
Les plugins
Multisite et déploiement Écueils à éviter : Incohérence fonctionnelle Maintenance lourde Évolution longue et complexe Customisation dégrade l outil
Multisite et déploiement Séparation du core et du spécifique Automatiser le déploiement Simplifier les mises à jour
Les plugins comme solution Ocari est un ensemble de plugins sfocariplugin sfocaricontentplugin sfocariuser... ocarimediaplugin ocarischeduleplugin
Les plugins comme solution Chaque site les utilise avec une configuration différente Chaque site implémente d éventuelles surcharges
Les plugins comme solution Conservation d une application de développement grâce à une tâche de génération de plugins Nécessité d un nommage très strict qui permet de séparer les différentes parties fonctionnelles d Ocari
Objectifs atteints grâce à Symfony Ocari est : déployable avec les fonctionnalités attendues configurable pour personnaliser suivant les sites les différentes fonctionnalités surchargeable pour les besoins spécifiques maintenable facilement
Questions sangele@groupe-exp.com jmacias@groupe-exp.com