it-swarm.it

Aggiunta di un suggerimento di tema a livello di codice

Ho creato un modulo funzionale contenente solo una vista e un tipo di contenuto.

In questo momento il mio page-node-x.tpl.php e la mia views-view-y.tpl.php I file si trovano nella mia directory dei temi.

È possibile spostarli nel mio modulo funzionale?

8
jantimon

Ho iniziato con 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)));
  }
}

Permette non solo di sovrascrivere la posizione e il nome del nodo e 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 modificare facilmente il registro dei temi per utilizzare la tua directory dei modelli:

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');
}
1
jantimon

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() che consenta alla funzione di capire se la pagina è associata a una vista.

5
kiamlaluno

La soluzione per aggiungere la chiave "file modello" a hook_views_api() non sembra funzionare in Drupal 7. Tuttavia, questo funziona come un incantesimo:

/**
 * 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',
  ),
 );
}
3
Joe Hyde

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.

2
Daniel Wehner

Il registro dei temi è dove Drupal memorizza tutti i tipi di informazioni su quali file modello, funzioni dei temi ecc. Usare. Il pasticcio con esso può portare a momenti WTF in seguito, poiché le cose non funzioneranno come predefinite.

Comunque come tutte le cose drupal, c'è un gancio: hook_theme_registry_alter è possibile utilizzare per modificare il registro dei temi e spostare i file modello in un modulo. Non consiglierei di farlo, poiché renderà più complesso il mantenimento del sito. Ma se vuoi farlo è così.

2
googletorp

Il modo più semplice è usare hook_theme_registry_alter() e aggiungere semplicemente il percorso del tuo 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');
}
2
Damien Tournoud

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 ti consente di aggiungere il percorso del tuo modulo (e sottocartelle ) da sottoporre a scansione per tutti i tipi di file .tpl.php.

L'ho leggermente modificato, poiché conteneva una variabile "percorsi tematici" che non sembra 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!

1
lmeurs

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 Drupal guru che cerca di creare qualcosa di più profondo e conoscere il percorso.

1
doublejosh