Drupal'a modül dizinindeki şablonları aramasını nasıl söyleyebilirim?


11

Modülümde şablon uygulamasını sağlamak ve temaların geçersiz kılmasına izin vermek istiyorum. Temel olarak, bu basitleştirilmiş kod ile bir öneri ekleyin:

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

(Ön işlem düğümü işlevlerini yeniden kullanmak istediğim için yeni bir tema eklemek için hook_theme kullanmak istemiyorum. Tema adı garip ama düğüm türü ile karışıklığı önlemek için node_ attach _% yazmak istemiyorum .)

Sonra modül yolu eklemek için hook_theme_registry_alter () kullanın:

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

Ancak işe yaramıyor. Bunun anlamı: dosya temaları / düğümü - super.tpl.php kullanılmıyor. Yalnızca tema klasörüne kopyaladıysam kullanılır.


Açıklama: Drupal'ın kod tarafından tanımlanan bir şablon için modül dizinine (ve ayrıca tema dizinlerine) bakmasını istiyorum (burada: düğüm şablonu). Yeni bir şablon tanımlamak istemiyorum.
jcisio

Yanıtlar:


5

Temel olarak hook_theme()kayıt defterini değiştirmek yerine uygulayarak kendinizi biraz baş ağrısından kurtarabilirsiniz .

Örnekler projesindeki theming_example öğesine , bu API doküman sayfasında kolayca çoğaltılabilir , belki de bu sayfadaki özellikle yararlı kodla bakmanızı öneririm .

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;
}

Bunların hepsi Drupal 7 için.


Soruda söylediğim gibi, ben düğüm şablonunda $ değişkenleri yeniden kullanmak istiyorum çünkü hook_theme () kullanmak istemiyorum. Bu değişkenler, temamın varlığını bilmeyen birçok modülün hook_ (pre) sürecinde üretilir (eğer bir tane tanımlarsam).
jcisio

Bir temayı tanımlama şekliniz ... hook_theme () ile. :-) Tema işlevlerini hook_theme () içinde tanımlayabilirsiniz. İstediğiniz her şeyi adlandırın. İsterseniz şim işlevlerini yapın. API dokümanları: "hook_theme_HOOK () ... yalnızca bir modülün tanımlayamadığı bir tema kancası için tema önişlemini geçersiz kılması veya eklenmesi gerektiğinde kullanılmalıdır."
paul-m

Bir tema tanımlamak istemiyorum. 'Düğüm'ü yeniden kullanmak yerine' mynode 'temanızı tanımlarsanız, .tpl.php dosyanızda herhangi bir değişkeniniz olmaz.
jcisio

1
Bu doğru görünmüyor: tema çağrıları kümülatiftir, bu nedenle uygulama size bir şeyi değiştirmenize izin vermeyen bir parametre hook_themevermelidir $existing. Eğer durum böyle değilse, belki de bir hataya çarpıyorsunuzdur.
Countzero

@Countzero, node_attach temasını bildirdiğinizde, tüm hook_preprocess_node işlevleri yeni temanızla gerçekleşmez. Yani node-attach.tpl.php dosyasında hiçbir şey yok.
jcisio

5

Belki bu işe yarar:

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

Burada önemli olan ' temel kanca '.


Şunun için belge ekleme sorunu base hook: drupal.org/node/2106635
Andy

+1 upvote - bu ve çalıştığım batigotixin türev cevabı. Teşekkürler.
therobyouknow

2

Ben dashohoxha'nın hook_theme uygulamasının çözümünü seviyorum ama çalıştıramadım. Biraz daha googling yaptıktan sonra benim için iyi çalışan bir varyasyon buldum :

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

Notlar: Özel modülüme 'mymodule' ve özel içerik türüme 'blog_post' denir. Kullandığım tpl.php 'node - blog_post.tpl.php' olarak adlandırılıyor ve modülümün 'şablonlar' alt klasöründe bulunuyor.


+1 teşekkürler bunu çalışmak için buldum. Özel modülünüzdeki template.php işlevlerini geçersiz kılmakla da ilgileniyorsanız, şuraya bakın: snugug.com/musings/override-theme-functions-drupal-7-module - Bunu çok iyi buldum
therobyouknow

2

İşte benim snippet benim "custom_module" benim "template" klasöründe saklanan görünüm şablonları bildirmek için:

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

Umarım birine yardımcı olur.


zamanımı kurtardı. Ayrıca çalışır ve d8 için gerekli
Mykola Mykolayovich Dolynskyi

-1

Bunu bir kez Stack Overflow'da sordum . Temel olarak, hook_theme_registry_alter()yolunuzun tema kanca şablonu yoluna eklenmesini sağlamak için uygulamanız gerekir; Daha sonra, üzerine hook_enable(), aramak () drupal_theme_rebuild tema kayıt önbelleğini temizleyin ve şablonlar için taranmış yolunu almak için.


Belki seni geride tutan şey önbellekleri temizlemektir.
Capi Etheriel

Yani, temelde aynı çözüm. En az 50 kez "drush cc all" denedim, yeni bir yükleme sitesinde vb. Kodumu değiştirip herkesin test edebilmesi için minimum modüle sıkıştırırım.
jcisio

hook_enable()bir modül etkinleştirildiğinde çağrılır; modül zaten etkinse devre dışı bırakılıp tekrar etkinleştirilmelidir.
kiamlaluno

@ kiamlaluno: iḿ önbellekleri temizlemek için hook_enable kullanarak, zaten kurulu ise kullanıcı önbellekleri manuel olarak temizleyebilir.
Capi Etheriel

NO , -1 puan. Bu çözüm çok eski (2009), bunun D7 için tasarlandığından bile emin değilim. Eski çözümünüz Görünümler için uyarlanmış olsa da, geliştiricilerin modüllerindeki tema anahtarı başına 1'den fazla varsayılan şablon için paketlemek isteyebilecekleri Görünümler dışındaki durumlar için ideal değildir. Çözümünüzü tek bir tema anahtarı için 100 dinamik tema önerisi için uyguladığınızı düşünün. Views bağlamının dışında uygulandığında, çözümünüze bir karşı kalıp derim.
amatör barista
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.