Snippets

Les snippets sont des bout de code.

Présenté ici de manière volontairement « brute », ces snippets ont vocation à servir d'aide mémoire.

N'hésitez-pas à poser un commentaire si vous rencontrez un problème avec un des éléments.

Vous pouvez utiliser la navigation via les tags présents sur la droite

  • Drupal 8 - Views - Changer le titre d'une vue en fonction du nombre de résultats

    Posté le Lundi 13 novembre 2017 - 09:07
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    Utile dans le cadre d'une vue affichant des résultats d'une recherche via Search API :

    1. function MONMODULE_views_post_render(\Drupal\views\ViewExecutable $view) {
    2. if($view->storage->id() === 'NOM_MACHINE_VUE' && $view->current_display === 'NOM_MACHINE_AFFICHAGE') {
    3. $view->setTitle($view->getTitle() . ' (' . count($view->result) . ')');
    4. }
    5. }

     

  • Drupal - afficher en live le contenu du watchdog avec drush

    Posté le Mardi 31 octobre 2017 - 16:08
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    Parfois on se retrouve avec un gros White Screen Of Death sur son site, et impossible de se connecter.

    Dans ce cas là il est pratique de pouvoir afficher en live le contenu du watchdog, c'est possible avec Drush et la commande watchdog-show :

    1. drush @alias watchdog-show --tail --full --count=50

    --tail affichera les nouvelles entrées du watchdog en direct

    --full pour afficher le détail des erreurs

    --count=50 permettra d'afficher les 50 lignes les plus récentes du watchdog.

    2017-10-31-16-13-09-Screenshot-01.jpg

    (Deux fois dans la journée que je recherche cette commande, au moins je saurai maintenant ou la retrouver...)

  • Exemple de fichier gitlab-ci.yml

    Posté le Dimanche 29 octobre 2017 - 17:27
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    .gitlab-ci.yml

    1. stages :
    2. - predeploy
    3. - deploy
    4. - postdeploy
    5. - scheduled
    6.  
    7.   prod_backup_db:
    8.   script:
    9. - ssh <a href="mailto:user@serveur">user@serveur</a> 'drush @kg cr'
    10. - ssh <a href="mailto:user@serveur">user@serveur</a> 'drush @kg sql-dump --gzip > "/home/site/db/`date +%Y-%m-%d_%H-%M-%S`-kgaut.net-$(hostname).sql.gz"'
    11.   only:
    12. - master
    13.   stage : predeploy
    14.   environment:
    15.   name: preprod
    16.  
    17.   prod_diff_git:
    18.   script:
    19. - ssh <a href="mailto:user@serveur">user@serveur</a> 'bash -s' < scripts/deploy/2-diff.sh
    20.   only:
    21. - master
    22.   except:
    23. - schedules
    24.   stage : predeploy
    25.   environment:
    26.   name: preprod
    27.  
    28.   prod_diff_config:
    29.   script:
    30. - ssh <a href="mailto:user@serveur">user@serveur</a> 'bash -s' < scripts/deploy/3-diff-config.sh
    31.   only:
    32. - master
    33.   except:
    34. - schedules
    35.   stage : predeploy
    36.   environment:
    37.   name: preprod
    38.  
    39.   prod_deploy:
    40.   script:
    41. - ssh <a href="mailto:user@serveur">user@serveur</a> 'bash -s' < scripts/deploy/4-deploy.sh
    42.   only:
    43. - master
    44.   except:
    45. - schedules
    46.   stage : deploy
    47.   environment:
    48.   name: preprod
    49.  
    50.   dump:
    51.   only:
    52. - schedules
    53.   stage : scheduled
    54.   script:
    55. - ssh <a href="mailto:user@serveur">user@serveur</a> 'find "/home/kgaut_net/db" -type f -mtime +"3" -delete'

    2-diff.sh

    1. #!/bin/bash
    2. set -e
    3. cd website
    4. if [[ $(git diff) ]]; then
    5. FILENAME="$(date +"%Y-%m-%d_%H-%M-%S")-diff.patch"
    6. git diff > "/home/site/diffs/$FILENAME"
    7. echo "---------------------------------";
    8. echo "modifications en prod detectées, patch créé : $FILENAME";
    9. echo "Modifications de fichier en prod detectées, patch créé" | mail -s "Fichiers modifiés" -a "/home/site/diffs/$FILENAME" <a href="mailto:moi@email.com">moi@email.com</a>
    10. echo "Liste des fichiers modifiés : ";
    11. echo $(git diff --name-only)
    12. echo "---------------------------------";
    13. git checkout ./
    14. else
    15. if [[ $(git ls-files --others --exclude-standard) ]]; then
    16. echo "---------------------------------";
    17. echo "Fichiers non versionnés : "
    18. echo $(git ls-files --others --exclude-standard)
    19. echo "---------------------------------";
    20. FAIL;
    21. else
    22. echo "Pas de modification en prod à signaler"
    23. fi
    24. fi

    3-diff-config.sh

    1. #!/bin/bash
    2. set -e
    3.  
    4. cd /home/site/website
    5. drush @kg cr
    6. drush @kg config-export sync -y
    7. if [[ $(git diff files/config/) ]]; then
    8. echo "---------------------------------";
    9. FILENAME="$(date +"%Y-%m-%d_%H-%M-%S")-config.patch"
    10. git diff files/config/ > "/home/site/diffs/$FILENAME"
    11. echo "Modifications de configuration en prod detectées, patch créé : $FILENAME";
    12. echo "Configuration modifiée, patch créé" | mail -s "Configuration modifiée" -a "/home/site/diffs/$FILENAME" <a href="mailto:contact+kgn@kgaut.net">contact+kgn@kgaut.net</a>
    13. git checkout ./
    14. echo "---------------------------------";
    15. #FAIL;
    16. fi
    17.  
    18. cd /home/site/website/files/config
    19. if [[ $(git ls-files --others --exclude-standard) ]]; then
    20. echo "---------------------------------";
    21. FILENAME="$(date +"%Y-%m-%d_%H-%M-%S")-config.tar"
    22. echo "Config en prod non versionnée : "
    23. echo $(git ls-files --others --exclude-standard)
    24. tar -zcvf "/home/site/diffs/$FILENAME" ./
    25. echo "Archive crée : $FILENAME";
    26. echo "Configuration modifiée, non versionnée, patch créé" | mail -s "Configuration non versionnée" -a "/home/site/diffs/$FILENAME" <a href="mailto:contact+kgn@kgaut.net">contact+kgn@kgaut.net</a>
    27. rm ./*/*.yml
    28. git checkout ./
    29. echo "---------------------------------";
    30. #FAIL;
    31. fi

    4-deploy.sh

    1. #!/bin/bash
    2. set -e
    3. cd /home/site/website
    4. git pull
    5. composer install --no-dev
    6. drush @kg updb -y
    7. drush @kg entup -y
    8. drush @kg updb -y
    9. drush @kg config-import sync -y
    10. gulp prod
    11. drush @kg cr
  • Drupal 8 - Formulaire - « ajouter un élément » et « supprimer un élément »

    Posté le Lundi 9 octobre 2017 - 17:19
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    Voici comment dans un formulaire custom D8, avoir un ensemble de champ "multiples" dans un formulaire de config par exemple.

    drupal8-formulaire-add-more.jpg

    Dans mon exemple je n'ai que le champ « titre », mais c'est simplement pour alléger le snippet.

    Le code en question :

    1. <?php
    2.  
    3. namespace Drupal\monmodule\Form;
    4.  
    5. use Drupal\Core\Form\ConfigFormBase;
    6. use Drupal\Core\Form\FormStateInterface;
    7. use Drupal\file\Entity\File;
    8.  
    9. /**
    10.  * Class PopoteConfigForm.
    11.  */
    12. class HomepageConfigForm extends ConfigFormBase {
    13.  
    14. protected function getEditableConfigNames() {
    15. return [
    16. 'monmodule.homepage',
    17. ];
    18. }
    19.  
    20. public function getFormId() {
    21. return 'homepage_config_form';
    22. }
    23.  
    24. public function buildForm(array $form, FormStateInterface $form_state) {
    25. $config = $this->config('monmodule.homepage');
    26. $pomoted_items = $config->get('promoted', []);
    27. $number_promoted = $form_state->getValue('number_promoted', count($pomoted_items));
    28. $removed = $form_state->getValue('removed_promoted', []);
    29.  
    30. $form['number_promoted'] = [
    31. '#type' => 'value',
    32. '#value' => $number_promoted,
    33. ];
    34. $form['removed'] = [
    35. '#type' => 'value',
    36. '#value' => $removed,
    37. ];
    38. $form['promoted'] = [
    39. '#type' => 'fieldset',
    40. '#title' => t("À la une"),
    41. '#tree' => TRUE,
    42. ];
    43. for ($i = 1; $i <= $number_promoted; $i++) {
    44. $item = array_shift($pomoted_items);
    45. if (in_array($i, $removed)) {continue;}
    46. $form['promoted'][$i] = [
    47. '#type' => 'fieldset',
    48. '#title' => t("À la une #@i", ['@i' => $i]),
    49. ];
    50. $form['promoted'][$i]['title'] = [
    51. '#type' => 'textfield',
    52. '#title' => $this->t("Titre"),
    53. '#default_value' => $item['title'],
    54. ];
    55. $form['promoted'][$i]['remove_' . $i] = [
    56. '#type' => 'submit',
    57. '#value' => t("Supprimer l'élément #@i", ['@i' => $i]),
    58. '#submit' => ['::removeItem'],
    59. '#attributes' => [
    60. 'class' => ['button--danger'],
    61. 'data-toRemove' => $i,
    62. ]
    63. ];
    64. }
    65. $form['promoted']['add_item'] = [
    66. '#type' => 'submit',
    67. '#value' => t('Ajouter un autre élément'),
    68. '#submit' => ['::addPromotedItem'],
    69. ];
    70.  
    71. return parent::buildForm($form, $form_state);
    72. }
    73.  
    74. public function addPromotedItem(array &$form, FormStateInterface $form_state) {
    75. $form_state->setValue('number_promoted', $form_state->getValue('number_promoted') + 1);
    76. $form_state->setRebuild();
    77. }
    78.  
    79. public function removeItem(array &$form, FormStateInterface $form_state) {
    80. $removed = $form_state->getValue('removed_promoted', []);
    81. $removed[] = $form_state->getTriggeringElement()['#attributes']['data-toRemove'];
    82. $form_state->setValue('removed_promoted', $removed);
    83. $form_state->setRebuild();
    84. }
    85.  
    86. public function submitForm(array &$form, FormStateInterface $form_state) {
    87. parent::submitForm($form, $form_state);
    88. $parsed = [];
    89. $promoted = $form_state->getValue('promoted');
    90. foreach ($promoted as $promoted_item) {
    91. if(is_array($promoted_item)) {
    92. $parsed[] = $promoted_item;
    93. }
    94. }
    95. $this->config('monmodule.homepage')->set('promoted', $parsed)->save();
    96. }
    97. }

     

     
  • Drupal 8 - Accèder à $_GET et $_POST

    Posté le Lundi 2 octobre 2017 - 10:02
    Dernière mise à jour le Vendredi 9 mars 2018 - 11:15

    Récupérer $_GET['test'] :

    1. $test = \Drupal::request()->query->get('test');

    Récupérer $_POST['test'] :

    1. $test = \Drupal::request()->request->get('test');

    Récupérer un tableau associatif avec toutes les variables $_GET :

    1. $variables_get = \Drupal::request()->query->all();

    Récupérer un tableau associatif avec toutes les variables $_POST :

    1. $variables_post = \Drupal::request()->request->all();

     

  • Drupal 8 - Définir l'item de menu actif en fonction du type de noeud

    Posté le Mercredi 20 septembre 2017 - 17:48
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    Sur ce site, j'ai trois types de contenu :

    • Article
    • Snippet
    • Réalisation

    Pour chacun de ces trois types de contenu, j'ai une vue (View) de listing qui correspond (cf le menu ci-dessus).

    Par défaut quand on est sur la vue de listing des snippets par exemple, on a bien l'élément de menu "Snippets" qui est marqué comme actif, par contre quand on va sur le détail d'un snippet, on perd cette information. Nous allons voir comment sélectionner le menu item qui doit être actif en fonction du type de contenu sur lequel on se trouve.

    1ère étape : surcharger le service MenuActiveTrail

    dans mon module « kgaut » je créé le fichier KgautMenuActiveTrail.php dans le dossier src/Menu avec le contenu suivant :

    1. <?php
    2.  
    3. namespace Drupal\kgaut\Menu;
    4.  
    5. use Drupal\Core\Menu\MenuActiveTrail;
    6. use Drupal\node\NodeInterface;
    7.  
    8. /**
    9.  * Extend the MenuActiveTrail class.
    10.  */
    11. class KgautMenuActiveTrail extends MenuActiveTrail {
    12.  
    13. /**
    14.   * {@inheritdoc}
    15.   */
    16. public function getActiveLink($menu_name = NULL) {
    17. // Call the parent method to implement the default behavior.
    18. $found = parent::getActiveLink($menu_name);
    19.  
    20. // If a node is displayed, load the default parent menu item
    21. // from the node type's menu settings and return it instead
    22. // of the default one.
    23. $node = $this->routeMatch->getParameter('node');
    24.  
    25. if ($node instanceof NodeInterface) {
    26. $bundle = $node->bundle();
    27. switch ($bundle) {
    28. case 'article':
    29. //Ici je demande à recherche le menu item qui utilise la route correspondant à mon type de contenu
    30. $links = $this->menuLinkManager->loadLinksByRoute('view.front_articles.page', [], $menu_name);
    31. break;
    32.  
    33. case 'snippet':
    34. $links = $this->menuLinkManager->loadLinksByRoute('view.front_snippets.page', [], $menu_name);
    35. break;
    36.  
    37. case 'realisation':
    38. $links = $this->menuLinkManager->loadLinksByRoute('view.front_realisations.page', [], $menu_name);
    39. break;
    40. }
    41.  
    42. if (isset($links) && $links) {
    43. $found = reset($links);
    44. }
    45. }
    46. return $found;
    47. }
    48. }

    C'est bien beau, mais maintenant il faut signaler à Drupal que l'on a surchargé un de ses services. Pour cela il faut créer le fichier src/MonModuleServiceProvider.php (attention c'est normé !) Dans mon cas j'ai donc créé le fichier KgautServiceProvider.php dans le dossier src de mon module kgaut (oui je suis très égocentrique).
    En voici le contenu :

    1. <?php
    2. /**
    3.  * @file
    4.  * Contains Drupal\kgaut\KgautServiceProvider.
    5.  */
    6.  
    7. namespace Drupal\kgaut;
    8.  
    9. use Drupal\Core\DependencyInjection\ContainerBuilder;
    10. use Drupal\Core\DependencyInjection\ServiceProviderBase;
    11.  
    12. class KgautServiceProvider extends ServiceProviderBase {
    13.  
    14. /**
    15.   * {@inheritdoc}
    16.   */
    17. public function alter(ContainerBuilder $container) {
    18. $container->getDefinition('menu.active_trail')->setClass('Drupal\kgaut\Menu\KgautMenuActiveTrail');
    19. }
    20.  
    21. }

    Un petit vidage de cache plus tard, et on est bon !

  • Drupal 8 - Rediriger un utilisateur lors de sa connexion

    Posté le Jeudi 14 septembre 2017 - 17:45
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    Pour rediriger un utilisateur lorsqu'il se connecte on peut utiliser le hook HOOK_user_login().

    Le code qui suit ne redirige que si une redirection n'est pas déjà présente dans l'url :

    1. function MONMODULE_user_login($account) {
    2. if (!isset($_GET['destination'])) {
    3. $response = new \Symfony\Component\HttpFoundation\RedirectResponse(\Drupal::url('popote.user.commandes'));
    4. $response->send();
    5. }
    6. }

     

  • Drupal 8 - Ajouter des suggestions de template pour les Noeuds

    Posté le Jeudi 14 septembre 2017 - 16:18
    Dernière mise à jour le Vendredi 26 janvier 2018 - 18:35

    Dans drupal 8, parfois le thème ajoute des suggestions de template qui vont bien, en fonction du type de noeud et du view_mode, mais ça n'est pas toujours le cas, voici comment faire pour ajouter des suggestions de template via le hook HOOK_theme_suggestions_HOOK() :

    function MONMODULE_theme_suggestions_node(array $variables) {
      $suggestions = [];
      /** @var \Drupal\node\Entity\Node $node */
      $node = $variables['elements']['#node'];
      $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
      $suggestions[] = $variables['theme_hook_original'] . '__' . $sanitized_view_mode;
      $bundle = $node->bundle();
      $sanitized_bundle = strtr($bundle, '.', '_');
      $suggestions[] = $variables['theme_hook_original'] . '__' . $sanitized_bundle;
      $suggestions[] = $variables['theme_hook_original'] . '__' . $sanitized_bundle . '__' . $sanitized_view_mode;
      return $suggestions;
    }

    Pour un type de contenu article en mode de vue teaser on aura ainsi les possibilités de templates suivantes :

    • node.html.twig
    • node--article.html.twig
    • node--teaser.html.twig
    • node--article--teaser.html.twig