Introducing Publish It Yourself: a self-managed libre CMS
Publish It Yourself is a self-managed CMS. It is designed to create autonomous communities where users can directly create and manage content.
It is a mix between blogs and blogs platforms, digg-likes and open publishing websites such as the Indymedia network.
It allows to publish and promote rich text articles and news. It includes many features: tagging with triple tags support, comments, spam protection, themes, interface translation, registration system, peronnal users pages, Atom feeds, microformats, and more! Every pages are optimized for search engines, including expressives URLs and uniques titles.
It is written in PHP using the symfony framework. It is modular and object oriented. The Javascript part of the code uses jQuery, the built-in theme is (x)HTML 5 compliant.
This software is still in an early stage of development and probably has many bugs, please report them! It is a free software covered by the GNU Affero General Public License version 3.
You can try it online (database cleared periodically) or download it on GitHub. Contributions are welcome (see the TODO file inside the project root directory) and can be submitted directly on GitHub.
Tag Suggestion for symfony
I just have created a patch for sfFormExtraPlugin. It provides a new form widget called sfWidgetFormJqueryTagSuggestion designed to suggest tags. It is based on the Tag Suggestion jQuery plugin of Remy Sharp.

You can download it from GitHub, just copy the files to the corresponding directories of your existing sfFormExtraPlugin installation or wait for upstream inclusion of my patch.
This widget integrates easily with sfPropelActAsTaggableBehaviorPlugin. Here is how to use it with this plugin.
You must have sfFormExtraPlugin with my patch and sfPropelActAsTaggableBehaviorPlugin properly installed and working. We consider that you have a model called Article with the taggable behavior.
Add jQuery to your javascripts
Like many others sfFormExtraPlugin widgets, the sfWidgetFormJqueryTagSuggestion requires jQuery to work. If you already have it installed, you can skip this step. Either, download jQuery to the web/js/ directory of your project, open the config/view.yml file of your application and set it like that:
default:
javascripts: [jquery-1.3.2.min.js]
Of course, change the filename if needed.
Put Javascripts and CSS into your web directory
sfFormExtraPlugin need some CSS and Javascripts to work properly, run the symfony plugin:publish-assets command to put them into corrects directories.
Create a static function to retrieve matching tags
Its time to extend the TagPeer model class to add it a method allowing to retrieve tags corresponding to a query. Creates a new file called MyTagPeer.class.php into the lib/model/ directory of your project containing the following code:
class MyTagPeer extends TagPeer {
/**
* Gets tags for a selector
*
* @param string $q
* @param int $limit
* @return array
*/
static public function retrieveForSelect($q, $limit = 10)
{
$criteria = new Criteria();
$criteria->add(TagPeer::NAME, '%'.$q.'%', Criteria::LIKE);
$criteria->addAscendingOrderByColumn(TagPeer::NAME);
$criteria->setLimit($limit);
$tags = array();
foreach (TagPeer::doSelect($criteria) as $tag) {
$tags[] = $tag->getName();
}
return $tags;
}
}
Do not forget to run symfony cc to clear the cache after that.
Create a controller method to send the result as JSON
We have the model, we need the controller. Create a new module called tag by running symfony generate:module yourapp tag and add the following method to the tagActions class:
/**
* Displays a JSON encoded tags array
*
* @param sfWebRequest $request
* @return string
*/
public function executeSelect(sfWebRequest $request)
{
$this->getResponse()->setContentType('application/json');
$tags = MyTagPeer::retrieveForSelect($request->getParameter('tag'));
return $this->renderText(json_encode($tags));
}
Open your routing.yml file and add the following line to be able to access this action:
tag_select:
url: /select-tag
param: { module: tag, action: select }
Modify your form to add the new tags suggestion widget
Open the form class you want to add this widget and add the following line to the end of the configure method:
$this->widgetSchema['tags'] = new sfWidgetFormJqueryTagSuggestion(array('url' => $this->getOption('url'), 'separator' => ', '));
We use the comma as separator instead of the space by default because this is the separator used by sfPropelActAsTaggableBehaviorPlugin.
Next, modify your call to the form in your actions to pass the AJAX URL as form option:
$this->form = new ArticleForm($article,
array('url' => $this->generateUrl('article_select_tag'))
);
It’s done!
Patch to use sfXssSafePlugin with symfony 1.2
HTML Purifier is a awesome PHP filter library designed to secure and add standard compliance to HTML. In websites including user generated content, this library allow to have mutlimedia pages including image, text formating and YouTube videos in a secure and SEO proof way thanks to rich text editors like Tiny MCE or FCK Editor and HTML purifier.

A plugin called sfXssSafePlugin is designed to integrate this library as an escapement strategy in symfony. If you have tried it with symfony 1.2 you can see this message:
HTML Purifier autoloader registrar is not compatible
with non-static object methods due to PHP Bug #44144;
Please do not use HTMLPurifier.autoload.php (or any
file that includes this file); instead, place the code:
spl_autoload_register(array(’HTMLPurifier_Bootstrap’, ‘autoload’))
after your own autoloaders.
There are also some strict standards and constants compatibility problems. I’ve just wrote a patch to get this plugin working with symfony 1.2.
- Install sfXssSafePlugin like described in its README file
- Download my patch in the plugin’s folder
- Go into the plugin’s folder and run patch lib/helper/XssSafeHelper.php < XssSafeHelper.php.patch
- Edit your application configuration file (ie: apps/frontend/config/frontendConfiguration.class.php) and add the following code into the
configure()method:require_once(sfConfig::get('sf_plugins_dir').'/sfXssSafePlugin/lib/vendor/htmlpurifier/HTMLPurifier/Bootstrap.php'); spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload'));
It’s done ! I’ve submitted this patch to the plugin’s author. I hope it will be upstream soon
Add reCAPTCHA widgets to Symfony forms
I’ve wrote a new Symfony plugin to add reCAPTCHA widgets and validation to Symfony new forms. reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows.

To install: checkout it from http://selfpublish.googlecode.com/svn/trunk/plugins/sfAnotherReCaptchaPlugin/ and put it in your Symfony plugins directory.
Next, get a reCAPTCHA key and put the following lines in your app.yml:
recaptcha:
public_key: <your public reCAPTCHA key>
private_key: <your private reCAPTCHA key>
Clear the cache with the symfony cc and check that the plugin activated in projectConfiguration.class.php.
You are now able to add reCAPTCHA widgets and validators.
See the plugin’s README file or this register form with reCAPTCHA enabled to learn how to use it.
This plugin is distributed under the MIT license and is based on Arthur Koziel work.
Un formulaire de création de compte avec Symfony et sfGuard
sfGuard fait parti des plugins Symfony les plus utiles. Il ajoute à notre framework un système de gestion avancé des utilisateurs, groupes et permissions. Il inclut en standard un back office complet ainsi qu’un formulaire de connexion mais pas pour de la création de compte en front.
![]()
Alors qu’il fût assez fastidieux de le réaliser avec la version 1.0 de Symfony, le nouveau système de création de formulaires introduit dans la version 1.1 nous facilite bien la tache.
Je ne reviendrais pas sur l’installation du plugin qui est très bien détaillée dans sa documentation.
Commençons par générer les formulaires associés à nos tables grâce à Propel : php symfony propel:build-forms. Attaquons-nous maintenant à la classe de notre formulaire d’enregistrement. Créez un fichier nommé sfGuardRegisterForm.class.php dans le répertoire lib/form/ qui contient ce code :
<?php
class sfGuardRegisterForm extends sfGuardUserForm
{
public function configure()
{
parent::configure();
/* Ici on ajoute une validation
pour le mot de passe afin qu'il soit long
d'au moins 6 caractères et d'au plus 128. */
$this->validatorSchema['password'] = new sfValidatorString(
array('min_length' => 6, 'max_length' => 128)
);
}
}
Comme vous pouvez le lire, on se contente de créer une classe qui hérite de sfGuardUserForm fournie avec le plugin et d’y ajouter une validation supplémentaire pour le mot de passe (par défaut il peut être vide). C’est également dans cette méthode configure que se déroulera la validation de vos champs personnalisés sur lesquels nous reviendrons plus bas.
Effacez la cache avec la commande php symfony cc. C’est déjà presque fini !
Créons un répertoire sfGuardAuth dans le répertoire modules de votre application puis deux sous répertoires dans sfGuardAuth nommés actions et templates. Ce pseudo-module nous permettre de surcharger le module sfGuardAuth du plugin afin de lui ajouter une action et une vue qui permettront à vos visiteurs de s’enregistrer sur votre site.
Créez un fichier actions.class.php dans le répertoire actions qui contient :
<?php
/* On doit inclure manuellement
l'action du plugin car l'autoloading ne fonctionne pas dans ce cas. */
require_once(sfConfig::get('sf_plugins_dir').
'/sfGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php');
/* Notre action dérive de celle fournie par le module
afin d'hériter de ses actions propres. */
class sfGuardAuthActions extends BasesfGuardAuthActions
{
public function executeRegister($request) {
/* Passe le formulaire à la vue. */
$this->form = new sfGuardRegisterForm();
/* Si l'action est appelé via la méthode POST... */
if ($request->isMethod('post')) {
$this->form->bind(
$request->getParameter('sf_guard_user')
);
/* ...et que les données sont valides */
if ($this->form->isValid()) {
/* On crée l'utilisateur */
$sf_guard_user = $this->form->save();
$this->getUser()->setFlash('message',
'Vous êtes enregistré,
<a href="/login">connectez-vous</a> !');
$this->redirect('@homepage');
}
/* Sinon le formulaire ainsi que l'erreur sera ré-affiché */
}
}
}
Quand l’utilisateur est créé on redirige le visiteur vers la page d’accueil et on l’avertit grâce à un attribut flash.
Passons à la vue qui se nommera registerSuccess.php et qui se trouvera dans le répertoire templates :
<form action="<?php echo url_for('sfGuardAuth/register') ?>" method="POST">
<table>
<?php echo $form ?>
<tr>
<td colspan="2">
<input type="submit" />
</td>
</tr>
</table>
</form>
Très bien, notre formulaire fonctionne. Mais le plus fort arrive !
Vous avez ajouter des champs personnalisés au profil de votre utilisateur dans la table sf_guard_user_profile (cf. la documentation de sfGuard) ? Régénérez les formulaires associés à vos tables avec la commande php symfony propel:build-forms, effacez la cache à grand coup de php symfony cc, rechargez la page /sfGuardAuth/register et admirez : nos champs sont automatiquement reconnus et affichés. Vous pourrez leur ajouter des étapes de validation dans notre première classe sfGuardRegisterForm ou dans sfGuardUserProfileForm si vous voulez qu’elles s’appliquent à tous les formulaires héritant de cette classe (page de modification du profil, ….).
Les vacances !
Après 5 mois chez Ankama, enfin les vacances !
Ce fût l’occasion (même si ils élèvent des chiens) de rencontrer (même si ils ont des franges) pas (même si ils sont fan de VBS) mal (même si ils veulent restaurer la grandeur de l’Empire austro-hongrois) de gens sympas (oééééé) et de travailler sur des projets intéressants à l’aide de technologies d’avant garde tels que Symfony, Yahoo! User Interface, les microformats, AIR, PureMVC, Python ou encore Smartfox server.
Je vais profiter des 15 prochains jours pour changer un peu d’air avant de retourner à l’Université de Lille 1 pour ma 3ème année de licence informatique.

6 plugins Symfony indispensables
Écrit en PHP, orienté objet, implémentant le design pattern Moèle-Vue-Controlleur, doté de nombreuses fonctionnalités et soutenu par Yahoo! : Symfony, le framework web développé par Sensio Labs, à tout pour plaire.
L’une des forces de ce framework est la disponibilité de nombreux plugins qui permettent d’étendre ses fonctionnalités. On y trouve du bon et du moins bon, de l’utile comme du futile. Pour vous aider à bien démarré vos projets Symfony et vous faire gagner du temps lors de vos développement, j’ai sélectionné pour vous quelques plugins indispensables, que vous devriez installé dès les prémices du développement.

sfGuard
C’est le plus connu de tous les plugins Symfony. Il permet une gestion fine des utilisateurs ainsi leur authentification. Son utilisation est quasi-indispensable à tout déploiement de Symfony. De plus, c’est une dépendance d’autres plugins populaires tel que sfSimpleCMSPlugin ou sfSimpleForumPlugin.
sfThumbnailPlugin
Ce plugin permet tout simplement de générer des miniatures d’images uploadées. Indispensable !
A voir aussi, ce bout de code qui permet d’utiliser sfThumbnailPlugin avec le générateur d’admin.
sfFeed2Plugin
Avec sfFeed2Plugin générés des flux RSS et Atom à partir de vos modèle. Rapide à mettre en œuvre, il offre un service utile à vos visiteurs et qui ravie les robots des moteurs de recherche qui indexent votre site.
sfPropelActAsSluggableBehaviorPlugin
Ce plugin est destiné à l’ORM Propel qui est fourni par défaut avec Symfony. Il permet la génération automatique de slugs, c’est à dire d’identifiants descriptifs. Ces slugs sont très utiles au référencement car ajoutent à vos URLs des mots clefs pertinents. Autre avantage : ils masquent les IDs numériques de vos éléments et rend plus difficile à un pirate de découvrir l’architecture interne de votre application.
sfYzAjaxValidationPlugin
sfYzAjaxValidationPlugin ajoute une validation des formulaires côté client via AJAX. Il utilise les fichiers YAML définis côté serveur. Pas de code à écrire pour vous mais un gain de temps appréciable pour le visiteur (aucun rechargement de la page pour valider le formulaire) et une charge serveur réduite.
sfPropelSqlDiffPlugin
Avec Ruby On Rails et Django lorsque vous modifiez votre modèle, les changements sont répercutés sur la base de données. Ce n’est pas le cas par défaut avec Symfony, il faut effectuer les modifications à la main sur la base de données ou perde toutes nos données de test et ça devient vite très agaçant. Heureusement sfPropelSqlDiffPlugin est la ! Ce plugin ajoute quelques options à l’utilitaire en ligne de commande de Symfony et permet de répercuter uniquement les changements effectués dans le modèle sur la base de données.

