모듈 디렉토리에서 템플릿을 찾도록 Drupal에 지시하는 방법은 무엇입니까?


11

내 모듈에 템플릿 구현을 제공하고 테마가 그것을 재정의하도록 허용하고 싶습니다. 기본적 으로이 단순화 된 코드로 제안을 추가합니다.

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

(전처리 노드 함수를 재사용하고 싶기 때문에 hook_theme을 사용하여 새 테마를 추가하고 싶지 않습니다. 테마 이름이 어색하지만 노드 유형과의 혼동을 피하기 위해 node_ attach _ %를 작성하고 싶지 않습니다 .)

그런 다음 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을위한 것입니다.


질문에서 말했듯이 노드 템플릿에서 $ variables를 재사용하고 싶기 때문에 hook_theme ()을 사용하고 싶지 않습니다. 이러한 변수는 내 테마의 존재를 모르는 많은 모듈의 hook_ (pre) 프로세스에서 생성됩니다 (내가 정의한 경우).
jcisio

테마를 정의하는 방법은 ... hook_theme ()입니다. :-) hook_theme ()에서 테마 함수를 정의 할 수 있습니다. 원하는 이름을 지정하십시오. 원하는 경우 심 기능을 만드십시오. API 문서 : "hook_theme_HOOK () ... 모듈이 정의하지 않은 테마 후크에 대한 테마 사전 처리에 모듈을 재정의하거나 추가해야하는 경우에만 사용해야합니다."
paul-m

테마를 정의하고 싶지 않습니다. 'node'를 재사용하는 대신 테마 'mynode'를 정의하면 .tpl.php 파일에 변수가 없습니다.
jcisio

1
이것은 사실이 아닙니다 : 테마 호출은 누적되므로 구현 하면 항목을 재정의하지 않고 수정할 수 hook_theme있는 $existing매개 변수를 제공해야 합니다. 그렇지 않은 경우 아마도 버그가 발생했을 수 있습니다.
Countzero

테마 node_attach를 선언하면 @Countzero, 모든 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'),
    ),
  );
}

중요한 것은 ' 베이스 훅 ' 키 입니다.



+1 공감-이것과 내가 작동하는 batigotix의 파생 답변. 감사.
therobyouknow

2

hook_theme 구현에 대한 dashohoxha의 솔루션 을 좋아 하지만 작동시키지 못했습니다. 더 많은 인터넷 검색 후 나에게 맞는 변형을 발견 했습니다 .

/**
 * 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'이며 내 모듈의 'templates'하위 폴더에 있습니다.


+1 감사합니다. 당신은 또한 사용자 정의 모듈 내부 template.php 기능을 오버라이드 (override)에 관심이 있다면, 한 번 봐 걸릴 : snugug.com/musings/override-theme-functions-drupal-7-module를 - 나는 아주 잘 작동이 발견
therobyouknow

2

다음은 "custom_module"의 "template"폴더에 저장된 뷰 템플릿을 선언하는 스 니펫입니다.

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

나는 이것을 Stack Overflow에서 한 번 물었다 . 기본적으로, hook_theme_registry_alter()경로를 테마 후크 템플리트 경로에 추가하려면 구현 해야합니다. 그런 다음에서 drupal_theme_rebuild ()hook_enable()호출 하여 테마 레지스트리 캐시를 지우고 경로가 템플릿을 스캔되도록합니다.


어쩌면 당신을 방해하는 것은 캐시를 지우는 것입니다.
Capi Etheriel

따라서 기본적으로 동일한 솔루션입니다. 나는 "drush cc all"을 50 번 이상 시도하여 새로운 설치 사이트 등에서 성공적으로 테스트했습니다. 모든 사람이 테스트 할 수 있도록 코드를 최소한의 모듈로 수정하고 압축합니다.
jcisio

hook_enable()모듈이 활성화되면 호출됩니다. 모듈이 이미 활성화 된 경우 비활성화 한 다음 다시 활성화해야합니다.
kiamlaluno

@kiamlaluno : iḿ 캐시를 지우려면 hook_enable을 사용하십시오. 이미 설치되어 있으면 사용자는 캐시를 수동으로 지울 수 있습니다.
Capi Etheriel

NO , -1 포인트 그 솔루션은 너무 오래되어서 (2009), D7을위한 것인지조차 확실하지 않습니다. 기존 솔루션은 뷰에 맞게 조정되었지만 개발자가 모듈의 테마 키당 기본 템플릿을 두 개 이상 포장하려는 뷰가 아닌 상황에는 적합하지 않습니다. 하나의 테마 키에 대해 100 가지 동적 테마 제안을위한 솔루션을 구현한다고 상상해보십시오. Views 컨텍스트 외부에 적용하면 솔루션을 카운터 패턴이라고합니다.
아마추어 바리 스타
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.