以编程方式添加主题建议


8

我创建了仅包含视图和内容类型的功能模块。

现在,我page-node-x.tpl.php和我的views-view-y.tpl.php文件位于主题目录中。

是否可以将它们移入我的功能模块?

Answers:


5

通过更改变量来实现hook_preprocess_page()hook_preprocess_node()可以建议新模板文件的模块$variables['theme_hook_suggestions']

template_preprocess_page()中包含的用于初始化该变量的代码如下。

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

每个主题建议都需要与hook_theme()返回的条目匹配。

在视图中,应该有一个等效的预处理功能以类似的方式使用,或者hook_preprocess_page()允许该功能使该功能了解页面是否与视图关联的方式。


3

在' hook_views_api()Drupal 7 '中似乎没有添加'template file'键的解决方案。但是,这就像一个魅力:

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

2

在主题注册表中,Drupal存储了有关要使用的模板文件,主题功能等的各种信息。混乱可能导致稍后的WTF时刻,因为事情不会像默认情况那样起作用。

无论如何像drupal一样,都有一个钩子:hook_theme_registry_alter您可以使用它来更改主题注册表,并将模板文件移动到模块中。我不建议这样做,因为这会使站点维护更加复杂。但是,如果您想这样做,就是这样完成的。


+1-我尝试过但没有成功。.请您举个例子吗?
jantimon 2011年

@Ghommey:提供的链接附带示例代码,不确定如何更好地解释它。
googletorp

2

对于视图,理论上有一种用于视图模板的机制(也许它适用于所有模板)。

您可以在自定义模块的hook_views_api实现中设置键“模板路径”。

拥有此视图后,将在指定的目录中扫描模板文件。遗憾的是,目前最简单的测试失败了,因此该功能可能尚未移植到drupal7,但是如果有人想进入它,请在views.module中查看_views_find_module_templates()。


2

最简单的方法是使用hook_theme_registry_alter()模块路径并将其添加到主题路径中:

function mymodule_theme_registry_alter(&$theme_registry) {
  $theme_registry['[theme hook name, ie. page or views-view]']['theme paths'][] = drupal_get_path('module', 'mymodule');
}

theme()实现的角度看,它似乎不是theme path一个数组。您确定这可行吗?参见api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel 2012年

关于我上面的评论:theme paths曾经在Drupal 6中工作,但是Drupal 7在drupal.org/node/678714中更改了该行为。 从上述问题的评论#29和#31看来,必须声明模块的主题建议在该模块的hook_theme中,但如何做作为练习留给读者:/
Capi Etheriel 2012年


1

我从googletorp答案开始,并构建了一个通用函数:

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

它不仅可以覆盖节点和视图的tpl文件的位置和名称,还可以为视图提供预处理功能。

因此,如果mymodule使用模板文件调用了自己的模块,例如sites/all/modules/mymodule/templates/foo--variant.tpl.php,现在可以轻松地修改主题注册表以使用自己的模板目录:

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');
}

这将迫使Drupal使用模块文件夹中的模板。主题将无法覆盖它(应该覆盖)。
jcisio 2012年

1

正如@jcsio所说,此页面上可接受的答案有效,但是模板不能被主题覆盖。

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry提供了一种解决方案,可让您添加要扫描的模块(和子文件夹)的路径,以进行各种扫描.tpl.php文件。

我对其做了些微更改,因为它包含了一个看起来没有被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);
}

我尝试了已接受的答案和此解决方案,到目前为止,后者对我有用!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.