Development

Documentation/fr_FR/askeet/trunk/D3 (diff)

You must first sign up to be able to contribute.

Changes between Version 9 and Version 10 of Documentation/fr_FR/askeet/trunk/D3

Show
Ignore:
Author:
forresst (IP: 82.64.139.147)
Timestamp:
03/13/08 19:23:03 (10 years ago)
Comment:

Traduction et relecture faite : déplacement dans la doc FR

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/fr_FR/askeet/trunk/D3

    v9 v10  
    11{{{ 
    22#!html 
    3 <div style="border: solid 2px #f00;padding:10px;margin:5px;background-color: #faa"> 
     3<div style="border: solid 3px #ff8;padding:10px;margin:5px;background-color: #ffd"> 
    44}}} 
    5 Cette page fait partie de la traduction en français de la documentation de Symfony. Il s'agit d'une version traduite qui peut comporter des erreurs. La seule version officielle est la [http://www.symfony-project.com/askeet/3 version en anglais]. 
    6  
    7  * Traduction : Nicosgamer 
    8  * Relecture : mikael.randy 
    9  * Date de traduction : 20 Juillet 2007 
    10  * Date de dernière modification : 12 Mars 2008 
     5Cette partie de la documentation d'Askeet est déjà traduite. 
     6[http://trac.symfony-project.com/wiki/Documentation/fr_FR/askeet/3 Symfony - Calendrier de l'Avent, 3ème jour : Plongez dans l’architecture MVC2]. 
    117{{{ 
    128#!html 
    139</div> 
    1410}}} 
    15  
    16 {{{ 
    17 #!WikiMarkdown 
    18  
    19 Calendrier de l’avent troisième jour : plongez dans l’architecture MVC 
    20 ==================================================================== 
    21  
    22 Précédemment dans Symfony 
    23 ------------------------- 
    24  
    25 Au cours du [deuxième jour] (2.txt) vous avez appris à construire  un modèle objet basé sur un modèle de données relationnel, et générer une ébauche pour un de ces objets. A ce propos, l’application générée durant les jours précédents est disponible dans l’espace de stockage SVN d’askeet:  
    26  
    27         http://svn.askeet.com/ 
    28  
    29 Les objectifs du troisième jour sont de définir une mise en page plus esthétique, définir la liste des questions comme page d’accueil par défaut, afficher le nombre d’utilisateurs intéressés par une question, et de remplir la base de données en utilisant des extraits de fichiers textes afin de disposer de données de test. Ce n’est pas grand chose à faire, mais un peu plus à lire et à comprendre.  
    30  
    31 Pour lire ce tutoriel, vous devriez être familiarisé avec les concepts de projet, d’application, module et d’action dans Symfony comme expliqué dans le [chapitre sur le contrôleur](http://www.symfony-project.com/content/book/page/controller.html) du livre Symfony. 
    32  
    33 Le modèle MVC 
    34 -------------- 
    35  
    36 Aujourd’hui sera le premier plongeon dans le monde de [l’architecture MVC] [1]. Qu’est ce que c’est ? Simplement que le code utilisé pour générer une page est situé dans différents fichiers en fonction de leur nature. 
    37  
    38 Si le code concerne la manipulation des données indépendante d’une page, il devrait être situé dans le **Modèle** (la plupart du temps dans `askeet/lib/model/`). S’il concerne la présentation finale, il devrait être situé dans la **Vue** ; dans Symfony, la couche Vue se base sur les templates (par exemple dans `askeet/apps/frontend/modules/question/templates/`) et les fichiers de configuration. Finalement, le code qui sert à lier tout cela et à traduire la logique du site en bon vieux PHP est situé dans le Contrôleur,  et dans Symfony le contrôleur pour une page spécifique est appelé une action (recherchez les actions dans `askeet/apps/frontend/modules/question/actions/`). Vous pouvez en lire plus à propos de ce modèle dans le chapitre sur [l’implémentation de MVC dans Symfony](http://www.symfony-project.com/content/book/page/mvc.html) du livre Symfony.  
    39 Alors que la vue de notre application changera peu aujourd’hui, nous allons manipuler beaucoup de fichiers différents. Cependant ne paniquez pas, puisque l’organisation des fichiers et la séparation du code en différentes couches va bientôt devenir évidente et très utile. 
    40  
    41 Changer la mise en page 
    42 ------------------------- 
    43  
    44 Dans l’application du [décorateur][2], le contenu du template appelé par une action est intégré dans un template global, également nommé gabarit principal. En d’autres termes, le gabarit principal contient toutes les parties invariantes de l’interface, il « décore » le résultat de l’action. Ouvrez le gabarit principal (situé dans  `askeet/apps/frontend/templates/layout.php`) et changez-le comme suit :  
    45  
    46     [php] 
    47     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    48     <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
    49     <head> 
    50      
    51     <?php echo include_http_metas() ?> 
    52     <?php echo include_metas() ?> 
    53      
    54     <?php echo include_title() ?> 
    55      
    56     <link rel="shortcut icon" href="/favicon.ico" /> 
    57      
    58     </head> 
    59     <body> 
    60      
    61       <div id="header"> 
    62         <ul> 
    63           <li><?php echo link_to('about', '@homepage') ?></li> 
    64         </ul> 
    65         <h1><?php echo link_to(image_tag('askeet_logo.gif', 'alt=askeet'), '@homepage') ?></h1> 
    66       </div> 
    67      
    68       <div id="content"> 
    69         <div id="content_main"> 
    70           <?php echo $sf_data->getRaw('sf_content') ?> 
    71           <div class="verticalalign"></div> 
    72         </div> 
    73      
    74         <div id="content_bar"> 
    75           <!-- Nothing for the moment --> 
    76           <div class="verticalalign"></div> 
    77         </div> 
    78       </div> 
    79      
    80     </body> 
    81     </html> 
    82  
    83 >**Note**: nous avons essayé de garder les balises aussi sémantique que possible, et de déplacer tout le style dans les feuilles de styles CSS. Ces feuilles de styles ne seront pas décrites ici, puisque la syntaxe CSS n’est pas le but de ce tutoriel. Cependant elles sont disponibles en téléchargement, dans [l’espace de stockage SVN](http://svn.askeet.com/tags/release_day_3/web/css/). 
    84 > 
    85 >Nous avons créé deux feuilles de styles (`main.css` et `layout.css`). Copiez les dans le répertoire `askeet/web/css/` et éditez votre `frontend/config/view.yml` pour changer l’auto chargement des feuilles >de styles : 
    86 > 
    87 >       stylesheets:    [main, layout] 
    88  
    89  
    90 Cette mise en page, un peu légère pour le moment, sera refaite plus tard (dans une semaine environ). Les choses importantes dans ce template sont la partie `<head>`, qui est la plupart du temps générée, et la variable `sf_content`, qui contient le résultat des actions. 
    91  
    92 Vérifiez que les modifications s’affichent correctement en demandant la page d’accueil – cette fois dans l’environnement de développement : 
    93  
    94     http://askeet/frontend_dev.php/ 
    95      
    96 ![updated layout](http://www.symfony-project.org/images/askeet/1_0/congratulations_new.gif) 
    97      
    98 Quelques mots sur les environnements 
    99 --------------------------------------- 
    100  
    101 Si vous vous demandez quelle est la différence entre `http://askeet/frontend_dev.php/` et `http://askeet/`, vous devriez jeter un œil sur [le chapitre sur la configuration](http://www.symfony-project.com/content/book/page/configuration.html) du livre Symfony. Pour le moment, vous devez juste savoir qu’elles pointent sur la même application, mais dans des environnements différents. Un environnement est une configuration unique, où quelques fonctionnalités du framework peuvent êtres activées ou désactivées selon le besoin. 
    102  
    103 Dans ce cas, l’url `/frontend_dev.php/` pointe sur **l’environnement de développement**, où toute la configuration est analysée à chaque requête, le cache HTML est désactivé, et les outils de débogage sont tous disponibles (y compris une barre d’outils semi-transparente située dans le coin supérieur de la fenêtre). L’url `/` - équivalent à `/index/` - pointe sur **l’environnement de production**, où la configuration est « compilée » et les outils de débogage sont désactivés pour accélérer la vitesse d’accès aux pages. 
    104  
    105 Ces deux scripts PHP - `frontend_dev.php` et `index.php` – sont appelés **front controllers**, et toutes les requêtes de l’application sont manipulées par eux. Vous pouvez les trouver dans le répertoire `askeet/web/`. En fait, le fichier `index.php` devrait s’appeler `frontend_prod.php`, mais comme le `frontend` est la première application que vous créez, Symfony déduit que vous voudriez probablement que ce soit votre application par défaut et le renomme en index.php, c’est donc pour cela que vous pouvez voir votre application en environnement de production juste en demandant `/`. Si vous voulez en apprendre plus à propos du front controller et de la couche contrôleur du modèle MVC en général, référez vous au [chapitre sur le contrôleur] (http://www.symfony-project.com/content/book/page/controller.html) dans le livre Symfony. 
    106 Un bon principe de base est de naviguer dans l’environnement de développement jusqu'à ce que vous soyez satisfait des fonctionnalités sur lesquelles vous travaillez et de passer à l’environnement de production pour vérifier la vitesse et la beauté des urls. 
    107  
    108 >**Note**: Ne pas oublier de toujours effacer le cache quand vous ajoutez des classes ou quand vous changez des fichiers de configurations pour voir le résultat en environnement de production. 
    109  
    110  
    111  
    112 Redéfinir la page d’accueil 
    113 ----------------------------- 
    114 Pour le moment, si vous demandez la page d’accueil du nouveau site, il affiche une page de ‘félicitations’. Une meilleur idée serait d’afficher la liste des questions (référencée dans ces documents comme `question/list` et traduit comme : l’action `list` du module `question`). Pour faire cela, ouvrez le fichier de configuration de routage de l’application frontend, situé dans `askeet/apps/frontend/config/routing.yml` et trouvez la section `homepage:`. Changez-la-en : 
    115  
    116     homepage: 
    117       url:   / 
    118       param: { module: question, action: list } 
    119  
    120 Rafraichissez la page d’accueil de l’environnement de développement (`http://askeet/frontend_dev.php/`); elle affiche maintenant la liste des questions. 
    121  
    122 >**Note**: si vous êtes une personne curieuse, vous avez peut être cherché la page contenant le message de ‘félicitation’. Et vous avez surement été surpris de ne pas la trouver dans votre répertoire `askeet`. En fait, le template pour l’action `defaut/index` est situé dans le répertoire data de Symfony et est indépendant du projet. Si vous ne voulez pas en tenir compte, vous pouvez toujours créer un module `défault` dans votre propre projet. 
    123  
    124 Les possibilités offertes par le système de routage seront détaillées prochainement, mais si cela vous intéresse, vous pouvez lire le [chapitre sur le routage](http://www.symfony-project.com/content/book/page/routing.html) du livre Symfony. 
    125  
    126 Définir des données de test 
    127 --------------------------- 
    128  
    129 La liste affichée par la page d’accueil restera vide, à moins que vous ajoutiez vos propres questions. Quand vous développez une application, c’est une bonne idée d’avoir quelques données de test à votre disposition. Entrer des données de test à la main (ou via l’interface CRUD) peut être rébarbatif, c’est pourquoi Symfony peut utiliser les fichiers textes pour remplir les bases de données. 
    130  
    131 Nous allons créer un fichier de données de test dans le répertoire `askeet/data/fixtures/` (ce répertoire doit être créé). Créez un fichier nommé `test_data.yml` avec le contenu suivant : 
    132  
    133     User: 
    134       anonymous: 
    135         nickname:   anonymous 
    136         first_name: Anonymous 
    137         last_name:  Coward 
    138  
    139       fabien: 
    140         nickname:   fabpot 
    141         first_name: Fabien 
    142         last_name:  Potencier 
    143      
    144       francois: 
    145         nickname:   francoisz 
    146         first_name: François 
    147         last_name:  Zaninotto 
    148      
    149     Question: 
    150       q1: 
    151         title: What shall I do tonight with my girlfriend? 
    152         user_id: fabien 
    153         body:  | 
    154           We shall meet in front of the Dunkin'Donuts before dinner,  
    155           and I haven't the slightest idea of what I can do with her.  
    156           She's not interested in programming, space opera movies nor insects. 
    157           She's kinda cute, so I really need to find something  
    158           that will keep her to my side for another evening. 
    159      
    160       q2: 
    161         title: What can I offer to my step mother? 
    162         user_id: anonymous 
    163         body:  | 
    164           My stepmother has everything a stepmother is usually offered 
    165           (watch, vacuum cleaner, earrings, del.icio.us account).  
    166           Her birthday comes next week, I am broke, and I know that  
    167           if I don't offer her something sweet, my girlfriend  
    168           won't look at me in the eyes for another month. 
    169      
    170       q3: 
    171         title: How can I generate traffic to my blog? 
    172         user_id: francois 
    173         body:  | 
    174           I have a very swell blog that talks  
    175           about my class and mates and pets and favorite movies. 
    176            
    177     Interest: 
    178       i1: { user_id: fabien, question_id: q1 } 
    179       i2: { user_id: francois, question_id: q1 } 
    180       i3: { user_id: francois, question_id: q2 } 
    181       i4: { user_id: fabien, question_id: q2 } 
    182  
    183 Avant tout, vous pouvez reconnaitre ici [YAML] [3]. Si vous n’êtes pas familiarisé avec Symfony, vous pourriez ne pas savoir que le format YAML est le format favori des fichiers de configurations de ce framework. Il n’est pas exclusif – si vous êtes attachés aux fichiers XML ou .ini, il est très facile d’ajouter un gestionnaire de configuration pour permettre à Symfony de les lire. Si vous avez le temps et la patience, vous pouvez en lire plus à propos de YAML et des fichiers de configuration dans le [chapitre de la configuration en pratique](http://www.symfony-project.com/content/book/page/configuration_practice.html) du livre Symfony. A partir de maintenant, si vous n’êtes pas familiarisé avec la syntaxe YAML, vous devriez [commencer tout de suite] [3], puisque ce tutoriel l’emploiera intensivement. 
    184  
    185 Ok, revenons au fichier de données de test. Il définit des instances d’objets, intitulés avec un nom interne. L’intitulé est d’une bonne utilité pour relier les objets relatifs sans avoir à définir les `id` (qui sont souvent auto incrémentés et qui ne peuvent pas être initialisés). Par exemple, le premier objet créé d’une classe `User`, est intitulé `fabien`. La première `question` est intitulée `q1`. Ceci rend facile de créer un objet de la classe `Interest` en mentionnant les intitulés des objets relatifs :  
    186  
    187     Interest: 
    188       i1: 
    189         user_id: fabien 
    190         question_id: q1 
    191  
    192 Le fichier de données donné précédemment utilise la syntaxe courte de YAML pour dire la même chose. Vous pouvez en savoir plus à propos des fichiers de population de données dans le [chapitre sur les fichiers de données](http://www.symfony-project.com/content/book/page/populate.html) dans le livre Symfony. 
    193  
    194 >**Note**: il n’est pas nécessaire de définir les valeurs pour les colonnes `created_at` and `updated_at` puisque Symfony sait comment les remplir par défaut. 
    195  
    196 Créer un batch pour peupler la base de données 
    197 ---------------------------------------------- 
    198  
    199 La prochaine étape est de peupler réellement la base de données, et nous désirons le faire avec un script PHP qui peut être appelé en ligne de commande – un batch.  
    200  
    201 ### Squelette du batch 
    202  
    203 Créez un fichier appelé `load_data.php` dans le répertoire `askeet/batch/` avec le contenu suivant : 
    204  
    205     [php] 
    206     <?php 
    207      
    208     define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/..')); 
    209     define('SF_APP',         'frontend'); 
    210     define('SF_ENVIRONMENT', 'dev'); 
    211     define('SF_DEBUG',       true); 
    212      
    213     require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); 
    214      
    215     // initialize database manager 
    216     $databaseManager = new sfDatabaseManager(); 
    217     $databaseManager->initialize(); 
    218      
    219     ?> 
    220  
    221 Le script ne fait rien, ou presque : il définit un chemin, une application et un environnement pour aboutir à une configuration, la charge, et initialise le gestionnaire de base de données. Mais c’est déjà beaucoup : cela signifie que tout le code écrit ci-dessous profitera de l’auto chargement des classes, la connexion automatique aux objets Propel, et des classes racines de Symfony. 
    222  
    223 >**Note**: si vous avez regardé les front controllers de Symfony (comme `askeet/web/index.php`), vous pourriez trouver ce code extrêmement familier. C’est parce que chaque requête web nécessite l’accès aux mêmes objets et configuration, que le batch. 
    224  
    225 ### Importation des données 
    226  
    227 Maintenant que la structure du batch est prête, il est temps d’en faire quelque chose. Le batch doit : 
    228  
    229 1. lire le fichier YAML 
    230 2. Créer des instances d’objets Propel 
    231 2. Créer les enregistrements relatifs dans les tables de la base de données concernée 
    232  
    233 Ceci pourrait sembler compliqué, mais avec Symfony, vous pouvez le faire avec deux lignes de code, grâce à l’objet `sfPropelData`. Ajoutez juste le code suivant avant le dernier `?>` dans le script `askeet/batch/load_data.php` : 
    234  
    235     [php] 
    236     $data = new sfPropelData(); 
    237     $data->loadData(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures'); 
    238  
    239 C’est tout. Un objet `sfPropelData` est créé, et dit de charger toutes les données d’un dossier spécifique - notre répertoire `fixtures` – dans la base de données définie dans le fichier de configuration `database.yml`.  
    240  
    241 >**Note**: la constante `DIRECTORY_SEPARATOR` est ici utilisée pour être compatible avec les plateformes Windows et *nix. 
    242  
    243 ### Exécuter le batch 
    244  
    245 Enfin, vous pouvez vérifier si ces quelques lignes de code en valaient la peine. Tapez dans la console: 
    246  
    247     $ cd /home/sfprojects/askeet/batch 
    248     $ php load_data.php 
    249      
    250 Vérifiez les modifications en rechargeant la page d'accueil de développement : 
    251  
    252     http://askeet/frontend_dev.php 
    253      
    254 ![loaded data](http://www.symfony-project.org/images/askeet/1_0/fixtures.gif) 
    255  
    256 Hourra, les données sont là. 
    257  
    258 >**Note**: Par défaut, l’objet `sfPropelData` supprime toutes les données avant de charger les nouvelles. Vous pouvez les ajouter aux données actuelles : 
    259 > 
    260 >     [php] 
    261 >     $data = new sfPropelData(); 
    262 >     $data->setDeleteCurrentData(false); 
    263 >     $data->loadData(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures'); 
    264  
    265 Accès aux données dans le modèle 
    266 -------------------------------- 
    267  
    268 La page affichée en demandant l’action `list` du module question est le résultat de la fonction `executeList()` (située dans le fichier action `askeet/apps/frontend/modules/question/actions/action.class.php`) passée au template `askeet/apps/frontend/modules/question/templates/listSuccess.php`. Ceci est basé sur la convention de nommage qui est expliquée dans le [chapitre sur le controller](http://www.symfony-project.com/content/book/page/controller.html) dans le livre Symfony. Jetons un œil au code qui est exécuté: 
    269      
    270 actions.class.php: 
    271  
    272     [php] 
    273     public function executeList () 
    274     { 
    275       $this->questions = QuestionPeer::doSelect(new Criteria()); 
    276     } 
    277  
    278 listSuccess.php: 
    279  
    280     [php] 
    281     ... 
    282     <?php foreach ($questions as $question): ?> 
    283     <tr> 
    284         <td><?php echo link_to($question->getId(), 'question/show?id='.$question->getId()) ?></td> 
    285         <td><?php echo $question->getTitle() ?></td> 
    286         <td><?php echo $question->getBody() ?></td> 
    287         <td><?php echo $question->getCreatedAt() ?></td> 
    288         <td><?php echo $question->getUpdatedAt() ?></td> 
    289       </tr> 
    290     <?php endforeach; ?> 
    291  
    292 Etape par étape, voici ce qui est fait : 
    293  
    294 1. L’action demande les enregistrements  de la table `Question` qui satisfont un critère vide - i.e. toutes les questions 
    295 2. Cette liste d’enregistrements est mise dans un tableau (`$question`) qui est transmis au template 
    296 3. Le template passe en revue toutes les questions transmis par l’action 
    297 4. Le template affiche la valeur des colonnes de chaque enregistrement 
    298  
    299 Les fonctions `->getId()`,`->getTitle()`,`->getBody()`, ... ont été créés lors de l’appel à la commande `symfony propel-build-model` (vous vous rappelez [d’hier](2.text) ?) pour rechercher la valeur des champs `id`, `title`, `body`, etc. Ce sont les accesseurs standards, formé en ajoutant le préfix `get` et le nom du champ en camelCase – et Propel fournit aussi des mutateurs standards, préfixés de set. La [documentation de Propel][4] décrit les accesseurs créés pour chaque classe. 
    300 Quant à l’appel mystérieux `QuestionPeer::doSelect(new Criteria())`, c’est aussi une requête standard Propel. La documentation Propel l’expliquera complètement. 
    301 Ne vous inquiétez pas si vous ne comprenez pas tout le code écrit ci-dessus, il deviendra clair dans quelques jours. 
    302  
    303  
    304 Modifier le template question/list 
    305 ---------------------------------- 
    306  
    307 Maintenant que la base de données contient les intérêts pour des questions, il sera facile de récupérer le nombre d’utilisateurs intéressés par une question. Si vous jetez un œil à la classe BaseQuestion.php générée par Propel dans le répertoire `askeet/lib/model/om/`, vous noterez la fonction `->getInterests()`. Propel a vu la clé étrangère `question_id` dans la définition de la table Interest, et déduit qu'une question a plusieurs intéressés. De ce fait, il est très facile d’afficher ce que nous voulons en modifiant le template `listSuccess.php`, situé dans `askeet/apps/frontend/modules/question/templates/`. Par la suite, nous remplacerons les horribles tables par des jolis div :   
    308  
    309     [php] 
    310     <?php use_helper('Text') ?> 
    311      
    312     <h1>popular questions</h1>  
    313      
    314     <?php foreach($questions as $question): ?> 
    315       <div class="question"> 
    316         <div class="interested_block"> 
    317           <div class="interested_mark" id="interested_in_<?php echo $question->getId() ?>"> 
    318             <?php echo count($question->getInterests()) ?> 
    319           </div> 
    320         </div> 
    321        
    322         <h2><?php echo link_to($question->getTitle(), 'question/show?id='.$question->getId()) ?></h2> 
    323        
    324         <div class="question_body"> 
    325           <?php echo truncate_text($question->getBody(), 200) ?> 
    326         </div> 
    327       </div> 
    328     <?php endforeach; ?> 
    329  
    330 Ici vous reconnaissez la même boucle `foreach` que dans le fichier original `listSuccess.php`. Les fonctions `link_to()` et `truncate_text()` sont des **assistants aux templates** fournis par Symfony. La première créée un lien hypertexte d’une autre action du même module, et la seconde tronque le corps de la question à 200 caractères. L’assistant `link_to()` est chargé automatiquement, mais vous devez déclarer l’utilisation du groupe d'assistants `Text` pour utiliser `truncate_text()`. 
    331  
    332 Allez, essayez notre nouveau template en rafraichissant la page d’accueil de développement. 
    333  
    334     http://askeet/frontend_dev.php/ 
    335      
    336 ![better question list](http://www.symfony-project.org/images/askeet/1_0/question_list_day3.gif) 
    337  
    338 Le nombre d’utilisateurs intéressés apparait correctement à coté de chaque question. Pour obtenir la présentation de la capture ci dessus, téléchargez la feuille de styles [`main.css`](http://svn.askeet.com/tags/release_day_3/web/css/main.css) et mettez la dans votre répertoire `askeet/web/css/`. 
    339  
    340 Nettoyage 
    341 --------- 
    342  
    343 La commande `propel-generate-crud` a créé quelques actions et templates qui ne seront pas nécessaires. Il est temps de les supprimer. 
    344  
    345 Les actions à supprimer dans `askeet/apps/frontend/modules/question/actions/actions.class.php`: 
    346  
    347 * `executeIndex` 
    348 * `executeEdit` 
    349 * `executeUpdate` 
    350 * `executeCreate` 
    351 * `executeDelete` 
    352  
    353 Les templates à supprimer dans `askeet/apps/frontend/modules/question/templates/` : 
    354  
    355 * `editSuccess.php` 
    356  
    357 A demain 
    358 -------- 
    359  
    360 Aujourd’hui était une première grande étape dans le monde du paradigme Modèle-Vue-Contrôleur : en manipulant des gabarits, des templates, des actions et des objets du modèle objet Propel, vous avez accédé à toutes les couches d’une application structurée par MVC. Ne vous inquiétez pas si vous n’avez pas compris tous les liens entre ces couches : cela deviendra plus clair petit à petit. 
    361  
    362 Beaucoup de fichiers ont été ouverts aujourd’hui, et si vous voulez savoir comment les fichiers sont organisés dans un projet, référez vous au [chapitre sur la structure de fichier](http://www.symfony-project.com/content/book/page/file_structure.html) du livre Symfony. 
    363  
    364 Demain sera un autre grand jour : nous modifierons les vues, installerons une politique de routage plus complexe, modifierons le modèle, et plongerons en profondeur dans la manipulation des données et les liens entre les tables. 
    365  
    366 Jusque-là, dormez bien, et sentez vous libre de consulter la source du tutorial d’aujourd’hui (tag `release_day_3`) à: 
    367  
    368         http://svn.askeet.com/tags/release_day_3 
    369  
    370 [1]: http://fr.wikipedia.org/wiki/Mod%C3%A8le-Vue-Contr%C3%B4leur "Model-View-Controller definition at Wikipedia" 
    371 [2]: http://fr.wikipedia.org/wiki/D%C3%A9corateur_%28motif_de_conception%29     "Decorator pattern definition at Wikipedia" 
    372 [3]: http://www.yaml.org/                               "YAML" 
    373 [4]: http://propel.phpdb.org/docs/user_guide/           "Propel documentation" 
    374  
    375  
    376  
    377 }}}