Articles de l'utilisateur

Par Artusamak
Julien Dubois

Créer un système d'annonces simple avec Drupal 8 (seconde partie)

Créer un système d'annonces simple avec Drupal 8 (seconde partie)
DuaelFr
mar 04/12/2018 - 09:30

La première partie de cet article décrivait l'analyse et l'implémentation du système d'annonce présent sur notre site. Dans cette partie nous aborderons l'affichage de l'annonce et la gestion du cache.

Corps

Dans la première partie de cet article, nous avons créé un formulaire qui nous permet de configurer une annonce, sa date de début, sa date de fin et son contenu. Désormais, il nous faut afficher ces informations en respectant la configuration, notamment les dates.

Pour afficher des informations dans une zone définie d'un site Drupal, en dehors de la zone de contenu, nous avons un mécanisme tout désigné : les blocs. Selon la demande initiale, nous devons donc créer un bloc qui sera présent sur toutes les pages du site, lorsque l'annonce est activée et que nous sommes entre la date de début et la date de fin de l'annonce.

Création du bloc

Nous l'avons déjà couvert dans les billets issus de notre formation, la création d'un bloc passe par la création d'un Plugin, soit la forme d'une classe PHP munie d'une Annotation. Dans notre cas, comme pour le formulaire de paramétrage, nous aurons besoin de pouvoir accéder aux données stockées dans la State API et nous aurons donc une dépendance à injecter. La différence principale est que la classe BlockBase n'implémente pas déjà l'interface nécessaire et qu'il faudra donc le faire nous même. Vous le constaterez, du fait que nous manipulions un Plugin et plus juste un formulaire, les méthodes create() et __construct() auront besoin de quelques paramètres complémentaires. Voyons voir ce que l'on doit mettre dans notre fichier src/Plugin/Block/Announcement.php.

namespace Drupal\hc_announce\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\State\StateInterface;

/**
* Provides a 'Announcement' block.
*
* @Block(
*  id = "announcement",
*  admin_label = @Translation("Announcement"),
* )
*/
class Announcement extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * @var array
   */
  protected $config;

  /**
   * Constructs a new Announcement object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param string $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\State\StateInterface $state
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    StateInterface $state
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->config = $state->get('hc_announcement');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('state')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    return ['#markup' => 'Content of the block'];
  }

}

Bien, maintenant que le bloc est créé et après une petite vidange du cache, vous devriez le voir apparaître dans la liste des blocs disponibles dans l'administration du site. Une fois positionné dans la région de notre choix, on a bien la chaîne "Content of the block" qui apparaît sur le site. Tâchons de faire un petit peu mieux en affichant au moins le contenu stocké dans le State pour que les personnes en charge de l'intégration puissent commencer à travailler sur l'aspect visuel. Nous enrichissons donc la méthode build() de notre bloc comme suit.

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];

    $build['#title'] = $this->config['title'];
    $build['#attributes'] = [
      'class' => ['announcement'],
    ];

    $build['announcement'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['announcement__content']],
      'content' => [
        '#type' => 'processed_text',
        '#text' => $this->config['announcement']['value'],
        '#format' => $this->config['announcement']['format'],
      ],
    ];

    return $build;
  }

Cela fonctionne bien. Cependant, nous ne respectons pas l'état d'activation de l'annonce ni ses dates de début et de fin. Pour l'état de l'annonce rien de plus simple. Avec un test dans la méthode build(), il est toujours possible de renvoyer un tableau vide si l'annonce est inactive. Pour manipuler les dates, nous avons par contre besoin d'une nouvelle dépendance sur le service datetime.time du cœur. Nous ajoutons donc ce service à la méthode create(), à la méthode __construct() et l'enregistrons dans un attribut $time au niveau de l'objet. Puis, nous ajoutons le code suivant à la méthode build() pour renvoyer un bloc vide si le bloc n'est pas supposé être actif.

    if (empty($this->config['enabled'])) {
      return $build;
    }

    $now = $this->time->getRequestTime();
    $start = (new \DateTime($this->config['start_date'] . ' 00:00:00'))->getTimestamp();
    $end = (new \DateTime($this->config['end_date'] . ' 23:59:59'))->getTimestamp();
    if ($now < $start || $now > $end) {
      return $build;
    }

Trop facile ? Vous n'avez pas tort...

Le problème du cache

Comme indiqué en introduction de cet article, ce bloc va être visible sur toutes les pages du site. Il est donc particulièrement important de bien gérer son cache car sinon nous pouvons être confrontés à deux problématiques majeures :

  1. le bloc est affiché quand il est supposé être inactif ou ne s'affiche pas quand il est supposé être actif,
  2. aucune des pages du site n'est mise en cache.

Nous avions déjà abordé le sujet du cache dans Drupal 8 dans un précédent article sans toutefois aborder le cas un peu spécifique des blocs. En effet, ces derniers utilisent les mêmes métadonnées que les render arrays abordés dans l'article mais définies par des méthodes spécifiques : getCacheContexts(), getCacheMaxAge() et getCacheTags(). Ces dernières vont permettre d'indiquer au service BlockManager, comment mettre en cache le bloc dans son intégralité. Lors du rendu d'une page, si le BlockManager se voit demander un bloc qu'il considère comme ayant un cache valide, il va le renvoyer sans même tenter d'instancier sa classe ou d'appeler sa méthode build() ! Par défaut, tous les blocs sont mis en cache de façon permanente et sans aucune variante. Comme pour le reste des métadonnées de cache, ces dernières se propagent vers le conteneur. Il n'est donc pas souhaitable de se faciliter la vie en désactivant totalement le cache de notre bloc sinon cela signifierait désactiver le cache de toutes les pages du site (en vrai c'est mieux fait que ça, mais on simplifie un peu pour avancer).

Gérer la temporalité du cache

Dans notre cas bien particulier, nous allons devoir prévoir trois cas distincts :

  1. si la date de début n'est pas encore arrivée nous devons mettre en cache jusqu'à cette date,
  2. si la date de début est passée mais la date de fin pas encore, nous devons mettre en cache jusqu'à la date de fin,
  3. si la date de début et de fin sont passées ou si l'annonce est désactivée, nous devons mettre en cache de façon permanente.

Pour atteindre ce but, nous allons simplement implémenter la méthode getCacheMaxAge() de la façon suivante :

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    $max_age = parent::getCacheMaxAge();
    if (!empty($this->config['enabled'])) {
      $now = $this->time->getRequestTime();
      $start = (new \DateTime($this->config['start_date'] . ' 00:00:00'))->getTimestamp();
      $end = (new \DateTime($this->config['end_date'] . ' 23:59:59'))->getTimestamp();

      if ($now < $start) {
        $max_age = Cache::mergeMaxAges($max_age, $start - $now);
      }
      elseif ($now < $end) {
        $max_age = Cache::mergeMaxAges($max_age, $end - $now);
      }
    }

    return $max_age;
  }

Notez l'usage de la méthode \Drupal\Core\Cache\Cache::mergeMaxAges() qui permet de proprement fusionner le max-age par défaut avec la valeur que l'on souhaite configurer. Dans notre cas, cela n'aurait rien changé de renvoyer directement la valeur calculée mais c'est une bonne habitude à prendre d'utiliser les méthodes de fusion des métadonnées de cache pour éviter les mauvaises surprises. La méthode mergeMaxAges() s'assure que l'on conserve toujours le max-age le plus contraignant (et c'est exactement pour cette raison que si on désactive le cache d'un bloc, toute la page est impactée).

Gérer les changements de configuration

Maintenance que la temporalité de notre cache est bien établie, il nous faut prendre en compte les changements qui pourraient venir de l'action d'une personne dans l'interface d'administration. En effet, si le titre ou une date change, par exemple, le cache du bloc devrait immédiatement être invalidé pour prendre en compte les nouvelles données. Dans le cas contraire, les gestionnaires du site n'auraient pas d'autre option que d'invalider la totalité du cache du site. Le mécanisme qui permet cette invalidation, ce sont les cache tags. La plupart des objets gérés par le cœur comme les entités de contenu ou de configuration disposent de cache tags pour les identifier mais ce n'est malheureusement pas le cas de la State API. Fort heureusement, c'est un problème très simple à contourner.

Tout d'abord, définissons un cache tag personnalisé et rattachons le à notre bloc grâce à l'implémentation de la méthode getCacheTags(). Son nom est arbitraire alors, comme souvent, nous allons le préfixer du nom du module pour éviter les collisions. Comme précédemment, nous allons utiliser une méthode pour fusionner ce nouveau cache tag avec d'éventuels autres définis par la classe parente.

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    return Cache::mergeTags(parent::getCacheTags(), ['hc_announcement_settings']);
  }

Ensuite, il nous faut juste modifier légèrement le formulaire d'administration de l'annonce pour lui demander d'invalider ce tag lors de l'enregistrement. Pour cela, nous avons besoin de faire appel au service cache_tags.invalidator que nous allons ajouter à notre injection de dépendances et à notre constructeur :

  /**
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface
   */
  protected $invalidator;

  /**
   * Constructs a new AnnouncementSettingsForm object.
   *
   * @param \Drupal\Core\State\StateInterface $state
   * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $invalidator
   */
  public function __construct(StateInterface $state, CacheTagsInvalidatorInterface $invalidator) {
    $this->state = $state;
    $this->invalidator = $invalidator;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('state'),
      $container->get('cache_tags.invalidator')
    );
  }

Ceci étant fait, il ne nous reste plus qu'à ajouter une petite ligne dans la méthode submitForm() pour provoquer l'invalidation.

$this->invalidator->invalidateTags(['hc_announcement_settings']);

Un dernier "petit" problème

Désormais, notre bloc est mis en cache suivant une logique qui s'appuie sur le mécanisme d'âge maximum pour définir quand l'expiration a lieu de façon très précise. Nous nous attendons donc à ce que le bloc apparaisse ou disparaisse approximativement au moment indiqué et ça fonctionne particulièrement bien... pour les utilisateurs authentifiés...

Le module Internal Page Cache du cœur permet de mettre en cache les pages entières à destination des anonymes afin d'améliorer drastiquement les performances. Le problème, c'est que ce cache, très agressif, ne tient pas actuellement compte des métadonnées de cache et notamment pas du max-age. En attendant que le cœur change de fonctionnement, vous pouvez contourner ce problème en installant le module Cache Control Override, qui ne nécessite aucune configuration particulière.

Conclusion

Au terme de cette paire d'articles, vous devriez y voir plus clair sur la façon de créer un formulaire et un bloc ainsi que sur la gestion du cache. Par cet exemple concret, j'espère que j'aurai réussi à vous faire visualiser des concepts qui étaient traités de façon bien plus académique dans nos précédents articles. S'il reste des zones d'ombre ou si vous voulez en savoir plus sur un point en particulier, n'hésitez pas à vous manifester dans les commentaires ci-dessous.

 

Crédit photo de couverture : Sue Cro

Catégories
Développement
Drupal
Drupal 8
Tags
state api
cache
blocs
Par Artusamak
Julien Dubois

Créer un système d'annonces simple avec Drupal 8

Créer un système d'annonces simple avec Drupal 8
DuaelFr
jeu 22/11/2018 - 16:56

Développé initialement pour ce site, notre système d'annonce simple regroupe plusieurs concepts intéressants à mettre en valeur dans un article en deux parties. Ici, nous évoquerons la réflexion autour du stockage de l'information et la construction du formulaire.

Corps

Le besoin fonctionnel à l'origine de ce développement est relativement simple et se retrouve dans de nombreux projets : nous souhaitons pouvoir faire apparaître sur tout notre site un bandeau qui permettra de mettre en valeur, de façon bornée dans le temps, une information importante. Un peu d'analyse autour de cette demande nous permet de la détailler comme suit.

Une personne en charge du contenu du site doit pouvoir activer et configurer une annonce, qui apparaîtra toujours au même emplacement sur toutes les pages du site. La configuration doit permettre de choisir une date de démarrage et une date de fin d'apparition de l'annonce ainsi que son contenu.

Côté technique, la lecture de ce type de besoin soulève deux problématiques pour lesquelles il nous faudra faire preuve de vigilance :

  1. puisque cet élément est administrable, il faut qu'une interface facile d'accès et sécurisée soit mise en place ;
  2. puisque cette annonce va apparaître et disparaître sans nécessaire action humaine, il faut se méfier des problématiques liées au cache.

Saisie et stockage du contenu

En premier lieu, nous devons donc déterminer la manière dont sera stocké ce contenu car c'est de cela que découlera la façon dont il sera saisi. Plusieurs options s'offrent à nous :

  • une entité de contenu personnalisée,
  • un objet de configuration simple,
  • un bloc personnalisé,
  • un système de stockage à plat.

Choisir la bonne option

Puisque le besoin fonctionnel ne demande qu'à ce qu'une annonce soit configurée à la fois, l'utilisation d'une entité de contenu personnalisée semble un petit peu exagérée. En effet, générer une telle entité demande beaucoup de code (bien que l'on puisse utiliser un générateur pour aller plus vite) et nécessitera la création d'au moins une table dans la base de données, de nombreuses routes et contrôleurs pour l'administration. Cela aurait été tout à fait justifié s'il avait fallu pouvoir gérer plusieurs annonces à la fois mais dans notre cas cela représente trop de complexité.

Un objet de configuration simple pourrait également remplir son rôle pour le stockage mais, étant donné qu'il s'agit de permettre à la personne en charge du contenu de mettre en place cette annonce, nous ne conserverons pas cette option. En effet, nos procédures de déploiement provoquent par défaut un écrasement de la configuration de la production au profit de celle versionnée par l'équipe. Bien qu'il soit possible de préserver un ensemble d'objets de configuration lors d'un import, afin d'éviter à la personne en charge du contenu de perdre le fruit de son travail, cela nécessite d'y consacrer du temps et d'ajouter des modules au cœur. Dans le cadre de cette demande, nous avons d'autres options qui nous semblent plus judicieuses.

Un bloc personnalisé, basé sur un type de bloc spécialement conçu pour l'occasion, pourrait bien être une réponse pour sa simplicité de configuration et la mise à disposition d'une interface d'édition similaire à celle d'un nœud. Cette solution, bien que très alléchante, nous pose trois problèmes majeurs. Tout d'abord, nous n'avons pas le module Block Content actif sur notre site, ce qui signifie que nous ne l'activerions que pour un seul type de bloc qui ne contiendrait lui-même qu'un seul bloc. Deuxièmement, pour permettre à la personne en charge du contenu de modifier les champs de ce bloc, il aurait été nécessaire d'intégrer un module de la communauté supplémentaire, sinon elle aurait également pu modifier toute la configuration de tous les blocs. Enfin, la gestion très spécifique du cache dont nous avons fait mention précédemment aurait nécessité d'altérer en profondeur le fonctionnement des blocs personnalisés, ce qui nous semblait, une fois de plus, très disproportionné par rapport à la demande.

Finalement, c'est donc un système de stockage à plat, dans la State API, qui nous semble la meilleure option. En effet, le contenu de la State API est indépendant de la configuration et spécifique à l'environnement sur lequel il est défini. Son accès est très rapide et il ne nécessite aucune configuration particulière ni aucun module complémentaire. Son seul défaut par rapport aux entités de contenu personnalisées ou aux blocs personnalisés, c'est qu'il faut manuellement créer le formulaire qui permettra d'administrer l'annonce. Notez que cette option n'est viable que parce que les données que nous souhaitons stocker ne sont pas critiques pour le fonctionnement du site. Dans le cas contraire, conformément à ce qui est indiqué dans la documentation officielle, il nous aurait fallu trouver une autre solution.

Route et permissions

Entrons dans le vif du sujet ! Pour tout le code qui va suivre, il est important de noter qu'il prend place dans un module nommé hc_announce ; le namespace racine de tous les objets sera donc \Drupal\hc_announce et le nom du module sera utilisé, autant que possible, en préfixe de tous les noms machines qui pourraient entrer en collision avec d'autres modules.

En règle générale, je commence toujours par me poser la question des permissions. Dans notre cas, je souhaite pouvoir assigner le droit de modifier l'annonce indépendamment de toutes les autres permissions du site. Je vais donc créer un fichier hc_announce.permissions.yml contenant le code suivant :

administer announcement:
  title: 'Administer announcement'
  description: 'Allow to access the announcement settings form'

Ensuite, je passe à la route d'accès au formulaire, dans le fichier hc_announce.routing.yml j'ajoute l'entrée :

hc_announce.announcement_settings_form:
  path: '/admin/config/announcement'
  defaults:
    _form: '\Drupal\hc_announce\Form\AnnouncementSettingsForm'
    _title: 'Announcement settings'
  requirements:
    _permission: 'administer announcement'

Puis, comme je suis un peu perfectionniste et que je pense aux personnes en charge du contenu, j'ajoute cette route dans le menu d'administration grâce à une entrée dans le fichier hc_announce.links.menu.yml :

hc_announce.announcement_settings_form:
  title: Announcement
  parent: system.admin_config
  description: 'Announcement settings.'
  route_name: hc_announce.announcement_settings_form

Le lien "Announcement" apparaîtra donc dans le menu d'administration sous l'entrée "Configuration" matérialisée par la route parente system.admin_config.

Si vous voulez en savoir plus sur le fonctionnement des routes de Drupal 8, je vous renvoie à un ancien article issu de notre formation.

La base du formulaire

Ces actions préparatoires terminées, il est temps de passer aux choses sérieuses, le formulaire en lui même.

Il nous faut récupérer une date de début, une date de fin, un titre et un message au minimum. Pour des soucis pratiques, nous ajouterons un système pour activer ou désactiver l'annonce rapidement (c'est à dire sans avoir à jouer avec les dates). Pour clarifier l'utilisation de ce formulaire, nous n'afficherons les champs utiles que si la case à cocher pour activer l'annonce est cochée. C'est parti !

Nous créons donc le fichier src/Form/AnnouncementSettingsForm.php dans notre module avec le minimum pour que cela soit considéré comme un formulaire valide :

namespace Drupal\hc_announce\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
* Class AnnouncementSettingsForm.
*/
class AnnouncementSettingsForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'announcement_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->messenger()->addStatus($this->t('The configuration options have been saved.'));
  }

}

Le résultat n'est pas encore exceptionnel mais il nous permet de valider que la route pointe bien sur notre classe.

Capture d'écran du formulaire ne présentant qu'un bouton de validation.

L'étape suivante consiste à étoffer la méthode buildForm() pour afficher tous les champs dont nous avons besoin.

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['enabled'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable announcement'),
      '#default_value' => FALSE,
    ];

    $form['announcement'] = [
      '#type' => 'details',
      '#title' => $this->t('Announcement settings'),
      '#open' => TRUE,
      '#states' => [
        'visible' => [
          ':input[name="enabled"]' => ['checked' => TRUE],
        ],
      ],
    ];
    $form['announcement']['start_date'] = [
      '#type' => 'date',
      '#title' => $this->t('Start date'),
      '#default_value' => '',
      '#required' => TRUE,
    ];
    $form['announcement']['end_date'] = [
      '#type' => 'date',
      '#title' => $this->t('End date'),
      '#default_value' => '',
      '#required' => TRUE,
    ];
    $form['announcement']['title'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Announcement title'),
      '#default_value' => '',
      '#maxlength' => 64,
      '#size' => 64,
    ];
    $form['announcement']['announcement'] = [
      '#type' => 'text_format',
      '#title' => $this->t('Announcement'),
      '#default_value' => '',
      '#required' => TRUE,
      '#format' => 'full_html',
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

    return $form;
  }

Ce qui nous donne un résultat déjà plus proche de nos besoins.

Capture d'écran du formulaire présentant tous les champs définis par le code : activation de l'annonce, date de début, de fin, titre et contenu.

Validation de la saisie

La magie de Drupal fait que les champs marqués comme required seront validés automatiquement, de même que les données relatives aux types de champs auront leur format vérifié avant soumission. Il ne nous reste qu'à vérifier que la date de fin est bien postérieure à la date de début et nous allons pour cela implémenter la méthode validateForm().

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();
    if ($values['end_date'] < $values['start_date']) {
      $form_state->setErrorByName('end_date', $this->t('The ending date must be greater or equal than the starting date.'));
    }
  }

Le résultat avec le module du cœur Inline Form Error actif (vous devriez activer ce module sur tous vos projets par défaut) est plutôt sympa.

Champ date de fin en erreur indiquant que sa valeur doit être supérieur ou égale à la date de début.

Enregistrement et injection de dépendances

Pour finir, il va nous falloir enregistrer l'information dans la State API et nous assurer que le formulaire tiendra compte des données existantes lors de son prochain affichage. Contrairement aux formulaires de configuration qui proposent un ensemble de méthodes pour accéder aux objets de configuration, nous ne disposons d'aucune aide pour accéder à la State API. Pour y parvenir, nous pourrions faire appel directement à l'objet \Drupal qui contient toutes les méthodes d'assistance nécessaires mais, puisque nous aimons le travail bien fait et le respect des bonnes pratiques, mais aussi dans l'intérêt de l'exercice, nous allons faire appel à l'injection de dépendances.

Dans le cas d'un formulaire qui étend la classe FormBase, nous n'avons pas besoin de spécifier que nous souhaitons implémenter l'interface ContainerInjectionInterface car c'est déjà fait dans la hiérarchie de classe. Il nous suffit donc d'implémenter la méthode statique create() et de spécifier le constructeur de notre objet.

namespace Drupal\hc_announce\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\State\StateInterface;

/**
* Class AnnouncementSettingsForm.
*/
class AnnouncementSettingsForm extends FormBase {

  /**
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * Constructs a new AnnouncementSettingsForm object.
   *
   * @param \Drupal\Core\State\StateInterface $state
   */
  public function __construct(StateInterface $state) {
    $this->state = $state;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('state')
    );
  }

// [...]

Le service de construction de formulaire, sachant que notre classe implémente ContainerInjectionInterface, instanciera notre objet par l'intermédiaire de sa méthode create(), en lui fournissant le conteneur de services en paramètres. C'est cette méthode qui créera l'instance du formulaire à proprement parler en lui fournissant les services dont elle a besoin pour fonctionner, dans notre cas, la State API.

Maintenant qu'on a notre service à disposition, rien n'est plus simple que de stocker les données saisies. Il nous faut juste un peu enrichir la méthode submitForm().

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();

    $this->state->set('hc_announcement', [
      'enabled' => $values['enabled'],
      'start_date' => $values['start_date'],
      'end_date' => $values['end_date'],
      'title' => $values['title'],
      'announcement' => $values['announcement'],
    ]);

    $this->messenger()->addStatus($this->t('The configuration options have been saved.'));
  }

En faisant le choix de ne pas filtrer les données saisies, notamment pour le titre qui est un champ texte simple, nous gardons en tête qu'il faudra être vigilants lors de leur affichage. Heureusement, Twig est là pour nous aider à éviter les failles XSS ! Nous y reviendrons dans la seconde partie de cette série.

La dernière chose à faire est d'enrichir la méthode buildForm() pour afficher les données enregistrées dans la State API lors de l'affichage du formulaire. Je vous épargne la totalité du code pour vous montrer uniquement l'exemple sur le champ "enabled" :

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->state->get('hc_announcement');

    $form['enabled'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable announcement'),
      '#default_value' => !empty($config['enabled']) ? $config['enabled'] : FALSE,
    ];

// [...]

Lorsque vous repasserez sur tous les champs pour utiliser les valeurs stockées, n'oubliez pas le #format du champ "announcement".

Et voilà le travail !

Formulaire de configuration de l'annonce complet affichant tous les champs ainsi que leurs données actuelles.

 

Voilà déjà une bonne chose de faîte ! Dans la prochaine partie de cet article, nous aborderons l'affichage de ces données en front et la gestion du cache.

À très bientôt !

 

Crédit photo de couverture : Sue Cro

Catégories
Développement
Drupal
Drupal 8
Tags
state api
formulaires
configuration
entités
Par Artusamak
Julien Dubois

Installer Drupal depuis la configuration

Installer Drupal depuis la configuration
DuaelFr
jeu 15/11/2018 - 09:30

Depuis Drupal 8.6.0 il est possible d'installer un site depuis un ensemble de fichiers de configuration, voyons comment cela fonctionne.

Corps

Depuis la sortie de Drupal 8 et de son système de gestion de la configuration, la communauté n'a cessé de demander à ce qu'il soit possible de procéder à une installation complète à partir d'un jeu de fichiers de configuration existant. Il aura fallu plus de deux ans et des efforts considérables de dizaines de contributeurs et contributrices pour rendre cela possible.

Utilité

Cette nouvelle fonctionnalité, jusqu'à présent accessible avec un peu de bricolage grâce au profil d'installation Configuration Installer, ouvre de nombreuses possibilités. Tout d'abord, il y a les agences qui souhaiteraient avoir un socle pour démarrer rapidement leurs projets (c'est notre cas), mais aussi les développeurs et développeuses qui veulent pouvoir expérimenter des choses tout en étant capables de reconstruire rapidement leur environnement si besoin ou de monter des environnements de test à la volée. Côté fonctionnel cela rend également plus simple le clonage de site sans avoir à nettoyer les contenus et cela permet également, dans certains cas comme pour un système d'usine à sites, de disposer d'un socle minimal de configuration disponible lors de la création d'un nouveau site.

Préparation

Comme vous vous en doutez, la première étape est d'avoir un jeu de fichiers de configuration disponible. Si ce n'est pas votre cas, faîtes une installation classique avec le profil d'installation minimal, activez quelques modules, changez quelques options dans l'administration du site, puis exportez la configuration via le backoffice (chemin : admin/config/development/configuration/full/export) ou via Drush (drush config:export).

Placez vos fichiers de configuration dans un répertoire prévisible, hors de votre DocumentRoot si possible. Par exemple, si vous suivez l'organisation proposée par le drupal-project, cela se fera dans un répertoire config/sync à la racine du projet. Puis, indiquez l'emplacement de cette configuration dans votre fichier settings.php (ou settings.local.php si vous en avez un) de façon relative à la racine de Drupal, c'est à dire à l'emplacement du fichier index.php. Par exemple :

$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync';

Note : il est aussi possible de stocker cette configuration dans le répertoire config/sync de votre profil d'installation sans avoir besoin de modifier le fichier de settings. Cela peut être très utile dans le cadre d'une distribution (interne ou contribuée) mais, dans la plupart des cas, un répertoire indépendant sera préférable car il permettra de maintenir la configuration à jour plus simplement au fil du projet.

Utilisation

Une fois votre référentiel de configuration et vos fichiers prêts, vous n'avez plus qu'à installer votre site.

C'est possible de réaliser cette opération depuis l'interface graphique fournie par Drupal, comme illustré ci-dessous.

Écran d'installation de Drupal faisant apparaître l'option "Use existing configuration" qui permet d'installer le site en se basant sur la configuration existante.

Cela est également possible via Drush 9.4 ou supérieur grâce à l'option --existing-config de la commande drush site:install.

Limitations et dépannage

Attention ! À l'heure actuelle, cette fonctionnalité ne fonctionne pas avec les profils d'installation qui implémentent un hook_install. C'est pour cette raison que je vous ai conseillé de tester en utilisant le profil minimal. Cela sera sans doute amené à changer dans le futur puisque la communauté travaille actuellement sur cette problématique.

De plus, si vous décidez de créer votre propre profil d'installation (ce que je recommande chaleureusement, j'en parlerai dans un futur billet), faîtes bien attention à l'export du fichier core.extension.yml. En effet, celui-ci contient la liste de tous les modules activés, y compris votre profil qui est considéré comme un module, ainsi qu'une référence directe au profil avec lequel le site a été installé. Si vous avez procédé à une installation via le profil minimal, il faudra remplacer ce dernier dans le fichier par le nom machine de votre propre profil sous les clefs "module" et "profile". Si vous ne faîtes pas cette modification, l'installation échouera.

Extrait d'un différentiel de code illustrant le changement de profil dans le fichier core.extension.yml.

Et voilà ! Vous savez tout. Si vous tombez sur des cas étranges, n'hésitez pas à nous laisser un petit commentaire !

 

Crédit photo de couverture : Sally Wilson

Catégories
Développement
Drupal
Drupal 8
Tags
configuration management
profil d'installation
Par Artusamak
Julien Dubois

Driesnote – State of Drupal – Drupal Europe 2018

Comme régulièrement, voici un mini transcript de la keynote de Dries pour Drupal Europe 2018 visant à raconter l’état de l’art de Drupal.

Pourquoi sommes nous ici ? Car nous avons envie de construire un Drupal que les gens et nous aimons.

« Impact gives purpose »

L’impact de Drupal dans le monde réel, aide à se motiver et se rappeler dans les moments difficiles qu’on a un impact concret lorsque l’on se prend la tête avec les issues.

Il y a un plan pour y arriver : promouvoir Drupal, améliorer drupal pour les créateurs de contenu, les développeurs, les nouveaux venus. Chaque piste a des étapes intermédiaires. Et cela fonctionne !

I) State of Drupal

8.6.0 a été publié la semaine dernière… comme prévu ! Ce qui est nouveau depuis Drupal 8 mais toujours rassurant et efficace pour rassurer tout le monde.

Il y a de plus en plus de contributeurs et de modules stables sur la dernière année et surtout des actifs dans les initiatives du cœur.

12 initiatives officielles ont lieu en parallèle (est-ce trop ?). Voici un récap sur ces initiatives.

A/ Améliorer Drupal pour les créateurs de contenu

Se satisfaire de copier du texte depuis Word rendu à peu près normalement dans le contenu ne suffit plus. Les contributeurs passent plus de temps sur l’interface qu’avant.

Démo des initiatives : Layout, media, out of the box, workflow. (Contenu de la démo : édition de contenu en ligne, mise en page par article, utilisation du site de démo Umami, préparation de contenu pour mise en ligne plus tard (staging de contenu).

[ndr : C’est vraiment impressionnant comparé à ce que l’on avait il y a 2 ou 3 ans !]

B/ Améliorer Drupal pour les développeurs

Initiatives : Admin UI, API-first, Javascript modernisation

1 an s’est écoulé depuis le début de l’initiative sur la modernisation du JS. Les objectifs étaient d’améliorer l’expérience d’admin, moderniser les API internes et le JS, tisser plus de liens avec la communauté Javascript.

La communauté s’appuie maintenant sur des tests utilisateurs pour avoir une idée plus fiable des fonctionnalités sur lesquelles travailler et qui sont attendues par les utilisateurs.

Un rafraîchissement du thème d’admin est en cours pour redonner un coup de frais à l’admin en attendant le travail de fond sur la refonte complète de l’expérience d’admin.

Drupal va s’appuyer sur React-UI pour sa nouvelle expérience d’administration (et seulement son administration). Twig ou un autre framework JS peut et pourra toujours être utilisé en front.
Pour réussir, le module contrib JSON API est utilisé (il s’agit de l’initiative API-First) en attendant que le module soit mature pour intégrer le cœur.
L’équipe s’appuie sur un prototype pour faire la démo du projet, on peut y voir des formulaires plus réactifs, une expérience bien plus dynamique et fluide.
Ce travail a aussi permis de faire du nettoyage dans le code JS existant.

C/ Améliorer Drupal pour les nouveaux venus

Il y a 6 mois, une critique a été formulée sur le temps d’installation de Drupal pour un nouveau venu (plus de 20 clics et 15 minutes pour installer Drupal).
Le profil d’installation Umami permet d’avoir un site avec du contenu dès leur première installation pour expérimenter Drupal. Un gros travail d’amélioration de la documentation est en cours sur drupal.org.
La page de téléchargement de Drupal a été améliorée en ajoutant des liens pour apprendre à installer Drupal et le tester et en simplifiant des commandes.
Grâce à cela, 3 clics et 1 minute 20 suffisent maintenant pour avoir un Drupal testable !

D/ Améliorer Drupal pour les développeurs

Initiatives : Automatic updates, migrate, composer œ core, config management 2.0, security LTS.

Beaucoup de progrès, trop pour en parler correctement. Des billets de Dries suivront.

Gros plan sur Security LTS. Jusqu’à maintenant, les équipes ont 1 mois pour mettre à jour Drupal avant qu’une branche majeure ne soit plus maintenue.  (Lors de la sortie de 8.5.x, 8.4.x était maintenue pour un mois avant d’être dépréciée). Avec la sortie de Drupal 8.6.x, la version précédente sera maintenue 6 mois. La durée de vie d’une version majeure sera donc d’un an (6 mois de vie active + 6 mois supportés par l’équipe de sécurité) contre 7 mois précédemment.

Les prochaines étapes pour les initiatives actuelles
Les prochaines étapes pour les initiatives actuelles

E/ Promouvoir Drupal

L’équipe va avancer malgré le fait que 78k des 100k$ aient été levés pour faire la promotion de Drupal. Le première action a été la publication d’un communiqué de presse pour la sortie de la 8.6.0. Préparation d’une plaquette, de références et d’espace de collaboration en cours de travail.

Drupal 7, 8 et 9.

Drupal 8 a des dépendances externes. Symfony 3 sera déprécié en novembre 2021. La migration vers une nouvelle version de Symfony devra se faire en passant à Drupal 9 pour des raisons de rétro-compatibilité. Drupal 8 devrait donc être en fin de vie en novembre 2021. L’objectif est de laisser un an aux mainteneurs pour passer de Drupal 8 à Drupal 9. Un an est une durée courte mais la politique de gestion des versions a été modifiée pour simplifier ces transitions. Il faut un an pour préparer Drupal 9. Drupal 9 serait donc prévu pour 2020. Drupal 8.7.0 et 8.9.0 existeront pour sûr.
Fin de vie pour Drupal 7 en 2020 en théorie mais prolongé jusqu’à novembre 2021. Drupal LTS sera toujours présent pour 7 comme il existe pour 6.

d9

Drupal.org bascule sur Gitlab

Réduction de la barrière à l’entrée pour les contributeurs en passant à des contributions à base de pull requests plutôt que de patches. Ce changement sera majeur et vraiment une excellente nouvelle pour la communauté.

L’intégration va se dérouler en 3 temps :

  1. Phase 1 : Q4 2018 / bascule des dépôts Git vers Gitlab + revue de code via Gitlab
  2. Phase 2 : Q1-Q2 2019 / merge requests et édition de code en ligne (via le navigateur)
  3. Phase 3 : Un jour / Fonctionnalités complémentaires (graphs, CI/CD…)

Annonces complètes :

Et dernière info…

Il y aura une DrupalCon en Europe en 2019 et elle aura lieu à Amsterdam du 28 octobre au 1er novembre !

 

Par Artusamak
Julien Dubois

Drupal 8 : déclarer un champ extrafield calculé (computed field)

Drupal 8 : déclarer un champ extrafield calculé (computed field)
admin
lun 13/08/2018 - 07:25

Lorsque vous devez insérer un champ sur une entité mais que cette donnée est calculée et n'est pas saisie par l'utilisateur, vous avez le réflexe de penser à un extra field.

Corps

Lorsque vous devez insérer un champ sur une entité mais que cette donnée est calculée et n'est pas saisie par l'utilisateur, vous avez le réflexe de penser à un extra field. C'est un bon début mais pour appliquer un formateur de champ, vous serez limités car cela n'est pas possible ! Fort heureusement, une solution a été introduite dans Drupal 8, il s'agit des computed fields.

Comment cela fonctionne-t-il ?

Au lieu d'utiliser le hook_entity_extra_field_info(), vous allez cette fois déclarer un hook_entity_bundle_field_info() et allez déclarer un base field auquel vous direz qu'il est calculé et indiquerez la classe qui fournie ses données. Avec du code c'est plus simple :

/**
* Implements hook_entity_bundle_field_info().
*/
function hc_core_entity_bundle_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
  $fields = [];
  if ($entity_type->id() == 'node') {
    if ($bundle == 'blog') {
      $fields['blog_related_posts'] = BaseFieldDefinition::create('entity_reference')
        ->setLabel(t('Related posts'))
        ->setComputed(TRUE)
        ->setClass('\Drupal\hc_core\BlogRelatedPostsComputed')
        ->setDisplayConfigurable('view', TRUE);
    }
  }
  return $fields;
}

Avec ce code, si vous videz les caches, vous verrez apparaître dans la gestion de l'affichage de votre entité ce nouveau champ auquel vous pourrez appliquer les formateurs pertinents. Cela dépendra du type de données que vous aurez sélectionné sur lequel il se basera.

Jetons maintenant un œil à la classe qui fournit les données sources du champ.

Pour faire les choses simplement, je vous conseille d'étendre la classe de liste du type de données de votre champ (dans mon exemple je m'appuierai sur EntityReferenceFieldItemList) et nous utiliserons le trait dédié aux champs calculés (computed fields). La classe retourne les NIDs des nœuds qui partagent les mêmes catégories que le nœud actuellement consulté.

<?php

namespace Drupal\hc_core;

use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;

class BlogRelatedPostsComputed extends EntityReferenceFieldItemList {
  use ComputedItemListTrait;

  /**
   * Computed related blog posts.
   */
  protected function computeValue() {
    $delta = 0;

    // It's a bit tricky, authors are not UIDs but NIDs because we are looking
    // for humans and humans are nodes, not users.
    $blog_categories = $this->getParent()->getValue()->get('field_category')->getValue();
    $blog_nid = $this->getParent()->getValue()->id();

    if (count($blog_categories) > 0) {
      foreach ($blog_categories as $category) {
        $category_ids[] = $category['target_id'];
      }

      $q = \Drupal::entityQuery('node')
        ->condition('type', 'blog', '=')
        ->condition('field_category', $category_ids, 'IN')
        ->condition('status', NODE_PUBLISHED, '=')
        ->condition('nid', $blog_nid, '<>')
        ->range(0, 5)
        ->sort('created', 'DESC')
        ->execute();
      if ($q) {
        foreach ($q as $rev => $r) {
          $this->list[$delta] = $this->createItem($delta, $r);
          $delta++;
        }
      }
    }
  }
}

Grâce au trait, on se concentre uniquement sur la récupération des valeurs qui nous intéressent et on utilise $this->createItem() pour remplir la collection de valeurs de $this->list.

Vous pourrez ajouter à cela quelques tags pour optimiser le rendu de vos données et vous voilà prêts à exploiter la puissance des champs calculés et rendus grâce à des formateurs de champs ! Plutôt simple, non ?

Catégories
Développement
Drupal
Drupal 8
Tags
formateur
champ
computed field
Par Artusamak
Julien Dubois

Les nouveautés de Drupal 8.4.0

Les nouveautés de Drupal 8.4.0
admin
jeu 16/11/2017 - 10:53

Toujours dans les temps, la nouvelle version mineure de Drupal, 8.4.0, est disponible depuis le 4 octobre 2017. Pour la première fois depuis deux ans, cette mise à jour contient des éléments qui pourront casser la rétrocompatibilité de certains sites.

null

Corps

Toujours dans les temps, la nouvelle version mineure de Drupal, 8.4.0, est disponible depuis le 4 octobre 2017. Pour la première fois depuis deux ans, cette mise à jour contient des éléments qui pourront casser la rétrocompatibilité de certains sites. Comme pour la sortie des précédentes versions mineures de Drupal, et notamment la mise à jour vers Drupal 8.3.0, cet article vous dévoilera les détails des changements apportés ces six derniers mois.

Attention à la rétro-compatibilité des dépendances (librairies) !

La technologie progresse et l'équipe de maintenance du cœur doit faire des choix pour concentrer les efforts de la communauté sur des tâches à valeur ajoutée pour l'avenir. Parfois, il s'agit simplement de faire des arbitrages entre des fonctionnalités fondamentales pour l'avenir et la compatibilité avec des choix ou projets passés. Pour la première fois depuis la sortie de Drupal 8, cette version mineure introduit des changements qui pourraient poser des problèmes de compatibilité avec certains projets existants. Il est donc demandé à toutes les personnes en charge de la maintenance d'un site Drupal 8 d'être extrêmement vigilantes lors du passage à la 8.4.

Arrêt du support de Internet Explorer 9 et 10

Depuis avril 2017 Microsoft a arrêté le support de Internet Explorer 9 et 10. Ces vielles versions ont longtemps été la plaie des intégrateurs et, pour un outil comme Drupal, leur support représentait un coût assez important alors que le nombre d'utilisateurs concernés ne cessait de baisser. Officiellement, à partir de la 8.4.0, ces versions ne sont donc plus supportées. Cela signifie que les sites continueront de fonctionner comme précédemment mais qu'aucun effort supplémentaire ne sera alloué à cette compatibilité à l'avenir. Les hacks en place pour faire fonctionner certaines choses pour ces versions seront progressivement retirés à partir de Drupal 8.5.

Mise à jour majeure de Symfony et jQuery

Que vous soyez plutôt back ou front, pas de répit avec cette nouvelle version ! Symfony passe à la version 3.2.8+ (au lieu de 2.8+) et jQuery à la version 3.2.1 (au lieu de 2.2.4). Bien que ces deux versions aient une forte compatibilité descendante, si certaines de vos fonctionnalités s'appuient sur des fonctions dépréciées, elles cesseront probablement de fonctionner lors de la mise à jour. Cela a été le cas pour nous sur le menu déroulant d'un projet, par exemple. 

En cas de besoin, vous pouvez consulter le rapport de changement de la mise à jour de Symfony dans le cœur ou le guide de mise à jour de jQuery.

Rupture de compatibilité avec Drush

Du fait des divers changements dans les dépendances et dans la façon dont le cœur gère quelques services, Drush 8.1.14 et inférieur n'est pas compatible avec Drupal 8.4.0 et supérieurs. Si votre Drush est installé localement au projet (il devrait), un simple composer update devrait résoudre le problème. Dans le cas contraire, référez vous à la documentation officielle.

Attention, indépendamment de l'évolution du cœur de Drupal, Drush évolue également vers une nouvelle version majeure, Drush 9. Cette dernière est une réécriture complète de Drush et apporte son lot de nouveautés très intéressantes (on en parlera dans un autre article). Cependant, si vous avez des commandes drush personnalisées, des alias de sites ou des scripts qui utilisent cet outil de façon intensive, prenez votre temps pour monter de version car vous aurez un peu de travail pour adapter votre usage.

Ça bouge chez les expérimentaux !

Si vous avez suivi un peu nos articles concernant les nouveautés de Drupal 8, vous saurez déjà que les versions mineures sont l'occasion d'introduire de nouvelles fonctionnalités sous la forme de modules expérimentaux. Pour la version 8.4, nul nouveau module expérimental mais de nombreux changements.

Les modules Datetime Range, Inline Form Errors, Layout Discovery, Media et Workflows, sont désormais considérés comme stables et plus expérimentaux.

Media, n'est qu'un support pour les modules contribués et ne propose aucune fonctionnalité de lui même. Il est caché dans l'interface de gestion des modules pour éviter les confusions mais sera automatiquement activé en cas de besoin. Si vous utilisiez le module contribué Media Entity avec la précédente version de Drupal, sa version 2.0 contient un chemin de migration obligatoire pour transiter vers le module du cœur.

Workflows, en passant en version stable, a procédé à quelques derniers changements de fond. Selon votre usage du module (surtout si vous l'utilisez autrement qu'avec Content Moderation), vous devriez consulter le rapport de changement associé pour adapter votre code au nouveau fonctionnement. Si vous utilisez Content Moderation, qui a lui aussi subi son lot d'évolutions, vous devriez jeter un œil à son chemin de mise à jour non officiel qui vous permettra de continuer à vous en servir sans altérer vos données.

Migrate, Migrate Drupal et Migrate Drupal UI continuent leur progression vers le support complet d'un chemin de migration de Drupal 6 ou 7 vers Drupal 8. Par exemple, les champs date et node_reference de Drupal 6 pourront désormais être migrés vers Drupal.

Field Layout, dont nous avons détaillé le fonctionnement lors de la précédente mise à jour, a vu quelques corrections de bug mais pas de changement fondamental. Malgré son intérêt fonctionnel, il ne lui reste plus que quelques mois de période probatoire avant d'être éjecté du cœur pour retourner dans le mode des modules contribués.

Settings Tray et Place Blocks continuent leur progression. Le premier s'offre une version beta et pourrait donc accéder à la stabilité à la prochaine version mineure. Le second, lui, va progressivement disparaître pour être absorbé dans le module Block du cœur lors du passage à la 8.5 si tout se déroule comme prévu.

Évolutions de l'interface

Suite à des tests d'utilisabilité auprès d'un large panel d'utilisateurs finaux, il est apparu que le bouton déroulant était trop déroutant. La décision a donc été prise de revenir à un bouton simple doublé d'une case à cocher pour gérer la publication. Dans le cas de l'utilisation du module Workflows, la case à cocher est remplacée par le widget de gestion des états.

Évolution des boutons de publication de contenu entre Drupal 8.3 et 8.4.

Autre amélioration plus mineure : le choix du fuseau horaire dans le compte utilisateur se fait désormais via un menu déroulant groupé par continent et classé par ordre alphabétique (au lieu du classement par décalage horaire qui était utilisé auparavant).

Amélioration des performances

Afin d'adresser des problèmes de tables de cache grossissant jusqu'à atteindre plusieurs Gigas sur certains projets, une option a été ajoutée pour pouvoir poser une limite, par entrepôt de cache, au nombre d'enregistrements pouvant coexister. Cette limite, fixée par défaut à 5000 entrées, peut être ajustée en fonction des besoins du projet très facilement. Par exemple :

$settings['database_cache_max_rows']['bins']['cache_config'] = 500;

De plus, le temps maximal durant lequel un formulaire est conservé dans le cache avant d'avoir été soumis est désormais également configurable. Par défaut, cette durée est de 6 heures mais sur la plupart des sites, une durée bien plus courte est largement suffisante.

Enfin, parmi les autres améliorations, une réécriture du système de gestion des messages de statut permet une économie d'environ 10% de performances sur les pages qui ne contiennent aucun message.

 

Si vous voulez en savoir plus, vous pouvez lire le résumé complet des modifications apportées par la version 8.4.0 de Drupal sur le site officiel de Drupal.

 

 

Photo de couverture © Dominic Alves, retouchée par Happyculture.

Catégories
Développement
Drupal
Drupal 8
Tags
cache
rétro compatibilité
media
Par Artusamak
Julien Dubois

Rendez-vous au Drupalcamp Lannion à la fin du mois

Rendez-vous au Drupalcamp Lannion à la fin du mois
admin
lun 16/10/2017 - 17:46

null

Corps

Nous tentons de ne jamais manquer une occasion de soutenir la communauté Drupal française, c'est toujours un moment de plaisir et de partage. C'est également un bon prétexte pour nous retrouver au sein de l'équipe et de voyager un peu. Alors si vous aimez ou êtes curieux de Drupal et serez du côté de Lannion du 27 au 29 octobre 2017, venez nous retrouver. L'événement est gratuit pour y participer et vous pourrez profiter d'un super repas pour 15 € si vous réservez dès maintenant.

N'attendez plus !

Logo du DCLannion

 

 

Catégories
Drupal
Tags
drupalcamp
Par Artusamak
Julien Dubois

Formation Drupal 8 : De Drupal 7 à Drupal 8 (Session novembre)

Formation Drupal 8 : De Drupal 7 à Drupal 8 (Session novembre)
admin
lun 02/10/2017 - 12:13

null

Corps

Drupal 8.4.0 approche à très grand pas, sa sortie est prévue dans les semaines qui viennent. Vous êtes toujours entrain de travailler sur des projets Drupal 7 et lorgnez sur Drupal 8 ?

Profitez de notre formation pour sauter le pas. Nous organisons une session du 27 au 29 novembre en inter entreprise à Paris.

Vous pourrez apprendre dans cette formation comment fonctionnent sous Drupal 8 vos habitudes et connaissances Drupal 7. Blocs, menus, champs, formateurs, formulaires, modules, outils, industrialisation, cache sont quelques uns des thèmes couverts au cours de ces 3 jours. La liste complète est à découvrir dans le programme détaillé.

Combien coûte cette formation ? De moins en moins selon le nombre de participants ! Le coût est partagé entre chacun. 3 à 6 personnes peuvent participer à chaque session. Le prix global est de 4 500 € HT, ce qui vous donne une formation de 1 500 à 750 € pour trois jours bien remplis d'informations, de réponses à vos questions et de super déjeuners car bien manger est primordial ! (Et puis nous sommes français quand même...).

Je sens que vous ne pouvez plus résister, correct ? Et bien dans ce cas, je vous invite à nous laisser un message pour que l'on vous réserve une place ou lève les doutes / questions que vous pourriez vous poser !

On vous attend !

Catégories
Drupal
Drupal 7
Drupal 8
Par Artusamak
Julien Dubois

Contourner l'erreur : "The SQL storage cannot change the schema for an existing field"

Contourner l'erreur : "The SQL storage cannot change the schema for an existing field"
admin
mar 11/07/2017 - 09:02

null

Corps

Je vous partage aujourd’hui une astuce qui peut vous épargner de perdre quelques cheveux. Il s’agit de l’erreur suivante :

The SQL storage cannot change the schema for an existing field (field_meta_keywords in taxonomy_term entity) with data.

Cette erreur survient lorsque vous avez créé un champ et que vous avez configuré ses settings, que cette configuration est passée en production et que vos utilisateurs ont créé du contenu qui remplit les données de ce champ.
Il arrive que vous ayez besoin de modifier la configuration de ce champ. Simple me direz-vous ? Et bien non, pas toujours car Drupal ne va pas vous laisser faire (à raison).

Selon le type de champ que vous modifiez, les settings du champ peuvent être utilisés pour créer les colonnes de la table. Avec du contenu dans la table, hors de question de vous laisser faire n’importe quoi au risque de perdre des données. Drupal va donc lever une exception (FieldStorageDefinitionUpdateForbiddenException) qui est assez explicite, pas de mise à jour du stockage du champ lorsque des données sont présentes.

Comment contourner cela ?

Vous pourriez tenter de modifier directement le fichier .yml de configuration de l’instance du champ à la main mais cela ne contournerait pas votre problème, Drupal comprendrait toujours que vous voulez modifier la configuration et vous protégerait contre la perte de vos données.

La seule solution pour cela est de travailler à un plus bas niveau via un hook_update_N() pour faire le changement de configuration. Il faudra travailler directement sur les fonctions de base de données pour manipuler les colonnes.

Voici donc le code qui permet de faire cela :

/**
* Changement du schéma de field_meta_keywords stocké dans la configuration.
*/
function project_social_update_8006() {
  // Augmentation de la longueur max du champ de 255 à 500 caractères.
  try {
    // 1. On vide le cache de la définition des champs pour travailler les mains libres.
    \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();

    // 2. On récupère la définition de notre instance de champ depuis les fichiers de config et on la sauve.
    $storage_definition = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('taxonomy_term')['field_meta_keywords'];
    \Drupal::service('entity.last_installed_schema.repository')->setLastInstalledFieldStorageDefinition($storage_definition);

    // 3. On récupère la définition du champ.
    $field_schema = \Drupal::keyValue('entity.storage_schema.sql')->get('taxonomy_term.field_schema_data.field_meta_keywords');

    // 4. On définit la nouvelle valeur de notre configuration.
    $field_schema['taxonomy_term__field_meta_keywords']['fields']['field_meta_keywords_value']['length'] = 500;
    // 6. On applique notre nouvelle configuration dans le stockage du champ.
    \Drupal::keyValue('entity.storage_schema.sql')->set('taxonomy_term.field_schema_data.field_meta_keywords', $field_schema);
  }
  catch (SchemaException $e) {
    \Drupal::logger('project_social')->error($e->getMessage());
  }
}

La solution a été réalisée suite à ce patch très inspiré de Berdir qui montre la voie de l'implémentation : https://www.drupal.org/node/2641828#comment-10711058

Bien que l'on ait utilisé les fonctions de bas niveau pour faire les modifications, on aura tout de même exporté la configuration dans son état final pour s'assurer que le la longueur du champ de l'exemple est bien définie à 500 caractères. Cela permet de ne pas détecter de diff une fois notre correctif effectué. (L'export YML et la définition en base doivent être raccords).

Il est à noter évidemment que si vous aviez dû faire des modifications plus compliquée du type supprimer une colonne il aurait fallu des étapes supplémentaires pour ne pas perdre des données. Vous saurez maintenant comment vous y prendre.

 

 

Image de couverture par Florent Darraultvia Wikimedia Commons.

Catégories
Développement
Drupal
Drupal 8
Tags
configuration
fatal
Par Artusamak
Julien Dubois

Les nouveautés de Drupal 8.3.0

Les nouveautés de Drupal 8.3.0
admin
jeu 06/04/2017 - 18:30

Depuis le 6 avril 2017 la nouvelle version mineure de Drupal, 8.3.0, est disponible. Bien que de nombreuses initiatives se développent rapidement, le contenu du cœur n'a, cette fois-ci, pas énormément évolué.

null

Corps

Depuis le 6 avril 2017 la nouvelle version mineure de Drupal, 8.3.0, est disponible. Bien que de nombreuses initiatives se développent rapidement, le contenu du cœur n'a, cette fois-ci, pas énormément évolué. Comme pour la sortie de Drupal 8.2.0, cet article vous dévoilera les détails de cette nouvelle mise à jour.

Modules expérimentaux

BigPipe suite et fin

Après un an de développement et de tests, le module expérimental BigPipe est le premier à être reconnu comme stable et à intégrer officiellement le cœur. Celui-ci, dont on vous a déjà parlé à chaque version mineure depuis la 8.1.0, permet d'améliorer l'expérience des utilisateurs en réduisant le temps passé à attendre le chargement de la page en apparence. En effet, il fournit au navigateur du contenu à afficher le plus rapidement possible tout en continuant de calculer l'affichage des zones complexes ou spécifiques à l'utilisateur⋅rice en parallèle.

Particulièrement efficace dans le cadre d'un trafic d'utilisateur⋅rice⋅s connecté⋅e⋅s, BigPipe souffrait d'un défaut lorsqu'il fallait servir une page anonyme pour la première fois, avant même sa mise en cache. Heureusement, ce cas précis se résout maintenant très simplement à l'aide du module Sessionless BigPipe.

Workflows et Content Moderation

Dans le cadre de l'avancement de la Workflow Initiative qui vise à intégrer un système générique de gestion d'états et de transitions dans le cœur, le module Content Moderation a été créé et intégré en tant que module expérimental dans la version 8.2.0. Initialement, ce module ne permettait que de gérer un workflow de publication appliqué aux nœuds. Dans cette nouvelle mouture, tout le code générique concernant la création et l'organisation d'un workflow a été déplacé dans le module Workflow. Le module Content Moderation, lui, ne contient plus que le code spécifique pour gérer le workflow de publication des nœuds et, en bonus, des commentaires.

Avec ce nouveau découpage, de nombreux bugs ont été corrigés et une nouvelle interface d'administration, simplifiée, a été mise en place.

Layout Discovery et Field Layout

D'abord abandonnée lors de la phase de développement initial de Drupal 8, la Layout Initiative refait son entrée dans le cœur à l'initiative des mainteneur⋅euse⋅s de quelques uns des modules les plus utilisés de Drupal 7 : Display Suite, Field Group et Panels. En effet, lors du portage de leurs modules vers Drupal 8, tou⋅te⋅s ont dû commencer à développer le même type d'interface et ils et elles ont rapidement constaté qu'il serait préférable de faire converger leurs besoins communs pour mutualiser le code au sein du cœur. Ainsi est né le module Layout Discovery, qui permet de définir et de manipuler de nouveaux objets de configuration, associés à des templates, les Layouts. Une fois n'est pas coutume, Display Suite en a profité pour se décharger d'une partie de ses fonctionnalités dans le cœur, sous la forme du module Field Layout. Ce dernier permet, comme Display Suite en Drupal 7, d'organiser les champs des entités pour les placer dans diverses zones, définies par le Layout sélectionné.

Bien qu'en alpha, ces deux modules aux fonctionnalités relativement simples remplissent déjà plutôt bien leur office et n'ont à ce jour aucun bug majeur de connu.

Autres modules expérimentaux

Le module Migrate passe enfin en bêta ! Cela signifie que les tâches majeures ont été effectuées et qu'il proposera désormais des chemins de migration d'une version bêta à la suivante si jamais un changement devait casser la compatibilité descendante.

En parallèle, Migrate Drupal et Migrate Drupal UI avancent doucement. La migration de sites Drupal 6 vers Drupal 8 sera bientôt en bêta. Celle de sites Drupal 7 est toujours à la traîne mais c'est normal car les dites Drupal 7 ont encore de beaux jours devant eux.

On a pu également constater de nombreuses améliorations du côté du module Content Moderation pour rendre la modération disponible pour toutes les entités. Attention toutefois, du fait de son statut d'alpha, la version 8.3 ne contient pas de chemin de mise à jour depuis les versions antérieures !

Le module DateTime Range, nécessaire aux modules contribués de calendriers notamment, avance sûrement vers une version stable qui devrait arriver prochainement.

Enfin, les modules Settings Tray, Place Block et Inline Form Errors n'ont pas connu de changements majeurs depuis la dernier version mineure.

Améliorations pour les éditeur⋅rice⋅s

Du côté des créateur⋅rice⋅s de contenus, pas grand chose à se mettre sous la dent si ce n'est la mise à jour de la librairie CKEditor qui fournit l'éditeur de texte riche par défaut de Drupal 8. Celle-ci apporte un nouveau thème visuel, plus léger et moderne, permettant de se concentrer plus sur le contenu. Elle fait désormais également apparaître les raccourcis clavier des différents boutons lorsqu'ils sont survolés avec votre souris, elle s'ajuste automatiquement en hauteur à mesure que vous rédigez du contenu (jusqu'à une taille maximale lui permettant de tenir dans l'écran) et intègre enfin la possibilité de coller du contenu depuis le web ou depuis Word en préservant la mise en page ou en le purifiant (selon le bouton utilisé).

Hormis la mise à jour de l'éditeur, une petite nouveauté pratique fait son apparition dans l'édition rapide du contenu. En effet, les champs de type image permettent désormais de faire glisser une image directement dans le navigateur au lieu de passer par le bouton "Parcourir" (qui reste cependant accessible en cliquant directement sur la zone).

Améliorations pour les "site-builders"

Pour avoir à l'œil son site, Drupal dispose d'une page dans les rapports contenant un récapitulatif de l'état général du site. Cette page, nommée "Tableau de bord d'administration", contient des informations sur le serveur mais aussi sur diverses options de configuration importantes et sur des points d'attention généraux soulevés par le cœur et les modules. Auparavant, cette page était une longue liste de points classés par ordre alphabétique. Désormais, les informations les plus utiles sont mises en avant et sont classées par leur criticité.

Nouveau tableau de bord d'administration mettant en valeur les éléments les plus importants et permettant de savoir d'un coup d'œil rapide si tout va bien sur le site.

D'autres améliorations diverses ont été apportées à l'interface d'administration pour la rendre plus fluide :

  • la liste des vues a été refondue pour être plus homogène avec le reste des listes d'administration, la rendre plus lisible et compacte ;
  • dans toutes les listes d'administration, l'ordre des filtres a été calqué sur l'ordre des colonnes ;
  • les actions "Supprimer" sur les blocs, que ce soit dans la liste de tous les blocs ou dans les liens contextuels, ont été harmonisées pour éviter les mauvaises manipulations (certains liens désactivaient juste le bloc alors que d'autres le supprimaient totalement).

Améliorations pour les développeur⋅euse⋅s

Comme à chaque version mineure, les fonctionnalités liées au webservices ont fait un bond en avant :

Côté architecture et industrialisation, Drupal 8 incite les projets à utiliser le système de gestion de paquets Composer. C'est donc tout naturellement que le packagist de drupal.org a été ajouté au composer.json du cœur, de même que les types de packages drupal-module, drupal-theme, drupal-profile, drupal-drush, drupal-custom-module et drupal-custom-theme ont été ajoutés, permettant à Composer de placer les paquets dans les bons répertoires.

Enfin, côté code et notamment côté standards, la syntaxe de tous les arrays du cœur a été modernisée pour passer à la notation avec crochets. De plus, la majorité des constantes utilisées par le cœur ont été intégrées dans des classes pour éviter le risque de conflit avec des librairies tierces et respecter les bonnes pratiques de la profession.
 

 

Photo de couverture © Mark Robinson, retouchée par Happyculture

Catégories
Drupal
Drupal 8
Tags
expérimentation
module
migration
workflow
administration
layout
Par Artusamak
Julien Dubois

Happyculture aux Drupal Developer Days Séville

Happyculture aux Drupal Developer Days Séville
admin
ven 10/03/2017 - 14:31

Corps

Du 21/03/2017 au 25/03/2017 se tiendra la nouvelle édition des Drupal Dev Days à Séville. Si vous nous suivez, vous savez que nous sommes des fidèles de l'événement puisque nous n'en avons raté aucun depuis leur création ! Milan l'année dernière, Montpellier l'année d'avant...

Cette année l'équipe se rendra au sud de l'Espagne pour retrouver la communauté, débattre des sujets du moment et sprinter pendant la semaine. Nous ne serons pas au grand complet malheureusement pour une raison tout à fait valable mais nous serons tout de même bien présents pour vous permettre d'être bien éveillés tout au long de la semaine grâce à notre package de sponsoring café !

Badge sponsor café pour les DDD 2017

Il reste des places pour vous inscrire, vous pouvez également consulter le programme. Si vous n'avez jamais participé à un événement du genre, c'est toujours une parfaite occasion de rejoindre la communauté et de prendre part aux nombreux sprints.

En espérant vous y voir, n'hésitez pas à venir nous dire coucou sur place.

Catégories
Drupal
Tags
ddd
Par Artusamak
Julien Dubois

Les nouveautés de Drupal 8.2.0

Les nouveautés de Drupal 8.2.0
admin
mar 10/01/2017 - 09:45

Il y a trois mois de cela, le 5 octobre, sortait, à l'heure, la version 8.2.0 de Drupal, apportant une fois encore son lot de correctifs et quelques nouveautés.

null

Corps

Il y a trois mois de cela, le 5 octobre, sortait, à l'heure, la version 8.2.0 de Drupal, apportant une fois encore son lot de correctifs et quelques nouveautés. Comme notre précédent article sur les évolutions de Drupal 8.1.0, cet article s'attardera sur les points essentiels de cette mise à jour "mineure" de notre CMS favori.

Content Moderation

Petit nouveau dans les modules expérimentaux, Content Moderation est issu de la Workflow initiative et pose les bases de la mise en place de workflows dans Drupal. Qu'il s'agisse d'un processus de validation de publication de contenus ou d'un processus de commande sur un site e-commerce, la possibilité d'associer des états à des entités ouvre les portes à de nombreuses fonctionnalités. Content Moderation est un portage éclairé du module Workbench Moderation et est la première pierre qui amènera Drupal à proposer des expériences de publication innovantes comme la possibilité de préparer et prévisualiser l'évolution d'un site complet et pas juste d'une page de contenu.

Contrairement à ce que permettait Workbench Moderation sous Drupal 7, il est désormais possible avec ce module de définir précisément ses propres états et transitions et même de définir plusieurs workflows différents car il est possible de choisir quels états seront accessibles en fonction du type de contenu.

Date Range

Ce module fait revenir dans le cœur une fonctionnalité présente dans le module Date de Drupal 7. Elle consiste, pour un même champ de saisie de date, de permettre la saisie d'une date de début et d'une date de fin. Durant le développement de Drupal 8 et l'intégration de ce module dans le cœur, cette fonctionnalité avait été écartée sous prétexte qu'il suffisait de créer un second champ pour saisir la date de fin. Cependant, au fil du portage des modules exploitant ces données comme le module Calendar, les équipes se sont aperçues que ce choix était problématique et il a donc été décidé de réintégrer cette fonctionnalité dans le cœur pour cette version mineure.

Rien d'incroyable à montrer ici ; le module met à disposition un nouveau type de champ qui affichera deux widgets de saisie de date, respectant la configuration que vous auriez choisie comme pour un champ date classique.

Widget de saisie d'une date de début et de fin.

Outside-in

Il y a quelques mois, Dries, le créateur de Drupal, annoncait sur son blog vouloir moderniser l'expérience des éditeurs et site builders en améliorant la façon dont certains éléments sont administrés. Son billet se focalisait alors sur l'exemple des menus et des blocs qu'il aurait aimé rendre éditables directement via la partie publique du site, comme Drupal 8 le permet déjà pour les contenus via le module Quickedit. Entre le concept, appelé «outside-in», et la réalisation, le saut est immense mais, la communauté ayant bien réagi à cette idée, un groupe s'est organisé pour en planifier la réalisation. La tâche est loin d'être terminée mais cette version 8.2.0 a vu apparaître ses deux premières émanations : les modules Place Block et Settings Tray.

Place Block

Comme son nom l'indique, l'objectif de ce module est de simplifier le placement des blocs dans les régions. Une fois actif, il ajoute un bouton dans la barre d'administration qui permet de faire apparaître les régions existant dans le design et, pour chacune d'elles, d'y insérer un bloc. Une première fenêtre modale permet de choisir quel bloc insérer, et une seconde de le configurer plus finement. Actuellement, le module ne permet pas de déplacer les blocs ni de créer directement un nouveau bloc personnalisé dans les modales. Loin d'être satisfaisant, ce module a tout de même le mérite de poser les bases pour une fonctionnalité qui sera certainement très utile lorsqu'elle sera terminée.

 

Settings Tray

Pour aller plus loin et permettre l'édition des paramètres des blocs présents sur la page, et même parfois de certains paramètres leur étant rattachés, c'est le module Settings Tray qu'il faut activer. Ce dernier donne une nouvelle dimension au bouton "Edit" de la barre d'administration en lui permettant, en plus de faire apparaître les icônes liées aux liens contextuels, de rendre tous les blocs de la page administrable en place. En cliquant sur un bloc, une barre latérale s'ouvre et permet d'éditer directement les options de base comme le titre et parfois plus. Par exemple, les blocs de menus exposeront les éléments présents dans le menu, ainsi que les options d'affichage telles que la profondeur maximale à afficher. Autre exemple, le bloc affichant le nom du site et le logo donne aussi la possibilité de modifier ces informations directement depuis la barre latérale alors qu'elles ne sont habituellement pas du tout exposées au niveau de la configuration des blocs.

 

Autres améliorations diverses

Comme pour la version 8.1.0, cette nouvelle mouture contient des dizaines de corrections et d'améliorations diverses. On peut noter entres autres :

  • le passage du module expérimental Big Pipe d'alpha à bêta ;
  • l'amélioration de l'expérience d'édition par l'activation par défaut des révisions et la normalisation des modales de CKEditor ;
  • et la possibilité de supprimer facilement tous les contenus d'un type d'entité avant de désinstaller le module associé.Interface de désinstallation des modules faisant mention de la possibilité de supprimer tous les contenus liés.

Et pour les développeurs alors ?

Cette nouvelle version a été très orientée vers les web services (et ça continue, si l'on en croit l'actualité). Ainsi, outre le fait qu'il soit désormais plus simple d'utiliser des modes d'affichages pour les commentaires, l'accès REST aux entités de configuration a été amélioré et de nouveaux points d'accès ont été créés pour permettre à un utilisateur de s'authentifier, s'inscrire et se déconnecter. En bonus, la mise en cache des pages 404 et des fils d'Ariane a été améliorée pour éviter de saturer les serveurs sur des sites à fort trafic.

À l'heure où j'écris ces lignes, nous approchons de la bêta de Drupal 8.3.0 qui figera les fonctionnalités ajoutées dans la prochaine mouture et tout ce que l'on peut dire pour le moment c'est que c'est très prometteur ! Rendez-vous après le 5 avril pour faire le point !

 

Crédits : couverture créée par Sacha Chua, modifiée par Happyculture

Catégories
Drupal
Drupal 8
Tags
expérimentation
module
migration
workflow
administration
Par Artusamak
Julien Dubois

Les nouveautés de Drupal 8.1.0

Les nouveautés de Drupal 8.1.0
admin
lun 28/11/2016 - 09:30

Mieux vaut tard que jamais. Avec le nouveau modèle de numérotation des versions de Drupal est apparue la possibilité d'ajouter des fonctionnalités pendant la vie d'une version majeure.

null

Corps

Mieux vaut tard que jamais. Avec le nouveau modèle de numérotation des versions de Drupal est apparue la possibilité d'ajouter des fonctionnalités pendant la vie d'une version majeure. Alors que nous fêtons le premier anniversaire de Drupal 6 et que Drupal 8.1.0 a déjà plus de 6 mois, il est plus que temps de faire le point sur les nouveautés que cette version a apporté pour la plupart sous la forme de modules expérimentaux.

BigPipe

Il y a 8 mois de ça, dans mon article sur l'incroyable cache de Drupal 8, j'évoquais déjà l'existence du module BigPipe, inspiré de la technique inventée par Facebook pour permettre aux utilisateurs de voir un premier rendu de la page, même incomplet, bien plus rapidement et ainsi avoir la sensation que le site se charge plus rapidement. En deux mots, cette technique repose sur le fait de remplacer les parties de la page complexes à calculer par des espaces vides et de les remplacer à la volée après que le contenu principal a été chargé.

La grande nouveauté à propos de ce module est simplement qu'il a été intégré dans le cœur de Drupal et permet donc à tou⋅te⋅s les courageux/ses d'en bénéficier à leurs risques et périls.

Inline Form Errors

Afin de satisfaire les exigences de la norme WCAG en terme d'accessibilité, Drupal a fait le choix de rassembler toutes les erreurs survenues à la soumission d'un formulaire dans un seul message en haut de page. En effet, il est important pour les personnes souffrant de problèmes visuels et utilisant un lecteur d'écran d'avoir un point d'entrée unique pour comprendre pourquoi leur soumission ne s'est pas déroulée comme prévu. Pour les personnes n'ayant pas ce type de problème, l'ergonomie de ce rassemblement de messages laisse à désirer car il est difficile de comprendre le contexte lié aux erreurs.

Avec Inline Form Errors il est désormais possible de proposer des messages ciblés tout en maintenant l'accessibilité. Ce module dispose chaque message à proximité du champ ayant généré l'erreur et utilise la zone centralisée, destinée aux malvoyants, pour afficher un message d'erreur générique pourvu de liens renvoyant vers chaque champ à corriger.

Illustration des différences entre les erreurs sans et avec le module Inline Form Errors

Migrate, Migrate Drupal et  Migrate Drupal UI

Note : Migrate Drupal UI s'appelait à l'origine Drupal Upgrade UI mais a été renommé pour des raisons de cohérence.

L'une des promesses du développement de Drupal 8 était de permettre de simplifier la mise à jour d'un site en Drupal 6 ou 7 vers Drupal 8. Malheureusement, la complexité d'une telle tâche n'a pas permis aux contributeurs de fournir les outils nécessaires à temps pour la sortie de la version stable. Tout d'abord, en lieu et place de l'ancienne méthode de montée de version, il a été décidé de s'appuyer sur le module Migrate, présent dans l'écosystème depuis déjà plusieurs années, en l'étendant pour qu'il soit en mesure de traiter nativement toutes les données nécessaires. 

Avec Drupal 8.1.0, les équipes de développement du cœur ont enfin eu le temps de finaliser une première version de ces outils et de les intégrer. Cette suite de modules sert donc de socle aux équipes de développement et permet même de convertir la configuration et le contenu d'un site très simple sans une ligne de code. En prime, la présence de Migrate dans le cœur permet également de procéder à des imports de contenus venant d'autres sources comme d'un autre CMS ou d'une base de données indépendante. Dans ce dernier cas, on s'appuiera volontiers sur des modules contribués comme Migrate Source CSV, Migrate Plus et Migrate Tools pour aller encore plus loin.

Pour en savoir plus, vous pouvez consulter le replay du webinar sur les problématiques liées à la migration de contenu et à la montée de version que nous avons tenu par deux fois en collaboration avec Kaliop.

Capture d'écran de la page de récapitulatif des capacités de migration pour un projet donné

Autres améliorations diverses

Outre ces quelques modules expérimentaux, le reste des fonctionnalités de Drupal a continué d'évoluer afin de proposer des nouveautés qui, même si elles semblent parfois minuscules, contribuent à se rapprocher des besoins de notre industrie.

Choix de la langue lors de l'installation

Cette fonctionnalité qui devait être présente dès Drupal 8.0.0 avait été désactivée en raison d'un trop grand nombre de bugs. Depuis Drupal 8.1.0 il est donc possible d'installer Drupal directement dans une autre langue que l'anglais, en profitant des traductions de la communauté.

Choix de la langue dans l'éditeur de texte riche

Certains sites jonglent dans une même page entre plusieurs langues. Dans le but de satisfaire aux exigences des normes d'accessibilité, il est important de pouvoir spécifier qu'une partie du contenu est dans une autre langue que la page. Ce nouveau plugin pour l'éditeur de texte riche propose de choisir la langue du texte en cours de frapper via un menu déroulant.

Capture d'écran du sélecteur de langue de l'éditeur de texte riche

Correction orthographique dans l'éditeur de texte riche

Les éditeurs de texte riche étant de petites applications, elles regorgent d'options. Cette modification est l'une des plus petites réalisées dans cette nouvelle version mais son impact est sensible. En 2 lignes de code il s'agit de permettre au navigateur d'accéder au texte inscrit dans l'éditeur pour y appliquer son système de correction orthographique.

Capture d'écran du correcteur orthographique dans l'éditeur de texte riche

Évolutions à destination des développeurs

Bien évidemment, outre les évolutions fonctionnelles, Drupal a aussi beaucoup avancé du point de vue du code et de l'expérience développeur (DX). Voici une petite liste non exhaustive des nouveautés que l'on peut retrouver dans cette version :

 

À suivre avec les nouveautés de la version 8.2.0… dans moins de 6 mois c'est promis ;)

 

Photo de couverture © Frank Taillandier

Catégories
Drupal
Drupal 8
Tags
expérimentation
module
migration
bigpipe
accessibilité
expérience utilisateur
Par Artusamak
Julien Dubois

Alors comme ça t'es développeur ?

Alors comme ça t'es développeur ?
admin
mar 08/11/2016 - 15:39

null

Corps

A chaque fois que l'on démarre une formation, on fait un petit tour de table pour que chacun se présente et nous parle un peu de son expérience. C'est une super occasion de briser la glace et de mettre tout le monde en confiance. Pour moi c'est aussi un bon prétexte pour picorer des bribes d'informations qui me serviront à lancer la conversation par la suite et à rebondir avec mon contenu. Parmi nos pré-requis de formation (et son intitulé) figure la mention "pour développeur Drupal". Oui mais voilà, ça veut dire quoi un développeur Drupal ?

C'est là que les choses se compliquent. Dans chaque société que l'on croise, la fiche de poste du développeur Drupal a un périmètre (très) variable. Je ne suis pas sûr qu'il y ait une bonne réponse parmi tous les cas d'usage mais au final j'ai le sentiment que cela se ressent un peu sur le marché. Les (vrais) développeurs Drupal finissent par être pénalisés car noyés dans la masse. Il en va de même sur la liste des critères de l'expert Drupal.

Regardons cette petite mise en scène qui se déroule il y a 2 ou 3 ans, les deux protagonistes sont Marc, un chef d'agence web et Thomas, un développeur PHP qui a déjà sauvé l'agence plusieurs fois pour des clients clés avec des demandes un peu trop tatillonnes le week-end.

Marc : Hey Thomas, viens me voir une seconde. Tu as vu l'email que je t'ai envoyé il y a cinq minutes ?
Thomas : Hmm, oui ? A propos du site vitrine avec Durpal ?
Marc : Ouais, Drupal, ouais. Le client a demandé à ce que l'on réponde avec et j'aimerais bien que tu te lances dessus pour qu'on se fasse les pieds.
Thomas : OK.

Quelques semaines plus tard, Thomas a réussi à mettre en ligne le projet en un temps record, faisant la fierté de Marc. Nos deux compères se croisent à la machine à café.

Marc : Bravo Thomas pour ta mise en ligne, c'est super. Le client est super content et t'as bien bossé.
Thomas : Merci Marc, content que ça plaise à tout le monde.
Marc : Dis moi, on est entrain de répondre à un plus gros projet avec Sarah d'ici la semaine prochaine et on pense que Drupal fera le job, tu pourras jeter un oeil ? T'es notre expert Drupal maintenant !
Thomas : Je dois mettre en prod MonSuperBoulanger.fr d'ici 10 jours, ça va être compliqué. Il fait quoi votre site ?
Marc : Oh bah les trucs classiques, de la gestion de contenu, un moteur de recherche de ressources, on a de la gestion de groupes et peut être que l'on doit importer les contenus de l'existant.
Thomas : Ah ouais quand même, bon ça devrait le faire alors. J'ai lu que Drupal savait faire ces trucs.

La réponse de l'appel d'offre part, par chance l'agence remporte le projet et voilà Thomas qui par la force des choses enchaine son deuxième projet. D'autres suivront jusqu'à cette fin d'année 2016 où le client historique de la boite souhaite refondre son site. Drupal 8 semble être le candidat idéal pour cette refonte mais Thomas ne connaît pas encore cette nouvelle version. L'esprit éclairé qu'est Marc lui propose alors de participer à la prochaine session de formation à Drupal 8 d'Happyculture.

La session de formation démarre, 4 participants ont répondu présent, Thomas est l'un d'eux et vient son tour de se présenter.

Thomas : Je suis Thomas, 29 ans, développeur Drupal, j'ai commencé Drupal en 2014 et j'ai uniquement fait du Drupal 7. Pour cette formation, j'attends de découvrir les nouveautés de Drupal 8 et de m'imprégner des bonnes pratiques du moment.

Nous y voilà, tous les participants nous racontent plus ou moins la même chose, tout le monde est impatient de découvrir Drupal 8. Lorsque l'on pose quelques questions, ils ont tous fait du développement avec Drupal. Et puis au fur et à mesure que la formation avance, lorsque l'on parle de paramètres de formateurs de champs, de types de champs personnalisés, de contrôleurs dédiés, de handlers de views, de types d'entités personnalisés, de cache etc on se rend compte que très rarement un participant a déjà fait tout (ou une partie de) cela. Alors on s'adapte car l'une des qualités les plus importantes dans la formation c'est la capacité à s'adapter faute de quoi on risquerait de s'emporter. Alors beaucoup de ces participants se présentent comme développeurs mais le sont-ils vraiment ?

Quels profils pour une équipe

Selon moi il y a 3 métiers dans l'écosystème Drupal. Je serai ravi d'en débattre avec vous si votre avis diffère.

Profil 1 : le thémeur

C'est à mon avis, le profil le plus rare sur le marché Drupal. Il s'agit d'une personne qui fait traditionnellement de l'intégration (ou du dév front-end si l'on veut être à la mode) et qui comprend le PHP pour extraire ses variables afin de les faire remonter dans ses .tpl.php si l'on parle de Drupal 7 ou dans les .html.twig si l'on parle de Drupal 8. Sa compétence première c'est l'intégration et le développement n'est pas sa priorité mais elle y porte un intérêt relatif pour comprendre ce qu'il est possible de faire. En cas de besoin, l'équipe aide cette personne à faire ce dont elle a besoin côté PHP.

Table avec des éléments créatifs éparpillés

Profil 2 : le développeur

Le vrai développeur est celui qui va s'appuyer sur les mécanismes d'extensibilité de Drupal pour créer des nouvelles briques si besoin, faire le modèle de données de son projet, concevoir l'application et faire les choix d'architecture. Il va tordre Drupal pour créer les nouveaux modules et modifier les existants afin de faire en sorte que Drupal s'adapte aux demandes du client, on parle aussi souvent de l'écriture de glue code. C'est lui qui est impliqué sur les composants "bas niveau" du site et qui maîtrise les APIs de Drupal.

Photo d'un clavier

Profil 3 : le site builder

Compétence peu répandue, peut être spécifique aux agences Drupal. Le profil de site builder est un profil qui connait extrêmement bien les options avancées, voire cachées, des modules contribués. Il sait quel module utiliser pour quelle situation, il s'appuie sur le travail du développeur pour mettre en oeuvre les nouvelles options exposées par les développeurs. Son arme principale : sa souris. Il clic à tout va à travers les nombreux écrans de Drupal. Si le développeur n'est pas disponible, il finira très souvent par trouver un module qui fait 80% de la fonctionnalité demandée.

Tour Jenga en gros plan

La complémentarité de ces trois profils vous donne une équipe technique robuste et capable de faire efficacement des sites avec Drupal. Hormis le développeur, les deux autres profils cités sont nécessaires et recherchés, n'ayez pas peur de vous revendiquer comme l'un d'entre eux si tel est le cas, vous vous ouvrirez certainement des portes. Beaucoup de personnes rentrent dans le monde de Drupal par le monde du site building (pour ne plus en sortir, rire machiavélique).

Et l'expert Drupal dans tout ça ?

Beaucoup de "développeurs Drupal" que l'on rencontre sont des personnes qui écrivent le glue code mais qui ne vont guère au-delà sans avoir trifouillé les entrailles de Drupal. C'est pour cela que le titre de "développeur drupal" paraît toujours ambitieux lorsque l'on creuse un peu plus. Concernant le titre d'expert Drupal, là... 

Que les choses soient claires, un expert, c'est quelqu'un qui maîtrise son sujet. S'il n'a pas une connaissance avancée du fonctionnement du coeur, de la gestion des performances et de la montée en charge, de comment faire un site multilingue, des mécanismes d'extensibilité, de l'inter-connexion avec des systèmes tiers, d'un peu de sécurité et qu'il n'a pas mélangé cela au cours de plusieurs dizaines de projets. Je pense que le titre d'expert Drupal est usurpé. L'Expert Drupal n'est pas un titre que l'on attribue à celui qui a le plus de projets dans les pattes et qui existe obligatoirement dans une société. Il est tout à fait possible que vous n'en ayez pas à la maison et par respect pour le poste, vous feriez mieux d'en avoir conscience. Si tout le monde s'autoproclame expert, qui l'est vraiment ? Et comment les clients peuvent-ils faire le tri ? Les certifications sont une piste de réponse possible. En attendant, essayons tous d'appeler un chat, un chat.

Catégories
Développement
Drupal
Tags
expert drupal
développeur drupal
thémeur
site builder
Par Artusamak
Julien Dubois

Keynote de Dries – Drupalcon Austin 2014

La keynote que Dries a tenu pour le lancement de la nouvelle édition américaine de la Drupalcon 2014 à Austin se résume à se demander ce que sera le web de demain et comment Drupal pourrait jouer un rôle dans cet écosystème.

Drupalcon Austin 2014C’est une question intéressante à se poser lorsque l’on constate que de plus en plus d’acteurs venus à Drupal commencent à faire marche arrière faute de libertés suffisantes avec Drupal 7 et d’une arrivée très tardive de Drupal 8. S’interroger sur ce à quoi ressemblera le web dans quelques années est une chose, mais s’inquiéter de savoir si Drupal fera partie de ce tableau en est une autre. La réponse est probablement non.

Mais il est intéressant de constater que l’évolution à laquelle on assiste auprès des acteurs du web est que les géants deviennent de plus en plus géants et qu’ils écrasent complètement les nouveaux venus. Il va falloir que les gens acceptent de se rebeller contre ça pour que l’équilibre d’internet ne soit pas en danger.

Il est presque déjà trop tard, Google décide actuellement de ne plus montrer certains sites, qu’en sera-t-il demain lorsqu’il aura aspiré toutes les données de vos sites et les montrera directement dans sa page de recherche sans vous renvoyer le moindre trafic ?

Dries pose cette question et se dit que Drupal pourrait avoir un rôle à jouer en vous permettant d’avoir entre les mains un outil permettant de créer un genre de plateforme riche à partir de laquelle le contenu pourrait être disséminé facilement selon le format dans lequel vous le consommeriez (article sur un PC, billet sur votre téléphone, etc).

Je trouve que cette keynote a le mérite de mettre en lumière ce problème pour lequel nous n’avons pas forcément conscience mais je reste sceptique sur le rôle que Drupal pourra jouer. Le pouvoir réside principalement sur le trafic plus que sur les moyens technologiques à disposition pour formater le contenu et adapter le message au visiteur. Drupal n’a pas d’emprise sur l’acquisition du trafic et l’on peut légitimement se demander comment s’affranchir d’un Google pour faire venir les visiteurs. C’est un acte citoyen de s’interroger sur ce point et sur nos habitudes de consommation, la réponse n’est pas simple mais il faudra accepter de soutenir des petits acteurs prometteurs faute de tous les voir disparaitre les uns après les autres.

La keynote complète :

Par Artusamak
Julien Dubois

Drupal Dev Days Szeged 2014 – Episode 3

Toutes les bonnes choses ont une fin, les Dev Days n’y font pas exception. Après vous avoir raconté ce à quoi j’ai participé au cours de la première journée et de la deuxième journée de la conférence à Szeged, voilà ce que j’ai retenu de ma dernière journée.

Marvin assis devant un micro

Marvin se prépare à donner sa session (c) Mr.TeeCee

The future of media management in Drupal 8

Démarrage de la journée par cette présentation, je suis un peu curieux de savoir ce qu’il se trame pour D8 sachant que je sors d’un projet où nous avons dû gérer des médias. La session est présentée par Janez Urevc, ses slides sont disponibles sur son site. Sauf qu’en fait le chantier n’est pas hyper avancé, des discussions ont lieu depuis Prague mais sont un peu bloquées faute d’accord sur la direction dans laquelle aller. Du coup si des bonnes volontés veulent aider, rejoignez les issues, la conversation doit avancer.

Develop for D8 on D6 and D7

Ensuite direction la présentation de FGM qui a donné son point de vue sur la bascule vers Drupal 8. Il s’appuie sur des expériences passées pour décrire les situations à préférer pour faire du D8 ou non. Tout n’était pas hyper clair pour moi, j’attends ses slides pour résumer sa pensée et donner mon avis. (Il était trop tôt pour moi :)).

Graph databases for D8

Cette session a été la session de la conférence pour moi. J’avais découvert ce qu’étaient les graph databases lors des Human Talks de Paris (rendez-vous tous les deuxième mardi du mois pour venir nous voir) et Peter Arato nous a fait une présentation de Neo4j, une solution en Java, pendant 40 minutes en expliquant les usages que l’on pouvait en tirer. Comme tweeté en sortant de la salle :

Le constat est simple, lorsque vous cherchez à afficher les résultats de requêtes complexes telles que « liste les amis, des amis de mes amis » les bases de données relationnelles ne sont pas compétitives, par design elles ne sont pas faites pour ça. L’idée est donc de stocker les données différemment. Et c’est là que les graph databases apportent leur solution, au lieu de normaliser les entrées en ajoutant des clés pour faire des jointures vous décrivez les relations entre les éléments. Exemple : John / cuisine pour / Lisa, John / habite / Londres, Lisa / habite / San Franciso, John / aime / Lisa. En multipliant les relations entre les objets vous obtenez un réseau de connexions. Le principe suivant est que lorsque vous allez requêter votre base de données vous allez définir un point de départ, décrire les conditions de relations que vous voulez poser, leur profondeur et potentiellement le type de connexions attendues. Exemple : « Trouve moi une fête où il y aura au moins 20 de mes amis proches qui ne connaissent pas mon ex ». C’est très « naturel » comme langage, si vous regardez la syntaxe des requêtes vous verrez que c’est très lisible.
Quel intérêt à utiliser ce genre de base de données ? Non, elles ne remplaceront pas totalement un MySQL pour le moment, l’idée est plutôt de s’appuyer sur ce type de bases pour faire les calculs complexes et laisser MySQL servir la page de détails d’un résultat de recherche par exemple. Les tendances du web sont à la recommandation et à la personnalisation, c’est tout à fait approprié d’avoir un index à côté du site principal à partir duquel on extraira les résultats de ces calculs avancé (à la Solr).
Le niveau d’intégration avec Drupal est très basique, il y a la possibilité d’indexer des données, quelques types de champs sont supportés et il est faisable de requêter depuis une fenêtre le serveur Neo4j sans aller plus loin pour l’instant.
Les slides de Peter sont en ligne, allez y jeter un oeil et intéressez-vous au sujet, vous en entendrez de plus en plus parler, tout comme les bases de données document.

Configuring D8

L’un des nouveaux morceaux très attendus de Drupal 8 est l’intégration dans le core d’un outil pour l’industrialisation, un remplaçant de Features. Un système permettant d’exporter et d’importer de la configuration d’un environnement à un autre. Gabor s’est dévoué pour remplacer Alex Pott souffrant pour la présentation. En gros le meilleur moyen que vous plongiez dans le système est de le manipuler. La page de documentation de l’API de configuration est une lecture obligatoire pour plonger dans ce nouveau morceau. Il a été pensé pour permettre d’éviter les problèmes connus de Features et permettre de facilement générer des diffs, facilement s’interfacer avec le multilinguisme et facilement être déployable.
Il faudra juger à l’usage, mes premiers tests pour le portage de Views Megarow m’ont paru satisfaisants. Sachez que la configuration est stockée sous forme de Yaml maintenant et que le bon vieil adage Don’t hack core est devenu Don’t hack your active config car cela peut faire exploser votre site assez facilement si vous le bidouillez.
Pas de slides à disposition, lisez la page de documentation, vous découvrirez entre autres qu’il y a plusieurs niveaux de configuration, la configuration « simple », que vous stockiez avant via un variable get / set et les configurations « complexes » qui introduisent le concept de config entities.

D8 for real

Dernière présentation de la dernière journée et dernier speaker que j’aime beaucoup, Florian. Il nous partage son point de vue sur l’état de Drupal 8 et ce que l’on peut faire avec dès maintenant. Il dresse un constat de ce qui va évoluer dans nos façons de faire les projets avec un ratio d’utilisation des modules contrib qui devrait baisser comparé à Drupal 7 compte tenu du fait que chaque nouvelle version majeure rend le produit de plus en plus utilisable out of the box.
Mais Florian ne s’arrête pas là, il pointe du doigt le fait qu’avec tous les changements apportés au coeur les modules les plus populaires devraient être réécrits pour profiter de la nouvelle façon dont Drupal fonctionne. Et quitte à réécrire un module, peut être qu’il faut complètement ré-envisager la façon dont on s’en sert. Il s’appuie pour cela sur l’exemple de Panels, avec toutes les technos qui sont apparues ces dernières années, peut être qu’il sera possible de faire un outil répondant à nos besoins d’une façon complètement nouvelle. Ou peut être que l’on n’aura pas besoin de Panels du tout maintenant !
L’important c’est que les gens commencent à se servir de Drupal 8 pour qu’il monte en puissance très vite. Si vous souhaitez être un acteur significatif de l’éco-système il est crucial que vous vous y intéressiez plus tôt que tard. En construisant de vrais projets, en utilisant Drupal 8 pour de vrai, vous identifierez des besoins et proposerez des solutions qui seront peut être les Panels de demain.

Par Artusamak
Julien Dubois

Drupal Dev Days Szeged 2014 – Episode 2

Les Drupal Dev Days ce sont trois jours de conférence, si vous voulez savoir ce qu’il s’est dit précédemment, n’hésitez pas à lire mon compte-rendu de la première journée des Drupal Dev Days Szeged. Voilà ce que j’ai retenu de la deuxième journée.

Drupal Developer Days - J2

Keynote

Pour continuer sur leur lancée, les organisateurs ont proposé une Keynote avec un intervenant de qualité, en l’occurence une intervenante car il s’agissait de Cathy Theys (@YesCT sur drupal.org). Le sujet de sa présentation était à propos de l’organisation de sprints. Cathy est l’une des figures incontournables lorsque l’on parle de sprints, elle a aidé à se former des sprints allant de 10 personnes à plus de 600.

Les messages qu’elle a envoyé lors de son intervention sont assez simples, pour réussir vos sprints les nouveaux arrivants sont la clé. Il y a un cercle vertueux à les mentorer efficacement. Un débutant est impressionné par toute la mécanique du développement du coeur alors prenez le par la main en l’aiguillant vers des issues qui sont à sa portée pour le mettre en confiance. Prenez également le temps de faire du suivi avec ces nouveaux venus pour qu’ils ne soient pas lâchés dans la nature.
La principale difficulté consiste à réussir à « fidéliser » les contributeurs, trop souvent ils viennent aider pendant 1 ou 2 jours puis repartent dans la nature. Si vos sprints sont bien gérés, vos mentors vont prendre soins de ces nouveaux arrivants et pourront petit à petit les aider à devenir eux même mentors.
Être mentor n’est pas une mission réservée à une élite, si vous avez appris à faire une chose vous pouvez la réapprendre tout de suite à quelqu’un d’autre (et vous devenez alors son mentor). Les mentors peuvent ne pas savoir et vont vous transmettre leur approche pour trouver des réponses « voilà comment je m’y prendrais pour chercher », « j’irais parler à cette personne pour lui demander son avis », etc.
C’est grâce à l’envie de partager que la communauté fonctionne et que les sprints prennent chaque année un peu plus d’ampleur. Ne soyez donc pas effrayés et tentez de proposer un coup de main autour de vous en organisant vos sprints. Même si les gens ne viennent pas en masse la première fois, martelez vos messages, continuez de laisser une porte ouverte pour permettre aux plus timides de sauter le pas et la sauce prendra autour des sprints.
Par ici pour lire ses slides.

Building really fast websites with D8

Ma première session de la journée a été celle de Wim Leers, il y a parlé des performances de notre cher Drupal et de comment l’on pouvait les améliorer. La session était principalement orientée autour des problématiques de cache et bien entendu des problèmes d’invalidation de cache (l’un des deux sujets les plus compliqués en informatique avec le nommage des choses). L’un des principaux problèmes du cache généré par D7 est que le markup de certains éléments comme les liens contextuels, ou l’affichage d’un drapeau « nouveau contenu » change d’un utilisateur à l’autre, obligeant à générer autant de variantes d’un même cache. Changer de technique pour cacher ces données est donc une piste qui a été suivie, l’idée consiste à générer la même base de markup pour tous et d’injecter des placeholders qui sont remplacés à la volée pour chaque utilisateur. Cela coûte quelques requêtes supplémentaire par page mais cela est beaucoup plus bénéfique dans son ensemble. S’appuyer sur des techniques comme le localStorage / sessionStorage (stockage de données côté client plutôt dans une base de données) fait aussi parti des nouvelles façons de faire qui permettent de rendre la gestion du cache plus maligne.
Dans Drupal 7, il était impossible de savoir quels caches invalider lorsqu’un contenu était mis à jour, il y avait le cache du rendu direct de l’entité mais peut être aussi des rules ou des pages de listing à invalider. Difficile donc de savoir qu’est ce qui était utilisé où.
Il a donc été décidé d’ajouter des tags aux bins de cache, permettant ainsi de tagger un élément avec un node id, un user id ou un type de contenu (mais pas que), de cette façon lorsque vous allez invalider un cache, vous allez invalider un tag « je veux vider tous les caches qui sont liés au node 2254″. Imbattable comme technique pour améliorer la finesse des invalidations !
La présentation était vraiment intéressante, vous pouvez consulter les slides de Wim sur son site.

D8 plugin system

Un des gros morceaux de Drupal 8 a été présenté par Aspilicious. Le système de plugin de Drupal 8 pourrait être présenté de plein de façons différentes et avec des degrés de profondeur plus ou moins importants. Je vais me contenter de vous en faire la description qui me parait la plus pertinante.
Le système de plugin se base sur le principe des annotations introduit par un composant de Symfony. Les annotations sont des commentaires autour des classes qui suivent une structure bien définie et qui permettent au système d’étendre les composants de votre application. C’est ni plus ni moins que l’équivalent de vos hook_info_*() dans Drupal 7.
Le système de plugins en lui même est la possibilité qu’il vous est donnée de créer vos propres composants, vos propres hook_info(). Jetez un oeil aux slides, Aspilicious a pris le temps d’introduire tous les concepts de la plugin API par une suite d’exemples de plus en plus complexes.

Themer VS Coder

Moment de légèreté de la journée, Campbell et Adam, développeur pour l’un et thémeur pour l’autre, sont partis d’une base de wireframe de site et se sont donné comme mission de s’approcher de la mise en page demandée au plus près en partant d’un site Drupal avec des contenus déjà saisis et un peu de configuration faite.
Après 15 minutes chacun, on se rend compte que certaines choses sont faciles à faire pour l’un des deux mais plus compliquées pour l’autre (et inversement).
La conclusion de leur démo (où ils arrivent presque tous les deux au résultat demandé) est que tous les corps de métier doivent collaborer car leurs compétences sont complémentaires.

Get ready for fully translated sites with Entity Translation

Schnitzel impliqué dans l’équipe multilingue qui travaille sur Drupal 8 a présenté l’état de l’art des traductions pour Drupal 7. Il n’est pas toujours simple de choisir sa stratégie de traduction de contenu mais ça l’est un peu si vous lisez les slides de la présentation. Michael a montré comment utiliser Entity Translation et comment basculer vers ce module si précédemment vous utilisiez content translation ou field translation. Ce module est une référence et a été utilisé dans la nouvelle version majeure de Drupal. Ses slides sont en ligne (attention aux allergiques, beaucoup de chatons dans les slides !)

Care for your backoffice

Cette dernière présentation de la journée est celle que Guillaume et moi avons donné, les slides sont ci-dessous. Pendant cette présentation nous avons listé les conseils et modules que vous pouvez utiliser pour améliorer vos backoffice. Des utilisateurs passent des heures à se servir de ces interfaces, optimisez les, profitez de modules disponibles côté contrib pour rendre vos backoffices plus utilisables et si vous avez de bonnes idées, contribuez les !

Lire le compte-rendu de la troisième journée.

Par Artusamak
Julien Dubois

Drupal Dev Days Szeged 2014 – Episode 1

Voilà que la première journée de conférence des Drupal Dev Days 2014 se termine.  Moins d’un an après l’édition de Dublin, la communauté des développeurs Drupal se retrouve à Szeged (Hongrie) pour son rendez-vous préféré.

Photo de groupe pour les Drupal Dev Days 2014 à Szeged (Par mr.TeeCee)

Photo de groupe pour les Drupal Dev Days 2014 à Szeged (Par mr.TeeCee)

La conférence se déroule sur toute la semaine avec depuis lundi (et même dimanche soir) des journées de sprint. L’idée est de profiter de ces moments ensemble pour faire plusieurs choses : aider des nouveaux contributeurs à mettre le pied à l’étrier (presque 2 000 contributeurs déjà impliqués pour Drupal 8), échanger de vive voix entre contributeurs core afin de débloquer certains points, ou tout simplement découvrir Drupal 8.
Les sujets sont divers et variés, on y trouve par exemple du débuggage pour le site drupal.org, la gestion du multilinguisme, le thèming autour de Twig, la résolution des beta blockers, etc.

Keynote

A propos du contenu, le coup d’envoi de la journée a été donné par Jam lors d’une keynote dédiée à Drupal 8, il  a profité de sa tribune pour rendre hommage aux contributeurs déjà impliqués et a invité les nouveaux venus à s’impliquer également. Il y a du travail pour tous les niveaux et si vous ne savez pas à qui parler la technique qu’il a recommandé est très bonne : « Vous tendez votre bras et pointez votre doigt devant vous, vous fermez les yeux et faites trois tours sur vous même. En rouvrant les yeux vous parlez à la personne que pointe votre doigt et lui demandez comment contribuer, il y a de fortes chances qu’elle sache vous dire quoi faire ou vers qui vous tourner. »

Entity API pour Drupal 8

Après cette keynote Fago a pris le relai pour présenter entity API pour Drupal 8. Quoi de neuf au programme ? L’entity API dans sa version pour Drupal 7 n’était pas terminée, elle a donc été unifiée, réécrite, optimisée.
Changement le plus notable, les propriétés et les champs sont maintenant tous des champs. Ils sont respectivement des base fields et des bundle fields. Cela signifique que manipuler des propriétés ou des champs se fera de façon transparente, les mêmes méthodes pourront être appelées. Autre bénéfice, on peut donc maintenant appliquer des formateurs et des widgets aux base fields (anciennement appelés propriétés) et c’est une très bonne nouvelle !
Obtenir des informations sur le modèle des données se résume à appeler une simple méthode là où avant il fallait appeler un hook_entity_info() et faire pas mal de navigation au sein du tableau de données retourné.
J’ai aimé ses explications sur la validation API qui prend tout son sens lorsque vous faites du REST, vous ne pouvez pas valider vos données comme si un formulaire venait d’être soumis, il vous faut donc vous appuyer sur une autre logique de validation, et c’est là que la validation API entre en jeu.
Prenez le temps de parcourir les slides, il y a beaucoup d’informations très intéressantes, on y parle du stockage, de la façon de définir de nouveaux types d’entités, de contrôle d’accès etc.

Point sur les initiatives non officielles

Pour la deuxième session de la journée, je suis allé voir Pedro nous partager ce qu’il se passe du côté des initiatives « non officielles » pour Drupal 8. Il s’agit de changements plus ou moins grands portés par quelques individus qui continuent de rendre Drupal meilleur. En vrac, il a parlé de WYSIWYG, Twig, Menus comme entités, de l’introduction des form modes (yay \o/), de la nouvelle façon de faire la migration et de plein d’autres sujets. Jetez un oeil à ses slides elles valent le coup et vous découvrirez sûrement pas mal de nouveautés pour Drupal 8.

D8: Fields reborn

A la reprise des sessions suite  à la pause déjeuner, Swentel a donné sa présentation sur le nouveau fonctionnement des champs pour Drupal 8. Le sujet a été rapidement évoqué par Fago dans sa session sur Entity API mais Kristof est allé plus loin. Il y a beaucoup de choses spécifiques détaillées dans ses slides et il sera bien plus intéressant pour vous de les consulter.

Cracking Drupal

La bonne surprise de la journée a été la présentation de Klausi sur la sécurité. Je m’attendais en rentrant dans la salle à écouter encore une session sur la sécurité qui était abstraite et pas vraiment appliquée à Drupal et ça n’a pas été le cas du coup. Klausi a pris le temps de vulgariser les principales failles de sécurités identifiées sur les sites et de faire un parallèle pour Drupal avec des exemples concrets.

Drupal and Scrum from the trenches

Cette session a été plus particulière, je n’y ai pas assisté, je l’ai donnée avec Guillaume. Nous avons partagé nos retours d’expériences sur Drupal et Scrum, vous pouvez accéder aux slides de notre présentation « Drupal and Scrum from the trenches » pour lire ce que nous avons présenté.

JS Pulp Fiction

Pour terminer les sessions de ce jour 1, direction la salle principale pour écouter nod_ nous parler de Pulp Fiction et de l’état de Javascript dans Drupal 8. Ses messages étaient autour des bonnes pratiques, de la nouvelle façon de travailler avec Javascript et de l’avenir potentiel du sujet.

La suite demain après une courte nuit de sommeil !

Lire le compte-rendu de la deuxième journée et de la troisième journée.

Par Artusamak
Julien Dubois

Happyculture : Le premier jour du reste de ta vie

Il arrive que certains matins lorsque vous posez vos pieds hors de votre lit encore chaud la journée qui débute n’ait rien à voir avec les précédentes.
Il y a quelques semaines j’ai vécu cette expérience car j’ai vécu mon premier jour « post Commerce Guys ».
Se lever et ne pas se rendre au bureau, lorsque tu l’as fait pendant les 4 années précédentes sans vraiment te poser de question ça fait un peu bizarre.

Source : Todd Klassy > http://www.flickr.com/photos/latitudes/513503159/

Source : Todd Klassy > http://www.flickr.com/photos/latitudes/513503159/


Mais pourquoi les choses se sont elles arrêtées ?

Et bien parfois lorsque vous avez des convictions il faut avoir le courage de les assumer, le projet d’entreprise ne me séduisait plus et ma volonté de travailler « en famille » n’était plus satisfaite.

Je ne pars pas fâché, au cours de mes 4 ans au sein de Commerce Guys j’ai eu l’occasion d’apprendre et d’expérimenter beaucoup de choses, j’y ai rencontré beaucoup de personnes et la principale raison pour laquelle j’étais motivé de venir bosser étant justement de retrouver cette équipe. Mon départ n’est pas un soulagement comme si j’étais débarrassé d’un poids mais une page qui se tourne, je leur souhaite bon vent, je vais laisser quelques places vacantes (oui, être boulimique de travail c’est mal).

Alors à quoi va ressembler l’avenir ? C’est la vraie bonne question !

Il y a plus d’un an déjà je me souviens avoir eu une discussion au bord d’une piscine avec Guillaume lui demandant à moitié sérieusement quand est ce qu’il quittait sa boite, sa réponse n’ayant pas été un « jamais » ferme nous avons échangé sur la vision que nous avions du travail et de l’entreprise idéale. Plusieurs termes sont revenus au cours de cette discussion et notamment « différent », « Drupal » (quand même) et « agile ».
Le séjour se terminant, chacun est retourné à ses occupations puis quelques semaines plus tard l’idée ayant continué de germer nous avons fini par nous dire « et si on le faisait vraiment ? ».
Pensant que 3 valent mieux que 2, mon fidèle compagnon Nicolas est déjà informé du plan machiavélique qui se prépare.
Se glisse donc dans nos agendas respectifs un créneau hebdomadaire dédié à mieux définir ce projet.

Les semaines passent et le projet s’affine, vient le moment fatidique où les démissions doivent être posées. Guillaume saute le pas avant nous, profite de la vie de papa au foyer un bon mois puis Nicolas et moi le rejoignons. L’aventure Happyculture est maintenant lancée.

Mais c’est quoi ce projet ?

Et bien c’est assez simple, chez Happyculture nous pensons qu’il est possible de faire évoluer le marché, nous sommes convaincus que les jours des projets en cycle en V sont comptés pour la majorité des projets et nous souhaitons ouvrir les yeux des clients pour leur expliquer en quoi l’agile est dans leur intérêt et dans le nôtre. En ayant plus de maîtrise sur les projets le livrable final sera de meilleure qualité.
Nous allons donc continuer à faire ce que nous faisions dans nos boites respectives, faire des projets pour garder la main, se creuser les méninges sur de l’expertise et du consulting et former les équipes à Drupal et aux méthodes agiles.
Nous souhaitons aider le marché à progresser en montrant comment vendre les méthodes agiles, en éduquant les équipes de développement aux bonnes pratiques de Drupal, en montrant ce que signifie travailler en agile. L’accompagnement plutôt que de la formation « classique » se prête à merveille à l’exercice, permettant de voir les équipes grandir plutôt que de n’échanger avec elles qu’une seule fois.

Et puis quitte à créer notre boite autant la faire différente, vous connaissez les Scop ? Bah oui, les Scop quoi. Si non, regardez cette vidéo.

On ne sait pas pour vous, mais nous ça nous excite de changer un peu le paradigme actuel !

Et puis franchement, on ne veut vraiment pas faire comme tout le monde alors comme le nom « Happyculture » n’était pas assez, on a choisi de se donner comme mission d’être un laboratoire d’expérimentations des pratiques à épanouir les gens. Et ça c’est une sacrée mission. Qu’est ce que ça signifie ? Simplement que l’on préfèrera les projets qui seront d’utilité publique ou qui nous évoqueront vraiment quelque chose plutôt que certains projets parfois un peu fades. Pendant ces projets nous ferons notre possible pour nous appuyer sur des outils / pratiques qui permettent de satisfaire tout le monde, même si ça n’est parfois pas la solution de la rentabilité, nous cherchons à construire des partenariats plutôt qu’une expérience mercantile approximative.
Et puis si l’on peut travailler avec les copains on essaiera de le faire au maximum.

Happyculture relaiera « les initiatives qui rendent les gens heureux » alors si vous avez des suggestions, n’hésitez pas, il n’est pas nécessaire que cela soit lié au web ou à Drupal.

L’avenir s’annonce excitant, nous avons hâte de pouvoir rendre service à nos clients et de vous croiser lors des prochains événements pour vous parler du projet si vous êtes curieux. Si le projet vous inspire et que vous souhaitez collaborer avec nous, rendez-vous sur le site d’Happyculture pour que nous rentrions en contact.

PS : Le cordonnier étant toujours le plus mal chaussé, nous nous occuperons du site un peu plus tard, nous terminons les papiers de création pour le moment.

Par Artusamak
Julien Dubois

Expérimentation : Génération de rapport de traduction

La semaine qui vient de s’écouler a été une semaine « hors du temps », plusieurs développeurs et moi-même avons eut le hasard de nous retrouver en même temps sans projet. La décision a donc été prise de profiter de cette opportunité pour en tirer quelque chose, nom de code : « Zamak experiment week ».
L’objectif ? Trouver un projet à accomplir sur la techno et le sujet de notre choix. En vrac les idées qui ont émergé ont été : du social commerce, un lecteur de musique collaboratif, un bot de générateur de rapports de traduction et un bot d’alertes (vocales ou lumineuses). Silex, Angular JS, Raspberry pi, Twitter & Facebook API et Herokuapp étaient de la partie.
De mon côté, j’ai réussi à enrôler un autre développeur pour donner vie à une idée de l’équipe de traduction française.

 

Source : http://www.flickr.com/photos/valdemarne/7465763444/

Source : http://www.flickr.com/photos/valdemarne/7465763444/

Lorsque les traducteurs doivent convertir les chaînes dans la langue de Molière, ils se retrouvent assez fréquemment à devoir traduire des chaînes très similaires car les mainteneurs n’ont pas de vision globale des chaînes utilisées dans leur module. Seuls les traducteurs se rendent compte de ce problème. Le souhait a logiquement été émis de trouver un moyen de remonter ces problèmes aux mainteneurs. La semaine serait donc réussie si nous réussissions à donner vie à ce projet.

Page d'accueil

Aperçu du projet

Une façon d’y parvenir consiste à le faire tourner régulièrement sur la liste des modules publiés extraite du FTP de d.o (attention chargement très long) pour fournir tous les mois un rapport de traduction au mainteneur de chaque module. Si l’on parse quelques modules deux scénarios s’offrent à nous, le premier (et le meilleur) aucune chaîne ne fait doublon, le mainteneur gagne des points de karma auprès des traducteurs. Le second, des chaînes font doublons, le mainteneur doit voir s’il peut s’améliorer.

Résultat de l'analyse de 5 modules

Résultat de l’analyse de 5 modules

La liste des doublons est établie selon plusieurs critères, bien entendu plus la chaîne est longue plus l’analyse est pertinente. Deux méthodes sont employées pour faire l’analyse : la première est la similarité (le nombre de caractères identiques entre deux chaînes) et la seconde est basée sur la prononciation des deux chaînes. Les chaînes de moins de 4 caractères sont en revanche ignorées. Le rapport généré ressemble à cela :

Rapport de l'analyse d'un module

Rapport de l’analyse d’un module

La dernière fonctionnalité (probablement la plus intéressante à date) est que l’on peut publier une issue dans l’issue queue du module de façon automatique, de cette façon ce script tourne sur un serveur et le mainteneur est alerté du résultat de l’analyse de son module directement à la source.

Rapports sur Drupal.org

Rapports sur Drupal.org

Quelles sont les prochaines étapes de cette expérience ? Tout d’abord les sources de ce projet son publiques, vous êtes les bienvenus pour y contribuer et pour l’améliorer, le README contient quelques suggestions d’améliorations et la liste n’est pas exhaustive. On compte à minima la discussion avec les administrateurs de l’infrastructure de d.o de la fréquence de passage du bot et d’un moyen plus simple de récupérer la liste des projets afin de rendre le projet accessible en ligne. Les mainteneurs devraient également être en mesure de dire si un doublon identifié a du sens ou non afin qu’il ne leur soit plus présenté. On pourra également lier une base de données au projet afin de stocker les rapports pour ne pas les regénérer à l’infini.
Notez que je ne prévois pas spécialement de maintenir le projet de mon côté, si vous souhaitez le voir continuer, impliquez-vous !

Ce projet a en tous cas été l’occasion de mettre en pratique sur un cycle court de l’agilité, MVP, itérations, daily scrums, refactoring ont étés un fil rouge très intéressant. Ça a été pour moi aussi l’occasion de re-goûter à la POO, j’ai expérimenté Silex, Twig et l’API de config, une belle excuse pour doucement basculer vers D8 en douceur.
Je vous recommande vivement d’essayer de mettre en place ce genre d’atelier chez vous, les gens aiment se challenger, ils manquent seulement de prétextes pour le faire.

Et un dernier mot pour dire merci à Maciej qui s’est occupé de la partie algo, parsing et publication du rapport !

Par Artusamak
Julien Dubois

Retour d’expérience : Drupal et les besoins métier

Il y a parfois certains projets qui vous marquent plus que d’autres et il y en a certains dont vous vous souviendrez toute votre carrière. Le sujet de ce billet fait référence à l’un de ces projets.

J’ai eut l’occasion de passer 18 mois en tant que lead développeur sur un projet métier pour un joailler de luxe. Ce projet était démesuré à bien des niveaux à commencer par son périmètre mais aussi sa taille d’équipe. Une vingtaine de personnes étaient potentiellement amenées à contribuer du code en même temps et la politique du projet était de tout passer à la loupe de la revue de code. Autant dire que ça n’a pas toujours été simple.

Source : http://www.sxc.hu/photo/1406895

Source : http://www.sxc.hu/photo/1406895

Parler plus longuement de ce projet et des leçons à en tirer pourra faire l’occasion d’un billet dédié, mon objectif ici est de partager avec vous le retour d’expérience que nous en avons extrait avec Laurent Chardin, directeur technique de Publicis Modem. Nous avons préparé une session présentée lors du Drupalcamp Paris 2013 au cours de laquelle nous avons montré un fragment des briques que nous avons conçu pour le projet.

Lorsque l’on est expert Drupal, travailler sur de grands projets est l’occasion de chercher à résoudre des problématiques à la mode Drupal à savoir en construisant de nouvelles briques extensibles et réutilisables. Ce projet démarré entre autre par Damien Tournoud a donné vie aux modules Entity Reference, Views Megarow, Entity Override, Migrate remote et à bien d’autres idées qui ont fait leur bout de chemin telle que les form modes qui ont été intégrés au cœur de Drupal 8 grâce à Andrei Amateescu (*dev content*).

Nous avons donc tenté de vous présenter en 45 minutes quelques uns des modules que nous avons développé et avons listé des conseils que nous vous recommandons de mettre en œuvre lorsque vous construisez un backoffice pour vos clients. Le front est toujours très important mais il ne faut pas négliger vos utilisateurs de backoffice, ils passent parfois (souvent) plus de temps à utiliser l’application que les utilisateurs finaux alors ne les délaissez pas ! Vous avez beaucoup d’outils à disposition pour cela aussi avec Drupal core (et notamment ses types d’entités) mais aussi via l’univers de la contrib : vous pouvez créer des vues, calculer des données, créer des groupes d’actions pré-déterminées, etc dans le but de faire gagner du temps à vos utilisateurs. Si en plus de cela vous invitez ces utilisateurs lors de démonstrations régulières (comme Scrum le propose, cf ma présentation de Scrum) vous pourrez intégrer leur avis et les aider à adopter votre travail encore plus vite.

N’hésitez pas à réagir à cette présentation au travers des commentaires, je me ferai un plaisir de vous répondre.

LIBEREZ DRUPAL ! Exploitez les concepts Drupal et magnifiez votre backend !

Par Artusamak
Julien Dubois

Scrum et Drupal, ça vous dit ?

Certains d’entre vous le savent peut être mais j’ai croisé la route de l’agilité il y a quelques années et continue de m’y intéresser en multipliant les lectures et en mettant en application cette philosophie.

Après avoir pris un peu de recul et multiplié les expériences avec l’agilité et Scrum en particulier j’ai décidé de soumettre une présentation au titre aguicheur (« Agilité : En quoi SCRUM et Drupal sont faits pour s’entendre ») au Drupalcamp Paris afin de présenter l’agilité (et Scrum en particulier) à mes homologues Drupaliens.
Le but de la session était plutôt de présenter Scrum que de parler de Drupal mais j’ai quand même pris le temps de montrer en quoi Drupal s’intégrait particulièrement bien avec Scrum.

Curieux d’en savoir plus ? Voici la vidéo de la présentation et les slides qui vont avec. N’hésitez pas à laisser un commentaire si vous avez aimé, détesté ou si vous pensez que des modifications mériteraient d’être apportées à la présentation.

L’ensemble des présentations ont été filmées ou enregistrée, je vous invite à consulter le super programme pour retrouver le détail des présentations.

J’en profite également pour dire un grand bravo à l’équipe d’organisation qui a beaucoup bossé pour faire de cette conférence un bel événement, avec un bravo particulier à Anne-sophie Picot (asplamagnifique) ainsi que mon cher et tendre quasi homonyme Julien Dubreuil (Julien_D).

En quoi Scrum et Drupal sont faits pour s’entendre (vidéo)

En quoi Scrum et Drupal sont faits pour s’entendre (slides) – Drupalcamp Paris 2013

Par Artusamak
Julien Dubois

Drupalcon Portland 2013 – L’état de Drupal – Dries Buytaert

Voici un résumé de ce qu’il s’est dit durant l’édition 2013 de la Keynote de Dries « State of Drupal ».

3500 participants  sont annoncés pour cette nouvelle édition à Portland, « la plus grande Drupalcon jamais organisée », on rajoute 50 personnes à chaque édition comme ça on continue de faire péter les scores !

Petit rappel « historique », Drupal se porte bien, des références comme NBC, la Maison Blanche, l’Université de standford sont fièrement propulsées par Drupal. Qui aurait cru à ça si l’on en avait parlé il y a encore quelques années ?

Dries partage un concept avec nous, celui du « do well, do good », (« pour bien s’en sortir, faisons de bonnes choses »).
L’essor de Drupal ne ralentit pas et continu à être de plus en plus utilisé par les ONG et les gouvernements, une très bonne illustration de l’évolution des mentalités est celui de la maison blanche qui s’est mise à contribuer du code et à ouvrir des APIs  (la Read API et bientôt Write API dédiées aux pétitions). Vous avez probablement entendu parler de cette initiative sans le savoir, c’était il y a quelques mois, une pétition proposait de construire l’étoile de la mort et les équipes de la maison blanche avaient pris le temps de rédiger une réponse à la demande non sans humour.
Ce genre d’initiative est sans conteste la preuve que les gouvernements évoluent et se mettent de plus en plus à communiquer avec les citoyens, le digital est au cœur de tous les métiers même celui de gouverner.

Source : https://twitter.com/drupalcon/status/336922901783654400

Source : https://twitter.com/drupalcon/status/336922901783654400

Le bon contenu, au bon bon endroit, au bon moment

Lorsque l’on cherche à bien faire les choses, il est plus efficace d’adapter le discours à la personne qui le reçoit, en regard du moment auquel elle le reçoit et de lui proposer de la bonne façon. Amazon et Netfix en sont deux parfaits exemples, souvent cités, ces deux sociétés ont construit un service basé sur la recommandation. Proposer le bon produit à l’utilisateur en se basant sur ses expériences passées et en les croisant avec le parcours de tous les autres utilisateurs assure une qualité de service.
C’est l’art d’offrir le bon contenu au bon moment en contextualisant la navigation.

Un autre exemple de la contextualisation de l’expérience de navigation est celle de deux liens de SEM pour des compagnies aériennes remontant suite à une recherche « vol pour londres », notre cher ami Big Brother (aussi connu sous le nom de Google) sait déjà que Dries se trouve à Boston et qu’il souhaite se rendre à Londres, en s’appuyant sur ces données, le premier site pré-sélectionne Londres comme ville de destination et Boston en ville de départ là où le second n’offre qu’un formulaire vide.
Contextualiser l’expérience de navigation c’est améliorer l’engagement vers l’utilisateur, la contextualisation peut se faire via la géolocalisation, le croisement des parcours utilisateurs, le périphérique par lequel il accède au contenu, l’heure à laquelle il le fait, la saison durant laquelle il navigue ou bien d’autres critères.

Mais quid de Drupal dans cette histoire ? Aujourd’hui si l’on prend les deux premiers liens naturels d’une recherche « Drupal gouvernement » on tombe d’abord sur une page de Groups.drupal.org recensant les pays / états utilisant Drupal pour leur site (pas trop mal) et la page d’accueil de Drupal… non contextualisée, pas très utile. Dries montre quelques créas où l’on pourrait voir à la place du contenu lié aux gouvernements puis explique que si l’on identifiait que l’utilisateur est un développeur ou un décideur on pourrait également adapter le contenu affiché ou bien le traduire s’il venait d’un autre pays.

Mais comment offrir cette expérience contextualisée dans Drupal ?

L’expérience ne se limite pas seulement au CMS, l’acquisition commence via différents moyens, le  SEO, l’e-mailing, les réseaux sociaux, l’objectif est ensuite de segmenter ces visiteurs pour ensuite convertir pour de l’e-commerce, pour votre CRM,  pour de la personnalisation. L’idée étant par la suite d’analyser leur comportement grâce à l’analytique, votre CRM ou des outils d’automatisation marketing afin de continuer à peaufiner et optimiser leur expérience.
D’après une étude de Forrester, le CMS est jugé par des marketeux comme étant le meilleur outil pour faire du CRM par 6% d’entre eux, 8% pour du e-commerce, 9% pour de la personnalisation et 11% de l’analytique. Ces évaluations sont basées sur des CMS proriétaires, il y a donc de la place pour Drupal.
Selon la même étude, lorsque la cible est interrogée sur la question « Quelle fonctionnalité aimeriez-vous voir intégrer dans votre CMS ? » la réponse est à 35% : « aucune, nous préfèrerions avoir un le meilleur outil de sa catégorie à la place » signifiant qu’un seul outil ne semble pas adapté pour répondre à tous les besoins mais qu’un outil spécialisé par segment fonctionnel parait plus adapté.
Toujours selon cette étude, 70% des sondés trouvent que l’intégration pour le mobile n’est pas optimale. Le responsive design est une fonctionnalité plébiscitée par 33% des votants et 43% d’entre eux aimeraient que l’expérience de rédaction de contenu soit facilitée.

Aujourd’hui les solutions propriétaires affirment avoir la réponse à ces besoins identifiés. Drupal n’est cependant pas sans réponse face à ces besoins, afin d’offrir une expérience contextualisée des sociétés se sont créées sur chaque segment cité précédemment (CRM, E-commerce, automatisation marketing…) mais ça n’est pas la seule solution, nous pouvons aussi nous appuyer sur des services déjà existants et embarquer leur savoir-faire dans les sites Drupal via des connecteurs. A l’heure actuelle les connecteurs n’utilisent qu’une partie infime des possibilités de ces services, continuer à les enrichir est une des pistes à explorer. En continuant à améliorer le core de Drupal, nous réussirons également à fournir une meilleure expérience dès la fin de l’installation et cela grâce aux nouvelles fonctionnalités de Drupal.

Drupal 8

En vrac des tonnes d’améliorations du côté de :

  • l’installeur a été amélioré pour être personnalisable, vous pouvez installer votre site directement dans la langue de votre choix.
  • la rédaction de contenu a été enrichie, un WYSIWYG est (enfin !) disponible par défaut, la structure des pages d’édition de contenu a été refondue, le copier-coller depuis Word est géré, des amélioration ont été apportées au niveau de la gestion des workflows, l’aperçu du contenu a été refondu (génial !) et le contenu est maintenant éditable en ligne (sans avoir à passer par une page d’édtion) ainsi que les blocs ou les vues.
  • les sites multilingues continuent de s’améliorer avec la possibilité de directement importer des traductions depuis le serveur centralisé, vous pouvez directement contribuer vos traductions depuis le backoffice de votre site, traduire vos contenus dans le contexte de la page (!) et afficher des blocs selon une nouvelle condition de langue.
  • le module le plus utilisé, Views, fait maintenant partie du coeur de Drupal, la page d’accueil et les listings des pages d’administration deviennent des vues, à vous les joies de la personnalisation facilitée.
  • l’exposition de contenu à des APIs, les entités sont exportables en JSON ou XML (ma-gni-fi-que !) et views propose un nouveau type d’affichage, les views REST afin d’exposer vos données à des APIs en quelques clics.
  • CMI, l’export de la configuration dans des fichiers YML permettant de déployer des changements de configuration en synchronisant des fichiers sur votre serveur, fini les conflits de base de données (du moins en théorie).
  • le mobile voit débarquer des thèmes responsives de base, des vues responsives, une barre d’outils horizontale ou verticale selon l’orientation et un aperçu du rendu pour différents supports (mobile, tablet, desktop).

La liste des nouveautés est très loin d’être exhaustive, plus de 1 100 contributeurs ont participé à rendre tout cela possible, merci à eux ! (Si vous êtes intéressés par toutes les nouveautés de Drupal 8 je vous invite à venir faire un tour à Paris lors de la prochaine édition du Drupalcamp, le programme est en ligne et la billetterie est ouverte. Plusieurs sessions seront dédiées à Drupal 8)

Concernant le calendrier, le « feature freeze » (gel de l’ajout de nouvelle fonctionnalité) a été prononcé le 18 février dernier, le « code freeze » (arrêt des changements d’API) est prévu pour le 1er juillet (si tout va bien) et l’espoir est toujours de livrer Drupal 8 à la fin de 2013. La première alpha a été publiée aujourd’hui, vous pouvez dès à présent la télécharger, l’installer et contribuer à résoudre les issues encore ouvertes.

Du CMS au WEM (« Web Engagement Management »)

Pour conclure, gérer du contenu ne suffit plus, il faut fournir une expérience plus globale. Les trois composants clés à adresser sont l’intégration avec les meilleurs outils de leur catégories (l’intégration des connecteurs), une expérience mobile solide et une facilité de prise en main de la solution, ces composants ajoutés aux fonctionnalités d’exposition de web services, la nouvelle gestion des blocs et du multilinguisme devraient nous aider à y parvenir achat cialis sans ordonnance.

La période 1996 – 2003 a été le début de l’ère des CMS, en 2010 l’explosion de l’open source a fini par détrôner les CMS propriétaires de l’époque et en 2013 les nouveaux CMS propriétaires se vendent comme étant LA meilleure solution, Drupal devrait parvenir à les contrer en publiant les bons outils pour les bonnes personnes. Publier des outils ouverts pour le plus grand nombre est capital : notre force c’est l’ouverture.

En tant que développeur, travaillez sur ce qui compte, les outils de demain. Si vous êtes une société, aidez à fournir une expérience léchée pour les utilisateurs. Si vous êtes un utilisateur, servez-vous de cet outil pour vous lancer en ligne. Et pour nous tous : « Do well, do good » (« pour bien s’en sortir, faisons de bonnes choses »).

Par Artusamak
Julien Dubois

Info utile #2 – Simpletest et le multilinguisme

J’ai identifié un problème assez ennuyeux il y a quelques jours lorsque j’essayais de lancer des tests simpletests depuis un module du core, quelque soit le test déclenché, le batch plantait. Après vérification que la résolution du nom de ma VM se faisait bien localement, c’est la panne sèche, pas d’idée sur la cause du problème.

La cause du problème était pourtant sous mes yeux depuis le début, dans la barre d’adresse, ce petit préfixe qui traîne et qui ne paie pas de mine, en remplaçant le ‘fr’ par un ‘en’ ou en le supprimant, le problème s’est résolu.

Pensez-y si le problème vous arrive, la négociation de langue n’est pas compatible avec simpletest.

Par Artusamak
Julien Dubois

Info utile #1 – Les fonctions de validation

Voilà un billet d’un style un peu différent, plus court qu’à l’habitude, à propos d’une information bête au sujet des fonctions de validation qui m’a fait perdre une heure hier et qui aurait pu être évitée.

Si vous vous retrouvez dans la situation où vous ajoutez une fonction de validation sur un formulaire mais que cette fonction n’est pas exécutée (et que bien sûr vous avez vérifié par trois fois la syntaxe de votre code), prenez le temps de regarder le détail du formulaire.

En fait il faut savoir que lorsque vous cliquez sur un élément de formulaire de type bouton, ses fonctions de validation et d’exécution sont exécutée et seulement celles de ce bouton. Ce qui au final est logique car cela vous permet d’avoir un comportement différent par bouton sans avoir de risque d’interférences entre les fonctions de validation / exécution de votre bouton et celles du formulaire global. Le détail des mécanismes de ces fonctions à exécuter se trouve dans la fonction form_execute_handlers().

A noter également qu’il existe un attribut du Form API qui a été introduit dans Drupal 7 qui permet de limiter les valeurs à contrôler lors de la soumission du formulaire, il s’agit de l’attribut #limit_validation_errors. Cet attribut prends un tableau comme valeur avec la liste des entrées du $form_state['values'] qui doivent être validées. Pratique pour contourner un champ obligatoire lorsque l’on a un bouton qui supprime un noeud par exemple.

Par Artusamak
Julien Dubois

Rules : Ajouter programmatiquement des événements, actions ou conditions

Dans les épisodes précédents vous avez pu lire une première présentation de Rules, module très utile et avec qui vous allez devoir devenir meilleurs amis lorsque vous utiliserez Drupal Commerce.

Nous allons donc voir comment exposer vos propres événements, conditions et actions à Rules. Rules est très flexible et offre la possibilité par défaut de rajouter les briques dont vous pourriez avoir besoin pour vos développements.

Commençons par les événements qui déclenchent les rules. Nous allons déclencher un événement lorsqu’un type de contenu précis sera visualisé, nous pourrions le faire avec les composants de base de Rules mais cela permet d’avoir un exemple assez simple. N’hésitez pas à consulter la documentation rédigée par fago pour rules, elle est assez complète et à jour.

Pour déclarer un événement il suffit d’implementer le hook hook_rules_event_info() et de décrire tous vos événements avec leurs paramètres. Exemple :

Source code    
<?php
/**
* Implements hook_rules_event_info().
* Déclaration d'un événement basé sur le type du node vu.
*/
function monmodule_rules_event_info() {
  return array(
    'nodearticle_is_viewed' => array( // Nom de l'événement à invoquer via Rules.
      'label' => t("Un node de type article est entrain d'être vu"), // Description de la rule.
      'module' => 'Mon Module', // Groupe dans lequel faire apparaitre l'événement (node, utilisateur ou mon module).
      'arguments' => array( // Tableau des paramètres à passer à la fonction.
        'article' => array('type' => 'node', 'label' => t('Article visualisé.')), // Ici seulement le node.
      ),
    ),
  );
}
?>

Pour que l’implémentation de l’événement soit complète il ne reste plus qu’à signaler à rules que l’événement se produit. Pour cela il suffit d’appeler la fonction rules_invoke_event() au bon moment. Dans notre exemple il suffit de faire cela au sein du hook_nodeapi() si le node est affiché et qu’il a le type article.

/**
* Implements hook_nodeapi().
*/
function monmodule_nodeapi(&$node, $op) {
  if ($op == 'view' && $node->type == 'article') {
    rules_invoke_event('nodearticle_is_viewed', $node); // Invocation de l'événement.
  }
}

Regardons maintenant comment déclarer de nouvelles conditions, l’exemple ici consiste à déterminer si le node que nous sommes entrain de visualiser possède un champ CCK précis (de type nodereférence )avec une valeur.

Cette fois ci il faut implémenter le hook hook_rules_condition_info() pour arriver à nos fins. Comme d’habitude un exemple est plus parlant.

Source code    
/**
 * Implements hook_rules_condition_info().
 */
function monmodule_rules_condition_info() {
  return array(
    'monmodule_has_nodereference' => array(
      'label' => t('Mon node a un node référence.'),
      'arguments' => array(
        'node' => array('type' => 'node', 'label' => t('Node à vérifier')),
      ),
      'module' => 'User',
    ),
  );
}

Comme pour la déclaration d’un événement, les conditions font appel à une fonction de callback, ici monmodule_has_nodereference. Dans cette fonction nous allons implémenter concrètement effectuer le test de la condition à évaluer.

Source code    
function monmodule_has_reference($node, $settings) {
  if (isset($node->field_book)) {
    if (!is_null($node->field_book[0]['nid'])) {
      return TRUE;
    }
  }
  return FALSE;
}

Ici nous évaluons la valeur d’un éventuel node reference pour le champ field_book mais le nom de ce champ pourrait être exposé dans la configuration de la condition, cette valeur se retrouverait dans le paramètre $settings. Pour voir comment configurer les conditions et actions, reportez à la documentation.

Une fois que les événements et conditions sont là, il ne reste qu’une chose à faire, écrire le code qui va être exécuté une fois notre évènement déclenché et notre condition remplie. Vous l’avez compris cette fois il faut exposer cette action via le hook hook_rules_action_info().

Source code    
/**
 * Implements hook_rules_action_info().
 */
function monmodule_rules_action_info() {
  return array(
    'monmodule_domyaction' => array(
      'label' => t('Effectuer mon traitement'),
      'arguments' => array(
        'node' => array('type' => 'node', 'label' => t('Node exposé')),
      ),
      'module' => 'Mon Module',
    ),
  );
}

Et toujours sur le même principe, la fonction de callback que vous avez déclaré est appelée lorsque la rule est déclenchée et satisfait les conditions configurée.

Source code    
function monmodule_domyaction(&$node) {
  drupal_set_message(t("Ce noeud est de type article et possède au moins un node comme node reference dans le champ field_book"));
  // Effectuer tous les traitements imaginables.
}

Etendre Rules 1 est donc quelque chose de très simple, tout se passe principalement dans ces trois hooks et grâce à eux vous pouvez étendre les possibilités de Rules à l’infini. N’hésitez pas à consulter la documentation pour découvrir d’autres fonctionnalités offertes par Rules.

Rules 2 (Drupal 7)  permet d’utiliser Rules comme une API de façon beaucoup plus simple,  cette nouvelle version explore très facilement les types d’entités et si vous installé entity metadata, vous pourrez également exploiter la puissance des informations additionnelles mises à disposition (accès à toutes les données d’un type d’entity).

Par Artusamak
Julien Dubois

Rules, pénétrez dans le monde merveilleux des actions automatisées

Comment faire pour déclencher des actions avancées de façon conditionnelles avec Drupal ? Avec trigger et action les modules de core ? Oui pourquoi pas, mais connaissez-vous Rules ?

Rules est un module développé par Wolfgang Ziegler AKA fago et est simplement une pure merveille et ça ne serait pas surprenant qu’il soit intégré à core sur Drupal 8 en remplacement de trigger et action. Rules était puissant sous Drupal 6 et l’est encore plus sous Drupal 7 (enfin là !).

Ensemble nous allons construire quelques rules simples via l’interface de Drupal et une action « custom » en implémentant les hooks à notre disposition.

Définition : Une rule représente une ou plusieurs actions réalisées lorsqu’une ou plusieurs conditions sont remplies suite au déclenchement d’un événement.

Trois termes clés ressortent ici :

Condition
Une condition peut être le test d’une valeur d’un champ CCK, le rôle d’un utilisateur, le type d’un node, la valeur de l’URL, la force de Rules est que chaque module peut étendre les conditions disponibles avec par exemple Organic Groups qui donne la possibilité de tester si l’utilisateur est membre d’un groupe.
Les conditions peuvent être multiples et peuvent être groupées et combinées via des opérateurs logique (ET et OU).

Action
Une action est une opération à executer lorsque les conditions listées précédement sont toutes remplies. Charger un noeud, envoyer un email, afficher un message, attribuer un rôle et dépublier un node sont des exemples d’actions possibles. Les actions pouvant être executées sont elles aussi extensibles par les modules contrib.
Les actions peuvent être multiples.

Evénement
Un événement est une opération qui déclenche l’évaluation des conditions d’une rule. Exemples possibles : un node est visualisé, un commentaire est publié, un utilisateur se connecte, etc. Les événements sont eux aussi extensibles par les modules contrib.

Un exemple complet d’une rule serait donc d’attribuer le rôle contributeur à un utilisateur lorsqu’il soumet un node de type article.

La puissance de Rules réside dans le fait que les actions peuvent se combiner et les conditions peuvent s’additionner pour donner des rules très complexes.

Note : Ceux qui ont déjà travaillé avec Ubercart et les predicats retrouveront des similitudes avec Rules.

Il faut ajouter aux conditions, actions et événements un élément clé supplémentaire, les arguments. Lorsque l’on veut évaluer une condition sur le rôle de l’utilisateur, il est nécessaire d’avoir l’objet utilisateur à disposition. Lorsque l’on veut tester le type d’un node, il fait avoit l’objet node à disposition. L’utilisateur ou le node sont donc les arguments utilisés dans l’évaluation des conditions ou des événements. Les arguments à transmettre dépendent du déclencheur que vous avez configuré pour lancer l’évaluation d’une rule. Lorsqu’une action ou une condition que vous aimeriez utiliser dans votre rule n’est pas disponible, cela signifie que vous n’avez pas à disposition l’argument dont vous avez besoin (exemple : vous voulez tester le type du node alors que vous avez utilisé l’événement de déclenchement de la rule « lorsque l’utilisateur se connecte », vous avez à disposition l’utilisateur alors que vous voulez utiliser le noeud). La solution dans ces cas là est d’utiliser un rules set.

Le rules set est un ensemble de rules à executer. Les rules sets peuvent être utilisés lorsque les actions doivent être programmées dans le temps, exemple : dépublier tous les lundi les articles de la page d’accueil datant de plus d’une semaine. Les rules sets ont l’avantage de pouvoir cumuler les arguments (utilisateur, noeud, taxonomie, etc) et donc d’élargir les conditions et actions pouvant être executées.

Partie 2 sur les rules implémentées programmatiquement à venir.

Par Artusamak
Julien Dubois

Créer un tri par glisser déposer

Votre module serait vraiment plus sympa si une liste d’éléments pouvait être triée via un glisser-déposer, non ? Long et compliqué à implémenter vous dites ? Et bien détromprez-vous, il existe des outils dans le coeur de Drupal pour justement pouvoir facilement implémenter cela, découverte de l’élément de formulaire de type #weight qui est assez méconnu.

Implémenter une telle fonctionnalité relève de l’ordre du theming, vous cherchez à afficher un formulaire d’une façon particulière et les éléments que vous voulez réordonner vont devoir être themés comme un tableau. La fonction qui nous intéresse pour arriver à nos fins s’appelle drupal_add_tabledrag(), elle est appelée au sein d’une fonction de theming que l’on applique à l’élément de formulaire qui englobe vos éléments à réordonner, regardons un peu de code :

/**
 * Implements hook_theme().
 */
function module_reorder_text_theme($existing, $type, $theme, $path) {
 return array(
 'MODULE_reorder_text' => array(
 'arguments' => array($form => NULL),
 ),
}

Il faut donc dans un premier temps déclarer votre fonction de thème. Cette fonction sera directement appliquée à un élément du formulaire comme suit :

function orderable_form($form_state) {
 $form = array();
 $form['#theme'] = 'module_reorder_text';
}

Regardons maintenant plus en détails le contenu de la fonction de thème :

function theme_module_reorder_text($form) {
 // Titre des colonnes du tableau à trier
 $header = array('', t('Weight'), t('Content'));
 // Ajout du comportement "triable" sur le tableau qui a l'ID "sortable-table"
 // Order signifie que les éléments seront triables voir la documentation pour les autres comportements
 // Sibling : comportement à utiliser sur les éléments du tableau
 // sortable-weight est un nom de classe à utiliser sur les champs qui sont liés dans le tableau
 drupal_add_tabledrag('sortable-table', 'order', 'sibling', 'sortable-weight');
 // $form['items'] est un tableau d'éléments à trier, cet élément de tableau a sa propriété #tree à TRUE.
 foreach ($form['items'] as $key => $value) {
  $value['weight']['#attributes']['class'] = 'upload-weight';
  // Il est nécessaire d'utiliser la fonction drupal_render() pour afficher le champ en HTML
  // Le javascript va remplacer le champ weight par des éléments qui peuvent être glissés / déposés pour réorganiser le tri.
  $row = array('', drupal_render($value['weight']), drupal_render($value['text']));
  $rows[] = array('data' => $row, 'class' => 'draggable');
 }
 $output .= theme('table', $header, $rows, array('id' => 'sortable-table'));
 return $output;
}


Le vrai point important ici consiste à utiliser la fonction drupal_render() pour afficher le contenu des éléments du tableau.
C’est vraiment grâce à ce genre de petits détails que Drupal devient toujours plus indispensable. Merci Drupal !

Par Artusamak
Julien Dubois

Ajouter une étape de confirmation à vos formulaires

C’est une petite fonctionnalité dont vous pourriez avoir besoin, voici une présentation du fonctionnement d’une telle fonctionnalité.
A première vue cela peut sembler très facile à implémenter mais au final ça ne l’est pas tant que ça.

Prenons l’exemple d’un formulaire qui permet de clore des votes sur des sessions, cette action étant importante nous allons ajouter une étape de confirmation avant de faire le traitement.

Je simplifie volontairement le formulaire que l’on créé, résumons le à un simple bouton d’action :

<?php
/**
 * Form to close votes on sessions.
 */
function feature_conference_close_sessions_form(&#038;$form_state) {
 
$form['submit'] = array(
 
'#type' => 'submit',
 
'#value' => t('Clore les votes'),
 );
 return
$form;
}
?>

Ensuite dans le traitement de ce formulaire il faut faire une redirection vers le formulaire de confirmation. Aucun traitement ne doit être fait ici sachant que le formulaire n’a pas encore été confirmé par l’utilisateur.

<?php
/**
 * Redirect to confirmation form.
 */
function feature_conference_close_sessions_form_submit($form, &#038;$form_state) {
 
$form_state['redirect'] = 'sessions/close/confirm';
}
?>

Sachant que nous faisons une redirection vers une entrée de menu, il faut la déclarer via un hook_menu().

<?php
/**
 * Implement hook_menu().
 */
function feature_conference_menu() {
 return array(
 
'sessions/close/confirm' => array(
 
'page callback' => 'drupal_get_form',
 
'page arguments' => array('feature_conference_close_sessions_confirm_form'),
 
'access callback' => TRUE,
 ),
}
?>

Dans ce formulaire il vous faut utiliser la fonction confirm_form() (http://api.drupal.org/api/function/confirm_form/6) pour obtenir la page de confirmation.

<?php
/**
 * Confirmation form before closing sessions.
 */
function feature_conference_close_sessions_confirm_form(&#038;$form_state) {
 
$form = array();
 
$desc = "Les votes ne seront plus possibles.";
 return
confirm_form($form, "Êtes-vous sûr de vouloir clore les votes ?",
 
"<front>", $desc);
}
?>

Ensuite on retombe dans le fonctionnement classique des formulaires, il suffit de faire le traitement des données dans la fonction de submit du formulaire.

<?php
/**
 * Close votes on sessions, send email to rejected contributions' authors
 */
function feature_conference_close_sessions_confirm_form_submit($form, &#038;$form_state) {
 // Set a variable to status closed
 
variable_set('feature_conference_status', 'closed');
 
drupal_set_message("Les votes sur les sessions sont maintenant clos.");
 
drupal_goto('<front>');
}
?>

Et nous voilà avec un formulaire de confirmation fonctionnel. Le cas d’usage est simple, si vous souhaitez faire une action plus avancée comme par exemple clore une session précise, il faut que vous passiez les données dans le formulaire de confirmation via un ou plusieurs arguments à l’url de traitement car le fait d’effectuer une redirection entraine la perte des données soumise par le formulaire principal.

Par Artusamak
Julien Dubois

Créer des templates (fichier.tpl.php) pour themer vos modules

Lors de la création de vos modules vous pouvez être amenés à mettre en forme votre contenu pour garder une approche cohérence avec la dissociation fond / forme. Il est donc nécessaire de donner la possibilité au themer de pouvoir modifier la mise en forme du contenu que vous aller afficher.
Afin de rendre une telle action possible, vous allez devoir déclarer au sein de votre module un hook_theme, qui va déclarer les éléments qui pourront être themés via vos templates.
Le hook_theme est simplement constitué d’un tableau d’éléments skinnables avec pour chaque entrée une clé « template » qui correspond au nom du fichier .tpl.php utilisé pour le theme et une clé « arguments » correspondant à un tableau de paramètres à passer à la fonction de theme().

function hook_theme() {
  return array(
    'my_themeable_call' => array(
      'template' => 'gabarit.tpl.php',
      'arguments' => array("param1" => NULL),
    ),
  );
}

A noter : Le « .tpl.php » est facultatif car toujours suggéré par le moteur de template et il est recommandé d’utiliser le même nom comme clé et comme nom de fichier pour le template. (Les noms sont ici différents pour vous permettre de décortiquer la mécanique). [Merci Cyril pour la remarque]

Voilà votre fonction de thème déclarée, il ne reste plus qu’à l’utiliser.
Prenons l’exemple d’un bloc, vous souhaitez utiliser votre fonction de thème dans son contenu, il vous suffit d’utiliser dans le contenu du bloc (cf hook_block) votre fonction de theme : $bloc['content'] = theme(‘my_themeable_call’, $param1);
De cette façon vous enverrez à votre fichier de template la variable $param1 (pouvant contenir tout type de données). Si vous omettez de passer un argument, la valeur par défaut déclarée dans le hook_theme sera utilisée (dans notre exemple si j’omets $param1, sa valeur sera NULL).

Plaçons-nous maintenant dans notre fichier de template gabarit.tpl.php, c’est le fichier que votre themer pourra surcharger en le copiant collant dans le dossier de son thème.
Les variables à disposition sont celles que vous avez passé en paramètres lors de l’appel de la fonction de thème (ici $param1) et les éventuelles variables ajoutées par les fonctions de preprocess. (La signature de la fonction est template_preprocess_my_themeable_call, surchargeable par THEME_preprocess_my_themeable_call).

De cette façon vous pouvez donc créer vos propres fichiers de theming lors de la publication de vos modules afin de vous faire adorer par les themers !

tag

Pages