Programowe dodawanie sugestii motywu

8

Utworzyłem moduł funkcji zawierający tylko widok i typ zawartości.

W tej chwili moje page-node-x.tpl.phpi moje views-view-y.tpl.phppliki znajdują się w moim katalogu motywów.

Czy można przenieść je do mojego modułu funkcji?

jantimon
źródło

Odpowiedzi:

5

Moduł, który implementuje hook_preprocess_page()lub hook_preprocess_node()może sugerować nowe pliki szablonów poprzez zmianę zmiennej $variables['theme_hook_suggestions'].

Kod zawarty w template_preprocess_page (), które inicjują tę zmienną, jest następujący.

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

Każda sugestia motywu musi być zgodna z wpisem zwróconym przez hook_theme () .

W widokach powinna istnieć równoważna funkcja przetwarzania wstępnego, której można używać w podobny sposób, lub sposób, hook_preprocess_page()który pozwala tej funkcji zrozumieć, czy strona jest powiązana z widokiem.

kiamlaluno
źródło
3

Rozwiązanie polegające na dodaniu klucza do pliku szablonu hook_views_api()nie działa jeszcze w Drupal 7. Działa to jednak jak urok:

/**
 * 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
źródło
2

Rejestr motywów to miejsce, w którym Drupal przechowuje różnego rodzaju informacje o tym, jakich plików szablonów, funkcji motywów itp. Użyć. Bałagan z tym może prowadzić do WTF chwilę później, ponieważ rzeczy nie będą działać jak domyślne.

W każdym razie, podobnie jak wszystkie rzeczy drupal, istnieje pewien haczyk: hook_theme_registry_altermożesz użyć, aby zmienić rejestr motywów i przenieść pliki szablonów do modułu. Nie radzę tego robić, ponieważ sprawi to, że utrzymanie strony będzie bardziej skomplikowane. Ale jeśli chcesz to zrobić, oto jak to zrobić.

googletorp
źródło
+1 - Próbowałem tego, ale bez powodzenia. Czy możesz podać przykład?
jantimon
@ Ghommey: podany link zawiera przykładowy kod, nie wiem, jak to lepiej wyjaśnić.
googletorp
2

W przypadku widoków teoretycznie istnieje mechanizm szablonów widoków (być może działa dla wszystkich szablonów).

Możesz ustawić kluczową „ścieżkę szablonu” w implementacji modułu niestandardowego hook_views_api.

Po uzyskaniu tych widoków przeskanuje podany katalog w poszukiwaniu plików szablonów. Niestety najprostszy obecnie nie działa, więc ta funkcja prawdopodobnie nie została jeszcze przeniesiona na drupal7, ale jeśli ktoś chce się do niej dostać, zobacz _views_find_module_templates () w views.module.

Daniel Wehner
źródło
2

Najprostszym sposobem jest użycie hook_theme_registry_alter()i dodanie ścieżki modułu do ścieżek motywu:

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
źródło
Patrząc na theme()implementację, nie wydaje się, że theme pathmoże być tablicą. Jesteś pewien, że to działa? Zobacz api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel,
Jeśli chodzi o mój komentarz powyżej: theme pathskiedyś działał w Drupal 6, ale Drupal 7 zmienił to zachowanie w drupal.org/node/678714 Wydaje się, że z komentarzy # 29 i # 31 we wspomnianym numerze, należy zadeklarować sugestie tematyczne z modułów w module hook_theme tego modułu, ale jak to zrobić, pozostaje dla czytelnika ćwiczenie: /
Capi Etheriel,
1

A może nieco abstrakcyjne podejście z tematem Reakcja kontekstowa?

http://drupal.org/project/context_reaction_theme

Zakończ swój kontekst w funkcjach, a nawet można go eksportować. Ale może to właściwie pytanie guru Drupala, które chce stworzyć coś głębszego i poznać trasę.

doublejosh
źródło
Nie ma modułu D7, a ostatnie zatwierdzenie było pół roku temu.
jantimon
Nadal działa naprawdę dobrze na moich stronach Drupal 6 :)
doublejosh
1

Zacząłem od odpowiedzi googletorp i zbudowałem ogólną funkcję:

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

Pozwala to nie tylko na zastąpienie pozycji i nazwy węzła oraz przeglądanie plików tpl, ale także zapewnia funkcję wstępnego przetwarzania dla widoków.

Więc jeśli masz własny moduł wywoływany mymodulez plikiem szablonu, np. sites/all/modules/mymodule/templates/foo--variant.tpl.phpMożesz teraz łatwo zmodyfikować rejestr motywów, aby używał własnego katalogu szablonów:

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
źródło
Zmusza to Drupal do korzystania z szablonu w folderze modułu. Motyw nie będzie w stanie go zastąpić (co powinno być).
jcisio
1

Jak powiedział @jcsio, zaakceptowana odpowiedź na tej stronie działa, ale szablon nie może zostać zastąpiony przez motyw.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry oferuje rozwiązanie, które pozwala dodać ścieżkę modułu (i podfolderów) do skanowania w poszukiwaniu wszystkich rodzajów plików .tpl.php.

Lekko go zmieniłem, ponieważ zawierał zmienną „ścieżki motywu”, która wydaje się nie używana przez Drupala 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);
}

Wypróbowałem zarówno zaakceptowaną odpowiedź, jak i to rozwiązanie, które do tej pory działa dla mnie!

lmeurs
źródło