จะบอก Drupal ให้ค้นหาแม่แบบในไดเรกทอรีโมดูลได้อย่างไร


11

ฉันต้องการให้แม่แบบการใช้งานในโมดูลของฉันและอนุญาตให้ใช้ชุดรูปแบบเพื่อแทนที่ โดยพื้นฐานแล้วฉันจะเพิ่มข้อเสนอแนะด้วยรหัสที่เรียบง่ายนี้:

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

(ฉันไม่ต้องการใช้ hook_theme เพื่อเพิ่มธีมใหม่เพราะฉันต้องการใช้ฟังก์ชั่นโหนด preprocess อีกครั้งชื่อชุดรูปแบบน่าอึดอัดใจ แต่ฉันไม่ต้องการเขียน node_ แนบ _% เพื่อหลีกเลี่ยงความสับสนกับประเภทโหนด)

จากนั้นฉันใช้ hook_theme_registry_alter () เพื่อเพิ่มเส้นทางโมดูล:

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

อย่างไรก็ตามมันไม่ทำงาน นั่นหมายความว่า: ไฟล์ธีม / โหนด - super.tpl.php จะไม่ถูกใช้ มันจะใช้เฉพาะในกรณีที่ฉันคัดลอกไปยังโฟลเดอร์ธีม


ชี้แจง: ฉันต้องการให้ Drupal ค้นหาในไดเรกทอรีโมดูล (และในไดเรกทอรีธีม) เพื่อหาแม่แบบที่กำหนดโดยรหัส (ที่นี่: แม่แบบโหนด) ฉันไม่ต้องการกำหนดเทมเพลตใหม่
jcisio

คำตอบ:


5

โดยทั่วไปคุณสามารถช่วยตัวเองเล็กน้อยปวดหัวโดยใช้hook_theme()แทนการแก้ไขรีจิสทรี

ฉันขอแนะนำให้ดูที่ theming_example ในโครงการตัวอย่างสร้างซ้ำบนหน้าเอกสาร API นี้อย่างคล่องแคล่วบางทีอาจมีรหัสที่มีประโยชน์เป็นพิเศษในหน้านี้

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

นี่คือทั้งหมดสำหรับ Drupal 7


อย่างที่ฉันพูดในคำถามฉันไม่ต้องการใช้ hook_theme () เพราะฉันต้องการใช้ตัวแปร $ ซ้ำในเทมเพลตโหนด ตัวแปรเหล่านั้นถูกสร้างขึ้นในกระบวนการ hook_ (ก่อนหน้า) ของโมดูลจำนวนมากที่ไม่ทราบว่ามีธีมของฉันอยู่ (ถ้าฉันกำหนดไว้)
jcisio

วิธีที่คุณกำหนดธีมคือ ... ด้วย hook_theme () :-) คุณสามารถกำหนดฟังก์ชั่นชุดรูปแบบใน hook_theme () ตั้งชื่อสิ่งที่คุณต้องการ ทำให้ฟังก์ชั่นชิมถ้าคุณต้องการ API เอกสาร: "hook_theme_HOOK () ... ควรใช้เฉพาะในกรณีที่โมดูลต้องการแทนที่หรือเพิ่มในการประมวลผลธีมล่วงหน้าสำหรับธีมตะขอที่ไม่ได้กำหนด"
paul-m

ฉันไม่ต้องการกำหนดธีม หากคุณกำหนดธีม 'mynode' แทนการใช้ 'node' ซ้ำคุณจะไม่มีตัวแปรใด ๆ ในไฟล์. tpl.php ของคุณ
jcisio

1
สิ่งนี้ไม่เป็นความจริง: การเรียกใช้ชุดรูปแบบเป็นแบบสะสมดังนั้นการนำไปใช้hook_themeควรให้$existingพารามิเตอร์ที่ให้คุณปรับเปลี่ยนสิ่งต่างๆ หากไม่ใช่ในกรณีนี้บางทีคุณอาจกำลังตีบั๊ก
Countzero

@Countzero เมื่อคุณประกาศธีม node_attach ดังนั้นฟังก์ชัน hook_preprocess_node ทั้งหมดจะไม่เกิดขึ้นกับธีมใหม่ของคุณ คือคุณไม่มีอะไรใน node-attach.tpl.php ของคุณ
jcisio

5

บางทีนี่อาจใช้งานได้:

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

สิ่งสำคัญนี่คือกุญแจ ' ตะขอฐาน '


นี่คือปัญหาสำหรับการเพิ่มเอกสารสำหรับbase hook: drupal.org/node/2106635
Andy

+1 upvote - นี่และคำตอบที่มาจาก batigotix ฉันพบว่าทำงานได้ ขอบคุณ
therobyouknow

2

ฉันชอบโซลูชันของ dashohoxha เกี่ยวกับการใช้งาน hook_theme แต่ไม่สามารถทำงานได้ หลังจาก googling เพิ่มเติมฉันพบการเปลี่ยนแปลงที่ทำงานได้ดีสำหรับฉัน:

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

หมายเหตุ: โมดูลที่กำหนดเองของฉันเรียกว่า 'mymodule' และประเภทเนื้อหาที่กำหนดเองของฉันเรียกว่า 'blog_post' tpl.php ที่ฉันใช้เรียกว่า 'node - blog_post.tpl.php' และอยู่ในโฟลเดอร์ย่อย 'แม่แบบ' ของโมดูลของฉัน


+1 ขอบคุณฉันพบว่ามันใช้งานได้ หากคุณสนใจที่จะเอาชนะฟังก์ชั่น template.php ภายในโมดูลที่กำหนดเองของคุณให้ดูที่: snugug.com/musings/override-theme-functions-drupal-7-module - ฉันพบว่าสิ่งนี้ทำงานได้ดีมาก
therobyouknow

2

ต่อไปนี้เป็นตัวอย่างข้อมูลของฉันในการประกาศเทมเพลตการดูที่เก็บไว้ในโฟลเดอร์ "เทมเพลต" ของ "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;
    }
  }
}

หวังว่าจะช่วยใครซักคน


บันทึกเวลาของฉัน ยังใช้งานได้และจำเป็นสำหรับ d8
Mykola Mykolayovich Dolynskyi

-1

ฉันถามครั้งเดียวนี้บนกองมากเกิน โดยทั่วไปคุณต้องใช้hook_theme_registry_alter()เพื่อเพิ่มพา ธ ของคุณไปยังพา ธ เท็มเพลตธีม hook จากนั้น, บนhook_enable(), คุณเรียกdrupal_theme_rebuild ()เพื่อล้างแคชรีจิสตรีของธีมและรับพา ธ ของคุณสแกนหา เท็มเพล


บางทีสิ่งที่คุณรั้งไว้คือล้างแคช
Capi Etheriel

ดังนั้นโดยทั่วไปทางออกเดียวกัน ฉันลอง "drush cc all" ไม่น้อยกว่า 50 ครั้งทดสอบบนไซต์การติดตั้งใหม่ ฯลฯ โดยไม่ประสบความสำเร็จ ฉันจะแก้ไขและกระชับรหัสของฉันให้เป็นโมดูลขั้นต่ำเพื่อให้ทุกคนสามารถทดสอบได้
jcisio

hook_enable()ถูกเรียกใช้เมื่อเปิดใช้งานโมดูล หากโมดูลนั้นเปิดใช้งานอยู่จะต้องปิดใช้งานและเปิดใช้งานอีกครั้ง
kiamlaluno

@kiamlaluno: iḿใช้ hook_enable เพื่อล้างแคชหากมีการติดตั้งแล้วผู้ใช้อาจจะล้างแคชด้วยตนเอง
Capi Etheriel

NO , -1 คะแนน ทางออกนั้นเก่ามาก (2009) ฉันไม่แน่ใจด้วยซ้ำว่ามันจะมีไว้สำหรับ D7 ในขณะที่โซลูชันเก่าของคุณได้รับการปรับให้เหมาะสมกับ Views แต่ก็ไม่เหมาะสำหรับสถานการณ์ที่ไม่ใช่วิวซึ่งนักพัฒนาอาจต้องการแพ็คสำหรับเทมเพลตเริ่มต้นมากกว่า 1 รายการต่อคีย์ธีมในโมดูลของพวกเขา ลองนึกภาพการนำโซลูชันของคุณไปใช้สำหรับคำแนะนำธีมแบบไดนามิก 100 ข้อสำหรับคีย์ธีมเดียว นำไปใช้นอกบริบท Views ฉันจะเรียกโซลูชันของคุณว่าเป็นแบบเคาน์เตอร์
บาริสต้ามือสมัครเล่น
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.