<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jérôme Tamarelle &#187; Symfony</title>
	<atom:link href="http://jerome.tamarelle.net/blog/indice/symfony/feed/" rel="self" type="application/rss+xml" />
	<link>http://jerome.tamarelle.net/blog</link>
	<description>I share so I am</description>
	<lastBuildDate>Sat, 17 Jul 2010 21:41:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>sfWidget rendu via un composant Symfony</title>
		<link>http://jerome.tamarelle.net/blog/2010/03/sfwidget-rendu-via-un-composant-symfony/</link>
		<comments>http://jerome.tamarelle.net/blog/2010/03/sfwidget-rendu-via-un-composant-symfony/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 02:22:45 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Applications web]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://jerome.tamarelle.net/blog/?p=143</guid>
		<description><![CDATA[Les formulaires créés en utilisant Symfony sont composés de widgets et de validators. Les widgets décrivent l'apparence des champs du formulaire alors que les validators décrivent leur contenu. Il est actuellement possible de choisir parmi plus de 80 types de widget différents (entre ceux de l'API et les plugins). Ils correspondent globalement à des éléments [...]]]></description>
			<content:encoded><![CDATA[<p>Les formulaires créés en utilisant Symfony sont composés de widgets et de validators. <strong>Les widgets décrivent l'apparence des champs du formulaire alors que les validators décrivent leur contenu. <span style="font-weight: normal;">Il est actuellement possible de choisir parmi plus de 80 types de widget différents (entre <a title="API Symfony 1.4 - Widgets" href="http://www.symfony-project.org/api/1_4/widget">ceux de l'API</a> et les <a title="Plugins Symfony - Catégorie Widgets" href="http://www.symfony-project.org/plugins/filter?filter[sf_1_0]=on&amp;filter[sf_1_1]=on&amp;filter[sf_1_2]=on&amp;filter[sf_1_3]=on&amp;filter[sf_1_4]=on&amp;filter[propel]=on&amp;filter[doctrine]=on&amp;filter[category_id]=2">plugins</a>). Ils correspondent globalement à des éléments d'interface standardisés.</span></strong></p>
<p>Si vous avez essayé de créer votre propre widget, vous avez du vous apercevoir que le rendu est fait a l'intérieur de la fonction <code>sfWidget-&gt;<a href="http://www.symfony-project.org/api/1_4/sfWidget#method_render">render</a>()</code>. Ce qui suffit pour des rendus simples, mais s'avère inapproprié lorsque votre champ de formulaire se complexifie. <strong>La structure vue-contrôleur du framework n'est pas respectée.</strong></p>
<p>Pour compenser ce manque, j'ai créé un <strong>widget dont le rendu se fait via un composant (component) ou une vue partielle (partial)</strong>. Ce widget est destiné à faciliter la création de champ de formulaire spécifiques pouvant utiliser entre autre AJAX, le profil de l'utilisateur, l'objet sfContext et sfRequest...</p>
<p><span id="more-143"></span></p>
<span id="Le_code_du_widget_sfWidgetFormComponent"><h2>Le code du widget <code>sfWidgetFormComponent</code></h2></span>
<pre class="brush: php;">
# /lib/widget/sfWidgetFormComponent.class.php
/**
 * sfWidgetComponent is a widget rendered on a component.
 * The component will recieve this vars :
 *  * $name        The element name
 *  * $value       The value selected in this widget
 *  * $attributes  An array of HTML attributes to be merged with the default HTML attributes
 *  * $errors      An array of errors for the field
 *  * $id          An unique id
 *  * $is_hidden   Is the field hidden ?
 *
 * @package    core
 * @subpackage widget
 * @author     Jerome TAMARELLE &lt;http://jerome.tamarelle.net/&gt;
 */
class sfWidgetFormComponent extends sfWidgetForm
{
  /**
   * Constructor.
   *
   * Available options:
   *  * module:       The module name
   *  * component:    The component name
   *  * context:      Current context object
   *
   * @param array $options     An array of options
   * @param array $attributes  An array of default HTML attributes
   * @see sfWidgetForm
   */
  protected function configure($options = array(), $attributes = array()) {
    $this-&gt;addRequiredOption('module');
    $this-&gt;addRequiredOption('component');
    $this-&gt;addOption('is_partial', false);
    $this-&gt;addOption('context', sfContext::hasInstance() ? sfContext::getInstance() : null);
  }

  /**
   * @param  string $name        The element name
   * @param  string $value       The value selected in this widget
   * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
   * @param  array  $errors      An array of errors for the field
   * @return string The rendered component
   * @see sfWidgetForm
   */
  public function render($name, $value = null, $attributes = array(), $errors = array()) {
    try {
      $this-&gt;getOption('context')-&gt;getConfiguration()-&gt;loadHelpers('Partial');
    } catch (Exception $e) {
      throw new Exception('sfWidgetFormComponent requires &amp;quot;context&amp;quot; option to be an instance of sfContext.');
    }

    $vars = array(
      'name'        =&gt; $name,
      'value'       =&gt; $value,
      'attributes'  =&gt; $attributes,
      'errors'      =&gt; $errors,
      'id'          =&gt; $this-&gt;generateId($name),
      'is_hidden'   =&gt; $this-&gt;getOption('is_hidden'),
    );

    if($this-&gt;getOption('is_partial')) {
      return get_partial($this-&gt;getOption('module').'/'.$this-&gt;getOption('component'), $vars);
    } else {
      return get_component($this-&gt;getOption('module'), $this-&gt;getOption('component'), $vars);
    }
  }
}
</pre>
<span id="Utilisation"><h2>Utilisation</h2></span>
<p><code>sfWidgetFormComponent</code> est un widget comme les autres ! Pour l'utiliser il suffit de l'ajouter à votre formulaire dans la fonction configure() de celui-ci.</p>
<pre class="brush: php;">
# /lib/form/MyModelForm.class.php
class MyModelForm extends BaseMyModelForm {
  public function configure() {
    $this-&gt;setWidget('field',
      new sfWidgetFormComponent(array(
                      'module'=&gt;'ajax',
                      'component'=&gt;'myModelWidget'
    )));
  }
}
</pre>
<span id="Options_du_widget"><h3>Options du widget</h3></span>
<table>
<thead>
<tr>
<th>Option</th>
<th>Valeur par défaut</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>module</td>
<td><em>(Obligatoire)</em></td>
<td>Nom du module</td>
</tr>
<tr>
<td>component</td>
<td><em>(Obligatoire)</em></td>
<td>Nom du composant ou de la vue partielle</td>
</tr>
<tr>
<td>is_partial</td>
<td>false</td>
<td>Indique s'il s'agit d'un composant ou d'une vue partielle</td>
</tr>
<tr>
<td>context</td>
<td>sfContext::getInstance()</td>
<td>Contexte d'exécution (pas besoin de le modifier)</td>
</tr>
</tbody>
</table>
<span id="Variables_transmises_au_componentpartial"><h3>Variables transmises au component/partial</h3></span>
<table>
<thead>
<tr>
<th>Variable</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>$name</td>
<td><em>string</em></td>
<td>Nom du champ contenant la valeur</td>
</tr>
<tr>
<td>$value</td>
<td><em>string/array</em></td>
<td>Valeur par défaut</td>
</tr>
<tr>
<td>$attributes</td>
<td>array</td>
<td>Liste d'attributs HTML</td>
</tr>
<tr>
<td>$errors</td>
<td>array</td>
<td>Liste des erreurs fournies par le validator</td>
</tr>
<tr>
<td>$id</td>
<td>string</td>
<td>Identifiant unique</td>
</tr>
<tr>
<td>$is_hidden</td>
<td>boolean</td>
<td>Indique si le champ doit être masqué</td>
</tr>
</tbody>
</table>
<p>Il ne vous reste plus qu'à <a href="http://www.symfony-project.org/book/1_2/07-Inside-the-View-Layer#chapter_07_code_fragments">créer le composant qui conviendra le mieux</a> à votre besoin !</p>
<span id="Voir_aussi"><h2>Voir aussi</h2></span>
<ul>
<li><a href="http://www.symfony-project.org/api/1_4/widget">Widgets de l'API Symfony</a></li>
<li><a href="http://www.symfony-project.org/plugins/filter?filter[sf_1_0]=on&amp;filter[sf_1_1]=on&amp;filter[sf_1_2]=on&amp;filter[sf_1_3]=on&amp;filter[sf_1_4]=on&amp;filter[propel]=on&amp;filter[doctrine]=on&amp;filter[category_id]=2">Plugins Symfony de la catégorie Widget</a></li>
<li><a href="http://www.symfony-project.org/more-with-symfony/1_4/fr/05-Custom-Widgets-and-Validators">Au Coeur des Widgets et Validateurs</a></li>
<li><a href="http://www.amicalement-web.net/personnaliser-le-code-html-dun-widget-symfony/2009/06/02/">Personnaliser le code d'un widget</a></li>
<li><a href="http://prendreuncafe.com/blog/post/2010/02/17/User-Dependant-Forms-with-Symfony">Générer un formulaire en fonction de l'utilisateur</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jerome.tamarelle.net/blog/2010/03/sfwidget-rendu-via-un-composant-symfony/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Configurer WAMP avec PHP 5.3.1 pour Symfony 2.0</title>
		<link>http://jerome.tamarelle.net/blog/2010/03/configurer-wamp-avec-php-5-3-1-pour-symfony-2-0/</link>
		<comments>http://jerome.tamarelle.net/blog/2010/03/configurer-wamp-avec-php-5-3-1-pour-symfony-2-0/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 06:20:17 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Applications web]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[WAMP]]></category>

		<guid isPermaLink="false">http://jerome.tamarelle.net/blog/?p=126</guid>
		<description><![CDATA[Symfony 2 va révolutionner le développement web. Sa nouvelle architecture et sa flexibilité permettront une prise en main plus rapide, une réutilisation de code plus facile et des performances adaptées à la taille de chaque application. Le nouveau framework est en développement, mais si comme moi vous voulez explorer les fonctionnalités de ce trésor, voici [...]]]></description>
			<content:encoded><![CDATA[<p>Symfony 2 va révolutionner le développement web. Sa nouvelle architecture et sa flexibilité permettront une <a title="Quick Tour" href="http://symfony-reloaded.org/learn">prise en main plus rapide</a>, une <a title="The Bundles" href="http://symfony-reloaded.org/quick-tour-part-4">réutilisation de code plus facile</a> et des performances adaptées à la taille de chaque application.</p>
<p>Le nouveau framework est en développement, mais si comme moi vous voulez explorer les fonctionnalités de ce trésor, voici comment bien démarrer sous Windows.</p>
<p>Le<a title="Télécharger Symfony 2.0" href="http://symfony-reloaded.org/code"> pack d'installation</a> fournit un fichier check.php permettant de vérifier la compatibilité de votre environnement PHP avec les pré-requis du nouveau framework.</p>
<p>La <a title="WAMP Server" href="http://www.wampserver.com/">distribution WAMP</a> correspond quasiment à la configuration suggérée pour Symfony 2.0 (dans la version dev du 10/03/2010 en tout cas).</p>
<div id="attachment_127" class="wp-caption aligncenter" style="width: 246px"><a href="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/symfony2-requirements.png"><img class="size-medium wp-image-127" title="symfony2-requirements" src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/symfony2-requirements-236x299.png" alt="Pré-requis Symfony 2.0" width="236" height="299" /></a><p class="wp-caption-text">Symfony 2.0 requière PHP 5.3.1 alors que WAMP propose par défaut la 5.3.0</p></div>
<p>Contrairement à <a title="Why will Symfony 2.0 finally use PHP 5.3" href="http://www.symfony-project.org/blog/2009/10/27/why-will-symfony-2-0-finally-use-php-5-3">ce qui avait été annoncé</a>, c'est PHP 5.3.1 qui est recommandé au lieu de la 5.3.0 (voir <a title="PHP 5.3.1 Released!" href="http://www.php.net/archive/2009.php#id2009-11-19-1">changelog</a>).</p>
<p><span id="more-126"></span></p>
<span id="Installation_de_WAMP"><h1>Installation de WAMP</h1></span>
<p style="text-align: center;"><strong>Pour installer PHP 5.3.1 sous WAMP, téléchargez simplement l'</strong><a title="Télécharger l'add-on PHP 5.3.1 pour WAMP" href="http://www.wampserver.com/addons_php.php"><strong>add-on éponyme</strong></a><strong>.</strong></p>
<p>Lorsque l'installation est terminée, il vous faut sélectionner cette version de PHP dans le menu contextuel de WAMP (icône en bas à droite) :<br />
<strong><img src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/icone_wamp.png" alt="WAMP" width="16" height="11" /> &gt; PHP &gt; Version &gt; 5.3.1</strong></p>
<p><a href="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/wamp-version-php.png"><img class="aligncenter size-full wp-image-128" title="wamp-version-php" src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/wamp-version-php.png" alt="" width="340" height="266" /></a></p>
<p style="text-align: left;">Si vous utilisez Propel, il vous faut aussi activer l'extension XSL (optionnel) :<br />
<strong><img src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/icone_wamp.png" alt="WAMP" width="16" height="11" /> &gt;PHP &gt; PHP extensions &gt; php_xsl</strong></p>
<span id="Installation_de_APC_acclrateur"><h1><strong>Installation de APC (accélérateur)</strong></h1></span>
<p>Même pour le développement il est intéressant d'améliorer les performances d'exécution de PHP. Pour cela on peut installer l'accélérateur APC.</p>
<p style="text-align: center;"><strong>Téléchargez la dll de APC : </strong><strong><a title="APC.dll pour PHP 5.3.1" href="http://downloads.php.net/pierre/php_apc-5.3-svn20100226-vc9-x86.zip">php_apc-5.3-svn20100226-vc9-x86.zip</a> </strong></p>
<p>Extraire le contenu de l'archive dans <strong>C:\wamp\bin\php\php5.3.1\ext</strong></p>
<p>Modifiez le fichier php.ini : <strong><img src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/icone_wamp.png" alt="WAMP" width="16" height="11" /> &gt; PHP &gt; php.ini</strong></p>
<pre class="brush: plain;">
extension=php_xsl.dll
;extension=php_zip.dll
extension=php_apc.dll
</pre>
<span id="Alias_Apache_et_rewrite"><h1><strong>Alias Apache et rewrite</strong></h1></span>
<p>Si vous souhaitez déposer votre code en dehors du répertoire www de WAMP, il vous faut créer un Alias :<br />
<strong><img src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/icone_wamp.png" alt="WAMP" width="16" height="11" /> &gt; Apache &gt; Alias directories &gt; Add an alias</strong></p>
<p>Dans l'invite de commande, saisissez le nom de votre alias (par exmple : symfony2) puis l'emplacement du répertoire web de votre installation. Pensez à utiliser des slash (/) comme séparateur et à mettre un slash à la fin (par exemple : C:/Programmation/Symfony2/web/).</p>
<p>Il est aussi conseillé d'activer le module rewrite de Apache :<br />
<strong><img src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/03/icone_wamp.png" alt="WAMP" width="16" height="11" /> &gt; Apache &gt; Apache modules &gt; rewrire_module</strong></p>
<p>Accédez maintenant à la page <a href="http://localhost/symfony2/">http://localhost/symfony2/</a>. Une page indiquant que Symfony est correctement installé doit s'afficher. Si vous avez une erreur du type "fichier *index.php non trouvé", modifiez le fichier .htaccess :</p>
<pre class="brush: plain;">
 &lt;IfModule mod_rewrite.c&gt;
  RewriteEngine On
  RewriteBase /symfony2
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php [QSA,L]
 &lt;/IfModule&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jerome.tamarelle.net/blog/2010/03/configurer-wamp-avec-php-5-3-1-pour-symfony-2-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I18n du routing pour les modules d&#8217;admin Symfony</title>
		<link>http://jerome.tamarelle.net/blog/2010/02/modules-dadmin-multilingues-dans-symfony/</link>
		<comments>http://jerome.tamarelle.net/blog/2010/02/modules-dadmin-multilingues-dans-symfony/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 23:35:12 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[generator]]></category>
		<category><![CDATA[I18n]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://jerome.tamarelle.net/blog/?p=112</guid>
		<description><![CDATA[L'internationalisation d'une application (i18n) consiste à servir les pages dans la langue de l'utilisateur. Par défaut, les modules d'admin de Symfony gèrent l'i18n. Ainsi, il est simple de traduire ces modules. Dans cet article je vais vous expliquer : comment gérer plusieurs langues pour l'interface de vos modules d'administration en indiquant la langue dans l'URL [...]]]></description>
			<content:encoded><![CDATA[<p>L'internationalisation d'une application (<strong>i18n</strong>) consiste à servir les pages dans la langue de l'utilisateur. Par défaut, les modules d'admin de Symfony gèrent l'i18n. Ainsi, il est simple de <a title="Traduire l'admin generator de Symfony." href="http://www.amicalement-web.net/traduire-ladmin-generator-symfony/2009/06/09/">traduire ces modules</a>. Dans cet article je vais vous expliquer :</p>
<ul>
<li>comment gérer plusieurs langues pour l'interface de vos modules d'administration en indiquant la langue dans l'URL</li>
<li>et comment basculer en un clic d'une langue à une autre.</li>
</ul>
<div id="attachment_113" class="wp-caption aligncenter" style="width: 510px"><a href="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/02/flags.png"><img class="size-full wp-image-113" title="Flags" src="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/02/flags.png" alt="Drapeaux des langues" width="500" height="15" /></a><p class="wp-caption-text">Basculer rapidement entre les langues.</p></div>
<p>Cet article est écrit pour Symfony 1.4 avec l'admin-generator Doctrine. Nous utiliseront également le plugin <a title="Plugin sfLanguageSwitchPlugin" href="sfLanguageSwitchPlugin">sfLanguageSwitchPlugin</a>.</p>
<span id="Internationaliser_les_modules_dadmin_via_lURL"><h1><span id="more-112"></span>1. Internationaliser les modules d'admin via l'URL</h1></span>
<span id="Les_routes_i18n"><h2>1.1. Les routes i18n</h2></span>
<p>La première étape importante est d'activer i18n dans le fichier settings.yml de l'application :</p>
<pre class="brush: plain;">
all:
  .settings:
    # Enable internationalization
    i18n:            true
    default_culture: fr
</pre>
<p>Le paramètre <code>default_culture</code> ne semble pas avoir d'incidence.</p>
<p>Dans les applications développées sous Symfony, la langue d'une page peut être indiquée dans l’URL via l’attribut <code>:sf_culture</code>. Une route localisée ressemble à cela :</p>
<pre class="brush: plain;">
map:
  url:   /:sf_culture/map/:id
  requirements: { sf_culture: (?:en|es|fr) }
  param: { module: map, action: view }
</pre>
<p>Le paramètre <em>requirements </em>décrit un pattern à respecter pour le champ <code>:sf_culture</code>. Le simple ajout du paramètre <code>:sf_culture</code> dans l'URL modifie automatiquement la langue de l'utilisateur. Il n'y a pas besoin de passer ce paramètre pour générer l'URL avec les <code>url_for(...)</code> et autres <code>link_to(...)</code>.</p>
<span id="Modification_de_sfDoctrineRoute"><h2>1.2. Modification de sfDoctrineRoute</h2></span>
<p>Pour prendre en compte ce paramètre dans les modules d’admin, j'ai créé des classes routing spécifiques. Deux fichiers dans le répertoire lib du projet ou de l'application (au choix) :</p>
<p>La classe sfI18NDoctrineRoute ajoute le paramètre <code>:sf_culture</code> aux routes.</p>
<pre>/lib/routing/sfI18NDoctrineRoute.class.php</pre>
<pre class="brush: php;">
class sfI18NDoctrineRoute extends sfDoctrineRoute
{
  /**
   * @see sfRoute
   */
  public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array())
  {
    // Add the culture prefix to admin routes
    $pattern = '/:sf_culture' . $pattern;
    parent::__construct($pattern, $defaults, $requirements, $options);
  }
}
</pre>
<pre>/lib/routing/sfI18NDoctrineRouteCollection.class.php</pre>
<pre class="brush: php;">
class sfI18NDoctrineRouteCollection extends sfObjectRouteCollection
{
  protected $routeClass = 'sfI18NDoctrineRoute';
}
</pre>
<p>Maintenant que vos classes sont crées, il faut modifier vos routes. Cela donne par exemple :</p>
<pre class="brush: plain;">
my_class:
  class: sfI18NDoctrineRouteCollection
  options:
    model:                MyClass
    module:               my_class
    prefix_path:          /my_class
    column:               id
    with_wildcard_routes: true
</pre>
<p>Essayer maintenant d'afficher votre module en modifiant le paramètre de langue :</p>
<pre>http://localhost/app/<strong>fr</strong>/my_class

http://localhost/app/<strong>hu</strong>/my_class</pre>
<p>Notez bien qu'il n'est ici pas nécessaire d'ajouter les fichiers XLIFF de langue dans le répertoire i18n de l'application. Les fichiers du plugin Doctrine sont directement utilisés.</p>
<span id="Installer_le_plugin_sfLanguageSwitchPlugin"><h1>2. Installer le plugin sfLanguageSwitchPlugin</h1></span>
<p>Si vous souhaitez afficher une barre de choix de la langue, rien de plus simple grâce au plugin sfLanguageSwitchPlugin qui vous fourni un composant dédié.</p>
<p>Téléchargez <a title="Plugin sfLanguageSwitchPlugin" href="http://www.symfony-project.org/plugins/sfLanguageSwitchPlugin">sfLanguageSwitchPlugin</a> et installez-le comme décrit dans la notice.</p>
<pre>/apps/backend/config/settings.yml</pre>
<pre class="brush: plain;">
all:
  .settings:
    enabled_modules:    [sfLanguageSwitch]
    i18n:                     true
</pre>
<pre>/apps/backend/config/app.yml</pre>
<pre class="brush: plain;">
all:
  # sfLanguageSwitchPlugin
  sfLanguageSwitch:
    flagPath: /sfLanguageSwitch/images/flag
    availableLanguages:
      en: { title: English }
      ar: { title: العربية}
      bg: { title: български език }
      ca: { title: Català }
      cs: { title: Česky }
      de: { title: Deutch }
      es: { title: Español }
      fi: { title: Suomen kieli }
      fr: { title: Français }
      hr: { title: Hrvatski }
      hu: { title: Magyar }
      id: { title: Bahasa Indonesia }
      it: { title: Italiano }
      lt: { title: Lietuvių kalba }
      lv: { title: Latviešu valoda }
      nl: { title: Nederlands }
      no: { title: Norsk }
      pl: { title: Polski }
      pt: { title: Português }
      ro: { title: Română }
      ru: { title: русский язык }
      sk: { title: Slovenčina }
      sl: { title: Slovenščina }
      sv: { title: Svenska }
      tr: { title: Türkçe }
</pre>
<p>(Wikipedia : <a title="Liste des codes ISO 639-1" href="http://fr.wikipedia.org/wiki/Liste_des_codes_ISO_639-1">Liste des codes langue</a>)</p>
<p>Ajoutez maintenant le composant à votre layout :</p>
<pre>/apps/backend/templates/layout.php</pre>
<pre class="brush: php;">
  &lt;body&gt;
    &lt;?php include_component('sfLanguageSwitch', 'get'); ?&gt;
    &lt;?php echo $sf_content ?&gt;
  &lt;/body&gt;
</pre>
<p>Pour afficher sous forme de liste, juste un petit bout de code CSS :</p>
<pre>/web/css/main.css</pre>
<pre class="brush: css;">
#lang li { display: inline; }
</pre>
<p><strong>Si vous avez des remarques ou suggestions, n'hésitez pas ! Les commentaires sont là pour ça.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://jerome.tamarelle.net/blog/2010/02/modules-dadmin-multilingues-dans-symfony/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Plugin sfDoctrineAdminGeneratorWithShowPlugin pour Symfony 1.4</title>
		<link>http://jerome.tamarelle.net/blog/2010/01/activer-with_show-du-generator-yml-dans-symfony-1-4/</link>
		<comments>http://jerome.tamarelle.net/blog/2010/01/activer-with_show-du-generator-yml-dans-symfony-1-4/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 16:42:47 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Applications web]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[generator]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://jerome.tamarelle.net/blog/?p=89</guid>
		<description><![CDATA[Une question récurrente sur les forums traitant du framework Symfony : A quoi sert le paramètre with_show dans le fichier generator.yml ? Aussi surprenante soit-elle, la réponse usuelle à cette question est : Par défaut, à rien... Alors comment afficher les détails d'un objet dans une page d'administration sans que celles-ci soient modifiables ? il [...]]]></description>
			<content:encoded><![CDATA[<p>Une question récurrente sur les forums traitant du framework Symfony :</p>
<blockquote><p><strong>A quoi sert le paramètre with_show dans le fichier generator.yml ?</strong></p></blockquote>
<p>Aussi surprenante soit-elle, la réponse usuelle à cette question est :</p>
<blockquote><p><strong>Par défaut, à rien...</strong></p></blockquote>
<p>Alors comment afficher les détails d'un objet dans une page d'administration sans que celles-ci soient modifiables ? il est bien nécessaire d'activer l'action show. Les plugins <a href="http://www.symfony-project.org/plugins/sfDoctrineAdminGeneratorWithShowPlugin">sfDoctrineAdminGeneratorWithShowPlugin</a> et <a href="http://www.symfony-project.org/plugins/sfPropelAdminGeneratorWithShowPlugin">sfPropelAdminGeneratorWithShowPlugin</a> ont été créés pour compenser ce manque. Malheureusement ils ne fonctionnent que pour Symfony 1.2 et 1.3.</p>
<p><span id="more-89"></span></p>
<span id="Plugin_sfDoctrineAdminGeneratorWithShowPlugin_pour_Symfony_1.4"><h2>Plugin sfDoctrineAdminGeneratorWithShowPlugin pour Symfony 1.4</h2></span>
<p>Paralysé par cette absence d'action show sous Symfony 1.4, je me suis lancé dans la correction du plugin <a href="http://www.symfony-project.org/plugins/sfDoctrineAdminGeneratorWithShowPlugin">sfDoctrineAdminGeneratorWithShowPlugin</a> pour le rendre compatible.</p>
<p><img class="alignleft" title="Archive" src="/blog/wp-includes/images/crystal/archive.png" alt="" width="46" height="60" /></p>
<p><a href="http://jerome.tamarelle.net/blog/wp-content/uploads/2010/01/sfDoctrineAdminGeneratorWithShowPlugin-Symfony-1.4.zip">Télécharger sfDoctrineAdminGeneratorWithShowPlugin pour Symfony 1.4</a></p>
<p>Pour installer le plugin, décompressez l'archive dans le répertoire <em>plugin/</em> de votre projet Symfony.</p>
<p>Activez le plugin en modifiant le fichier <em>config/ProjectConfiguration.class.php</em></p>
<pre class="brush: php; first-line: 9; toolbar: false;">$this-&gt;enablePlugins('sfDoctrinePlugin','sfDoctrineAdminGeneratorWithShowPlugin');</pre>
<p>Générez le module d'administration :</p>
<pre class="brush: plain; toolbar: false;">./symfony doctrine:generate-admin --theme=adminWithShow application ClasseExemple</pre>
<p>Activez l'action vue dans le fichier <em>application/modules/classe_exemple/config/generator.yml</em></p>
<pre class="brush: plain; first-line: 7; toolbar: false;">    with_show: true</pre>
<p>Cela donne par exemple :</p>
<pre class="brush: plain; toolbar: false;">
generator:
  class: sfDoctrineGenerator
  param:
    model_class:           ClasseExemple
    theme:                 adminWithShow
    non_verbose_templates: true
    with_show:             true
    singular:              ~
    plural:                ~
    route_prefix:          classe_exemple
    with_doctrine_route:   true

    config:
      actions: ~
      fields:  ~
      list:    ~
      filter:  ~
      form:    ~
      edit:    ~
      new:     ~
      show:    ~
</pre>
<p>Maintenant que l'action show est ajoutée, vous pouvez personnaliser à souhait votre module d'administration en modifiant le fichier generator.yml et/ou les templates. <a title="Documentation Symfony 1.4" href="http://www.symfony-project.org/reference/1_4/fr/06-Admin-Generator" target="_self">Toute la documentation utile est sur le site du framework</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jerome.tamarelle.net/blog/2010/01/activer-with_show-du-generator-yml-dans-symfony-1-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Détecter le contexte d&#8217;exécution sous Symfony</title>
		<link>http://jerome.tamarelle.net/blog/2010/01/detecter-le-contexte-dexecution-sous-symfony/</link>
		<comments>http://jerome.tamarelle.net/blog/2010/01/detecter-le-contexte-dexecution-sous-symfony/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 22:00:42 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Applications web]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://jerome.tamarelle.net/blog/2010/01/75/</guid>
		<description><![CDATA[Lorsqu'on développe avec le framework Symfony, ou plus généralement en PHP, il est parfois nécessaire de connaitre le contexte dans lequel est exécuté le code pour adapter les actions effectuées. Ainsi, il est possible d'identifier au moins 4 contextes d'appel pour lesquels je vous propose une méthode de détection : Depuis la console (communément appelé [...]]]></description>
			<content:encoded><![CDATA[<p>Lorsqu'on développe avec le framework Symfony, ou plus généralement en PHP, il est parfois nécessaire de connaitre le contexte dans lequel est exécuté le code pour adapter les actions effectuées. Ainsi, il est possible d'identifier au moins 4 contextes d'appel pour lesquels je vous propose une méthode de détection :</p>
<ol>
<li>Depuis la console (communément appelé CLI)</li>
<li>Depuis une adresse locale (localhost)</li>
<li>Depuis une requête AJAX (ou XMLHttpRequest JavaScript)</li>
<li>En mode debug</li>
<li>Contexte d'exécution</li>
</ol>
<p><span id="more-75"></span></p>
<span id="Dtecter_la_console_PHP"><h2><a name="CLI"></a>1. Détecter la console PHP</h2></span>
<p>La fonction <code><a title="Documentation PHP" href="http://php.net/manual/fr/function.php-sapi-name.php">php_sapi_name</a></code> retourne le type d'interface utilisée, par exemple "cli" ou "cgi". En analysant la valeur retournée par cette fonction vous pouvez donc facilement détecter une exécution dans la console PHP. Dans Symfony, ce sont les tâches qui sont généralement exécutées par cette interface.</p>
<pre class="brush: php;">
if(php_sapi_name() == 'cli')
{
  // Code exécuté uniquement lorsque le script est appelé en ligne de commande (cli).
}
</pre>
<span id="Dtecter_une_adresse_locale"><h2><a name="local"></a>2. Détecter une adresse locale</h2></span>
<p>Symfony fait déjà cette détection par défaut dans le fichier app_dev.php pour empêcher l'exécution de l'application en mode debug depuis d'extérieur. Les adresses 127.0.0.1 et ::1 sont les adresses IP v4 et v6 normalisées de rebouclage sur la machine locale, la condition ci-dessous vérifie que la requête est transmise depuis l'une de ces deux adresses.</p>
<pre class="brush: php;">
if (in_array($this-&gt;getRequest()-&gt;getRemoteAddress(), array('127.0.0.1', '::1')))
{
  // Code exécuté uniquement lorsque l'application est exécutée depuis une adresse locale.
}
</pre>
<span id="Dtecter_requte_AJAX"><h2><a name="XMLHttpRequest"></a>3. Détecter requête AJAX</h2></span>
<p>Parmi les fonctionnalités magiques de Symfony, vous pouvez appelé la fonction <code><a title="API Symfony" href="http://www.symfony-project.org/api/1_4/sfWebRequest#method_isxmlhttprequest">sfWebRequest::isXmlHttpRequest()</a></code> depuis vos sfAction(s). Vous saurez alors si la page a été appelée depuis JavaScript.</p>
<pre class="brush: php;">
if($this-&gt;getRequest()-&gt;isXmlHttpRequest())
{
  // Code exécuté uniquement lorsque l'action est appelée depuis JavaScript
}
</pre>
<span id="Dtecter_le_mode_debug"><h2><a name="Debug"></a>4. Détecter le mode debug</h2></span>
<p>Lorsque votre application est exécutée en mode debug, la constante <code>sf_debug</code> prend la valeur <code>true</code>. Il vous est donc facile de n'afficher certaines informations que pour le développement et le débogage de votre application.</p>
<pre class="brush: php;">
if(sfConfig::get('sf_debug'))
{
  // Code exécuté uniquement lorsque l'application est exécutée en mode debug
}
</pre>
<p>(Ajouté le 04/02/2010)</p>
<span id="Contexte_dexcution"><h2><a name="Debug"></a>5. Contexte d'exécution</h2></span>
<p>Pour éviter l'erreur « The "default" context does not exist. » lorsqu'on utilise i18n ou doctrine dans les models/widgets par exemple.</p>
<pre class="brush: php;">
if(sfContext::hasInstance())
{
  $contexte = sfContext::getInstance();
  // Code exécuté uniquement lorsque l'application est exécutée avec un contexte (depuis une application).
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jerome.tamarelle.net/blog/2010/01/detecter-le-contexte-dexecution-sous-symfony/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Vue au format JSON sous Symfony</title>
		<link>http://jerome.tamarelle.net/blog/2009/12/vue-au-format-json-sous-symfony/</link>
		<comments>http://jerome.tamarelle.net/blog/2009/12/vue-au-format-json-sous-symfony/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 16:23:18 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Applications web]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://jerome.tamarelle.net/blog/?p=18</guid>
		<description><![CDATA[Contrairement à ce que son nom indique, l'AJAX utilise de plus en plus le format JSON pour échanger des données entre le navigateur et le serveur. Le framework PHP Symfony se déclare "Easy AJAX", il l'est pour l'intégration de JavaScript, mais la création de vues non-HTML n'est pas toujours évidente. Cet article propose deux méthodes [...]]]></description>
			<content:encoded><![CDATA[<p>Contrairement à ce que son nom indique, l'<acronym title="Asynchronous JavaScript and XML">AJAX</acronym> utilise de plus en plus le format <a title="Format JSON" href="http://www.json.org/">JSON</a> pour échanger des données entre le navigateur et le serveur. Le <a title="Framework Symfony" href="http://www.symfony-project.com/">framework PHP Symfony</a> se déclare "Easy AJAX", il l'est pour l'intégration de JavaScript, mais la création de vues non-HTML n'est pas toujours évidente. Cet article propose deux méthodes pour générer du code JSON depuis Symfony avec ou sans aide au débuggage.</p>
<p>Les usages sont multiples, par exemple :</p>
<ul>
<li>Auto-complétion d'un champ avec le plugin <a title="The sfFormExtraPlugin packages useful validators, widgets, and forms." href="http://www.symfony-project.org/plugins/sfFormExtraPlugin">sfFormExtraPlugin</a>,</li>
<li>les événements issus de la base de données à afficher dans un calendrier <a title="FullCalendar is a jQuery plugin that provides a full-sized, drag &amp; drop calendar." href="http://arshaw.com/fullcalendar/">FullCalendar</a>,</li>
<li>ou une galerie photos AJAX avec <a title="minishowcase is a small and simple php/javascript online photo gallery" href="http://minishowcase.net/">minishowcase</a>.</li>
</ul>
<p><span id="more-18"></span></p>
<span id="JSON_simplement_mais_sans_dbuggage"><h2>1. JSON simplement mais sans débuggage</h2></span>
<p>Le plus simple pour envoyer du code JSON depuis Symfony est d'inclure les lignes suivantes à la fin du contrôleur :</p>
<pre class="brush: php;">
function executeAction() {
  $data = array();
  // ... Création du tableau $data ...

  // Indispensable : définie le l'en-tête HTTP correspondant au format JSON.
  $this-&gt;getResponse()-&gt;setHttpHeader('Content-type', 'application/json');
  // Contenu transmis.
  $this-&gt;getResponse()-&gt;setContent(json_encode($data));
  // N'affiche aucune vue.
  return return sfView::NONE;
}
</pre>
<p>Simple à mettre en œuvre, cette méthode peut poser problème pour le débuggage de l'application.</p>
<ul>
<li>Le contenu JSON transmis n'est pas visualisable dans le navigateur à cause du content-type non reconnu.</li>
<li>Si l'on laisse le content-type par défaut, le texte JSON transmis est parasité par la debug toolbar.</li>
</ul>
<span id="JSON_avec_dbuggage"><h2>2. JSON avec débuggage</h2></span>
<p>Pour rendre visible le format JSON au développeur, il faut adapter la réponse au contexte d'exécution de la page. Les données ne doivent être affichées lisiblement que lorsque le développeur affiche la page en mode débug, mais pas lorsqu'elle est appelée depuis JavaScript, même en mode débug. Pour cela, la méthode <a title="API Symfony" href="http://www.symfony-project.org/api/1_4/sfWebRequest#method_isxmlhttprequest"><code>sfWebRequest::isXmlHttpRequest()</code></a> est bien pratique.</p>
<p>Un petit aperçu du rendu dans le navigateur en mode débug, lorsque la page est appelée directement depuis la barre d'adresse du navigateur.</p>
<div id="attachment_26" class="wp-caption aligncenter" style="width: 310px"><a href="http://jerome.tamarelle.net/blog/wp-content/uploads/2006/03/json-symfony-template.png"><img class="size-medium wp-image-26" title="json-symfony-template" src="http://jerome.tamarelle.net/blog/wp-content/uploads/2006/03/json-symfony-template-300x217.png" alt="Template JSON" width="300" height="217" /></a><p class="wp-caption-text">Aperçu du rendu JSON en mode débug.</p></div>
<p><strong>1/3</strong> Créez le composant JSON. Fichier app/<em>app_name</em>/modules/<em>module_name</em>/actions/jsonComponent.class.php</p>
<pre class="brush: php;">
class jsonComponent extends sfComponent
{
  function execute($request)
  {
    if (sfConfig::get('sf_debug') &amp;&amp; !$this-&gt;getRequest()-&gt;isXmlHttpRequest())
    {
      $this-&gt;setVar('data', $this-&gt;data);
    }
    else
    {
      $this-&gt;getResponse()-&gt;setHttpHeader('Content-type', 'application/json');
      $this-&gt;getResponse()-&gt;setContent(json_encode($this-&gt;data));
      return sfView::NONE;
    }
  }
}
</pre>
<p><strong>2/3</strong> Créez ensuite la vue associée. Fichier app/<em>app_name</em>/modules/<em>module_name</em>/templates/_json.php</p>
<pre class="brush: php;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;&lt;title&gt;JSON response&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
  &lt;h2&gt;JSON&lt;/h2&gt;
  &lt;?php echo json_encode($sf_data-&gt;getRaw('data')); ?&gt;
  &lt;h2&gt;Data structure&lt;/h2&gt;
  &lt;pre&gt;&lt;?php print_r($sf_data-&gt;getRaw('data')); ?&gt;&lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong>3/3</strong> Enfin appelez le composant depuis votre contrôleur. Fichier app/<em>app_name</em>/modules/<em>module_name</em>/actions/actions.class.php</p>
<pre class="brush: php;">
function executeAction() {
  $data = array();
  // ... Création du tableau $data ...

  // Transmet la responsabilité de l'affichage au composant JSON
  return $this-&gt;renderComponent('module_name', 'json', array('data'=&gt;$data));
}
</pre>
<p>Le composant peut être créé dans un module spécifique et appelé depuis un autre module.</p>
<p>Reste plus qu'à en faire un plugin ...</p>
<p><strong>Deux articles pour aller plus loin :</strong></p>
<ul>
<li><a title="AJAX and JSON" href="http://trac.symfony-project.org/wiki/AjaxAndJSON">AJAX and JSON</a></li>
<li><a title="JSON" href="http://librosweb.es/symfony_1_2_en/capitulo11/json.html">Symfony 1.2 The definitive guide | JSON</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jerome.tamarelle.net/blog/2009/12/vue-au-format-json-sous-symfony/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
