Добавление тематического предложения программно

8

Я создал функциональный модуль, содержащий только вид и тип контента.

Прямо сейчас мои page-node-x.tpl.phpи мои views-view-y.tpl.phpфайлы лежат в моем каталоге тем.

Можно ли переместить их в мой функциональный модуль?

jantimon
источник

Ответы:

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

Решение по добавлению ключа 'template file' hook_views_api()пока не работает в Drupal 7. Тем не менее, это работает как шарм:

/**
 * 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, поскольку все будет работать не так, как по умолчанию.

В любом случае, как и у всех друпалов, есть ловушка: hook_theme_registry_alterвы можете использовать ее, чтобы изменить реестр тем, и это переместит ваши файлы шаблонов в модуль. Я бы не советовал делать это, поскольку это сделает обслуживание сайта более сложным. Но если вы хотите сделать это, вот как это делается.

googletorp
источник
+1 - я пробовал это, но безуспешно .. Не могли бы вы привести пример?
Январь
@Ghommey: предоставленная ссылка идет с примером кода, не знаю, как это объяснить лучше.
googletorp
2

Для представлений в теории существует механизм для шаблонов представлений (возможно, он работает для всех шаблонов).

Вы можете установить ключ "путь к шаблону" в вашей реализации hook_views_api вашего пользовательского модуля.

Как только у вас появятся эти представления, вы будете сканировать указанный каталог на наличие файлов шаблонов. К сожалению, самый простой в настоящее время не работает, так что эта функция, вероятно, еще не перенесена в drupal7, но если кто-то хочет попасть в него, смотрите _views_find_module_templates () в views.module.

Дэниел Венер
источник
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
Что касается моего комментария выше: theme pathsраньше работал в Drupal 6, но Drupal 7 изменил это поведение в drupal.org/node/678714 Из комментариев № 29 и № 31 в упомянутом выпуске кажется, что предложения тем из модулей должны быть объявлены в модуле hook_theme этого модуля, но как это сделать, оставлено читателю в качестве упражнения: /
Capi Etheriel
1

Как насчет слегка абстрагированного подхода с Context Theme?

http://drupal.org/project/context_reaction_theme

Оберните ваш контекст в функции, и это даже можно экспортировать. Но, возможно, это на самом деле вопрос гуру из Drupal, который хочет создать что-то более глубокое и узнать маршрут.

doublejosh
источник
Там нет модуля D7 и последний коммит был пол года назад.
Январь
По-прежнему работает очень хорошо на моих сайтах Drupal 6 :)
doublejosh
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');
}
jantimon
источник
Это заставляет Drupal использовать шаблон в папке вашего модуля. Тема не сможет ее переопределить (что и должно быть).
jcisio
1

Как сказал @jcsio, принятый ответ на этой странице работает, но шаблон не может быть переопределен темой.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry предлагает решение, позволяющее добавить путь для сканирования вашего модуля (и подпапок) для всех видов файлов .tpl.php.

Я немного изменил его, так как он содержал переменную 'theme paths', которая, похоже, не использовалась в 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);
}

Я попробовал как принятый ответ, так и это решение, последнее у меня пока работает!

lmeurs
источник