From 721c05de4d7462bd06c8d0261966652811556f2e Mon Sep 17 00:00:00 2001 From: kendo5731 Date: Mon, 1 Feb 2016 22:44:21 +0100 Subject: [PATCH] feat(): add support for responsive iframes --- .gitignore | 1 + TOTO.md | 1 - public/css/theme.scss | 16 + public/img/twitthome_schema.png | Bin 0 -> 86543 bytes public/index.html | 887 ++++++++++++++++++++++++++++++-- 5 files changed, 862 insertions(+), 43 deletions(-) create mode 100644 public/img/twitthome_schema.png diff --git a/.gitignore b/.gitignore index 39e08c2..a6cb17d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea +npm-debug.log public/**/*.css node_modules public/fonts diff --git a/TOTO.md b/TOTO.md index 070a8c4..1da8b75 100644 --- a/TOTO.md +++ b/TOTO.md @@ -1,4 +1,3 @@ -- Add support for elements like H*, blocquotes, images, etc ... - Add support for code highlighting - Display a list of categories and tags in the navbar - Change folder structure to be a actual theme for Hugo diff --git a/public/css/theme.scss b/public/css/theme.scss index d9b7237..1fab9d8 100644 --- a/public/css/theme.scss +++ b/public/css/theme.scss @@ -13,6 +13,7 @@ body { font-family: 'Source Code Pro'; background-color: $bg-color; color: $text-color; + overflow-x: hidden; &>.container-fluid { @extend .no-padding-left-and-right; } @@ -107,3 +108,18 @@ a { } } } + +.video-wrapper { + position: relative; + padding-bottom: 56.25%; + padding-top: 10px; + height: 0; + + iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } +} diff --git a/public/img/twitthome_schema.png b/public/img/twitthome_schema.png new file mode 100644 index 0000000000000000000000000000000000000000..e17dc846aa0f6e83b23dd3fad83ccab1e37eb044 GIT binary patch literal 86543 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 Q)5k|zTtTc-#4zCh0O<3rivR!s literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html index 6b27c55..2b80c31 100644 --- a/public/index.html +++ b/public/index.html @@ -35,61 +35,864 @@
-

Bonjour, ce petit article pour partager une de mes découvertes récentes. Il s’agit du serveur web - interne de - PHP, intégré depuis la version 5.4. La lecture de cette article ne vous apprendra surement pas grand - chose - si vous - avez déjà connaissance de cette fonctionnalité.

+

Mes premiers pas avec cakephp 3

+

Avant propos

-

Pour en savoir plus, rendez vous directement sur la documentation - officielle de - PHP. La documentation explique comment utiliser de façon très simple ce service. A noter que celui n’est - pas pensé pour être utilisé dans un environnement de production, mais est destiné à servir dans un - environnement de - développement. Il n’est, par conséquent, plus nécessaire de configurer une nouvelle vhost sur - votre - serveur - http (typiquement apache ou nginx), et d’ajouter une entrée dans le fichier hosts. Démarrez votre - application - à l’aide d’une simple commande dans votre terminal, et testez directement votre application - ! +

Profitant d’un peu de temps libre j’ai décidé de m’essayer à la dernière version en + date de + CakePHP, à savoir CakePHP 3. Je suis donc parti dans l’idée de pondre un Twitter-like en version + allégée (très + allégée).

+ +

Après avoir posé le contexte en présentant mon Twitter fait maison, je développerai cet article en + apportant des + précisions sur le code et les différentes fonctionnalités de CakePHP 3 que j’ai utilisées pour + construire le + site. A noter que l’objectif premier est de se concentrer sur les spécificités de CakePHP 3. Je + suggère - afin + de tirer meilleur parti de cette lecture - de bénéficier en amont d’une certaine expérience autour + d’outils + comme Composer, d’être à l’aise avec le modèle MVC, ou encore de savoir ce qu’est un + ORM.

+ +

Au départ, mes objectifs étaient de comprendre comment un projet CakePHP 3 est structuré et de découvrir + les + fonctionnalités offertes par le framework. C’est dans cet esprit que je vais écrire, tâchant de + rester dans + une simple description. Le but n’est donc pas de comparer CakePHP 3 à d’autres frameworks, + ni de + répondre directement à des questions comme “Cake est-il adapté pour tel type d’application ?”. + D’autant + que la forme ne s’y prête pas dans la mesure où un projet comme celui-ci ne permet pas de couvrir + tous ses + aspects.

+ +

Cet article est un bilan sur les quelques journées que j’ai passées à jongler entre mon IDE et la + documentation + officielle de CakePHP 3. Je l’écris avant tout pour moi, afin qu’il puisse éventuellement me + servir de + point de départ si j’ai un jour besoin de travailler avec ce framework. Ceci étant dit, comme il + semble qu’il + n’existe encore (du moins à l’heure où j’écris) que relativement peu de ressources sur + le sujet + (en dehors de la documentation officielle et en français du moins), je serais content d’apprendre + qu’il + a pu servir à d’autres développeurs.

+ +

Contexte

+ +

L’application que j’ai réalisée s’inspire ouvertement du fonctionnement de Twitter. + Voilà le + contenu de ma check-list en début de projet :

+ +
    +
  • Les utilisateurs enregistrés peuvent poster des messages (des tweets) de moins de 140 caractères +
  • +
  • Tous les tweets apparaissent en page d’accueil dans l’ordre du plus récent au plus + ancien +
  • +
  • La page d’un utilisateur affiche les détails de son profil et la liste de ses tweets
  • +
  • Possibilité d’ajouter des #hashtags dans les tweets, cliquer sur un hashtag affiche la liste + de tous les + tweets qui le mentionnent +
  • +
  • Pas de pagination pour les tweets, charger les tweets suivants au défilement de la page
  • +
  • Les utilisateurs peuvent modifier les détails de leur profil et télécharger une image pour + personnaliser leur + avatar +
  • +
  • Afficher un bloc listant les hashtags les plus populaires
  • +
+ +

N’ayant pas souhaité déployer sur un serveur, j’ai pris la peine de réaliser cette vidéo de + présentation + au cas où vous souhaiteriez voir l’application tourner.

+ +
+ +
+ +

Les sources sont disponibles sur Github. + Je + suggère de conserver l’onglet Github ouvert pendant la lecture afin de pouvoir facilement faire + des parallèles + entre les notions abordées et le code de l’application.

+ +

Le fichier database.sql contient les requêtes à exécuter pour ajouter les tables + dans une base + de données MySQL.

+ +
+ Schéma base de données Twitthome +
Une représentation graphique du schéma de la base de données.
+
+ +

Généralités et organisation du + code

+ +

A supposer que vous souhaitiez démarrer un projet CakePHP 3, la seule chose à faire après avoir installé + les + pré-requis nécessaires (PHP 5.3 et Composer) est de lancer cette commande :

+ +
composer create-project --prefer-dist -s dev cakephp/app my_app_name
+
+ +

Composer téléchargera CakePHP 3 et ses dépendances dans un nouveau dossier my_app_name. Le + script d’installation + est lancé automatiquement et propose de configurer les droits des répertoires pour vous. Vous pourrez + alors + commencer à travailler sur le site en utilisant le serveur HTTP embarqué :

+ +
bin/cake server
+
+ +

Comme pour beaucoup de frameworks web, CakePHP 3 propose une implémentation du pattern composite MVC pour + la gestion + du cycle de vie des requêtes HTTP. Le code de l’application va donc être segmenté en trois + couches, chacune + pouvant tirer parti d’un certain nombre d’éléments : composants, comportements, helpers, + etc … Il + s’agit là de termes propres à CakePHP que je développerai plus tard.

+ +

Le fichier d’entrée de l’application est /webroot/index.php. Son rôle est de + déclencher le + processus de démarrage de l’application, puis d’instancier le dispatcher + qui se + chargera de déléguer la requête au bon contrôleur. /webroot/ est le répertoire auquel doit + être + configuré le document root.index.php devrait y être le seul fichier PHP + aux côtés d’autres + ressources web comme des images, des fichiers CSS ou Javascript.

+ +

Si vous avez besoin d’intervenir sur des étapes du démarrage de l’application, vous aurez + alors besoin d’éditer + un peu de code dans /config/. Dans /config/app.php sont notamment définis les + paramètres + de connexion à la base de données, le niveau de debug ou encore la gestion des sessions. Les routes sont + définies + programmatiquement dans /config/routes.php.

+ +

Pour le reste, le répertoire /src/ se chargera d’héberger les sources de l’application. + Les + contrôleurs, les modèles ou encore les templates sont situés dans des sous-répertoires de + /src/. Cette + même structure est reprise au travers des + plugins. Pratique pour packager une application dans le but de la réutiliser dans une autre + (conceptuellement proche des bundles de Symfony 2).

+ +

Les routes

+ +

Déclarer des routes

+ +

Les routes sont définies dans /config/routes.php à l’intérieur de + scopes. Un + scope permet - entre autres - de factoriser plusieurs routes afin de leur attribuer un préfix.

+ +
Router::scope('/api/', function ($routes) {
+    $routes->connect('/tweets', [
+    'controller' => 'Tweets',
+    'action' => 'index'
+    ], [
+    '_name' => 'tweets_index'
+    ]);
+    });
+
+ +

Le code ci-dessus connecte la route /api/tweets au dispatcher. Le dispatcher se chargera de + passer la + requête à la méthode TweetsController::index(). Le tableau d’options en troisième + paramètre de la + méthode connect() est facultatif. Définir l’option _name permet de + générer les urls + plus facilement depuis les templates (vu plus tard).

+ +

Déclarer des ressources + restful

+ +

Supposons maintenant qu’il s’agisse de mettre en place une API restful. CakePHP 3 offre la + possibilité de + s’affranchir de portions de code répétitives en tirant parti de quelques conventions sur + lesquelles reposent + des comportements par défaut du framework. Cette philosophie - sans doute héritée de Ruby on Rails - est + omniprésente. Qu’il s’agisse de travailler avec les routes ou encore avec l’ORM, elle + peut faire + gagner un temps précieux.

+ +

Pour l’exemple, jetons un oeil sur ce tableau :

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GET/api/tweets.:formatTweetsController::index()
GET/api/tweets/:tweet_id.:formatTweetsController::view($tweet_id)
POST/api/tweets.:formatTweetsController::add()
PUT/api/tweets/:tweet_id.:formatTweetsController::edit($tweet_id)
PATCH/api/tweets/:tweet_id.:formatTweetsController::edit($tweet_id)
DELETE/api/tweets/:tweet_id.:formatTweetsController::delete($tweet_id)
+ +

Ces routes peuvent être configurées automatiquement avec ce seul extrait de code :

+ +
Router::scope('/api/', function ($routes) {
+    $routes->extensions(['xml', 'json']);
+    $routes->resources('tweets');
+    });
+
+ +

Les routes auto-déclarées

+ +

Une chose à savoir à propos de CakePHP 3 est qu’il connecte automatiquement une route au dispatcher + pour chaque + nouvelle action de contrôleur. Le nom de ces routes est défini en fonction du nom du contrôleur et de la + méthode. + Si bien que le code si dessous :

+ +
class TweetsController
+    {
+    function index()
+    {
+    ...
+    }
+
+    function add()
+    {
+    ...
+    }
+
+    function load()
+    {
+    ...
+    }
+    }
+
+ +

Connectera automatiquement les routes /tweets, /tweets/add et /tweets/load. + Ce + comportement est induit par cette instruction du fichier /config/routes.php :

+ +
$routes->fallbacks('InflectedRoute');
+
+ +

Naturellement, supprimer cette instruction supprimera ce comportement.

+ +

La couche Controller

+ +

Les classes de contrôleur

+ +

Les classes de contrôleur sont situées dans /src/Controller/. Elles doivent étendre la + classe \Cake\Controller\Controller + et leur nom doit - par convention - se terminer par le suffixe Controller.

+ +

L’application Twitthome utilise quatre classes de contrôleur : TweetsController, + HashtagsController, + UsersController et AccountParametersController. Comme suggéré dans la + documentation + officielle, ces classes étendent AppController. Cette pratique est un moyen simple de + définir des + comportements globaux pour l’application, comme par exemple des règles liées à l’authentification. + L’instruction ci-dessous extraite de la classe AppController autorise les accès + non-authentifiés + aux actions (i.e. aux méthodes) index, view et display pour tous + les + contrôleurs.

+ +
$this->Auth->allow(['index', 'view', 'display']);
+
+ +

Le router mis à part, le contrôleur est le point d’entrée de l’application. Depuis le + contrôleur, CakePHP + 3 permet de manipuler la requête et la réponse HTTP au moyen des attributs request + et response. + Les paramètres des routes sont quant à eux injectés en tant que paramètres des méthodes (des actions).

-

Encore mieux

+

Le contrôleur délègue la génération du contenu de la réponse à une vue. La méthode \Cake\Controller\Controller::render() + est automatiquement appelée et se charge d’invoquer le template correspondant à l’action (vu + plus tard). + Le contrôleur peut passer des données au template au moyen de + \Cake\View\ViewVarsTrait::set().

-

De nombreux framework de développement PHP, dont Symfony ou encore Laravel facillitent encore plus l’utilisation - de ce service. Pour l’exemple, si vous utilisez Symfony2 pour développer votre application, tapez - directement - dans votre terminal la commande suivante :

- -
php app/console server:run
+
$this->set([
+    'tweets' => $tweets,
+    'hashtag_name' => $name
+    ]);
 
-

La console vous affichera un message comme :

+

Les composants (components)

-
Server running on http://localhost:8000
+            

Les composants sont des objets qui peuvent être invoqués par un contrôleur dans le but de remplir une + tâche + spécifique. Le core de CakePHP 3 embarque des composants pour l’authentification, la manipulation + des cookies + ou encore l’utilisation de messages flash.

+ +

Charger des composants dans un contrôleur peut se faire à l’intérieur du hook + initialize() du + contrôleur.

+ +
public function initialize()
+    {
+    $this->loadComponent('Flash');
+    }
 
-

Ouvrez votre navigateur et rendez vous à l’adresse http:/localhost:8000 pour utiliser - votre - application. Note : la commande lance l’application dans l’environnement de développement, - vous - n’avez - donc pas besoin de faire précéder toutes vos route par app_dev.php.

+

Une fois fait, le composant est accessible en tant que variable d’instance du contrôleur :

-

Pour finir un petit coup d’oeil sur les informations que nous fournit la commande suivante :

- -
php app/console server:run --help
+
class UsersController extends Controller
+    {
+    public function add()
+    {
+    ...
+    $this->Flash->success(__('Your account has been created.'));
+    ...
+    }
+    }
 
-

Enfin, pour en savoir plus, rendez-vous directement sur la documentation - officelle - de Symfony.

+

Créer ses propres composants est une solution simple et ludique permettant d’isoler de la logique + dans des + classes utilisables à l’intérieur d’un ou plusieurs contrôleurs. “Où placer la logique + ?” + est une des premières questions que je me suis posées. Un cas pratique d’utilisation était la + possibilité de + télécharger une photo de profil pour les utilisateurs. Le téléchargement d’une image représente + une portion de + code susceptible de vouloir être ré-utilisée à différents emplacements de l’application. + Comme CakePHP 3 ne semble pas embarquer de composant d’injection de dépendances qui permettrait de + travailler + avec des classes de service (à l’instar de Symfony 2 par exemple) et qu’avoir recours à l’héritage + n’est pas toujours approprié, je me suis lancé de la construction de mon propre composant d’upload.

-

Et voilà, have fun :)

+

Le composant est une classe résident dans /src/Controller/Component/ dont le nom doit se + terminer par le + suffixe Component. Si la méthode initialize() du composant attend des + paramètres (comme c’est + le cas pour mon FileUploadComponent dont hérite ImageUploadComponent) :

+ +
class FileUploadComponent extends Component
+    {
+    public function initialize(array $config)
+    {
+    $this->upload_dir = $this->_getSystemPath($config['upload_dir']);
+    }
+    }
+
+ +

Les contrôleurs utilisant le composant fourniront ces paramètres lors du chargement de ce dernier. + Exemple dans mon + AccountParametersController :

+ +
class AccountParametersController extends AppController
+    {
+    public function initialize()
+    {
+    parent::initialize();
+    $this->loadComponent('ImageUpload', [
+    'upload_dir' => 'webroot/img/avatars'
+    ]);
+    }
+    }
+
+ +

La couche Model

+ +

Les tables (repositories)

+ +

Extraire des données

+ +

Utiliser l’ORM pour extraire les informations de la base de données est facile et ne requiert la + création d’aucune + classe personnalisée. + A l’intérieur de TweetsController, l’instruction ci-dessous permet d’extraire + l’ensemble + des lignes de la table tweets.

+ +
$tweets = $this->Tweets->find('all')->toArray();
+
+ +

Encore une fois, CakePHP 3 repose sur des conventions pour faire fonctionner cette instruction :

+ +
    +
  • Par soucis de performance (je suppose), les données des tweets ne sont chargées automatiquement que + dans le + TweetsController. Le chargement de ce modèle de données devra être + fait manuellement s’il s’agit d’un autre contrôleur. +
  • +
  • Le nom de la table dans la base de données doit correspondre au nom du contrôleur transformé en + lower-case + + underscores - soit pour cet exemple : tweets. +
  • +
+ +

CakePHP 3 matérialise l’interface entre l’application et une table de la base de données par + la création + d’un objet de type \Cake\ORM\Table. Sorti des conventions listées plus haut, pour + créer des + règles de validation ou encore pour exploiter des relations avec d’autres tables, vous aurez + besoin de créer + une classe spécialisée pour matérialiser cette interface.

+ +

La classe TweetsTable qui étend \Cake\ORM\Table dans le fichier /src/Model/Table/TweetsTable.php + sert justement ce rôle. Le hook initialize() est utilisé pour définir les relations avec + les autres + tables.

+ +
public function initialize(array $config)
+    {
+    $this->belongsTo('Users');
+    $this->belongsToMany('Hashtags');
+    }
+
+ +

La documentation officielle fournit les informations nécessaires pour utiliser les relations + entre les + tables.

+ +

Il est intéressant de noter que cet appel : $this->Tweets->find('all'); va - de + manière + transparente - exécuter la méthode \Cake\ORM\Table::findAll(). Il est donc possible de + modifier le + comportement de cette méthode en la redéfinissant à l’intérieur de TweetsTable. Voici + comment + demander à l’ORM de charger les données des modèles associés, et de trier les résultats du plus + récent au plus + ancien :

+ +
public function findAll(Query $query, array $options)
+    {
+    $query->contain(['Users', 'Users.AccountParameters']);
+    $query->order(['Tweets.created' => 'DESC']);
+    return $query;
+    }
+
+ +

Cette technique permet de garder les classes de contrôleur DRY tout en continuant d’exploiter toute + la + puissance de l’ORM. De la même manière il est possible de définir d’autres + finders. + Cette méthode est utilisée afin d’extraire les tweets pour un hashtag donné :

+ +
// Dans la classe TweetsTable
+    public function findTagged(Query $query, array $options)
+    {
+    $query->contain(['Users', 'Users.AccountParameters', 'Hashtags']);
+    $query->matching('Hashtags', function ($q) use ($options) {
+    return $q->where(['Hashtags.name' => $options['tag_name']]);
+    });
+    $query->order(['Tweets.created' => 'DESC']);
+    return $query;
+    }
+
+ +
// Dans la classe HashtagsController
+    $this->Tweets->find('tagged', [
+    'tag_name' => $tag_name
+    ]);
+
+ +

Insérer de nouvelles lignes

+ +

Insérer de nouvelles lignes dans la base de données ne pose pas de problème particulier. + Pour l’exemple, mon application requiert de pouvoir enregistrer de nouveaux utilisateurs. A chaque + nouvel + utilisateur, une nouvelle entrée dans la table account_parameters doit également être + ajoutée. + Le code ci-dessous permet d’accomplir cette tâche avec très peu de code :

+ +
class UsersController extends AppController
+    {
+    public function add()
+    {
+    ...
+    $user = $this->Users->newEntity($user_data);
+    $user->set('account_parameter', $this->AccountParameters->newEntity());
+    $this->Users->save($user);
+    ...
+    }
+    }
+
+ +

Valider des données

+ +

CakePHP 3 propose une double approche pour permettre de valider les données d’une entité. + De lors que des données de requête sont converties en entité, CakePHP 3 effectue automatiquement une + validation + basée sur les règles configurées dans le hook validationDefault(). Il est possible à ce + niveau de s’assurer + qu’une chaine de caractères respecte un format pré-défini ou encore de vérifier qu’un + attribut reçoit + bien une valeur en s’inspirant de ce code :

+ +
class UsersTable extends Table
+    {
+    public function validationDefault(Validator $validator)
+    {
+    return $validator
+    ->notEmpty('username', __('Username must not be empty'))
+    ->notEmpty('password', __('Password must not be empty'))
+    ->notEmpty('email', __('E-mail must not be empty'))
+    ->add('email', 'validFormat', [
+    'rule' => 'email',
+    'message' => __('E-mail must be valid')
+    ])
+    ->notEmpty('first_name', __('First name must not be empty'))
+    ->notEmpty('last_name', __('Last name must not be empty'));
+    }
+    }
+
+ +

D’autre part, lorsqu’une entité s’apprête à être persistée en base de données, CakePHP + 3 s’assure + que les données respectent les contraintes définies dans le hook buildRules(). Il s’agit + là de règles de domaine, elles sont relatives à un besoin métier + de l’application. + Vous pourriez par exemple vous assurer que le statut de ce ticket l’autorise à recevoir un + commentaire, ou + bien que ce produit est toujours disponible avant de l’ajouter au panier. L’exemple + ci-dessous est + extrait de Twitthome et montre comment s’assurer de l’unicité des champs + username et email + de la table users :

+ +
class UsersTable extends Table
+    {
+    public function buildRules(RulesChecker $rules)
+    {
+    $rules->add($rules->isUnique(['username']));
+    $rules->add($rules->isUnique(['email']));
+    return $rules;
+    }
+    }
+
+ +

Les comportements (behaviors)

+ +

Tout comme les composants permettent de factoriser de la logique des contrôleurs, les comportements + permettent de + réutiliser de la logique de la couche Model. La documentation officielle de CakePHP 3 les + présente comme étant “conceptuellement similaires aux traits”. Bien que n’ayant pas eu + besoin de + créer mes propres comportements, j’ai pu tirer parti de l’utilisation du TimestampBehavior + (défini dans le core du framework) pour mettre à jour automatiquement les champs created et + modified + des tables tweets et users. Voici comment utiliser un comportement dans une + table :

+ +
class UsersTable extends Table
+    {
+    public function initialize(array $config)
+    {
+    $this->addBehavior('Timestamp');
+    }
+    }
+
+ +

Les entités

+ +

Les objets table manipulent des objets de type \Cake\ORM\Entity. Chaque instance représente + une ligne d’une + table de la base de données. Comme pour les tables, il est possible de créer des classes spécialisées + qui seront + utilisées par l’ORM pour représenter les entités de l’application. Ces classes sont définies + dans des + fichiers à l’intérieur de /src/Model/Entity/ et leur nom (par convention) correspond + au nom de la + table ramené au singulier.

+ +

Un intérêt d’utiliser des classes spécialisées réside dans la possibilité de surcharger les + accesseurs et les + mutateurs des différents attributs. Pratique notamment dans le cas de l’entité User + pour crypter + le mot de passe de manière transparente :

+ +
class User extends Entity
+    {
+    protected function _setPassword($password)
+    {
+    return (new DefaultPasswordHasher)->hash($password);
+    }
+    }
+
+ +

J’ai utilisé cette même technique afin d’extraire + des informations du contenu d’un tweet, comme les hashtags ou les liens externes.

+ +

La couche View

+ +

Les templates

+ +

Les templates sont des fichiers contenant essentiellement du code HTML. Ils sont situés dans + /src/Templates/ et portent l’extension .ctp. Le répertoire contient les + templates + responsables du rendu d’une action spécifique d’un contrôleur, mais également des fichiers + responsables + du rendu des éléments, + des cellules + (vu un peu après), ou encore des layouts.

+ +

Par défaut, le rendu des actions des contrôleurs est encapsulé à l’intérieur du fichier /src/Template/Layout/default.ctp. + C’est dans ce fichier que doit être inséré le code commun à tous les templates. Pour mieux + comprendre, partons + du principe que le layout par défaut devrait contenir au minimum le code suivant :

+ +
<!DOCTYPE html>
+    <html>
+    <head>
+    <title><?= $this->fetch('title') ?></title>
+    </head>
+    <body>
+    <?= $this->fetch('content') ?>
+    </body>
+    </html>
+
+ +

L’affichage généré par le contrôleur sera rendu à l’emplacement de <?= $this->fetch('content') + ?>. Pour fonctionner, les templates doivent être nommés en corrélation avec le nom des + méthodes des + contrôleurs. Ainsi la méthode TweetsController::index() cherchera par default le fichier + /src/Template/Tweets/index.ctp. +

+ +

Le fonctionnement des layouts est basé sur la possibilité de travailler avec des blocks + de vue à + l’intérieur de vues étendues. Comme vu précédemment, le rendu de l’action sera positionné + dans le block + content, mais il est possible de définir d’autres blocks de façon arbitraire.

+ +

Pour l’application Twitthome, je m’étais donné à faire une sidebar dont le contenu serait + susceptible de + changer d’une page à l’autre. Un cas typique d’utilisation des blocks de vue. J’ai + donc + modifié mon layout default.ctp afin qu’il se rapproche de quelque chose comme ça : +

+ +
...
+    <body>
+    <div class="row">
+    <aside class="col-md-4">
+    <?= $this->fetch('sidebar') ?>
+    </aside>
+    <div class="col-md-8">
+    <?= $this->fetch('content') ?>
+    </div>
+    </div>
+    </body>
+    ...
+
+ +

Le contenu du block sidebar peut maintenant être défini dans un autre template, dans /src/Template/Tweets/index.ctp + par exemple :

+ +
<?php $this->start('sidebar'); ?>
+    <p>Contenu de la sidebar !</p>
+    <?php $this->end(); ?>
+
+    <?php foreach($tweets as $tweet): ?>
+    ...
+    <?php endforeach; ?>
+
+ +

Dans cet exemple, la variable $tweets est issue de l’appel à la méthode \Cake\View\ViewVarsTrait::set() + dans le contrôleur (cf. partie sur les classes de contrôleur).

+ +

Les helpers

+ +

Les helpers sont ce qui facilite la création des templates et ce qui la rend plus ludique. A l’image + des + composants pour les contrôleurs ou des comportements pour les tables, les helpers permettent de + ré-utiliser de la + logique de vue. Le core de CakePHP 3 embarque une dizaine de classes helpers chargées par défaut dans + les vues et + qui permettent entre autres :

+ +

De générer des urls :

+ +
<a href="<?= $this->Url->build(['_name' => 'login']) ?>"><?=
+    __('Sign in') ?></a>
+
+ +

D’afficher des formulaires :

+ +
<?= $this->Form->create(new Tweet()); ?>
+    <?= $this->Form->input('content', [
+    'label' => false,
+    'class' => 'form-control',
+    'placeholder' => __('What\'s up ?')
+    ]); ?>
+    <?= $this->Form->button(__('Tweeter')); ?>
+    <?= $this->Form->end(); ?>
+
+ +

Ou encore d’insérer une feuille de style :

+ +
<?= $this->Html->css('app.min.css') ?>
+
+ +

Des classes helpers personnalisées peuvent être ajoutées dans /src/View/Helper, leur nom + doit se + terminer par le suffixe Helper. L’exemple ci-dessous est utilisé dans l’application + Twitthome pour générer le code HTML correspondant à l’avatar d’un utilisateur.

+ +
class AvatarHelper extends Helper
+    {
+    public $helpers = ['Html'];
+
+    public function render($avatar_file_name)
+    {
+    $avatar_path = $avatar_file_name ?
+    'avatars/' . h($avatar_file_name) : 'no-avatar.jpg';
+
+    return $this->Html->image($avatar_path, [
+    'alt' => 'Avatar',
+    'class' => 'img-responsive thumbnail'
+    ]);
+    }
+    }
+
+    // Dans un template ...
+    ...
+    <?= $this->Avatar->render($avatar_file_name) ?>
+    ...
+
+ +

Comme le montre cet exemple, un helper peut dépendre d’autres helpers. Les classes d’helper + correspondant + aux éléments du tableau public $helpers seront automatiquement instanciées et ajoutées + comme attributs. +

+ +

Si vous souhaitez charger vos helpers pour les rendre utilisables à l’échelle de votre application, + vous pouvez + demander à CakePHP 3 de les instancier dans AppView via le hook + \Cake\View\View::initialize().

+ +
class AppView extends View
+    {
+    public function initialize()
+    {
+    $this->loadHelper('Avatar');
+    }
+    }
+
+ +

Les cellules (cells)

+ +

Il arrive que des fragments de page HTML dépendent de données qui n’ont pas de lien direct avec le + contenu + principale de la page. Par exemple : un nuage de tags, un feed Instagram ou une remontée des posts les + plus récents + d’un blog. Si ces fragments apparaissent dans plusieurs templates, cela implique que les données + doivent être + rassemblées et passées à la vue dans chaque action de contrôleur correspondant. En adoptant cette + approche, le code + des contrôleurs risque d’être rapidement pollué. Utiliser des cellules est une solution plus + pratique pour + répondre à ce genre de problématiques.

+ +

La documentation officielle du + framework définit les cellules comme “des mini-controllers qui peuvent invoquer de la logique + de vue et + afficher les templates”. Dans le cadre de Twitthome, j’ai utilisé une cellule pour afficher + le + bloc “Tendances”. La cellule existe au travers de deux fichiers. Le premier est une classe + définie dans + /src/View/Cell/PopularHashtagsCell.php :

+ +
class PopularHashtagsCell extends Cell
+    {
+    public function display()
+    {
+    $this->loadModel('Hashtags');
+    $hashtags = $this->Hashtags->find('popular')->toArray();
+    $this->set('hashtags', $hashtags);
+    }
+    }
+
+ +

Le comportement de cette classe est similaire à celui d’un contrôleur. Celle-ci est capable de + charger un + modèle, dans le but d’extraire les informations nécessaires de la base de données. Le second + fichier est le + template responsable du rendu de la cellule. Ce template est définit dans /src/Template/Cell/PopularHashtags/display.ctp.

+ +

Enfin la dernière étape consiste à afficher la cellule à l’intérieur d’un template. Une méthode + est justement + prévue pour tenir ce rôle.

+ +
<?= $this->cell('PopularHashtags'); ?>
+
+ +

Le mot de la fin

+ +

Il reste évidemment de nombreux points à aborder. Certains sur lesquels je me suis penchés sont + volontairement passés + sous silence (comme notamment la partie sur l’internationalisation) afin de ne pas trop alourdir + la lecture de + cet article. D’autres sujets mériteraient une attention particulière, comme l’outil en ligne + de + commande, la gestion du cache, les logs ou encore l’intégration des tests.

+ +

Ceci étant dit, si cet article ne peut pas prétendre couvrir (même de loin) tous les aspects de CakePHP + 3, j’ai + bon espoir qu’il aide à se forger un premier avis sur le framework et puisse éventuellement servir + de support + pour le démarrage d’un projet. + Pour aller plus loin, la documentation + officielle est plutôt bien fournie. Elle contient des exemples d’applications, un cookbook + complet et + une documentation soignée de l’API.

+ +

Si le coeur vous en dit, je vous encourage à commenter si vous pensez pouvoir souligner certains axes d’amélioration, + autant sur le support (Twitthome) que sur la forme. + Je vous remercie pour la lecture et happy coding à tous !

+ +