Développer un blog avec Symfony est une très belle initiative. Cela permet de se familiariser très rapidement avec tous les concepts classiques rencontrés dans la vaste majorité des projets. C’est même l’application idéale quand on découvre un nouveau langage ou une nouvelle version d’un framework, car c’est assez petit pour être réalisable (2 jours de travail pour mon blog), et vous obtenez un vrai produit fini destiné à être mis en ligne (ce qui vous permet de traiter l’ensemble de la chaîne de construction web, y compris la partie déploiement).
Cependant, bâtir un blog ex-nihilo sur un framework comme Symfony en (bientôt) 2011 est mauvais à long terme. Et c’est même inscrit dans la logique même des framework, puisqu’on nous conseille de ne pas se répéter. Or, pour une application ultra classique comme un blog, tout ce que vous ferez avec un blog custom est d’éternellement vous répéter. Vous répéter et perdre du temps, le tout pour une efficacité moindre, car votre intelligence d’atteindra jamais la somme de l’intelligence collective.
Pour ceux qui voudraient switcher d’un blog développé sous Symfony à un WordPress plus facile à gérer, je vous livre les petits scripts qui m’ont permis très rapidement (après intégration xHTML/CSS du thème, évidemment), de récupérer mes articles et mes commentaires en quelques secondes via l’outil d’import de WP.
Voici la structure de DB de mon ancien blog:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | mysql> show tables; +---------------------------+ | Tables_in_sadai_blog | +---------------------------+ | blog_category | | blog_comment | | blog_post | | blog_post_images | | sf_guard_group | | sf_guard_group_permission | | sf_guard_permission | | sf_guard_remember_key | | sf_guard_user | | sf_guard_user_group | | sf_guard_user_permission | | sf_tag | | sf_tagging | +---------------------------+ 13 rows in set (0.00 sec) |
Voici la description de la table “blog_post”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | mysql> show columns from blog_post; +----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------+----------------+ | user_id | int(11) | YES | MUL | NULL | | | category_id | int(11) | YES | MUL | NULL | | | title | varchar(255) | YES | | NULL | | | main_pic | varchar(100) | YES | | NULL | | | slug | varchar(255) | YES | | NULL | | | content | text | YES | | NULL | | | is_published | int(11) | YES | | NULL | | | allow_comments | int(11) | YES | | NULL | | | created_at | datetime | YES | | NULL | | | published_at | date | YES | | NULL | | | id | int(11) | NO | PRI | NULL | auto_increment | +----------------+--------------+------+-----+---------+----------------+ 11 rows in set (0.00 sec) |
L’image titre, quand elle est présente, va automatiquement s’ajouter au début du contenu de l’article. Ce mécanisme est repris dans le script d’import.
Les tags, eux, sont simplement des tags, il n’y a pas de version libre et de version normalisée. Enfin, les commentaires se décrivent ainsi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | mysql> show columns from blog_comment; +--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | post_id | int(11) | YES | MUL | NULL | | | author_name | varchar(200) | YES | | NULL | | | author_email | varchar(255) | YES | | NULL | | | author_url | varchar(255) | YES | | NULL | | | ip | varchar(100) | YES | | NULL | | | content | text | YES | | NULL | | | is_active | int(11) | YES | | NULL | | | created_at | datetime | YES | | NULL | | +--------------+--------------+------+-----+---------+----------------+ 9 rows in set (0.00 sec) |
Nous allons donc générer un XML d’export au format WordPress, qui va nous permettre d’importer l’ensemble de notre blog (articles, tags, commentaires, catégories) en une seule commande.
Côté action, il nous faut donc récupérer l’ensemble des catégories, tags, et articles contenus en DB (on récupérera les commentaires via un accesseur sur le modèle Post). Une execution très simple (sous… Propel! Eh oui, ce blog est vieux)
1 2 3 4 5 6 7 8 | public function executeExport() { $c = new Criteria(); $this->blogCats = CategoryPeer::doSelect($c); $this->blogTags = TagPeer::doSelect($c); $this->posts = PostPeer::doSelect($c); $this->setLayout(false); } |
Puis,du côté du template, on effectue toutes les transformations nécessaires afin de satisfaire au format d’export WordPress. Pour en savoir plsu sur ce format, fouillez tout simplement le script d’export de WordPress, et parcourez cette ressource.
Voici la copie exacte du template exportSuccess.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | <!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your blog. --> <!-- It contains information about your blog's posts, comments, and categories. --> <!-- You may use this file to transfer that content from one site to another. --> <!-- This file is not intended to serve as a complete backup of your blog. --> <!-- To import this information into a WordPress blog follow these steps. --> <!-- 1. Log into that blog as an administrator. --> <!-- 2. Go to Manage: Import in the blog's admin panels. --> <!-- 3. Choose "WordPress" from the list. --> <!-- 4. Upload this file using the form provided on that page. --> <!-- 5. You will first be asked to map the authors in this export file to users --> <!-- on the blog. For each author, you may choose to map to an --> <!-- existing user on the blog or to create a new user --> <!-- 6. WordPress will then import each of the posts, comments, and categories --> <!-- contained in this file into your blog --> <!-- generator="WordPress/MU" created="2008-05-16 22:49"--> <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:wp="http://wordpress.org/export/1.0/" > <?php $base = 'http://www.sadai.net';?> <channel> <title>Marketing & Technologies | Sadai.net</title> <link><?php echo $base;?></link> <description>Publicit´ digitale, Data, Science, Architectures.</description> <pubDate>Fri, 1 Jan 2008 22:46:22 +0000</pubDate> <generator>http://wordpress.org/?v=MU</generator> <language>fr</language> <wp:wxr_version>1.0</wp:wxr_version> <wp:base_site_url><?php echo $base;?></wp:base_site_url> <wp:base_blog_url><?php echo $base;?></wp:base_blog_url> <?php foreach ($blogCats as $blogCat):?> <wp:category> <wp:category_nicename><?php echo $blogCat->getSlug();?></wp:category_nicename> <wp:category_parent></wp:category_parent> <wp:cat_name><![CDATA[<?php echo $blogCat->getName()?>]]></wp:cat_name> </wp:category> <?php endforeach;?> <?php foreach ($blogTags as $blogTag):?> <wp:tag><wp:tag_slug><?php echo $blogTag->getName();?></wp:tag_slug><wp:tag_name><![CDATA[<?php echo $blogTag->getName();?>]]></wp:tag_name></wp:tag> <?php endforeach;?> <?php foreach ($posts as $post):?> <?php $content = $post->getContent()?> <?php if ($post->hasPic()):?> <?php $content = '<p>' . '<img src="'.$post->getPicUrl().'" border="0" align="left" style="padding-right:7px" />' . substr($content, 3);?> <?php endif;?> <item> <title><![CDATA[<?php echo $post->getTitle(); ?>]]></title> <link><?php $base . '/' . $post->getSlug(); ?></link> <pubDate><?php echo date( 'D, d M Y H:i:s +0000', strToTime($post->getCreatedAt())); ?></pubDate> <dc:creator><![CDATA[Cedric Sadai]]></dc:creator> <category><![CDATA[<?php echo $post->getCategory()->getName()?>]]></category> <category domain="category" nicename="<?php echo $post->getCategory()->getSlug()?>"><![CDATA[<?php echo $post->getCategory()->getName()?>]]></category> <?php foreach ($post->getTags() as $tag):?> <category domain="tag"><![CDATA[<?php echo $tag;?>]]></category> <category domain="tag" nicename="<?php echo $tag;?>"><![CDATA[<?php echo $tag;?>]]></category> <?php endforeach;?> <guid isPermaLink="false"><?php echo $base . '/' .$post->getSlug(); ?></guid> <description></description> <content:encoded><![CDATA[<?php echo preg_replace('/\/uploads\/assets\//i', '/wp-content/uploads/assets/', $content);?>]]></content:encoded> <wp:post_date><?php echo $post->getCreatedAt(); ?></wp:post_date> <wp:post_date_gmt><?php echo $post->getCreatedAt(); ?></wp:post_date_gmt> <wp:comment_status>open</wp:comment_status> <wp:ping_status>open</wp:ping_status> <wp:post_name><?php echo $post->getSlug(); ?></wp:post_name> <wp:status>publish</wp:status> <wp:post_type>post</wp:post_type> <wp:post_password></wp:post_password> <wp:is_sticky>0</wp:is_sticky> <?php foreach ($post->getAllComments() as $comment):?> <wp:comment> <wp:comment_id><?php echo $comment->getId()?></wp:comment_id> <wp:comment_author><![CDATA[<?php echo $comment->getAuthorName()?>]]></wp:comment_author> <wp:comment_author_email><?php echo $comment->getAuthorEmail()?></wp:comment_author_email> <wp:comment_author_url><?php echo $comment->getAuthorUrl()?></wp:comment_author_url> <wp:comment_author_IP><?php echo $comment->getIp()?></wp:comment_author_IP> <wp:comment_date><?php echo date( 'D, d M Y H:i:s +0000', strToTime($comment->getCreatedAt())); ?></wp:comment_date> <wp:comment_author_IP><?php echo $comment->getIp()?></wp:comment_author_IP> <wp:comment_date><?php echo date( 'D, d M Y H:i:s +0000', strToTime($comment->getCreatedAt())); ?></wp:comment_date> <wp:comment_date_gmt><?php echo date( 'D, d M Y H:i:s +0000', strToTime($comment->getCreatedAt())); ?></wp:comment_date_gmt> <wp:comment_content><![CDATA[<?php echo $comment->getContent()?>]]></wp:comment_content> <wp:comment_approved>1</wp:comment_approved> <wp:comment_parent>0</wp:comment_parent> <wp:comment_user_id>0</wp:comment_user_id> <wp:comment_type></wp:comment_type> </wp:comment> <?php endforeach;?> </item> <?php endforeach;?> </channel> </rss> |
Pas de grosse difficulté ici, à part qu’il faut bien donner un ID à chaque commentaire, sous peine de les voir assimiler à des doublons. Il faut également bien leur passer le statut “approved” à 1, sinon il ne seront pas importés. Enfin, à la ligne 71, je remplace toutes les occurences de /uploads/assets par /wp-content/uploads/assets/, afin que toutes mes images soient conservées au terme d’un simple copier-coller de répertoire au bon endroit.
J’ai hâte à présent de reprendre une activité de blogging plus soutenue!




Lorsqu’on réalise un projet web d’envergure, il convient de prendre en compte les éléments annexes au développement: le référencement naturel (c’est le cas pour de plus en plus de développeur), et, chose moins commune, le déploiement et l’évolutivité de l’hébergement.
C’est 
Si vous maîtrisez bien le