Ajout d'une suggestion de thème par programme

8

J'ai créé un module de fonctionnalités contenant uniquement une vue et un type de contenu.

À l'heure actuelle page-node-x.tpl.php, mes views-view-y.tpl.phpfichiers et moi se trouvent dans mon répertoire de thèmes.

Est-il possible de les déplacer dans mon module de fonctionnalités?

jantimon
la source

Réponses:

5

Un module qui implémente hook_preprocess_page()ou hook_preprocess_node()peut suggérer de nouveaux fichiers modèles en modifiant la variable $variables['theme_hook_suggestions'].

Le code contenu dans template_preprocess_page () qui initialise cette variable est le suivant.

// Populate the page template suggestions.
if ($suggestions = theme_get_suggestions(arg(), 'page')) {
  $variables['theme_hook_suggestions'] = $suggestions;
}

Chaque suggestion de thème doit correspondre à une entrée renvoyée par hook_theme () .

Dans les vues, il devrait y avoir une fonction de prétraitement équivalente à utiliser de la même manière, ou une manière hook_preprocess_page()qui permet à la fonction de comprendre si la page est associée à une vue.

kiamlaluno
la source
3

La solution à laquelle ajouter la clé «modèle de fichier» hook_views_api()ne semble pas encore fonctionner dans Drupal 7. Cependant, cela fonctionne comme un charme:

/**
 * Implements hook_theme().
 */
function bigtexas_theme() {
  return array(
    'views_view_fields__slideshow' => array(
    'variables' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
    'template' => 'views-view-fields--slideshow',
    'base hook' => 'views_view_fields',
    'path' => drupal_get_path('module', 'bigtexas') . '/theme',
  ),
 );
}
Joe Hyde
la source
2

Le registre des thèmes est l'endroit où Drupal stocke toutes sortes d'informations sur les fichiers de modèle, les fonctions de thème, etc. à utiliser. Jouer avec cela peut conduire à des moments WTF plus tard, car les choses ne fonctionneront pas comme par défaut.

Quoi qu'il en soit, comme tout ce qui est drupal, il y a un crochet: hook_theme_registry_altervous pouvez utiliser pour modifier le registre des thèmes et déplacer vos fichiers de modèle dans un module. Je ne conseillerais pas de faire cela, car cela rendra la maintenance du site plus complexe. Mais si vous voulez le faire, c'est comme ça que c'est fait.

googletorp
la source
+1 - J'ai essayé mais sans succès .. Pourriez-vous donner un exemple?
jantimon
@Ghommey: Le lien fourni contient un exemple de code, je ne sais pas comment l'expliquer mieux.
googletorp
2

Pour les vues, il existe en théorie un mécanisme pour les modèles de vues (peut-être que cela fonctionne pour tous les modèles).

Vous pouvez définir la clé "chemin du modèle" dans votre implémentation hook_views_api de votre module personnalisé.

Une fois que vous disposez de ces vues, le fichier spécifié sera analysé pour les fichiers de modèle. Malheureusement, le test le plus simple échoue actuellement, donc cette fonctionnalité n'est probablement pas encore portée sur drupal7, mais si quelqu'un veut y entrer, consultez _views_find_module_templates () dans views.module.

Daniel Wehner
la source
2

La façon la plus simple est d'utiliser hook_theme_registry_alter()et d'ajouter simplement le chemin de votre module aux chemins du thème:

function mymodule_theme_registry_alter(&$theme_registry) {
  $theme_registry['[theme hook name, ie. page or views-view]']['theme paths'][] = drupal_get_path('module', 'mymodule');
}
Damien Tournoud
la source
En regardant l' theme()implémentation, il ne semble pas que ce theme pathsoit un tableau. Êtes-vous sûr que cela fonctionne? Voir api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel
Concernant mon commentaire ci-dessus: fonctionnait theme pathsauparavant dans Drupal 6, mais Drupal 7 a changé ce comportement dans drupal.org/node/678714 Il semble, à partir des commentaires # 29 et # 31 dans le numéro mentionné, que les suggestions de thèmes des modules doivent être déclarées dans le hook_theme de ce module, mais comment le faire est laissé comme un exercice au lecteur: /
Capi Etheriel
1

Que diriez-vous d'une approche légèrement abstraite avec le thème de réaction contextuelle?

http://drupal.org/project/context_reaction_theme

Enveloppez votre contexte dans les fonctionnalités et il est même exportable. Mais c'est peut-être en fait une question de gourou Drupal qui cherche à créer quelque chose de plus profond et à connaître l'itinéraire.

doublejosh
la source
Il n'y a pas de module D7 et le dernier commit date d'il y a six mois.
jantimon
Fonctionne
1

J'ai commencé avec la réponse de googletorp et j'ai construit une fonction générique:

/**
 * Overrides a third-party template file with a local copy.
 *
 * To be called from hook_theme_registry_alter():
 * @code
 * function mymodule_theme_registry_alter(&$theme_registry) {
 *   // Override variant of foo template using local copy.
 *   custom_override_template($theme_registry, 'foo--variant', drupal_get_path('module', 'mymodule') . '/templates');
 * }
 * @endcode
 *
 * @param array $theme_registry
 *   Theme registry array as passed to hook_theme_registry_alter().
 * @param string $template
 *   Name of template file without '.tpl.php' extension. Example: 'foo--variant'.
 * @param string $path
 *   Directory to load $template from.
 * @param string $preprocess_function
 *   Optional preprocess function.
 */
function custom_override_template(&$theme_registry, $template, $path, $preprocess_function = NULL) {
  if (strpos($template, '--') !== FALSE) {
    $hook_name = array_shift(explode('--', $template));
  }
  else {
    $hook_name = $template;
  }
  $hook_name = str_replace('-', '_', $hook_name);
  if (isset($theme_registry[$hook_name])) {
    // Copy hook info.
    $hook_info = $theme_registry[$hook_name];
    $hook_info['path'] = $path;
    $hook_info['template'] = $template;
    // Add to theme registry.
    $new_hook = str_replace('-', '_', $template);
    $theme_registry[$new_hook] = $hook_info;
    // Add preprocess function.
    if(!is_null($preprocess_function)){
      $theme_registry[$new_hook]['preprocess functions'][] = $preprocess_function;
    }
    return $new_hook;
  }
  else {
    throw new Exception(t('Unknown theme hook %hook.', array('%hook' => $hook_name)));
  }
}

Il permet non seulement d'écraser la position et le nom du nœud et d'afficher les fichiers tpl, mais également de fournir une fonction de prétraitement pour les vues.

Donc, si vous avez appelé votre propre module mymoduleavec un fichier de modèle, sites/all/modules/mymodule/templates/foo--variant.tpl.phpvous pouvez maintenant facilement modifier le registre des thèmes pour utiliser votre propre répertoire de modèles:

function mymodule_theme_registry_alter(&$theme_registry) {
   // Override variant of foo template using local copy.
   custom_override_template($theme_registry, 'foo--variant', drupal_get_path('module', 'mymodule') . '/templates');
}
jantimon
la source
Cela oblige Drupal à utiliser le modèle dans votre dossier de module. Un thème ne pourra pas le remplacer (ce qu'il devrait être).
jcisio
1

Comme l'a dit @jcsio, la réponse acceptée sur cette page fonctionne, mais le modèle ne peut pas être remplacé par un thème.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry propose une solution qui vous permet d'ajouter le chemin de votre module (et sous-dossiers) à scanner pour toutes sortes des fichiers .tpl.php.

Je l'ai légèrement changé, car il contenait une variable `` chemins de thème '' qui ne semble pas utilisée par Drupal 7.

/**
 * Implements hook_theme_registry_alter()
**/
function mymodule_theme_registry_alter(&$theme_registry) {
  $mod_path = drupal_get_path('module', 'mymodule');
  $theme_registry_copy = $theme_registry;       // munge on a copy
  _theme_process_registry($theme_registry_copy, 'phptemplate', 'theme_engine', 'pow', $mod_path);
  $theme_registry += array_diff_key($theme_registry_copy, $theme_registry);
}

J'ai essayé à la fois la réponse acceptée et cette solution, cette dernière fonctionne pour moi jusqu'à présent!

lmeurs
la source