Відповіді:
Модуль, який реалізує 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;
}
Кожна пропозиція теми повинна збігатися із записом, поверненим mong_theme () .
У Переглядах має бути еквівалентна функція попередньої обробки, яка використовується аналогічним чином, або спосіб, hook_preprocess_page()
який дозволяє цій функції зрозуміти, чи пов’язана сторінка з представленням даних.
Рішення для додавання ключа "файл шаблону" 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',
),
);
}
Реєстр тем - це те, де Drupal зберігає всіляку інформацію про файли шаблонів, тематичні функції тощо. Невміння з ним може призвести до появи моментів WTF, оскільки все не працюватиме як за замовчуванням.
У будь-якому випадку, як у всіх речах drupal, є гачок: hook_theme_registry_alter
ви можете використовувати для зміни реєстру тем і переміщення файлів шаблонів у модуль. Я б не радив це робити, оскільки це зробить підтримку сайту більш складним. Але якщо ви хочете це зробити, так це робиться.
Для переглядів теоретично існує механізм для шаблонів поглядів (можливо, він працює для всіх шаблонів).
Ви можете встановити ключ "шлях до шаблону" у вашій реалізації куки-перегляду_апі вашого спеціального модуля.
Після того, як ви отримаєте цей вид, скануйте вказаний каталог для файлів шаблонів. На жаль, найпростіший на даний момент не вдається, тому ця функція, мабуть, ще не перенесена на drupal7, але якщо хтось хоче ввійти в нього, дивіться _views_find_module_templates () у views.module.
Найпростіший спосіб - використовувати 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
theme paths
раніше працював у Drupal 6, але Drupal 7 змінив таку поведінку в drupal.org/node/678714 З огляду на коментарі №29 та №31 у згаданому випуску, здається, що пропозиції щодо модулів повинні бути оголошені у гачці_теми цього модуля, але як це зробити, залишається читачеві вправу: /
Як щодо трохи абстрагованого підходу з темою реакції на контекст?
http://drupal.org/project/context_reaction_theme
Загорніть свій контекст у функції, і це навіть можна експортувати. Але, можливо, це насправді питання про гуру Друпала, яке хоче створити щось глибше і знати маршрут.
Я почав з відповіді 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');
}
Як сказав @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);
}
Я спробував і прийняту відповідь, і це рішення, останній для мене працює поки що!