Come dire a Drupal di cercare modelli nella directory del modulo?


11

Vorrei fornire l'implementazione del modello nel mio modulo e consentire ai temi di sovrascriverlo. Fondamentalmente, aggiungo un suggerimento con questo codice semplificato:

function attach_preprocess_node(&$vars) {
  $vars['theme_hook_suggestions'][] = 'node__test';
}

(Non voglio usare hook_theme per aggiungere un nuovo tema perché voglio riutilizzare le funzioni del nodo di preelaborazione. Il nome del tema è scomodo ma non voglio scrivere node_ attach _% per evitare confusione con il tipo di nodo.)

Quindi uso hook_theme_registry_alter () per aggiungere il percorso del modulo:

function attach_theme_registry_alter(&$theme_registry) {
  $path = drupal_get_path('module', 'attach') . '/themes';
  $theme_registry_copy = $theme_registry;
  _theme_process_registry($theme_registry_copy, 'phptemplate', 'theme_engine', 'node', drupal_get_path('module', 'node'));
  $theme_registry += array_diff_key($theme_registry_copy, $theme_registry);
  if (!isset($theme_registry['node']['theme paths'])) {
    $theme_registry['node']['theme paths'] = array();
  }
  if (!isset($theme_registry['node']['theme paths'])) {
    $first_element = array_shift($theme_registry['node']['theme paths']);
    if ($first_element) {
      array_unshift($theme_registry['node']['theme paths'], $first_element, $path);
    }
    else {
      array_unshift($theme_registry['node']['theme paths'], $path);
    }
  }
}

Comunque, non funziona. Ciò significa che il file temi / nodo - super.tpl.php non viene utilizzato. È usato solo se l'ho copiato nella cartella del tema.


Chiarimento: voglio che Drupal cerchi nella directory del modulo (e anche nelle directory dei temi) un modello definito dal codice (qui: modello di nodo). Non voglio definire un nuovo modello.
jcisio,

Risposte:


5

Fondamentalmente puoi risparmiare un po 'di mal di testa implementando hook_theme()invece di alterare il registro.

Suggerisco di dare un'occhiata a theming_example nel progetto Esempi , riprodotto facilmente in questa pagina del documento API , forse con un codice particolarmente utile in questa pagina .

function theming_example_list_page() {
  $items = array(
    t('First item'),
    t('Second item'),
    t('Third item'),
    t('Fourth item'),
  );

  // First we'll create a render array that simply uses theme_item_list.
  $title = t("A list returned to be rendered using theme('item_list')");
  $build['render_version'] = array(
    // We use #theme here instead of #theme_wrappers because theme_item_list()
    // is the classic type of theme function that does not just assume a
    // render array, but instead has its own properties (#type, #title, #items).
    '#theme' => 'item_list',
    // '#type' => 'ul',  // The default type is 'ul'
    // We can easily make sure that a css or js file is present using #attached. 
    '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), 
    '#title' => $title, 
    '#items' => $items, 
    '#attributes' => array('class' => array('render-version-list')),
  );

  // Now we'll create a render array which uses our own list formatter,
  // theme('theming_example_list').
  $title = t("The same list rendered by theme('theming_example_list')");
  $build['our_theme_function'] = array(
    '#theme' => 'theming_example_list', 
    '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), 
    '#title' => $title, 
    '#items' => $items,
  );
  return $build;
}

Questo è tutto per Drupal 7.


Come ho detto nella domanda, non voglio usare hook_theme () perché voglio riutilizzare $ variabili nel modello di nodo. Queste variabili sono generate nel processo hook_ (pre) di molti moduli che non conoscono l'esistenza del mio tema (se ne definisco uno).
jcisio,

Il modo in cui definisci un tema è ... con hook_theme (). :-) Puoi definire le funzioni tematiche in hook_theme (). Dai loro il nome che vuoi. Crea funzioni di shim, se vuoi. Documenti API: "hook_theme_HOOK () ... deve essere utilizzato solo se un modulo deve sovrascrivere o aggiungere alla preelaborazione del tema per un hook tema che non ha definito."
paul-m

Non voglio definire un tema. Se definisci il tema 'mynode' invece di riutilizzare 'nodo', non hai alcuna variabile nel tuo file .tpl.php.
jcisio,

1
Questo non sembra vero: le chiamate a tema sono cumulative, quindi l'implementazione hook_themedovrebbe darti il $existingparametro che ti permette di modificare la cosa, non ignorarla. Se non è così, forse stai colpendo un bug.
Countzero,

@Countzero quando dichiari un tema node_attach, allora tutte le funzioni hook_preprocess_node non avranno luogo con il tuo nuovo tema. Cioè non hai nulla nel tuo nodo-attach.tpl.php.
jcisio,

5

Forse questo funziona:

/**
 * Implements hook_theme().
 */
function MODULE_theme($existing, $type, $theme, $path) {
  return array (
    'node__CONTENTTYPE' => array (
      'variables' => array( . . . ),
      'template' => 'node--CONTENTTYPE' ,
      'base hook' => 'node',
      'path' => drupal_get_path('module', 'MODULE'),
    ),
  );
}

Importante qui è la chiave ' gancio di base '.


Ecco il problema per l'aggiunta di documentazione per base hook: drupal.org/node/2106635
Andy,

+1 voto - questa e la risposta derivata da batigotix ho trovato funzionante. Grazie.
therobyouknow,

2

Mi piace la soluzione di dashohoxha dell'implementazione hook_theme ma non sono riuscito a farlo funzionare. Dopo qualche altro googling ho trovato una variante che ha funzionato bene per me:

/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  $theme = array();
  $theme['node__blog_post'] = array(
    'render element' => 'content',
    'base hook' => 'node',
    'template' => 'node--blog_post',
    'path' => drupal_get_path('module', 'mymodule') . '/templates',
   );
  return $theme;
}

Note: il mio modulo personalizzato si chiama "mymodule" e il mio tipo di contenuto personalizzato si chiama "blog_post". Il tpl.php che uso si chiama 'nodo - blog_post.tpl.php' e si trova nella sottocartella 'modelli' del mio modulo.


+1 grazie ho scoperto che funziona. Se sei anche interessato a sovrascrivere le funzioni template.php all'interno del tuo modulo personalizzato, dai un'occhiata a: snugug.com/musings/override-theme-functions-drupal-7-module - Ho trovato che funziona molto bene
therobyouknow

2

Ecco il mio frammento per dichiarare i modelli di viste memorizzati nella cartella "template" del mio "custom_module":

/**
 * Implements hook_theme_registry_alter().
 */
function custom_module_theme_registry_alter(&$theme_registry) {
  $extension   = '.tpl.php';
  $module_path = drupal_get_path('module', 'custom_module');
  $files       = file_scan_directory($module_path . '/templates', '/' . preg_quote($extension) . '$/');

  foreach ($files as $file) {
    $template = drupal_basename($file->filename, $extension);
    $theme    = str_replace('-', '_', $template);
    list($base_theme, $specific) = explode('__', $theme, 2);

    // Don't override base theme.
    if (!empty($specific) && isset($theme_registry[$base_theme])) {
      $theme_info = array(
        'template'   => $template,
        'path'       => drupal_dirname($file->uri),
        'variables'  => $theme_registry[$base_theme]['variables'],
        'base hook'  => $base_theme,
        // Other available value: theme_engine.
        'type'       => 'module',
        'theme path' => $module_path,
      );

      $theme_registry[$theme] = $theme_info;
    }
  }
}

Spero che aiuti qualcuno.


mi ha salvato il tempo. Funziona e richiede anche per d8
Mykola Mykolayovich Dolynskyi il

-1

L'ho chiesto una volta su StackTranslate.it . Fondamentalmente, devi implementare hook_theme_registry_alter()per ottenere il tuo percorso aggiunto al percorso del modello di hook del tema; quindi, su hook_enable(), chiami drupal_theme_rebuild () per cancellare la cache del registro dei temi e scansionare il tuo percorso alla ricerca di modelli.


Forse ciò che ti sta trattenendo è solo svuotare le cache.
Capi Etheriel,

Quindi, sostanzialmente la stessa soluzione. Ho provato "drush cc all" non meno di 50 volte, l'ho provato su un nuovo sito di installazione ecc. Senza successo. Modificherò e compatterò il mio codice in un modulo minimo in modo che tutti possano testarlo.
jcisio,

hook_enable()viene richiamato quando un modulo è abilitato; se il modulo è già abilitato, deve essere disabilitato e quindi nuovamente abilitato.
kiamlaluno

@kiamlaluno: iḿ utilizzando hook_enable per cancellare le cache, se è già installato, l'utente potrebbe semplicemente cancellare manualmente le cache.
Capi Etheriel,

NO , -1 punti. Quella soluzione è così vecchia (2009), non sono nemmeno sicuro che fosse pensata per D7. Mentre la tua vecchia soluzione è su misura per Views, non è l'ideale per situazioni diverse da Views in cui gli sviluppatori potrebbero voler impacchettare più di 1 modello predefinito per chiave tema nei loro moduli. Immagina di implementare la tua soluzione per 100 suggerimenti di temi dinamici per una singola chiave del tema. Applicato al di fuori di un contesto di Views, definirei la tua soluzione un contromodello.
barista dilettante
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.