Risposte:
Un modulo che implementa hook_preprocess_page()
o hook_preprocess_node()
può suggerire nuovi file modello modificando la variabile $variables['theme_hook_suggestions']
.
Il codice contenuto in template_preprocess_page () che inizializza quella variabile è il seguente.
// Populate the page template suggestions.
if ($suggestions = theme_get_suggestions(arg(), 'page')) {
$variables['theme_hook_suggestions'] = $suggestions;
}
Ogni suggerimento del tema deve corrispondere a una voce restituita da hook_theme () .
In Views, dovrebbe esistere una funzione di preelaborazione equivalente da utilizzare in modo simile o un modo che consenta a hook_preprocess_page()
tale funzione di comprendere se la pagina è associata a una vista.
La soluzione per aggiungere la chiave "file modello" hook_views_api()
non sembra funzionare ancora in Drupal 7. Tuttavia, questo funziona come un fascino:
/**
* 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',
),
);
}
Il registro dei temi è il punto in cui Drupal memorizza ogni tipo di informazione su quali file modello, funzioni del tema ecc. Usare. Fare confusione con esso può portare a WTF qualche momento dopo, poiché le cose non funzioneranno come predefinite.
Comunque come tutte le cose drupal, c'è un gancio: hook_theme_registry_alter
puoi usare per modificare il registro dei temi e questo sposta i tuoi file modello in un modulo. Non consiglierei di farlo, poiché renderà più complesso il mantenimento del sito. Ma se vuoi farlo è così.
Per le viste esiste in teoria un meccanismo per i modelli di viste (forse funziona per tutti i modelli).
Puoi impostare il "percorso modello" chiave nella tua implementazione hook_views_api del tuo modulo personalizzato.
Una volta che hai queste visualizzazioni scansionerà la tua directory specificata per i file modello. Purtroppo il più semplice al momento fallisce, quindi questa funzione probabilmente non è ancora stata portata su drupal7, ma se qualcuno vuole entrarci, vedi _views_find_module_templates () in views.module.
Il modo più semplice è utilizzare hook_theme_registry_alter()
e aggiungere semplicemente il percorso del modulo ai percorsi del tema:
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()
implementazione, non sembra che theme path
possa essere un array. Sei sicuro che funzioni? Vedi api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
theme paths
solito lavorare in Drupal 6, ma Drupal 7 ha cambiato quel comportamento in drupal.org/node/678714 Sembra, dai commenti n. 29 e n. 31 del problema citato, che i suggerimenti sui temi dei moduli debbano essere dichiarati nel hook_theme di quel modulo, ma come farlo viene lasciato come esercizio al lettore: /
Che ne dite di un approccio leggermente astratto con il tema della reazione al contesto?
http://drupal.org/project/context_reaction_theme
Completa il tuo contesto in Funzionalità ed è persino esportabile. Ma forse questa è in realtà una domanda del guru Drupal che cerca di creare qualcosa di più profondo e conoscere il percorso.
Ho iniziato con la risposta di googletorp e ho creato una funzione generica:
/**
* 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)));
}
}
Consente non solo di sovrascrivere la posizione e il nome del nodo e di visualizzare i file tpl, ma anche di fornire una funzione di pre-elaborazione per le viste.
Quindi, se hai il tuo modulo chiamato mymodule
con un file modello, ad esempio sites/all/modules/mymodule/templates/foo--variant.tpl.php
, ora puoi facilmente modificare il registro temi per usare la tua directory modello:
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');
}
Come ha detto @jcsio, la risposta accettata in questa pagina funziona, ma il modello non può essere sovrascritto da un tema.
http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry offre una soluzione che consente di aggiungere il percorso del modulo (e delle sottocartelle) da sottoporre a scansione per tutti i tipi di file .tpl.php.
L'ho leggermente modificato, poiché conteneva una variabile "percorsi tematici" che sembra non essere utilizzata da 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);
}
Ho provato sia la risposta accettata che questa soluzione, quest'ultima funziona per me finora!