Salut
N'hésitez pas à poster à la suite vos propositions de questions et/ou réponses pour la FAQ symfony ;)
http://php.developpez.com/faq/?page=sf
:merci:
Version imprimable
Salut
N'hésitez pas à poster à la suite vos propositions de questions et/ou réponses pour la FAQ symfony ;)
http://php.developpez.com/faq/?page=sf
:merci:
- Télécharger le fichier de channel à l'adresse : http://pear.symfony-project.com/channel.xml
- Dans la console, taper : pear channel-add "monChemin/channel.xml"
- Télécharger la dernière version stable du framework à cette adresse : http://www.symfony-project.org/get/symfony-stable.tgz
- Dans la console, exécuter : pear install --offline "monChemin\symfony-stable.tgz"
Ceci peut être utile lorsque le proxy bloque PEAR pour accéder à pear.symfony-project.com ....
source : http://www.symfony-project.org/forum/index.php/t/51/
Comment ajouter des lignes js ou css entre <head> et </head> ?
On peut ajouter des lignes java script simplement dans le fichier de config apps/application/config/view.yml tu trouveras
un paramètre javascripts: []
Insérer les noms des fichiers javascript séparé par virgule
Pareille pour les styles css (stylesheets: [])
Comment mettre à jour simultanément + qu’un élément dans votre page avec ajax ?
Source : http://www.developpez.net/forums/sho...php?t=551166#7
Pour mettre à jour simultanément + qu’un élément dans votre page Vous devez un peut bricoler la fonction remote_function qui possède une propriété très utile « complete »
Lorsque l'appel ajax n:1 se termine ; il déclenche automatiquement l'appel num:2Code:
1
2
3
4
5
6
7
8
9
10 echo javascript_tag( remote_function(array( 'update' => 'Zone2', 'url' => 'ajax/updatediv1', 'script' => true , 'complete' => remote_function(array( 'update' => 'Zone1', 'url' => 'Le nom de votre module/le nom de laction qui va mettre à jour Zone1', 'script' => true)), )) )
Vous pouvez même faire le nombre d’appel que vous souhaiter en ajoutant dans chaque remote_function cette propriété «complete »
Quelle est la différence entre
forward $this->forward(NomDuModule,NomDeL'action)
et redirect $this->redirect(NomDuModule/NomDeL'action)
Source :
http://groups.google.com/group/symfo...f0d98d19?hl=fr
Foward change simplement l'action en cours pour une autre. On reste dans la même transaction HTTP. Pour le client, on est donc toujours dans la même URL.
Redirect redirige complètement le serveur vers la page appelé et produit donc une nouvelle requête complète. Du coup au niveau du navigateur ce n'est pas la même URL qui est affichée.
Comment je peut transférer un paramètre avec forward comme le cas de redirect ?
Source :
http://groups.google.com/group/symfo...f0d98d19?hl=fr
tu n'as pas besoin de repasser les paramètres à la nouvelle action si tu souhaites accéder aux paramètres envoyés par le client. Par contre si dans ta première action tu crées une variable et que tu veux avoir cette nouvelle variable dans l'action du forward, le plus simple est de l'ajouter dans les variables de la requête en faisant avant le forward :
$this->getRequest()->getParameterHolder()->set('ma_variable', $valeur) ;
Dans l'action du forward, tu la récupéres en faisant:
$this->ma_variable = $this->getRequestParameter('ma_variable) ;
Vous etes sous easyphp 2.01 et un message d’erreurs apparait : MySQL extension not loaded
L’or de génération du schéma de base de données avec propel
En fait, symfony ne cherchait pas le bon fichier de configuration php.ini.
Juste copier le php.ini situé dans le repertoire appache d'easyphp et coller le dans le dossier de php5 et changer le path vers le dossier des extensions dans le fichier copié
Je profite d'une réponse que je viens de donner pour contribuer à la FAQ :D
Comment insérer du code personnalisé entre les balises <head></head> (ou ailleurs) ?
Il suffit d'utiliser un slot. Un slot est un emplacement réservé que l'on peut placer dans n'importe quel élément : un layout, un partial ou un component. Il se comporte alors comme une variable dont on peut modifier à volonté la valeur.
Le code destiné à être placé dans le slot est contenu dans le response global, et peut être défini n'importe où.
Exemple: on souhaite intégrer des styles entre les balises <head> et </head> dans un template particulier, et uniquement dans ce template. On commence par placer le slot dans le layout.php de l'application, entre les balises <head> et </head>
Ensuite, on défint le slot dans le template en question (ex: indexSuccess.php)Code:
1
2
3
4 <?php if (has_slot('my_slot_style')): ?> <?php include_slot('my_slot_style') ?> <?php endif; ?>
Le style voulu apparaîtra alors uniquement avec le template indexSuccess.Code:
1
2
3
4
5
6
7
8
9 <?php slot('my_slot_style') ?> <style type="text/css"> h1{ font-size:36pt; text-decoration:underline; } </style> <?php end_slot() ?>
Tout comme pour le ZendFramework avec Zend Studio for Eclipse, nous pouvons configurer notre outils PDT pour nous faciliter le travail :
Avant tout télécharger PDT ou Zend Studio for Eclipse
- Rendez-vous sur PHP Explorer et faites dérouler votre projet
- Cliquez doit sur Include Paths et sélectionnez ConfigureInclude Path
- Sélectionnez l'onglet librairies et cliquez sur add External Folder pour ajouter le répertoire de votre projet Symfony /!\ à la racine /!\
Autocompletion Propel :
Editez la ligne où se trouve propel.builder.addComments
Code:propel.builder.addComments = true
Astuces supplémentaires :
Colorisation de la syntaxe YAML : http://grupy.net/yamlEditor/
Pour aller encore plus vite : Bash autocompletion linux
Les tests unitaires sont intégrés dans Symfony et celà est une bonne choses pour connaître l'impacte de nos mises à jour sur nos modules.
Voilà avant tout, quelques méthodes implémentés :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 - diag($msg) // Affiche un commentaire sans faire de test - ok($test, $msg) // Teste une condition et ne retourne aucunes erreurs si elle est vraie - is($value1, $value2, $msg) // Compare deux valeurs et ne retourne aucunes erreurs si elle est vrai - isnt($value1, $value2, $msg) // Test l'inégalité de deux valeurs - like($string, $regexp, $msg) // Test une chaine de caractère à travers un expression régulière - unlike($string, $regexp, $msg) // Contraire de like - cmp_ok($value1, $operator, $value2, $msg) // Compare deux arguments avec un opérateur - isa_ok($variable, $type, $msg) // Vérifie le type d'un argument - isa_ok($object, $class, $msg) // Vérifie la Classe d'un objet - can_ok($object, $method, $msg) // Vérifie une méthode d'une classe ou d'un objet - is_deeply($array1, $array2, $msg) // Vérifie que deux tableaux on les mêmes valeurs - include_ok($file, $msg) // Vérifie si un fichier existe et qu'il a bien pu être inclut - fail() // Une faille : Utile pour tester des excpetions - pass() // Valider : Pour tester une exception - skip($msg, $nb_tests) // Nombre de test à échapper : pour les tests conditionnels - todo() // Message compté comme un test
Commandes utiles :
Exemple de test unitaire (Cookbook SF) :Code:
1
2
3
4 > php symfony test-unit maFonction ## Test maFonctionTest.php > php symfony test-unit maFonction maSecondeFonction ## Execute deux test : maFonctionTest.php et maSecondeFonctionTest.php > php symfony test-unit '*' ## Execute tout les test du répertoire test/unit
exempleTest.php
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 <?php include(dirname(__FILE__).'/../bootstrap/unit.php'); // On inclut l'objet que l'on souhaite tester class monObjet { public function maMethode() { // Contenu de ma méthode } } function throw_an_exception() { // Envoi d'une exception throw new Exception('exception thrown'); } // Initialisation de l'objet de test $t = new lime_test(16, new lime_output_color()); $t->diag('hello world'); $t->ok(1 == '1', 'the equal operator ignores type'); $t->is(1, '1', 'a string is converted to a number for comparison'); $t->isnt(0, 1, 'zero and one are not equal'); $t->like('test01', '/test\d+/', 'test01 follows the test numbering pattern'); $t->unlike('tests01', '/test\d+/', 'tests01 does not follow the pattern'); $t->cmp_ok(1, '<', 2, 'one is inferior to two'); $t->cmp_ok(1, '!==', true, 'one and true are not identical'); $t->isa_ok('foobar', 'string', '\'foobar\' is a string'); $t->isa_ok(new monObjet(), 'monObjet', 'new creates object of the right class'); $t->can_ok(new monObjet(), 'maMethode', 'objects of class myObject do have amyMethod method'); $array1 = array(1, 2, array(1 => 'foo', 'a' => '4')); $t->is_deeply($array1, array(1, 2, array(1 => 'foo', 'a' => '4')), 'the first and the second array are the same'); $t->include_ok('./fooBar.php', 'the fooBar.php file was properly included'); try { // Essai throw_an_exception(); $t->fail('no code should be executed after throwing an exception'); } catch (Exception $e) { // Capture de l'exception si il y'en a $t->pass('exception catched successfully'); } if (!isset($foobar)) { $t->skip('skipping one test to keep the test count exact in the condition', 1); } else { $t->ok($foobar, 'foobar'); } $t->todo('one test left to do');
Lorsque vous créez une application, un fichier situé dans apps/<monapplication>/config se nommant settings.yml, contient les configurations principales de Symfony.
Pour chaques environnement vous pouvez spécifier une directive :
Résultat :Code:
1
2
3 .settings: no_script_name: off (ou "on" pour l'utilisation du url rewriting)
Lors de votre link_to si le no_script_name est en off, index.php sera présent dans votre url (Utilisation de l'INFOPATH seul), dans le cas contraire vous ne le verrez plus . :yaisse2:
Le cache permet d'accélerer ses applications en sauvegardant du code HTML ou une page complète pour les requêtes à venir.
Symfony possède un système de cache très flexible car il permet de stocker les informations intérprétées des fichiers de configuration YAML, le template, le résultat des actions, un composant partiel.
Activation du cache :
Pour activer ou désactiver le cache, vous devez modifier le champ cache du fichier config/settings.yml.
Pour configurer le cache de chaques modules, vous devez vous rendre à son fichier cache.yml : "monapplication/modules/monmodule/config/cache.yml"Code:
1
2
3
4 dev: .settings: cache: on
Mettre en cache une action
Avec ceci, vous pourez enregistrer chaques pages de l'action choisie avec un paramètre différent en URL :
Mettre en cache un composantCode:
1
2
3
4
5 votreaction: enabled: on with_layout: false # valeur par defaut lifetime: 86400 # valeur par defaut
Mettre en cache un templateCode:
1
2
3 _moncomposant: enabled: on
Ici nous regardons si le cache nommé "users" existe, sinon on le stock dans le cache.
"monapplication/modules/monmodule/templates/untemplate.php" :
Pour en savoir plusCode:
1
2
3
4
5
6
7 <?php if (!cache('users')): ?> <?php foreach ($users as $user): ?> <?php echo $user->getName() ?> <?php endforeach; ?> <?php cache_save() ?> <?php endif; ?>
Lorsque vous créez des articles ou des billets pour votre blog, vous voudriez changer l'aspect de vos Urls pour qu'elles soient le plus facilement référencées.
Nous allons donc pour cela configurer la classe de notre modèle concernée, nous prendrons Articles.php (que Propel à généré à partir du shema.yml "_attributes: { phpName: Articles }"). Commencez par éditez le fichier lib/model/Articles.php :
Maintenant créons qui se chargera de récupérer l'id de l'article pour pouvoir l'afficher :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 class Articles extends BaseArticles { public function getUrlTitle() { // Suppression et conversions des caractères $result = self::remove_accents($this->getTitle()); $result = strtolower($result); $result = preg_replace('/\W/', ' ', $result); $result = preg_replace('/\ +/', '-', $result); $result = preg_replace('/\-$/', '', $result); $result = preg_replace('/^\-/', '', $result); return $result; } public function remove_accents($str, $charset='utf-8') { $str = htmlentities($str, ENT_NOQUOTES, $charset); $str = preg_replace('#\&([A-za-z])(?:acute|cedil|circ|grave|ring|tilde|uml)\;#', '\1', $str); $str = preg_replace('#\&([A-za-z]{2})(?:lig)\;#', '\1', $str); // pour les ligatures e.g. 'œ' $str = preg_replace('#\&[^;]+\;#', '', $str); // supprime les autres caractères return $str; } }
Dans la page qui listera les articles, changer l'url par :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 public function executePermalink() { /* Methode de lien permanent (Doc. Symfony) */ $posts = PostPeer::doSelect(new Criteria()); $title = $this->getRequestParameter('title'); foreach ($articles as $articles) { if ($post->getStrippedTitle() == $title) { $this->getRequest()->setParameter('id', $article->getId()); return $this->forward('articles', 'show'); } } $this->forward404(); }
Pour finir, nous allons annoncer dans le fichier routing.yml, que nous voulons utiliser l'action permalink lorsque nous voudrons afficher un article apps/monapplication/config/routing.yml :Code:
1
2 link_to($article->getTitle(), '@article?title='.$article->getStrippedTitle())
Code:
1
2
3
4 article: url: /articles/:title param: { module: articles, action: permalink }
Fait ;)
Question que beaucoup poses pour envoyer leurs projets sur un autre serveur sans pour autant dépendre de la librairie installée avec PEAR ou manuellement avec la source.
Nous voudrons donc faire une sorte de sandbox maison.
On fait un freeze et on copie notre librairie
Sinon vous pouvez avoir recours à la solution manuelle :Code:
1
2 > symfony project:freeze [votre/repertoire/symfony]
1. Duplication des fichiers lib
Rendez-vous dans le répertoire ou à été installé Symfony de base : dans le répertoire PEAR si vous avez installé PEAR ou dans le répertoire de la source si avez télécharger la source manuellement.
Ensuite copiez le contenu du répertoire "symfony/lib" vers le répertoire "~monprojet/lib"
2. Configuration d'accès aux lib
Maintenant que notre répertoire librairie à été placé dans notre projet nous n'aurons plus qu'à modifier l'accès à celle-ci.
Modifions le fichier "config/ProjectConfiguration.class.php" :
(ligne 2)
Voilà vous pouvez maintenant utiliser votre projet Symfony indépendamment de votre librairie principale.Code:
1
2
3
4
5
6
7 <?php require_once dirname(__FILE__).'/../lib/autoload/sfCoreAutoload.class.php'; //... //... ?>
Il est possible d'utiliser plusieurs base de données avec Symfony. Pour ce faire, nous devons créer deux configuration dans "config/databases.yml" :
Lorsque cela est fait, faites un clear-cache "symfony cc" et vous pourrez exploiter ces deux bases comme ceci :Code:
1
2
3
4
5
6
7
8
9
10
11 all: propel: class: sfPropelDatabase param: dsn: pgsql://base1@hostname/database1 database2: class: sfPropelDatabase param: dsn: mysql://base2@hostname/database2
Pour des utilisations plus avancées, vous pouvez imaginer un système de backup et "RAID" :).Code:
1
2
3
4 $c = new Criteria(); $bd1 = ArticlePeer::doSelect($c, Propel::getConnection('propel')); // base 1 $bd2 = ArticlePeer::doSelect($c, Propel::getConnection('database2')); // base 2
[Edit] Fait : http://php.developpez.com/faq/?page=sf#sf-pls-bdd
1.3 et 1.4 mise en production en novembre 2009. 1.3 sera maintenue jusqu'en 11/2010 et 1.4 jusqu'en 11/2012. Elles tournent sur PHP >= 5.2.4 et inclut [ame="http://fr.wikipedia.org/wiki/Propel"]propel [/ame]1.4 et doctrine 1.2 (par défaut).
Les deux versions sont presque identique, la seul différence est que la version 1.3 ajoute le support des fonctionnalités des versions antérieurs. On utilisera donc la 1.3 pour la reprise d'un projet existant et la 1.4 pour tous nouveaux projets.
http://www.developpez.be/images/kiten.jpg Télécharger et installer Symphony 1.3
http://www.developpez.be/images/kiten.jpg Télécharger et installer Symphony 1.4
1.2 mise en production en novembre 2009 et maintenue jusqu'en février 2010. Elle tourne avec PHP >= 5.2.4, inclut [ame="http://fr.wikipedia.org/wiki/Propel"]propel [/ame]1.3 (par défaut) et doctrine 1.0. Elle a vu la refonte du système des formulaires.
http://www.developpez.be/images/kiten.jpg Télécharger et installer Symphony 1.2
1.1 fut une version intermédiaire avant la sortie de la 1.2, sortie en juin 2008, elle n'est plus maintenue depuis juin 2009. Elle n'est plus téléchargeable.
1.0 est la première version stable, sortie en janvier 2007, elle n'est plus maintenue depuis janvier 2010. Elle tourne avec PHP >= 5.0, inclut [ame="http://fr.wikipedia.org/wiki/Propel"]propel [/ame]1.2 pour l'accès aux données
http://www.developpez.be/images/kiten.jpg Télécharger et installer Symphony 1.0
http://php.developpez.com/faq/?page=sf#sf-choix-version
Version symfony 1.4
Au niveau des templates
On rajoute dans le code du template du module : apps/<app>/modules/<module>/templates/view1Success.php
qui rajoute cette feuille dans le tableau des feuilles a charger. C'est cette méthode qui est recommandée par symfony à partir de la 1.4.Code:
1
2 <?php use_stylesheet('main.css') ?> <?php use_javascript('jquery.js') ?>
Au niveau des fichiers de configuration
On peut ajouter des lignes JavaScript simplement dans les fichiers de configuration config/view.yml soit au niveau de l'application, soit au niveau de chaque module, on peut y trouver les paramètre :
Pour le javascript : javascripts: []
Pour le CSS : stylesheets: []
Exemple fichier view de l'application : apps/<app>/config/view.yml
va insérer une feuille de style main.css dans chaque page de votre application.Code:
1
2
3 default: stylesheets: [main.css]
Exemple fichier view pour un module : apps/<app>/modules/<module>/config/view/yml
va nous permettre d'insérer pour tous le module (default) ou pour une vue spécifique.Code:
1
2
3
4
5 view1: stylescheets: [view1.css] default stylescheets: [module.css, impression.css {media: print}]
Le résultat de ces deux exemples nous donnes :
- pour tous les autres modules : main.css
- pour notre module sauf view1 : main.css, module.css, impression.css (pour le média print)
- pour notre module view1 : view1.css,module.css, impression.css (pour le média print), main.css
Plus d'information : The symfony Reference Book, Le fichier de configuration view.yml
Générer le code xhtml dans votre template
Vous devez ajouter dans votre layout.php les lignes qui permettent d'inclure les styles sheet et les java scripts.
apps/<app>/template/layout.php
http://php.developpez.com/faq/?page=sf#sf-js-css-headCode:
1
2
3
4
5
6
7
8
9
10
11 ... <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title><?php include_slot('title', 'Jobeet - Your best job board') ?></title> ... <?php include_javascripts() ?> <?php include_stylesheets() ?> ... </head> ...
Je voudrais préciser une chose au niveau de la différence 1.3/1.4 :
Sachant que la version 1.4 "supprime" pas mal de fonctionnalités par rapport aux versions antérieurs, il sera plus simple pour un débutant de prendre la version 1.3 pour garder une certaine compatibilité avec les divers tutos trouvables sur le net (mêmes les "officiels") qui ne sont pas (encore) mis à jour.
C'est mon retour d'expérience sur la 1.4, en tant que (grand) débutant :aie:
Je ne suis pas sur que ce soit le sujet idéal pour un débat sur l'intérêt des différentes version, mais je vais y contribuer :ccool:
Je pense qu'il faut, au contraire, commencer sur la 1.4, qui a un fonctionnement largement différent et qui se rapproche un peu plus de la 2.0 a venir. Tant qu'à apprendre, autan apprendre des choses qui vont servir après l'apprentissage.
La 1.3 ne sera suivie que jusqu'en 11/2010, les projets construits sur celle-ci et utilisant d'anciennes fonctions devront être repris et modifié sur la 1.4 ou la 2 a venir.
Effectivement, on trouve pas mal de tuto sur des fonctionnalités propres à la 1.0 et qui sont maintenue jusqu'à la 1.3, mais dépréciées et en voie de disparition, parce que largement améliorée par les nouvelles fonctionnalités (surtout autour des objets forms qui montent en puissance au détriment des helpers dans les templates qui disparaissent). Reste que je ne vois pas trop l'intérêt de ce former sur des fonctionnalités promise à la disparition et fondamentalement modifiées juste parce qu'il y a plus de tuto.
Une seul solution, augmenter les tuto sur la 1.4. Je vais essayer d'y apporter mon grains de sel.
Dernier argument, l'équipe de symfony recommande fortement de débuter tous nouveaux projets avec la 1.4Et je suis près a t'aider dans les méandres de la 1.4 pour en tirer toute la substance !Citation:
Comme le fait remarquer mimi68, j'aimerais nuancer ma remarque de façon temporelle : à l'heure actuelle, celle-ci est pertinente mais avec le temps et l'arrivée de plus de tuto 1.4, elle ne servira plus à rien.
Exemple, on cherche à ajouter un lien permettant d'afficher pour chaque catégorie, tous les contenus qui lui sont associés.
Dans votre application Backend, sélectionnez votre module, puis créez/éditez votre fichier config/generator.yml
object_actions permet de rajouter des actions pour chaque élément de votre liste.Code:
1
2
3
4
5
6
7
8 config: actions: ~ fields: ~ list: object_actions: _edit: ~ _delete: ~ getContenu: { label: 'Voir les contenus', action: getContenu }
label: Affichera le lien avec le texte choisi
action: appelle l'action executeGetContenu dans actions.class.php
Dans votre fichier actions.class.php du même module, ajoutez l'action:
En premier lieu on utilise un flash. Le site de Symfony nous dit qu'un flash est un "message éphémère stocké dans la session de l'utilisateur qui sera automatiquement supprimé après la requête suivante".Code:
1
2
3
4
5 public function executeGetContenu($request) { $this->getUser()->setFlash('categorie', $request->getParameter('id')); $this->redirect('@route_contenu'); }
Ici on enregistre l'id de la ligne que l'on souhaite voir, dans un identifiant "categorie".
Et on redirige l'utilisateur vers la page des contenus.
Pour afficher seulement les contenus dépendant de notre catégorie, Symfony nous propose d'utiliser des filtres.
Dans le module contenu de votre Backend, éditez le fichier actions.class.php comme ci-dessous.
Tout d'abord on va modifier l'action executeIndex en récupérant le flash dans la session de l'utilisateur, en écrivant simplement un getFlash avec le nom de l'identifiant.Code:
1
2
3
4
5
6
7
8
9
10
11 public function executeIndex(sfWebRequest $request) { $categorie = $this->getUser()->getFlash('categorie'); $this->setFilters(array( 'categorie_id' => $categorie)); parent::executeIndex($request); }
Ensuite on rajoute dans les filtres l'élément que l'on veut filtrer, ici le champs categorie_id, qui aura pour valeur celle que l'on a passé avec le Flash.
Pour terminer on appelle le reste de la fonction de executeIndex (que l'on peut voir dans le cache).
Considérons une table comportant un champs stockant le chemin de l'image enregistrée et une description.
Lorsque l'on génère un module image dans le backend, on obtient une présentation des champs id, name et file.Code:
1
2
3
4 Image: columns: name: { type: string(255), notnull: true } file: { type: string(255) }
Si on enregistre une image, elle sera renommée en md5.extension, et ne nous affichera pas l'image mais son nom.
Pour obtenir l'image, il faut créer un template _photo.php permettant de générer cette image en utilisant l'helper image_tag.
Tout d'abord dans le fichier generator.yml de votre module
Dans le dossier templates du module, créez le fichier _photo.php. Ne pas oublier de créer le dossier photos dans le dossier web/uploads.Code:
1
2
3
4
5
6
7
8
9
10 config: actions: ~ fields: ~ list: hide: [id] # permet de cacher le champs id display: [name, _photo] filter: ~ form: ~ edit: ~ new: ~
Code:
1
2
3 <?php echo image_tag('/uploads/photos/'.$image->getFile()); ?>
Si vous avez un formulaire en bas de votre billet pour permettre à vos lecteurs de laisser un commentaire par exemple, vous ne voulez sans doute pas tout l'attirail de widgets que vous offre votre éditeur wysiwyg préfére tinyMCE, mais seulement quelques boutons:mrgreen:. Nous allons ensemble plonger dans la config de sfExtraWidgetsPlugin pour voir comment obtenir exactement le nombre de boutons que nous souhaitons.
Première des choses, vous devez installer sfExtraWidgetsPlugin et suivre les indications d'utilisation de tinyMCE données sur cette page.
Ensuite, allez dans le répertoire du plugin installé et rendez-vous dans le sous-répertoire lib/widget. Cherchez le fichier sfExtraWidgetFormRichTextarea.class.php, copiez-le et renommez-le comme bon vous semble. Disons par exemple sfRichTextareaLite.class.php. Ouvrez-le et donnez à la classe qu'elle contient exactement le même nom que vous avez donné au fichier. Dans notre cas ca donne ceci.
devientCode:class sfExtraWidgetFormRichTextarea extends sfWidgetFormTextarea
Attention: Remarquez que nous n'avons pas modifié l'héritage. Le nom de la classe mère demeure inchangé. Ceci fait, désormais, pour appeler votre éditeur, au lieu de faireCode:class sfRichTextareaLite extends sfWidgetFormTextarea
vous devrez faireCode:'mytextarea' => new sfExtraWidgetFormRichTextearea()
Bon, nous sommes à mi-chemin. Abordons maintenant les config proprement dites. Si vous avez suivi les instructions d'installations, vous avez dû mettre certains codes dans le fichier app.yml de votre application, en l'occurrence l'entrée tinymce: sous all:. Recopiez exactement ce code et collez le ailleurs dans le fichiers. Changez l'entrée tinymce que vous venez de coller en tinymcelite (ou en ce que vous voulez). Là-dessous, repérez les entrées suivantes:Code:'mytextarea' => new sfRichTextareaLite()
Ce sont là celles qui nous intéressent. Ces lignes correspondent aux trois barres de l'éditeur original avec leurs boutons respectifs. Dans theme_advanced_buttons1, supprimez les noms de tous les boutons dont vous n'avez pas besoins, (supprimez aussi les caractères | avec la virgule suivante si vous ne voulez pas de séparateurs dans les boutons) puis couper/coller à partir de theme_advanced_buttons2 et theme_advanced_buttons3 ceux que vous souhaitez ajouter.Code:
1
2
3 theme_advanced_buttons1: "save,bold,italic,underline,strikethrough,emotions,sub,sup,justifyleft,justifycenter,justifyright,justifyfull,bullist,numlist,formatselect,styleselect" theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,|,search,replace,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,|,insertdate,inserttime,|,pagebreak" theme_advanced_buttons3: "tablecontrols,|,charmap,emotions,media,|,fullscreen,code,cleanup,|,visualaid"
On va revenir dans notre fichier sfRichTextareaLite.class.php. Dans la fonction configure, vous pouvez configurer la largeur et la hauteur de votre éditeur personnalisé.
Abordons la méthode suivante de la classe: public function render(...)Code:
1
2
3
4
5
6
7
8
9 public function configure($options = array(), $attributes = array()) { $this->setAttribute('class', 'mceEditor'); $this->addOption('width', 460); $this->addOption('height', 180); parent::configure($options, $attributes); }
A l'intérieur vous voyez l'attribut $js qui contient beaucoup de configurations. C'est en fait le code js d'initialisation de votre éditeur, qui prend ses valeurs à partir de vos options dans le fichier app.yml. Donc remplacez dans toutes les occurrence de sfConfig::get('app_tinymce...') le morceau tinymce par la nouvelle entrée que vous avez spécifiée plus haut dans le fichier app.yml. Dans notre cas,devientCode:sfConfig::get('app_tinymce_theme_advanced_buttons1')
. On va désactiver les barres d'outils non voulues comme l'indique la docde tinyMCE. Supprimez donc les valeurs fournis pour theme_advance_buttons2 et theme_advance_button3. Vous devez obtenir quelque chose comme ceci:Code:sfConfig::get('app_tinymcelite_theme_advanced_buttons1')
Ensuite, il faut déclarer la désactivation des boutons dont nous ne voulons pas dans notre éditeur. Là encore, nous nous appuyons sur la doc de tinyMCECode:
1
2
3
4 // Theme options theme_advanced_buttons1 : '" . sfConfig::get('app_tinymcelite_theme_advanced_buttons1') . "', theme_advanced_buttons2 : '', theme_advanced_buttons3 : '',
Ouvrez quelque part sous //Theme options une ligneet citez dans les simples quotes tous les boutons que vous ne voulez pas voir apparaître en les séparant d'une virgule. Vous en avez sans doute supprimé lors de l'édition du fichier app.yml. Reportez-vous à l'entrée tinymce d'où vous aviez fait la copie pour retrouver leurs noms. Si vous ne citez pas les noms des boutons à désactiver, ils s'afficheront quand même, même si vous les supprimez.Code:theme_advanced_disable :''
Ouf, on est à la fin. Vous voulez admirer votre zoooli éditeur ? Sauvegardez tous vos fichiers modifiés et dans votre form, faites 'mytextarea' => sfRichTextareaLite() si vous ne l'avez pas encore fait et contempler le résultat dans votre navigateur.8O
Une dernière pour tenir la route, laissez aussi de simple quotes vides devant theme_advanced_statusbar_location : si vous ne voulez pas de la barre d'état qui s'affiche en dessous de l'éditeur.:ccool:
Quand vous lisez la documentation symfony, on vous parle surtout des url_for() et des link_to() pour faire vos liens. C'est donc naturellement que vous allez créer vos boutons de cette manière:
En parcourant l'API de l'helper pour les URLs, je suis tombée sur button_to(), dont la syntaxe est similaire à link_to, et qui permet de générer des boutons dans des cas simples:Code:
1
2 <a href="<?php echo url_for('@homepage')?>"><input type="button" name="homepage" value="Homepage"/></a> <?php echo link_to('<input type="button" name="homepage" value="Homepage"/>', '@homepage') ?>
Non seulement, cela vous épargne de coder l'entièreté de l'input mais en plus, l'helper génère également le lien. Le seul point qui pourrait vous déranger est l'absence de l'attribut "name" dans le code.Code:
1
2
3
4
5
6
7
8
9
10
11 //utilisation avec une route connue style homepage: nom de la valeur de l'input + nom de la route button_to('Games','@homepage') //utilisation avec une route d'une collection, sans passage de paramètre button_to('New', 'game/new') //utilisation avec une route d'une collection, avec paramètre button_to('Edit','game/edit?id='.$game->getId()) //utilisation un peu lourde dans le cas de routes "personnalisées" button_to('Back to Game', '@game_show_game?id='.$game->getId().'&name_game_slug='.$game->getNameGameSlug())
Symfony maintient actuellement deux versions principales:
- Symfony 3.x.y
- Symfony 4.x.y
Nous avons ici omis les versions qui ne sont plus maintenues par le framework https://symfony.com/roadmap
Le versioning de symfony fonctionne ainsi, par exemple la version 4.x.y
- 4 correspond à la MAJOR, cela signifie que la rétrocompatibilité ne peut-être assuré. (Si vous développez un projet en symfony 3 et que vous souhaitez migrer, vous devez vous assurer de la rendre compatible avec la version 4 https://symfony.com/doc/current/setu...ade_major.html)
- x correspond à la MINOR pour l'ajout d'une nouvelle fonctionnalité.
- y correspond au PATCH pour la correction d'un bug au sein du framework.
Le choix la version doit se porter sur une version stable avec un support sur le long terme, généralement celle conseillée par la communauté https://symfony.com/doc/current/setup.html .
Les dernières versions assurent un support ainsi que de nouvelles fonctionnalités et correctif du framework.
Vous devez aussi prendre une version compatible avec votre version php.