Menambahkan saran tema secara terprogram

8

Saya membuat modul fitur yang hanya berisi tampilan dan tipe konten.

Saat ini file page-node-x.tpl.phpsaya dan saya views-view-y.tpl.phpberada di direktori tema saya.

Apakah mungkin memindahkannya ke modul fitur saya?

Jimimon
sumber

Jawaban:

5

Modul yang mengimplementasikan hook_preprocess_page()atau hook_preprocess_node()dapat menyarankan file templat baru dengan mengubah variabel $variables['theme_hook_suggestions'].

Kode yang terkandung dalam template_preprocess_page () yang menginisialisasi variabel itu adalah sebagai berikut.

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

Setiap saran tema harus sesuai dengan entri yang dikembalikan oleh hook_theme () .

Dalam Tampilan, harus ada fungsi preprocess yang setara untuk digunakan dengan cara yang sama, atau cara yang memungkinkan untuk hook_preprocess_page()fungsi untuk memahami jika halaman terkait dengan tampilan.

kiamlaluno
sumber
3

Solusi untuk menambahkan kunci 'file templat' ke hook_views_api()tampaknya belum berfungsi di Drupal 7. Namun, ini berfungsi seperti pesona:

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

Registri tema adalah tempat Drupal menyimpan segala macam info tentang file templat apa, fungsi tema dll untuk digunakan. Mengobrol dengannya dapat menyebabkan WTF beberapa saat kemudian, karena hal-hal tidak akan berfungsi seperti default.

Bagaimanapun seperti semua hal drupal, ada sebuah kait: hook_theme_registry_alterAnda dapat menggunakan untuk mengubah tema registry dan ini memindahkan file template Anda ke dalam modul. Saya tidak akan menyarankan melakukan ini, karena itu akan membuat pemeliharaan situs lebih kompleks. Tetapi jika Anda ingin lakukan adalah, ini adalah bagaimana hal itu dilakukan.

googletorp
sumber
+1 - Saya mencoba ini tetapi tidak berhasil .. Bisakah Anda memberikan contoh?
jantimon
@ Ghommey: Tautan yang diberikan disertai dengan kode contoh, tidak yakin bagaimana menjelaskannya dengan lebih baik.
googletorp
2

Untuk tampilan ada secara teori mekanisme untuk tampilan template (mungkin itu bekerja untuk semua template).

Anda dapat mengatur "path templat" kunci dalam implementasi hook_views_api modul khusus Anda.

Setelah Anda memiliki pandangan ini akan memindai direktori yang Anda tentukan untuk file template. Sayangnya yang paling sederhana saat ini gagal, jadi fitur ini mungkin belum porting ke drupal7, tetapi jika seseorang ingin masuk ke dalamnya, lihat _views_find_module_templates () di views.module.

Daniel Wehner
sumber
2

Cara termudah adalah menggunakan hook_theme_registry_alter()dan cukup menambahkan jalur modul Anda ke jalur 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');
}
Damien Tournoud
sumber
Melihat theme()implementasi, sepertinya tidak theme pathbisa menjadi array. Apakah Anda yakin ini berhasil? Lihat api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel
Mengenai komentar saya di atas: theme pathsdulu bekerja di Drupal 6, tetapi Drupal 7 mengubah perilaku itu di drupal.org/node/678714 Tampaknya, dari komentar # 29 dan # 31 dalam masalah yang disebutkan, saran tema dari modul harus dideklarasikan dalam hook_theme modul itu, tetapi bagaimana melakukannya dibiarkan sebagai latihan untuk pembaca: /
Capi Etheriel
1

Bagaimana dengan pendekatan yang agak abstrak dengan Tema Reaksi Konteks?

http://drupal.org/project/context_reaction_theme

Bungkus konteks Anda di Fitur dan bahkan dapat diekspor. Tapi mungkin ini sebenarnya pertanyaan guru Drupal yang ingin membuat sesuatu yang lebih dalam dan tahu rute.

doublejosh
sumber
Tidak ada modul D7 dan komit terakhir setengah tahun yang lalu.
jantimon
Masih bekerja dengan sangat baik di situs Drupal 6 saya :)
doublejosh
1

Saya mulai dengan jawaban googletorp dan membangun fungsi generik:

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

Hal ini memungkinkan tidak hanya untuk menimpa posisi dan nama node dan melihat file tpl tetapi juga untuk menyediakan fungsi preprocess untuk dilihat.

Jadi jika Anda mendapatkan modul Anda sendiri yang dipanggil mymoduledengan file templat mis. sites/all/modules/mymodule/templates/foo--variant.tpl.phpAnda sekarang dapat dengan mudah memodifikasi registry theme untuk menggunakan direktori templat Anda sendiri:

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');
}
Jimimon
sumber
Ini memaksa Drupal untuk menggunakan templat di folder modul Anda. Sebuah tema tidak akan bisa menimpanya (yang seharusnya).
jcisio
1

Seperti yang dikatakan @jcsio, jawaban yang diterima pada halaman ini berfungsi, tetapi templat tidak dapat ditimpa oleh tema.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry menawarkan solusi yang memungkinkan Anda menambahkan jalur modul Anda (dan sub-folder) untuk dipindai untuk semua jenis file .tpl.php.

Saya sedikit mengubahnya, karena berisi variabel 'jalur tema' yang sepertinya tidak digunakan oleh 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);
}

Saya mencoba jawaban yang diterima dan solusi ini, yang terakhir ini bekerja untuk saya sejauh ini!

lmeurs
sumber