Agregar una sugerencia de tema programáticamente

8

Creé un módulo de características que contiene solo una vista y un tipo de contenido.

En este momento, mis page-node-x.tpl.phpy mis views-view-y.tpl.phparchivos se encuentran en mi directorio de temas.

¿Es posible moverlos a mi módulo de características?

jantimon
fuente

Respuestas:

5

Un módulo que implementa hook_preprocess_page()o hook_preprocess_node()puede sugerir nuevos archivos de plantilla alterando la variable $variables['theme_hook_suggestions'].

El código contenido en template_preprocess_page () que inicializa esa variable es el siguiente.

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

Cada sugerencia de tema debe coincidir con una entrada devuelta por hook_theme () .

En Vistas, debe haber una función de preproceso equivalente para usar de manera similar, o una forma que permita hook_preprocess_page()que la función entienda si la página está asociada con una vista.

kiamlaluno
fuente
3

La solución para agregar la clave de 'archivo de plantilla' hook_views_api()todavía no parece funcionar en Drupal 7. Sin embargo, esto funciona como un encanto:

/**
 * 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
fuente
2

El registro de temas es donde Drupal almacena todo tipo de información sobre qué archivos de plantilla, funciones de tema, etc. utilizar. Jugar con él puede llevar a WTF momentos después, ya que las cosas no funcionarán como predeterminadas.

De todos modos, como todas las cosas de Drupal, hay un gancho: hook_theme_registry_alterpuede usar para alterar el registro de temas y esto mueve sus archivos de plantilla a un módulo. No recomendaría hacer esto, ya que hará que el mantenimiento del sitio sea más complejo. Pero si quieres hacerlo, así es como se hace.

googletorp
fuente
+1 - Lo intenté pero sin éxito. ¿Podrías dar un ejemplo?
jantimon
@Ghommey: el enlace provisto viene con un código de ejemplo, no estoy seguro de cómo explicarlo mejor.
googletorp
2

Para las vistas, en teoría existe un mecanismo para las plantillas de vistas (tal vez funcione para todas las plantillas).

Puede establecer la clave "ruta de la plantilla" en su implementación hook_views_api de su módulo personalizado.

Una vez que tenga estas vistas, escaneará el directorio especificado para buscar archivos de plantilla. Lamentablemente, el más simple falla actualmente, por lo que esta característica probablemente aún no se ha portado a drupal7, pero si alguien quiere ingresar, consulte _views_find_module_templates () en views.module.

Daniel Wehner
fuente
2

La forma más fácil es usar hook_theme_registry_alter()y simplemente agregar la ruta de su módulo a las rutas de tema:

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
fuente
En cuanto a la theme()implementación, no parece que theme pathpueda ser una matriz. ¿Estás seguro de que esto funciona? Ver api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel
Con respecto a mi comentario anterior: theme pathssolía funcionar en Drupal 6, pero Drupal 7 cambió ese comportamiento en drupal.org/node/678714 Parece, de los comentarios # 29 y # 31 en el tema mencionado, que las sugerencias de temas de los módulos deben declararse en el hook_theme de ese módulo, pero cómo hacerlo se deja como ejercicio para el lector: /
Capi Etheriel
1

¿Qué tal un enfoque ligeramente abstracto con Context Reaction Theme?

http://drupal.org/project/context_reaction_theme

Termine su contexto en Características e incluso es exportable. Pero tal vez esta es realmente una pregunta del gurú de Drupal que busca crear algo más profundo y conocer la ruta.

doublejosh
fuente
No hay un módulo D7 y la última confirmación fue hace medio año.
jantimon
Todavía funciona muy bien en mis sitios de Drupal 6 :)
doublejosh
1

Comencé con la respuesta de googletorp y construí una función genérica:

/**
 * 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)));
  }
}

Permite no solo sobrescribir la posición y el nombre del nodo y ver los archivos tpl, sino también proporcionar una función de preproceso para las vistas.

Entonces, si llama a su propio módulo mymodulecon un archivo de plantilla, por ejemplo sites/all/modules/mymodule/templates/foo--variant.tpl.php, ahora puede modificar fácilmente el registro de temas para usar su propio directorio de plantillas:

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
fuente
Esto obliga a Drupal a usar la plantilla en la carpeta de su módulo. Un tema no podrá anularlo (que debería ser).
jcisio
1

Como dijo @jcsio, la respuesta aceptada en esta página funciona, pero la plantilla no puede ser anulada por un tema.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry ofrece una solución que le permite agregar la ruta de su módulo (y subcarpetas) para escanear todo tipo de archivos .tpl.php.

Lo cambié ligeramente, ya que contenía una variable de 'rutas de tema' que parece no ser utilizada por 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);
}

Intenté tanto la respuesta aceptada como esta solución, ¡esta última me funciona hasta ahora!

lmeurs
fuente