preprocess de tpl, modif de hook et pattern de chemin

Source: http://www.sitepoint.com/fine-tuning-drupal-themes-patterns-arg-types/

template preprocessing (pour def les var à utiliser ds page) et modif de hooks en utilisant des pattern de chemin, types et args() :
* args() est une fonction qui renvoie des parties d'URL. On va l'utiliser pour matcher un pattern dans URL.
* On va créer une var pour stocker un tableau des types de contenus.
* un hook modifié ou créé : quelque chose qui est lancé avant le rendu de la page, de facon à ajouter du js ou css à certaines pages ou types de contenus.
Ces hooks nous permettront de :

  • ajout classe <body> à une page pour le themer facilement
  • ajout de js ou css à des pages et des chemins
  • utiliser des arguments de chemin "joker" (comme *, ? ...)
  • pattern d'URL qui matchent en utilisant preg_match
  • création d'un tableau des types de contenus, variable qu'on utilisera dans l'argument
  • utiliser les arguments de chemin en paramètre

La base

Les fonctions seront à ajouter dans le template.php du thème qu'on utilise (ex: sites/all/themes/foobar/template.php). Il faut de plus spécifier que ces fonctions ne servent pas à des pages d'admin (bien qu'on puisse aussi utiliser ces fonctions dans un module perso).

Les fonctions API commencent par le nom du thème: pour utiliser hook_page_alter il faut nommer la fonction function foobar_page_alter()

classes body perso qui utilisent un tableau de type de contenu

Une classe body perso est une classe ajoutée à <body>.
Par ex, sur une page de blog : <body class="page-node page-node-blog">

On pourra utiliser cette classe (sass ou css) pour les pages de blog seules:

.page-node-blog h1 {
// custom Sass here
}

Le core drupal 7 en a déja un certain nombre, des modules et thèmes peuvent aussi en ajouter. Ici, des pages partagent des attribut communs, et on veux ajouter une classe à certaines pages (mais qui ne sont pas toutes du meme type de contenu). On va dc créer un tab avec les types de contenus voulus et l'utiliser pour ajouter cette classe.

Une fois le tableau créé, on doit s'assurer qu'un node donné existe bien, et lui passer alors le tableau :

<?php
/**
* Implements template_preprocess_html().
*
* Define custom classes for theming.
*/
function foobar_preprocess_html(&$vars) {

  // Build a node types array from our targeted content types.
  $foo_types = array(
    'landing_page',
    'our_services',
  );

    // Define the node.
    $node = menu_get_object();

  // Use the array to add a class to those content types.
  if (!empty($node) && in_array($node->type, $foo_types)) {
    $vars['classes_array'][] = 'page-style-foobar';
    }
  }

Cette fonction preprocesse les var pour tout ce qui est avant </head> (située dans html.tpl.php).
La var $vars['classes_array'] est affichée par <?php print $classes; ?> dans le body.
Ici, ajout d'une classe pour les types de contenus  "landing_page" et "our_services". On peux maintenant utiliser dans nos styles pour thémer ces pages .page-style-foobar

Matcher le pattern d'URL

Pour ajouter des classes perso, on peux utiliser un match de chemin (en utilisant:  preg_match, regex, PHP match et la fonction drupal request_uri).

Par ex, pour le type de contenu "Our Services" on a les pages:

example.com/our-services
- example.com/our-services/subpage-1
- example.com/our-services/subpage-2

<?php
function foobar_preprocess_html(&$vars) {
  // Define the URL path.
  $path = request_uri();
  // Add body classes to various pages for better theming.
  if (preg_match('|^/our-services((?:/[a-zA-Z0-9_\-]*)*)?|', $path, $matches)) {
    $vars['classes_array'][] = 'page-services';
  }
}

Utilisation (pour thémer les pages "our-services”) : .page-services .some-common-element

cf http://lzone.de/examples/PHP%20preg_match

arguments de chemin arg()

Ex: ajout script que sur page d'enregistrement (/user/register) -> créer un si selon l'arg() de chemin

On va utiliser hook_page_alter car c'est ce qui est lancé avant le rendu de page. Il faut d'abord def le chemin du thème, puis utiliser la fonction drupal :

<?php
/**
* Implements hook_page_alter().
* Add custom functions such as adding js or css.
*/
function foobar_page_alter(&$page, $form) {

  // Define the module path for use below.
  $theme_path = drupal_get_path('theme', 'foobar');

  if (arg(0) == "user" && arg(1) == "register") {
     $foobar_js = array(
      '#attached' => array(
        'js' => array(
          $theme_path . '/js/custom.js' => array(
            'group' => JS_THEME,
          ),
        ),
      ),
    );
    drupal_render($foobar_js);
  }
}

Pour ajouter un js que sur cette page user (et pas les chemins dessous), ajouter un arg NULL :

if (arg(0) == "user" && arg(1) == NULL) {
// code here
}

Ici, toutes les fonctions commencent par le nom du thème (car ds le template.php de notre thème).
Si ds module perso, les fonctions doivent commencer par le nom du module perso. En thémant à partir d'un module perso, il faut exclure les chemins d'admin avec

if (!path_is_admin(current_path())) {
// code here
}

Plus sur le web

logo drush