web-dev-qa-db-fra.com

Comment dire Drupal pour rechercher des modèles dans le répertoire du module?

Je voudrais fournir une implémentation de modèle dans mon module et permettre aux thèmes de le remplacer. Fondamentalement, j'ajoute une suggestion par ce code simplifié:

function attach_preprocess_node(&$vars) {
  $vars['theme_hook_suggestions'][] = 'node__test';
}

(Je ne veux pas utiliser hook_theme pour ajouter un nouveau thème parce que je veux réutiliser les fonctions de nœud de prétraitement. Le nom du thème est maladroit mais je ne veux pas écrire le nœud _attacher _% pour éviter la confusion avec le type de nœud.)

Ensuite, j'utilise hook_theme_registry_alter () pour ajouter le chemin du module:

function attach_theme_registry_alter(&$theme_registry) {
  $path = drupal_get_path('module', 'attach') . '/themes';
  $theme_registry_copy = $theme_registry;
  _theme_process_registry($theme_registry_copy, 'phptemplate', 'theme_engine', 'node', drupal_get_path('module', 'node'));
  $theme_registry += array_diff_key($theme_registry_copy, $theme_registry);
  if (!isset($theme_registry['node']['theme paths'])) {
    $theme_registry['node']['theme paths'] = array();
  }
  if (!isset($theme_registry['node']['theme paths'])) {
    $first_element = array_shift($theme_registry['node']['theme paths']);
    if ($first_element) {
      array_unshift($theme_registry['node']['theme paths'], $first_element, $path);
    }
    else {
      array_unshift($theme_registry['node']['theme paths'], $path);
    }
  }
}

Mais ça ne marche pas. Cela signifie que le fichier themes/node - super.tpl.php n'est pas utilisé. Il n'est utilisé que si je l'ai copié dans le dossier du thème.

11
jcisio

Fondamentalement, vous pouvez vous épargner quelques maux de tête en implémentant hook_theme() au lieu de modifier le registre.

Je suggère de regarder theming_example dans le Projet Exemples , reproduit facilement sur cette page de documentation API , peut-être avec un code particulièrement utile sur cette page .

function theming_example_list_page() {
  $items = array(
    t('First item'),
    t('Second item'),
    t('Third item'),
    t('Fourth item'),
  );

  // First we'll create a render array that simply uses theme_item_list.
  $title = t("A list returned to be rendered using theme('item_list')");
  $build['render_version'] = array(
    // We use #theme here instead of #theme_wrappers because theme_item_list()
    // is the classic type of theme function that does not just assume a
    // render array, but instead has its own properties (#type, #title, #items).
    '#theme' => 'item_list',
    // '#type' => 'ul',  // The default type is 'ul'
    // We can easily make sure that a css or js file is present using #attached. 
    '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), 
    '#title' => $title, 
    '#items' => $items, 
    '#attributes' => array('class' => array('render-version-list')),
  );

  // Now we'll create a render array which uses our own list formatter,
  // theme('theming_example_list').
  $title = t("The same list rendered by theme('theming_example_list')");
  $build['our_theme_function'] = array(
    '#theme' => 'theming_example_list', 
    '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), 
    '#title' => $title, 
    '#items' => $items,
  );
  return $build;
}

C'est tout pour Drupal 7.

5
paul-m

Peut-être que celui-ci fonctionne:

/**
 * Implements hook_theme().
 */
function MODULE_theme($existing, $type, $theme, $path) {
  return array (
    'node__CONTENTTYPE' => array (
      'variables' => array( . . . ),
      'template' => 'node--CONTENTTYPE' ,
      'base hook' => 'node',
      'path' => drupal_get_path('module', 'MODULE'),
    ),
  );
}

L'important ici est la clé 'base hook'.

5
dashohoxha

J'aime la solution de dashohoxha de l'implémentation de hook_theme mais n'a pas pu le faire fonctionner. Après un peu plus de recherche sur Google, j'ai trouvé ne variation qui fonctionnait bien pour moi:

/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  $theme = array();
  $theme['node__blog_post'] = array(
    'render element' => 'content',
    'base hook' => 'node',
    'template' => 'node--blog_post',
    'path' => drupal_get_path('module', 'mymodule') . '/templates',
   );
  return $theme;
}

Remarques: mon module personnalisé s'appelle 'mymodule' et mon type de contenu personnalisé s'appelle 'blog_post'. Le tpl.php que j'utilise s'appelle 'node - blog_post.tpl.php' et se trouve dans le sous-dossier 'templates' de mon module.

2
batigolix

Voici mon extrait de code pour déclarer les modèles de vues stockés dans le dossier "template" de mon "custom_module":

/**
 * Implements hook_theme_registry_alter().
 */
function custom_module_theme_registry_alter(&$theme_registry) {
  $extension   = '.tpl.php';
  $module_path = drupal_get_path('module', 'custom_module');
  $files       = file_scan_directory($module_path . '/templates', '/' . preg_quote($extension) . '$/');

  foreach ($files as $file) {
    $template = drupal_basename($file->filename, $extension);
    $theme    = str_replace('-', '_', $template);
    list($base_theme, $specific) = explode('__', $theme, 2);

    // Don't override base theme.
    if (!empty($specific) && isset($theme_registry[$base_theme])) {
      $theme_info = array(
        'template'   => $template,
        'path'       => drupal_dirname($file->uri),
        'variables'  => $theme_registry[$base_theme]['variables'],
        'base hook'  => $base_theme,
        // Other available value: theme_engine.
        'type'       => 'module',
        'theme path' => $module_path,
      );

      $theme_registry[$theme] = $theme_info;
    }
  }
}

J'espère que cela aide quelqu'un.

2
Sebastien M.