Programmgesteuertes Hinzufügen eines Themenvorschlags

8

Ich habe ein Feature-Modul erstellt, das nur eine Ansicht und einen Inhaltstyp enthält.

Im Moment liegen meine page-node-x.tpl.phpund meine views-view-y.tpl.phpDateien in meinem Themenverzeichnis.

Ist es möglich, sie in mein Funktionsmodul zu verschieben?

jantimon
quelle

Antworten:

5

Ein Modul, das neue Vorlagendateien implementiert hook_preprocess_page()oder hook_preprocess_node()vorschlagen kann, indem die Variable geändert wird $variables['theme_hook_suggestions'].

Der in template_preprocess_page () enthaltene Code , der diese Variable initialisiert, lautet wie folgt.

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

Jeder Themenvorschlag muss mit einem Eintrag übereinstimmen, der von hook_theme () zurückgegeben wird .

In Ansichten sollte es eine äquivalente Vorverarbeitungsfunktion geben, die auf ähnliche Weise verwendet werden kann, oder eine Möglichkeit, die hook_preprocess_page()es der Funktion ermöglicht, zu verstehen, ob die Seite einer Ansicht zugeordnet ist.

kiamlaluno
quelle
3

Die Lösung zum Hinzufügen des Schlüssels "Vorlagendatei" hook_views_api()scheint in Drupal 7 noch nicht zu funktionieren. Dies funktioniert jedoch wie ein Zauber:

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

In der Themenregistrierung speichert Drupal alle möglichen Informationen darüber, welche Vorlagendateien, Themenfunktionen usw. verwendet werden sollen. Das Spiel damit kann zu WTF-Momenten später führen, da die Dinge nicht wie standardmäßig funktionieren.

Wie bei allen Drupal-Dingen gibt es auch hier einen Haken: hook_theme_registry_alterSie können die Theme-Registrierung ändern und so Ihre Vorlagendateien in ein Modul verschieben. Ich würde dies nicht empfehlen, da dies die Wartung der Website komplexer macht. Aber wenn Sie es tun möchten, ist es so.

googletorp
quelle
+1 - Ich habe es versucht, aber ohne Erfolg. Könnten Sie bitte ein Beispiel geben?
Jantimon
@Ghommey: Der bereitgestellte Link enthält Beispielcode, nicht sicher, wie er besser erklärt werden soll.
googletorp
2

Für Ansichten gibt es theoretisch einen Mechanismus für Ansichtsvorlagen (möglicherweise funktioniert er für alle Vorlagen).

Sie können den Schlüssel "Vorlagenpfad" in Ihrer hook_views_api-Implementierung Ihres benutzerdefinierten Moduls festlegen.

Sobald Sie diese Ansichten haben, durchsucht es Ihr angegebenes Verzeichnis nach Vorlagendateien. Leider schlägt der einfachste Test derzeit fehl, sodass diese Funktion wahrscheinlich noch nicht auf drupal7 portiert ist. Wenn jedoch jemand darauf zugreifen möchte, lesen Sie _views_find_module_templates () in views.module.

Daniel Wehner
quelle
2

Am einfachsten ist es hook_theme_registry_alter(), den Pfad Ihres Moduls zu den Themenpfaden zu verwenden und hinzuzufügen:

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
quelle
In Bezug auf die theme()Implementierung scheint es nicht so, als könnte es theme pathsich um ein Array handeln. Bist du sicher, dass das funktioniert? Siehe api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel
Zu meinem obigen Kommentar: theme pathsFrüher in Drupal 6 gearbeitet, aber Drupal 7 hat dieses Verhalten in drupal.org/node/678714 geändert. Aus den Kommentaren Nr. 29 und Nr. 31 in der genannten Ausgabe geht hervor, dass Themenvorschläge von Modulen deklariert werden müssen im hook_theme dieses Moduls, aber wie das geht, bleibt dem Leser als Übung überlassen: /
Capi Etheriel
1

Wie wäre es mit einem leicht abstrahierten Ansatz mit Context Reaction Theme?

http://drupal.org/project/context_reaction_theme

Schließen Sie Ihren Kontext in Features ab und er kann sogar exportiert werden. Aber vielleicht ist dies tatsächlich eine Drupal-Guru-Frage, die etwas Tieferes erschaffen und den Weg kennen möchte.

Doublejosh
quelle
Es gibt kein D7-Modul und das letzte Commit war vor einem halben Jahr.
Jantimon
Funktioniert immer noch sehr gut auf meinen Drupal 6-Sites :)
DoubleJosh
1

Ich begann mit der Antwort von googletorp und baute eine generische Funktion auf:

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

Es ermöglicht nicht nur das Überschreiben der Position und des Namens von Knoten- und Ansichts-TPL-Dateien, sondern auch das Bereitstellen einer Vorverarbeitungsfunktion für Ansichten.

Wenn Sie also ein eigenes Modul mymodulemit einer Vorlagendatei aufgerufen haben sites/all/modules/mymodule/templates/foo--variant.tpl.php, können Sie jetzt einfach die Themenregistrierung so ändern, dass Ihr eigenes Vorlagenverzeichnis verwendet wird:

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
quelle
Dies zwingt Drupal, die Vorlage in Ihrem Modulordner zu verwenden. Ein Thema kann es nicht überschreiben (was es sein sollte).
Jcisio
1

Wie @jcsio sagte, funktioniert die akzeptierte Antwort auf dieser Seite, aber die Vorlage kann nicht durch ein Thema überschrieben werden.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry bietet eine Lösung, mit der Sie den Pfad Ihres Moduls (und Ihrer Unterordner) hinzufügen können, um nach allen Arten gescannt zu werden von .tpl.php-Dateien.

Ich habe es leicht geändert, da es eine Variable 'Themenpfade' enthielt, die von Drupal 7 nicht verwendet zu werden scheint.

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

Ich habe sowohl die akzeptierte Antwort als auch diese Lösung ausprobiert, letztere funktioniert bisher für mich!

lmeurs
quelle