3 commentaires
Posté par Cedric, le 14/07/2008 - Technologie
One of the recurring concern when developing an internationalized application, is to not let any element untranslated. This is natively complicated, even with the brand new symfony 1.1. You often end up with untranslated URLs or meta tags. But using the Framework in conjonction with the Yahoo!'s plugin ysfDimensionsPlugin will fill all the blanks you could have experienced once.
The role of the plugin is to let you define specific dimensions (can be cultures, can be themes, etc.), and to make it possible to override any part of your application (actions, templates, config) by simply adding a subdirectory, with the name of your dimension.
Let's have a quick exemple.
First of all, you will have to link your existing project to the plugin SVN.
svn propedit svn:externals plugins/
Then append to the file:
ysfDimensionsPlugin http://svn.symfony-project.com/plugins/ysfDimensionsPlugin/branches/1.1/
Update everything:
svn up
Let's say we want to internationalize the application in english and french. That means we will add a "culture" dimension with two possibilities in it: en, and fr. To do that, create a /config/dimensions.yml file and write:
allowed: culture: [en, fr]
Now, we have to edit the main configuration script, so the plugin can add our brand new configuration levels.
require_once '/path/to/your/project/lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();
require_once '/path/to/your/project/plugins/ysfDimensionsPlugin/lib/config/ysfProjectConfiguration.class.php';
class ProjectConfiguration extends ysfProjectConfiguration
{
public function setup()
{
}
}
Notice that the ProjectConfiguration class now extends ysfProjectConfiguration (against sfProjectConfiguration, the y stands for yahoo!).
The dimension will be set up on an application level. In my example, the user culture is determined by the domain he is browsing. French will be something like fr.mydomain.com, and his culture will be set to english otherwise. To industrialize this behaviour, we have to edit our application configuration file.
Edit /apps/YOURAPP/config/yourAppConfiguration.class.php. First, manually require the plugin library.
require_once(dirname(__FILE__).'/../../../plugins/ysfDimensionsPlugin/lib/config/ysfApplicationConfiguration.class.php');
Then, make your class extend the Yahoo! Application configuration class, instead of the core symfony one.
class frontConfiguration extends ysfApplicationConfiguration // instead of sfApplicationConfiguration
Ok. Now, let's define the dimension, in the configure method.
public function configure()
{
//-- hacky. Demonstration purpose only.
$host_part = explode('.', $_SERVER['HTTP_HOST']);
$culture = (
strLen($host_part[0])==2 &&
(in_array($host_part[0], array('fr', 'en')))
)?$host_part[0]:'en';
$this->setDimension(array('culture' => $culture));
parent::configure();
}
Note: this should go with an appropriate filter, like the one used here in symfonians.
Cool, we're almost done. If you have an APC extension up and running on your environment, you can pretty safely trigger a symfony cc command. If everything goes as usual, try to browse your app, and if you nothing weird happens, you're good to go.
If you don't have APC, you have good chance it won't work. Indeed, the plugin natively caches the configuration directories in the memory, using the PHP6 core library APC (you can grab it with "pecl install apc").
If you can't make it work, this is your last hope: override the main construction call, to make use of local cache or, if in debug mode, no cache at all (bad for production of course).
There you go:
class frontConfiguration extends ysfApplicationConfiguration
{
public function configure()
{
$this->debug = true;
//-- Hacky. Demonstration purpose only.
$host_part = explode('.', $_SERVER['HTTP_HOST']);
$culture = (
strLen($host_part[0])==2 &&
(in_array($host_part[0], array('fr', 'en')))
)?$host_part[0]:'en';
// setup dimensions before calling parent::configure();
$this->dimension = new ysfConfigDimension(
$this->getEventDispatcher(),
(!isset($this->debug) || (isset($this->debug) && $this->debug === true))
? new sfNoCache() :
new sfCache(
array(
'prefix' => 'symfony.dimensions.config.default:'.$this->application.':'.$this->environment,
'automatic_cleaning_factor' => 0, 'lifetime' => 86400)
)
);
$this->setDimension(array('culture' => $culture));
parent::configure();
}
}
I had to force the $this->debug = true; because I had mysterious bugs on my development machine (Mac OSX). Try to remove it, if it works without that, it's even better.
Now, let's trigger a clear cache (symfony cc) and hit a fresh browser pointing to your application. Everything works as expected? Congrats, now we can go to the fun part.
In a big scale project, you generally have four types of I18N:
symfony natively supports nb 1 (thanks to Doctrine or Propel), nb 2, and that's pretty much it. Let's go back to our little project. You're working hard on it, and the whole project is almost done. You have written pretty short SEO-friendly URL in /apps/YOUR_APP/config/routing.yml, and nice metas in your /apps/YOUR_APP/modules/YOUR_MOD/config/view.yml. Last, but not least, you decided to put all the static content in a "static" module, where you have empty actions and 5 to 10 HTML fragments.
Let's internationalize everything:
routing.yml
homepage:
url: /
param: { module: home, action: index }
team:
url: /team
param: { module: team, action: index }
about_us:
url: /about-us
param: { module: static, action: about }
Obviously, we don't need to translate the first routing rule (@homepage). So let's create a routing.yml file in /apps/YOUR_APP/config/fr/routing.yml. (create the fr directory if it doesn't exist yet).
team: url: /equipe about_us: url: /a-propos
And that's it! The plugin is smart enough to automatically inherit your main routing file, and as we gave them the same names, you can restrict your work to defining only the elements that change.
Now, try to go to http://fr.yoursite.dev, and hover a link to @team. It should show the french version now. Now point to the @about_us page. The URL is in french, but the content is in english, right? Remember, it's a static page we created in a dedicated module. Let's correct that:
Create a fr directory in
/apps/YOUR_APP/modules/static/templates
This process can be done for almost anything in your website. It's especially useful for metas. Just create a fr directory in /apps/YOUR_APP/modules/YOUR_MOD/config/fr/, and a view.yml file in it, and enjoy:
indexSuccess:
metas:
title: My French Title
[etc..]
When you've done that work once, you can reproduce a fully I18n environnement very quickly for your new project. Don't forget that this ysfDimensionsPlugin is very powerful, and can be the perfect solution when you need to build many websites using the same engine (like a white label).
If you have any tip with I18N or ysfDimensionsPlugin, feel free to leave a comment.
tags: i18n, symfony, tutorial, ysfDimensionsPlugin,
aucun commentaire
Posté par Cedric, le 09/06/2008 - Technologie
Voila déja plusieurs mois que l'on connait le projet d'OS mobile de Google, nommé Androïd. Mais très peu d'informations concrètes avaient filtré.
Jusqu'à la semaine dernière, moment choisi par Google pour dévoiler ce qui sera certainement leur produit technologique phare dans les années à venir. Un moment très bien choisi, à quelques jours seulement de la présentation par Steve Jobs de l'iPhone 3G.
J'ai été absolument stupéfait par cette vidéo. Google semble avoir réussi à égaler Apple sur son terrain, celui de la convivialité de l'interface utilisateur, sans toutefois tomber comme la pomme dans le piège du logiciel propriétaire. Ainsi, la firme de Mountain View a dès les premiers pas de l'OS fait participer les développeurs autour de son SDK, et ainsi fédérer une forte base de "geeks", pourtant éperdument amoureux de l'iPhone à ses débuts. Ce crowd-sourcing a fait émerger des idées géniales, et je me demande vraiment si la fabuleuse boussole intégrée au Google OS n'est pas inspirée du fabuleux projet Enkin, pourtant recalé au concours d'innovation Google Android.
Stratégiquement, ce projet est la conclusion de quatre année extrêmement bien calculées de la part de Google. Tout est parti de l'innovation fondamentale que fût Google Maps, qui les place aujourd'hui idéalement pour attaquer la monétisation des annonceurs offline (commencé avec AdWords pour mobile, que va faire littéralement exploser l'arrivée d'Androïd, comme Windows a fait exploser Internet Explorer). En effet, grâce à ces OS mobile de nouvelle génération, la frontière entre Internet et le monde réel va être de plus en plus fine, puisque des technologies embarquées permettront de connecter l'ensemble de la planète sans aucune connaissance technologique préalable.
Un coup de maitre aussi par rapport à Apple, qu'on pourrait illustrer de la manière suivante: c'est un peu comme si Google avait, lors de la sortie d'OS X, sorti un système qui reprend ses qualités et les poussent encore plus loin, mais sans la contraindre à une machine (le macintosh dans cet exemple), et tout en Open Source. On aurait alors pu installer ce Google OS X sur Mac comme sur PC, complètement gratuitemet, et le géant californien aurait logiquement raflé le marché du système d'exploitation.
C'est exactement ce qui risque d'arriver pour le marché du mobile.
10 commentaires
Posté par Cedric, le 20/05/2008 - Technologie
Je n'aurais jamais pensé écrire ce genre d'article il y a encore six mois. J'ai en effet toujours fait partie des méfiants vis-à-vis des Mac ; les produits élitistes, design, bénéficiant d'un fort consensus auprès de populations non-nerds me rendent toujours un peu sceptiques.
Mais voilà que depuis quelques années déjà, j'observe qu'une majorité de développeurs et autres administrateurs réseaux passent progressivement au Mac. Le délaissement du PC semble même s'être accéléré depuis la sortie de la catastrophe Windows Vista.
Rattrapé par des problèmes récurrents de pertes de performances sur mon PC, dûs à la très mauvaise gestion de la mémoire vive sous Windows, j'essayai Linux Ubuntu comme un baroud d'honneur (j'utilisais jusque là Linux Redhat/Debian/Gentoo uniquement en serveurs web). Mon goût pour Linux et mon amour de la ligne de commande n'ont cependant pas réussi à me faire oublier une interface graphique que je n'arrive définitivement pas à apprécier. Pas assez de fluidité, pas assez de design, quand son PC est son outil de travail, cela devient vite désagréable.
Alors j'ai cédé pour un portable Mac. Et plutôt qu'un long discours, sachez que j'ai rapidement compris pourquoi autant de développeurs ont fait le pas. Voici ce que j'en retiens après un mois de (joyeuse) utilisation :
L'éditeur TextMate est à la fois très bien fait et très joli. Les tabulations sont propres et il fait même un peu d'autocomplétion. En revanche je regrette mon EditPlus pour le support intégré du FTP (je dois passer par Transmit). Mais si vous marchez par miroirs SVN ce n'est plus trop un problème.
Bien sûr, il y a toujours des choses que je n'aime pas sous Mac. Ne pas pouvoir mettre une fenêtre en plein écran, l'obligation d'utiliser le menu « fenêtres » pour naviguer entre les différentes fenêtres d'un même programme (Windows permet de les changer dans le ALT TAB, même si on peut utiliser Exposé pour contourner le problème), et évidemment je n'aime pas l'absence du clic droit... même si là encore on peut configurer le TouchPad de manière à déclencher le menu contextuel quand deux doigts appuient dessus en même temps. Enfin, le prix du matériel simplement trop cher. J'ai pour la part acquis l'ensemble aux Etats-Unis, car les prix sont les mêmes là bas, et avec un dollar aussi faible qu'en ce moment le calcul est vite fait. Cependant, les accessoires vous couterons très cher ici en France (et 3 à 4 fois plus au Maghreb), comme les 19 euros à débourser pour un simple connecteur DVI/VGA.
Des détails parmi l'océan d'avantages que j'ai découvert depuis l'acquisition de cette machine. Je suis donc ravi d'avoir fait le pas, et attend désormais mon prochain passage en Allemagne où l'iPhone est à 99 euros pour achever ma conversion
tags: mac
un commentaire
Posté par Cedric, le 15/05/2008 - Technologie
C'est désormais officiel, la refonte du désormais célèbre Yahoo! Answers (questions/réponses en français) a été développé en PHP, avec le Framework symfony.
Dans une présentation très instructive, on apprend quels sont les éléments décisifs ayant amenés la firme de Sunnyvale a adopter le Framework open source symfony, développé et maintenu par des français. Parmi les avantages soulignés, sa séparation claire des couches métier, logique et présentation (le paradigme MVC), son extensibilité (système de plugins), sa facilité d'internationalisation, et son excellente documentation.
symfony semble donc continuer sa route dorée vers le statut tant convoité des applications open-source professionnelles. Sa crédibilité augmente à mesure que des sites à très fort trafic l'adoptent et arrivent ainsi à allier extensibilité et performances. Dustin Whittle cite d'ailleurs un chiffre impressionnant : moins de 100ms de chargement pour cette application 100% dynamique (l'application étant mise à jour trop souvent pour pouvoir être mise en cache).
On notera que Yahoo! n'en n'est pas à son coup d'essai, puisque l'application Yahoo! Bookmarks avait déjà été développée avec symfony en 2006. C'est à cette occasion que j'avais découvert le Framework, lors d'une conférence téléphonique appelée Tech Talks (oui, j'étais au marketing où je me suis d'ailleurs occupé d'une partie du lancement de Answers en France, mais ma schizophrénie professionnelle me rattrapa ;-) ), avant d'en faire la technologie de base utilisée dans mon agence. Yahoo! était pour cela une belle entreprise, avec un accès intranet assez incoryable où les discussions de pointe étaient ouvertes à tous, et faisaient intervenir quelques uns des meilleurs programmeurs au monde (dont Rasmus Lerdorf, inventeur du PHP et employé chez Yahoo!).
La sortie imminente de symfony 1.1 et son système de formulaire 100% indépendant et MVC compliant, de même que ses récentes évolutions conceptuelles (moins « prêt à l'emploi », mais plus fiable et plus extensible, une sorte de couche basse complète sur laquelle on peut bâtir des ensembles solides), font de symfony un outil extrêmement crédible pour développer des applications fiables et évolutives.
Il est temps d'observer les bénéfices de cette nouvelle : non seulement la communauté des développeurs devrait s'élargir à mesure que les applications professionnelles adopteront l'outil, mais Yahoo! va prochainement déverser dans la communauté les plugins fort intéressants qu'ils ont développé pour le projet. Vous avez la liste dans la présentation de Dustin. J'ai particulièrement hâte de voir à quoi va ressembler le plugin ysfBuildPlugin, qui semble offrir un superbe outil pour maximiser l'efficacité de son déploiement. L'évolution du plugin ysfDimensionPlugin semble également prometteuse dans le cadre d'applications distribuées et internationales.
aucun commentaire
Posté par Cedric, le 05/05/2008 - Technologie
Le vent tourne vite dans les technologies web. Après 4 ans de hype ininterrompue à propos du framework Ruby "Ruby on Rails", les problèmes continus rencontrés par Twitter (incapable d'adapter son application à la croissance de sa base) semblent avoir porté un coup de grâce à l'avenir professionnel de ce package.
La longue série de commentaires faisant suite à l'article de TechCrunch montre bien la situation dans le monde du développement: un peu comme les fervents supporters de Mac contre Windows, chaque programmeur a son langage fétiche, et a beaucoup de mal à reconnaître ses faiblesses ou ses limitations.
La réalité est moins radicale: aucune solution n'est parfaite, et RoR a l'avantage d'avoir introduit des concepts intéressants et largement repris par ailleurs. J'ai personnellement toujours préféré les applications qui reposent sur la base d'utilisateurs la plus importante, et sur un environnement serveur classique (Apache, PotsgreSQL ou MySQL, Unix). D'où ma grande préférence pour PHP et Python. PHP qui a d'ailleurs beaucoup évolué grâce à RoR, et l'apparition de nombreux frameworks de qualité comme Symfony ou Cake, inspirés en partie du framework Ruby. Avec l'arrivée de PHP6, de nouveaux ORM plus puissants (Propel 2, Doctrine), et une communauté toujours aussi active, je reste persuadé que le PHP est le bon choix pour les applications professionnelles, à condition qu'elles soient conçues intelligemment en amont (structure de base de données, jointures efficaces...), et optimisées à tous les niveaux (cache html, cache de requête SQL, cache de précompilation, cache en mémoire vive, reverse proxies etc.).
tags: php, ruby-on-rails
2 commentaires
Posté par Cedric, le 14/04/2008 - Technologie
Au lendemain du lancement par Google de App Engine, il est temps de revenir sur un des piliers de l’internet du futur, le cloud computing.
Depuis ses débuts, Internet se compose toujours de la même manière : un site, du trafic, une architecture serveur. Pour imager, on pourrait voir les serveurs comme la bâtisse d’un magasin, les sites comme les boutiques à proprement parler, et le trafic comme les chalands qui se déplacent dans ce centre commercial. Une même bâtisse peut contenir plusieurs boutiques, et plus cette bâtisse est solide et optimisée pour la chalandise (routes, parkings, solidité des fondations, service de sécurité etc..) plus elle est capable de drainer et de contenir de monde.
Il en va de même pour le web. Et c’est précisément là où le bat blesse. Reprenons notre exemple. Après avoir mené une formidable campagne de promotion (sur Internet évidemment), vous voila submergé : des kilomètres d’embouteillages encerclent votre centre commercial, si bien que votre infrastructure est dépassée et ne peut contenir tout cet afflux de visiteurs : vous fermez boutique, en attendant de décongestionner la zone.
Ce genre de problème arrive tous les jours sur Internet. Il est dû à la mauvaise adéquation entre l’architecture serveur et le trafic. Très souvent, les startups tentent d’économiser sur ce poste, en attendant de voir si le trafic augmente. Un beau jour, Michael Arrington leur accorde un article dans TechCrunch. Après les félicitations et la flatterie de rigueur, les créateurs sourient devant leurs courbes de suivi statistique en temps réel… avant de grimacer devant la lenteur soudaine de leur service. Quelques minutes après, la réponse se fait attendre plusieurs minutes, avant d’afficher une erreur 500.

C’est là qu’intervient la petite révolution du cloud computing. Le système est simple, les usines à gaz que sont Amazon et Google possèdent des architectures considérables de plusieurs dizaines de milliers de serveurs. Or, passé un certain stade, ajouter des machines à une architecture déjà existante et très bien structurée coûte très peu d’argent. Amazon s’est donc doté d’un parc additionnel considérable, qu’ils ont virtualisé pour le proposer au grand public. Ainsi est né Amazon EC2 (Elastic Computer Cloud). EC2 est un web service (une API) qui permet d’étendre un serveur facilement et rapidement, pour lui ajouter la puissance et la disponibilité des serveurs d’Amazon. La bande passante, la capacité de stockage, ainsi que la disponibilité sont théoriquement sans limite (dans la réalité, des accidents peuvent arriver). La startup a donc la possibilité, lorsqu’elle voit arriver une charge importante sur son serveur, de créer une image Amazon de leur système et de le dupliquer sur les serveurs distants du libraire Américain. Le trafic recevable est instantanément décuplé et la vitesse de chargement reste intacte pour les nouveaux arrivants.
Il s’agit d’une formidable innovation, qui aide à construire un web « scalable », évolutif et élastique. Une pratique rependue désormais au stockage d’image, avec Amazon S3 ou à la base de données avec SimpleDB. Ceci rend donc théoriquement possible de nouvelles pratiques : avoir un serveur minimal, indispensable pour bâtir son prototype et même lancer son service, et externaliser d’entrée le stockage de son contenu, ainsi que prévoir dès le départ l’addition de serveurs existants en préparant ses images disques prêtes à être lancées.
Un peu comme un supermarché dont la taille du bâtiment serait à même de changer selon l’affluence, permettant ainsi de réduire les couts de structure et de variabiliser des frais que l’on pensait condamnés à rester fixes. Une pratique destinée à se répandre et un marché que n’a pas voulu rater Google en proposant aux développeurs de bâtir leurs applications sur les mêmes serveurs que le célèbre moteur de recherche. La conquête des développeurs étant devenue stratégique pour les géants de l’Internet, on a du mal à croire que Yahoo! et Microsoft ne suivent pas la danse.
tags: amazon, cloud-computing, google
un commentaire
Posté par Cedric, le 04/04/2008 - Technologie
Pour ceux qui se demandent à quoi ressemble concrètement une attaque de hacker, voici un exemple simple.
A la commande suivante:
tail -200 /var/log/auth.log
Votre serveur Linux vous répond:
Apr 3 05:13:30 xxxxxx sshd[18197]: Invalid user dustin from 217.199.178.44 Apr 3 05:13:30 xxxxxx sshd[18200]: Invalid user dusty from 217.199.178.44 Apr 3 05:13:31 xxxxxx sshd[18203]: Invalid user joey from 217.199.178.44 Apr 3 05:13:31 xxxxxx sshd[18207]: Invalid user hirano from 217.199.178.44 Apr 3 05:13:31 xxxxxx sshd[18209]: Invalid user piranha from 217.199.178.44 Apr 3 05:13:31 xxxxxx sshd[18211]: Invalid user kobayashi from 217.199.178.44 Apr 3 05:13:31 xxxxxx sshd[18213]: Invalid user nishimura from 217.199.178.44 Apr 3 05:13:32 xxxxxx sshd[18215]: Invalid user nishida from 217.199.178.44 Apr 3 05:13:32 xxxxxx sshd[18217]: Invalid user ishihara from 217.199.178.44 Apr 3 05:13:32 xxxxxx sshd[18219]: Invalid user watanabe from 217.199.178.44 Apr 3 05:13:32 xxxxxx sshd[18223]: Invalid user glenn from 217.199.178.44 Apr 3 05:13:32 xxxxxx sshd[18227]: Invalid user hasegawa from 217.199.178.44 Apr 3 05:13:33 xxxxxx sshd[18229]: Invalid user suzuki from 217.199.178.44 Apr 3 05:13:33 xxxxxx sshd[18233]: Invalid user shimizu from 217.199.178.44 Apr 3 05:13:33 xxxxxx sshd[18236]: Invalid user wada from 217.199.178.44 Apr 3 05:13:33 xxxxxx sshd[18238]: Invalid user miyazaki from 217.199.178.44 Apr 3 05:13:33 xxxxxx sshd[18240]: Invalid user nakao from 217.199.178.44 Apr 3 05:13:33 xxxxxx sshd[18242]: Invalid user azuma from 217.199.178.44 Apr 3 05:13:34 xxxxxx sshd[18246]: Invalid user akiyama from 217.199.178.44 Apr 3 05:13:34 xxxxxx sshd[18248]: Invalid user katayama from 217.199.178.44 Apr 3 05:13:34 xxxxxx sshd[18252]: Invalid user kn from 217.199.178.44 Apr 3 05:13:35 xxxxxx sshd[18254]: Invalid user test from 217.199.178.44 Apr 3 05:13:35 xxxxxx sshd[18256]: Invalid user serwis from 217.199.178.44 Apr 3 05:13:35 xxxxxx sshd[18258]: Invalid user crowley from 217.199.178.44 Apr 3 05:13:35 xxxxxx sshd[18260]: Invalid user tomek from 217.199.178.44 Apr 3 05:13:35 xxxxxx sshd[18262]: Invalid user gizmo from 217.199.178.44 Apr 3 05:13:36 xxxxxx sshd[18264]: Invalid user zabbix from 217.199.178.44 Apr 3 05:13:36 xxxxxx sshd[18266]: Invalid user adsl from 217.199.178.44 Apr 3 05:13:36 xxxxxx sshd[18270]: Invalid user exam from 217.199.178.44 Apr 3 05:13:36 xxxxxx sshd[18272]: Invalid user puma from 217.199.178.44
En bon francais, ces lignes signifient qu'un programme pirate a pris possession d'un ordinateur et lance depuis cette adresse une série de tentative de connexion au serveur (en utilisant différents login, comme glen ou suzuki). Si vous êtes administrateur, il y a différents moyens de bloquer ce genre de tentatative. Comme elles se concentrent sur le port 22 (SSH), on peut utiliser un port non-conventionnel pour le SSH (c'est bête mais ca marche diablement bien), ou, plus classique, on peut logger ces tentatives infructueuses et blacklister totalement toute connection TCP avec cette IP pendant un certain temps avec Iptables. Cette série de scripts fait cela très bien.
2 commentaires
Posté par Cedric, le 23/03/2008 - Technologie
Le plugin sfSimpleBlog est une très bonne base de travail pour publier un blog rapidement avec Symfony. Les fonctionnalités de base sont présentes, et il est assez facile d'étendre le système. Pour les besoins de ce blog, je souhaitais pouvoir classer mes articles dans des catégories, ce qui n'était pas possible nativement. Voila comment je m'y suis pris.
Tout d'abord, il faut modifier la structure de la base de données, c'est à dire essentiellement modifier le schema.yml.
1/ Rajouter la table sf_blog_category
sf_blog_category:
_attributes: { phpName: sfSimpleBlogCategory }
id: ~
category_name: { type: varchar(255) }
2/ Modifier la table sf_blog_post
sf_blog_category_id: { type: integer, foreignTable: sf_blog_category, foreignReference: id, onDelete: cascade }
On va ensuite créer la page qui affiche l'ensemble des articles d'une catégorie. La dessus, inutile de réinventer la roue, on se base sur ce qui a été fait pour afficher les pages taggées.
1/ On créé une action executeShowByCategory()
public function executeShowByCategory()
{
$cat = $this->getRequestParameter('cat');
$this->forward404Unless($cat);
//-- on récupere le nom de la cat
$c = new Criteria();
$c->add(sfSimpleBlogCategoryPeer::ID, $cat);
$this->category = sfSimpleBlogCategoryPeer::doSelectOne($c);
//$this->forward404Unless($this->category);
$this->post_pager = sfSimpleBlogPostPeer::getCategoryPager(
$cat,
sfConfig::get('app_sfSimpleBlog_post_max_per_page', 5),
$this->getRequestParameter('page', 1)
);
}
2/ On créé getCategoryPager en dupliquant getTaggedPager
public static function getCategoryPager($cat, $max, $page)
{
$pager = new sfPropelPager('sfSimpleBlogPost', $max);
$c = new Criteria();
$c->add(self::IS_PUBLISHED, true);
$c->add(self::SF_BLOG_CATEGORY_ID, $cat);
$c->addDescendingOrderByColumn(self::CREATED_AT);
$pager->setCriteria($c);
$pager->setPage($page);
$pager->setPeerMethod('doSelectJoinAll');
$pager->init();
return $pager;
}
Voila, c'est aussi simple que cela, on a un listing des articles en marche. Côté back-office, on modifie modules/sfSimpleBlogPostAdmin/config/generator.yml pour ajouter "sf_blog_category_id" à cette ligne dans la partie edit:
display: [author_id, sf_blog_category_id, title, extract, content, tags_as_string, allow_comments, is_published]
Vous avez désormais un menu déroulant qui vous permet de choisir la catégorie de votre article.
Evidemment, beaucoup de réglages sont encore possibles. Par exemple, vous souhaitez sûrement afficher la catégorie de l'article en même temps que l'auteur ou encore la date. Pour cela, nous allons créer une méthode getCategory() dans PluginsfSimpleBlogPost.php
public function getCategory()
{
if (!@is_object($this->category))
{
$this->category = sfSimpleBlogCategoryPeer::retrieveByPk($this->sf_blog_category_id);
}
return $this->category;
}
Ensuite, on modifie simplement les templates d'affichage des articles. Ainsi, dans _post.php
getCategory(), 'sfSimpleBlog/showByCategory?cat='.$post->getCategory()->getId().'&catName='.utf8_encode($post->getCategory()->getCategoryName())) ?>
Voilà , on a fait le tour de cette fonctionnalité. La prochaine fois, j'expliquerai comment étendre cette fonctionnalité de catégories pour créer des pages de contenu tout en utilisant notre interface de blog native.
tags: sfSimpleBlog, symfony
un commentaire
Posté par Cedric, le 03/03/2008 - Technologie
Premier tutorial sur ce blog, avec la création d'un nouveau projet Symfony. Rien de bien compliqué en théorie puisque la documentation est déjà bien fournie, mais nous souhaitons ici avoir une installation permettant le travail collaboratif. Nous allons donc utiliser le système de versionnage Subversion. Rentrons dans le vif du sujet.
Un repository SVN est l'endroit où va être stocké l'ensemble des modifications apportées au projet.
mkdir /home/projects/sfProject svnadmin create /home/projects/sfProject
Un projet SVN se doit de comporter trois répertoires principaux: tags, branches et trunk. Le tronc étant la version actuelle, et les branches/tags des versions de développement ou des versions passées qui continuent néanmoins à être maintenues.
Je créé donc cette structure dans un répertoire temporaire, pour l'intégrer au repository
mkdir /tmp/project /tmp/project/trunk /tmp/project/tags /tmp/project/branches svn import /tmp/project/ file:///home/projects/sfProject -m "Import de la structure"
Voila. Si tout se passe bien on devrait désormais avoir une structure classique dans notre repository. On peut vérifier cela avec la fonction svn list.
root@localhost# svn list file:///home/projects/sfProject branches/ tags/ trunk/
La structure est bien installée. On va pouvoir créer la copie de travail.
La copie de travail, c'est une copie de votre projet que vous allez pouvoir modifier, enrichir, recréer, tout en étant certain que chacune des modification sera bien enregistrée dans le repository. Il doit donc exister autant de copies de travail que de personnes qui interviennent sur votre projet.
Si vous travaillez sur Linux, que vous avez configuré un sous domaine sur /home/domains/sfProject, voici comment extraire une copie de travail:
# cd /home/domains/sfProject # svn co file:///home/projects/sfProject ./
On se retrouve avec un répertoire contenant nos trois fameux dossiers: branches, tags et trunk. Nous allons rajouter un nouveau répertoire: vendor.
# mkdir vendor
Ce répertoire n'existe pas encore dans le repository, puisque nous l'avons créé dans une copie de travail. Pour l'intégrer au repository, nous effectuons la commande suivante (dans le répertoire /home/domaines/sfProject):
# svn add vendor
Puis nous allons connecter ce répertoire à une copie distante de Symfony. Cette opération permettra de récupérer automatiquement les nouvelles mises à jour du packages.
# svn propedit svn:externals ./vendor
Dans la fenetre qui s'ouvre on rentre simplement le nom du package, puis l'adresse SVN correspondant à la version que l'on souhaite récupérer. Ici, la version 1.0
symfony http://svn.symfony-project.com/branches/1.0/
Nous allons soumettre nos changements aux repository (une fenetre s'ouvre, fermer là puis validez):
# svn commit
Une fois les changements propagés, effectuez un simple update de votre copie de travail.
# svn up
Et là, miracle! Le système est en train de récupérer tout seul l'ensemble de l'arbre de Symfony. L'avantage, c'est qu'à chaque correction de bug sur la branche que vous avez choisie, votre version locale sera immédiatement patchée, à chaque fois que vous ferez un update.
Dans Symfony, beaucoup de choses se font en ligne de commande. Pour l'instant, l'executable symfony se trouve dans le répetoire vendor/data/bin/. Pour créer un projet, on va donc simplement se rendre dans le répertoire cible (trunk/ dans notre cas), puis ajouter un nouveau projet à partir de l'executable.
# cd /home/domaines/sfProject/trunk // toujours notre copie de travail # php5 /home/domaines/sfProject/vendor/symfony/data/bin/symfony init-project sfProject
Les fichiers se copient, voila, vous avez votre premier projet en bon état de marche.
Si l'on effectue un test coté web, il y a de fortes chances que cela ne marche pas. Ceci parce qu'il faut faire pointer Apache vers le bon répertoire, à savoir /home/domaines/sfProject/trunk/web. Par ailleurs, les feuilles de style par défaut du package se trouvent dans notre copie synchronisée. Nous allons donc créer un Alias. Ce qui vous donne:
# nano /usr/local/apache/conf/httpd.conf // dépend de votre configurationDocumentRoot /home/domaines/sfProject/trunk/web Alias /sf /home/domaines/sfProject/vendor/symfony/data/web/sf ServerName sfProject.mondomaine.com AddHandler x-httpd-php5 .php
Un petit test sur sfProject.mondomaine.com devrait également vous fournir une erreur. Il faut pour obtenir une réponse créer une application. C'est ce que nous faisons avec la ligne de commande suivante:
# cd /home/domaines/sfProject/trunk/ # php5 ./symfony init-app frontend # chown -fR vous:votregroupe ./
La dernière commande sert à donner les bons droits à votre projet, attribué a l'utilisateur root par défaut. Cette fois, un test sur sfProject.mondomaine.com fonctionne bien, avec la bonne feuille de style grâce à nos directives Apache.
Il nous reste à finaliser le projet. Nous avons effectué pas mal de changements, mais aucun n'est encore dans le repository. Une commande simple permet d'ajouter tous les nouveaux fichiers d'un coup (sur la racine de votre copie de travail):
# svn add * --force
Puis on commit ces changements pour les intégrer au repository.
# svn commit
Enfin, certains répertoires de Symfony n'ont pas vocation à être inclus dans les updates. C'est le cas pour les fichiers de cache et de logs. Nous corrigeons ce problème comme suit (dans le répertoire trunk de votre copie de travail):
# cd /home/domaines/sfProject/trunk # svn propedit svn:ignore ./cache
Un éditeur de texte s'ouvre, tapez simplement une étoile * puis sauvegardez. Puis refaite la meme chose avec la commande
# svn propedt svn:ignore ./log
Envoyez les changements au repository:
# svn commit
Et voilà, vous avez un environnement de travail puissant et propre, vous pouvez commencer à développer sur le framework puissant qu'est Symfony. D'autres articles sur ce framework vous seront bientôt proposés ici-même.
tags: subversion, symfony, tutorial
aucun commentaire
Posté par Cedric, le 29/02/2008 - Technologie
En introduction à ce blog, je souhaite faire un petit retour en arrière de l'Internet. Ceci afin de prendre la mesure des évolutions passées en une période très courte (10 ans), et ainsi de mieux cerner les évolutions technologiques nouvelles, défis de demain, dont ce blog tentera de traiter en profondeur.
Voici donc le premier épisode de cette série d'historiques, consacré ici à la programmation web open-source.
J'ai réalisé mon premier site en 1998. A l'époque l'acronyme LAMP n'existait pas, mais c'est bien sur ce stack (un stack est une pile en programmation, LAMP signifie Linux/Apache/MySQL/PHP) que la plupart des sites amateurs commençaient à être développés en France, grâce essentiellement à Free qui avait fait ce choix technologique très tôt pour sa plateforme gratuite (pages persos free), ainsi que pour son service d'hébergement professionnel (online.fr).
Le PHP en était à sa version 3, celle où la couche objet n'existait pas encore, mais où le programmeur web débutant pouvait si facilement réaliser des premiers projets tangibles, soutenus par une communauté naissante qui mettait à disposition des scripts complets. Côté client, la vie du développeur était un enfer. La très forte notoriété de Netscape, couplée à la domination farouche d'Internet Explorer, obligeait tous les concepteurs web à d'interminables nuits passées à jouer avec leurs tableaux et leurs codes JavaScript pour avoir des pages qui s'affichaient de manière à peu près cohérentes sur les différents navigateurs. Un JavaScript lui-même réduit à des fonctions très basiques, comme l'ouverture de pop-ups, les animations un peu grossières et quelques autres réjouissantes souvent bridées par l'absence de compatibilité cross-navigateurs (d'où l'utilisation intensive du if(document.all) ).
Les langages de programmation web ont très sensiblement évolué en 10 ans. Des nouvelles méthodes, des nouveaux langages, des nouvelles pratiques se sont progressivement mis en place, sous une commune bannière de la recherche d'efficacité, à un moment où le programmeur web commençait à réaliser que l'essentiel des briques nécessaires à un projet sont réutilisables, et que très peu de besoins sur Internet sont réellement nouveaux. Si je devais citer quelques changements, je parlerais côté client des nouvelles générations de navigateurs, Mozilla Firefox en tête, qui ont commencé à gérer de manière un peu plus cohérente le code HTML et JavaScript, en se référant de plus près aux recommandations du (http://fr.wikipedia.org/wiki/W3C) W3C. Un repère pour les développeurs qui pouvaient en plus s'appuyer sur les CSS2 et enfin abandonner les tableaux HTML pour de belles DIV au contenu facilement dynamisable. Pour cela, ils peuvent s'appuyer largement sur JavaScript, dont le développement a été intensif pendant les années 2000. Ce langage désormais très puissant, beaucoup plus portable qu'avant, avec une utilisation grandement facilitée par l'apparition de frameworks comme Prototype ou jQuery. D'ailleurs, l'innovation de rupture la plus importante des années 2000 concerne ce langage, avec l'apparition du XMLHTTPRequest, ce composant de JavaScript qui permet d'interroger un serveur distant sans recharger la page courante. Ce principe est plus connu sous le nom d'AJAX, et a littéralement transformé l'expérience utilisateurs depuis (il n'y a qu'à voir sa large intégration sur Facebook pour en prendre la mesure).
Côté PHP, ce langage Open-Source a évolué d'un rôle un peu décrié de langage d'amateur à destination des amateurs à celui de leader en forte évolution, grâce à la communauté de développeurs la plus active au monde. La maturité est incarnée par PHP5, et sa gestion des classes, qui a permis l'éclosion d'un grand nombre de frameworks très performants (Cake, Mojavi, Symfony..), respectant pour beaucoup le paradigme MVC (dont nous parlerons beaucoup ici), et l'approchant ainsi de JAVA. Cette évolution vise à rendre les applications PHP plus professionnelles, puisqu'évolutives, réutilisables, et mieux structurées, permettant ainsi de faire travailler plusieurs personnes complémentaires (intégrateurs, développeurs, designers…) grâce à la séparation des couches, et d'intégrer facilement des classes existantes. Un concept important, puisqu'au lieu de partager des scripts entiers, les développeurs partagent désormais des classes métiers, des briques sur lesquelles ils peuvent construire ou reconstruire, en gardant la maîtrise de la couche finale. Le développeur n'a plus à réinventer la roue à chaque projet, il récupère les ingrédients mis à disposition par la communauté et peut ainsi mieux focaliser son esprit sur la valeur ajoutée apportée par des services nouveaux. En dehors de PHP, citons enfin l'immense source d'inspiration née de l'éclosion de Ruby on Rails par l'équipe de 37signals, qui a chamboulé la manière de programmer de millions de développeurs (et a grandement inspiré certains frameworks PHP, nous y reviendrons également au travers de nos articles).
Idéologiquement, le développement web est rentré dans une phase de syndication intense. Alors même que les sites web étaient des sortes d'espaces cloisonnés reliés par des liens hypertextes, ils ne forment désormais plus qu'un, puisque chaque service est mis à dispositions de sites tiers par le biais d'APIs ou de widgets. Cela a permis l'arrivée d'un site d'un type nouveau, les mashups, qui sont des fusions entre deux (ou +) services web (par exemple, les objets mis en vente sur Craigslists affichés sur une carte via l'API Google Maps). Dans le même temps, les flux RSS sont devenus légion. Le XML, comme modèle de partage de données structurée, atteint donc son apogée, puisqu'indispensable dans toutes les formes de services web : affichage avec le XHTML, échanges avec REST et SOAP, et fidélisation avec RSS (on pourrait aussi parler des SiteMaps pour le référencement naturel, etc.)
L'avenir du web passera également par le XML, puisque ce format peut remplir un rôle de base de données échangeable. On parlera ici de microformats et de web sémantique, concept relativement nouveau poussé par le W3C et son président Tim Berners-Lee, visant à rendre le web intégralement lisible et analysable par des machines.
L'avenir du web, c'est aussi et avant tout les produits de demain, qui guident l'évolution des technologies. Ainsi, l'éclosion des mobiles, la baisse du prix du transfert de données nomades, sont autant d'éléments moteurs à l'apparition de nouvelles technologies destinées aux appareils mobiles. De la même manière, la généralisation du haut débit influe directement sur le développement de nouveaux média, comme la vidéo, dont la qualité ne cessera d'augmenter dans les années qui viennent, pour certainement se substituer in fine à la télévision (voir Joost ou Seesmic).
L'avenir du web, c'est aussi la convergence entre les applications de bureau, les applications web traditionnelles et les applications mobiles. Des technologies naissantes permettent de faire dialoguer facilement une application de bureau avec un serveur web (voir Adobe Air), et ces plateformes vont continuer à se développer, jusqu'à ce que le système même d'application de bureau ne disparaisse au profit des web-desktops, tendance inévitable et logique qui connaît déjà ses précurseurs.
Enfin, l'OS virtuel est une conséquence du stockage virtuel. Cette tendance est fondamentale, et le liant logique entre l'explosion de la mobilité et de la virtualisation des postes de travail. Nos données sont de plus en plus hébergées, cela a commencé en délaissant nos Outlook pour des gMail ou des Yahoo! Mail, puis ca a continué avec Writerly (ou Google Docs), Zimbra, et autres. L'avantage est d'accéder aux mêmes données quelques soit l'appareil utilisé, soit il mobile, ou fixe, quelque soit son emplacement géographique. Ce que l'on sait moins, c'est que les données présentes sur les serveurs web (déjà distants des postes clients) sont eux-mêmes stockés à l'extérieur, sur ce qu'on appelle des nuages de serveurs (cloud computing), un sujet sur lequel nous reviendrons largement. Une évolution du web qui va donc modifier l'informatique en elle-même, puisque l'ordinateur personnel pourra devenir impersonnel, sorte de station de travail où l'intégralité des données liées à un utilisateur sera désormais stockée à l'extérieur. Des machines à faible capacité de stockage, ne nécessitant plus autant de puissance qu'auparavant, donc plus abordables, pour un monde entièrement mobile et très interconnecté.
tags: javascript, PHP, programmation, symfony