컨텐츠 유형별 전처리 기능


25

다른 방법으로 사전 처리해야하는 몇 가지 콘텐츠 유형이 있습니다. 그래서 template.php내 테마 foo현재 다음과 같습니다

function foo_preprocess_node(&$variables) {
    if ('news' ==$variables['type']) _preprocess_news($variables);
    if ('event'==$variables['type']) _preprocess_event($variables);
    if ('alert'==$variables['type']) _preprocess_alert($variables);
    ...
}

function _preprocess_news(&$variables) {
    ...
}

function _preprocess_event(&$variables) {
    ...
}

function _preprocess_alert(&$variables) {
    ...
}

콘텐츠 유형의 컴퓨터 이름에 연결되는 Drupal 특정 전처리 기능을 지정할 수 있기를 원합니다. 사용을 시도 foo_preprocess_news했지만 결코 호출되지 않습니다.

더 좋은 방법이 있습니까?

답변:


10

전처리 기능의 이름은 테마 이름을 기반으로하므로 theme_table()전처리 기능은 MYTHEME_preprocess_table()입니다.

전혀 없기 때문에 theme_node_node_type함수는 전처리 후크 같은 foo_preprocess_news또는 foo_preprocess_node_news상자 밖으로 작동하지 않습니다.

노드에 대해 다르게 작동하도록 테마 레지스트리를 대체 있지만 실제로는 권장하지 않습니다. 매우 지저분해질 수 있습니다.

나는 리팩토링 코드의 열렬한 팬이지만 귀하의 경우에는 그것이 필요하다고 생각하지 않습니다. 노드 유형에 따라 사전 프로세스 후크에서 실행 해야하는 복잡한 논리가있는 경우 현재 수행중인 방식으로 다른 기능으로 팜을 작성하는 것이 나에게 좋은 습관처럼 보입니다.

물론 다른 방법은 서로 다른 컨텐츠 유형 각각에 대해 사용자 정의 모듈을 구현 hook_preprocess_node()하고 각각에 구현 하는 것입니다. 이렇게하면 각 모듈의 전처리 기능이 다른 컨텐츠 유형을 담당 할 수 있습니다.

그러나 이것은 상황에 따라 과도 할 수 있습니다. 각 컨텐츠 유형에 대해 수행 할 추가 로직 (예 : 테마가 아닌 전처리 로직)이없는 경우이 메소드는 추가 값을 추가하지 않습니다.


1
승인. if를 반복하지 않기 위해 foo_preprocess_node구현 하여 "자동화"할 수도 call_user_func('_preprocess_' . $vars['type'], $vars);있지만 단순하게 유지하는 것이 가장 좋습니다.
cherouvim

나는 hook_preprocess_node()커스텀 모듈을 구현 했고 후크가 호출 될 때 제한하기를 바랐지만 그렇지 않습니다. 컨텐츠 유형에 의해 후크가 호출되는시기를 제한 할 수있는 방법이 있습니까?
Keven

@Keven 함수가 존재하면 호출되는 것을 멈출 수 없지만 if ($vars['node']->type == 'foo') { ...원하는 효과를 얻을 수 있습니다.
Clive

나는 정말로 당신이 할 수있는 것과 비슷한 약간의 최적화를 찾고 있습니다 hook_block_view_MODULE_DELTA_alter(). 나는 현재 당신이 말하는 것을하지만 후크가 맞을 때를 제한하는 방법이 있었기를 바랍니다.
Keven

@Keven이지만 최적화 과정은 아닙니다. 의사 결정 과정을 다른 코드 부분으로 옮기는 것입니다. 실제로 Drupal이 그러한 재정의를 제공했다면, 그것은 일반적이어야하고, 거의 확실히 더 많은 프로세서 시간이 걸릴 것입니다. 당신은 이미 마지막 순간에 결정을함으로써 이미 승리했습니다
Clive

28

zen 서브 테마는 이것을 theme_preprocess_node 함수에 추가하여이를 수행합니다.

function foo_preprocess_node(&$variables, $hook) {
  ...
    // Optionally, run node-type-specific preprocess functions, like
  // foo_preprocess_node_page() or foo_preprocess_node_story().
  $function = __FUNCTION__ . '_' . $variables['node']->type;
  if (function_exists($function)) {
    $function($variables, $hook);
  } 
  ...
}

'news'라는 컨텐츠 유형이있는 경우 template.php 파일에 foo_preprocess_node_news라는 함수를 작성할 수 있습니다.


또한 ZURB 기반에서도 고유 한 의미, 매우 유용한 코드 스 니펫과 함께 사용합니다.
Marko Blazekovic 2016 년

2

방금 비슷한 문제 가 있었기 때문에 Google 에서이 페이지로 나를 가져 왔습니다. 노드 전처리 기능이 너무 커져서 기능을 여러 파일로 나눕니다.

이미 모든 alter 함수를 포함하는 template.php 파일에서 비슷한 접근 방식을 수행했으며 동일한 방법이 여기에서 완벽하게 작동하기 때문에 내 접근 방식을 공유한다고 생각했습니다.

폴더 내부의 파일 설정MYTHEME/preprocess :

- node.preprocess.inc
- node--blog-post.preprocess.inc
- node--device-variation.preprocess.inc
- (...)

당신은 이미 당신이 node.preprocess.inc직접 만들 수있는 다른 것들을 가져야 합니다. 그것들을 실제로 어떻게 부르는지는 다소 임의적이지만, 그것들을 잘 식별하고 전체 drupal 이름 지정 시스템에 맞는 이름을 더 잘 부여하는 것이 좋습니다.
이 파일의 내용으로 넘어갑니다!

node.preprocess.inc, 여기서 나는 이와 같은 일을하고있다 :

<?php

function MYTHEME_preprocess_node(&$variables) {

    switch($variables['type']) {

      case 'blog_post':
        // if the type of the node is a Blog Post, include this:
        include 'node--blog-post.preprocess.inc';
        break;

      case 'device_variation':
        // if Device Variation, include this:
        include 'node--device-variation.preprocess.inc';
        break;

      case 'foo':
        // ...
        break;
    }

    // additional stuff for all nodes

}

기본적으로 현재 노드의 유형을 전환합니다. 당신이 전환하는 것은 당신에게 달려 있습니다. #id, #view_mode모든 당신의 정확한 필요에 따라.
일치하는 항목이 있으면 지정된 파일을로드하고 마치이 함수 안에 작성된 것처럼 내용에 따라 작동합니다.

이러한 included파일 의 내용은 node.preprocess.inc전처리 기능을 다시 호출하지 않는 것을 제외하고는 파일에 넣은 것과 똑같이 보입니다 .

node--device-variation.preprocess.inc

<?php

    // Device Name
    $device = drupal_clean_css_identifier(strtolower($variables['title']));

    // Determine whether only Device Version is of type 'N/A' and set ppvHasVariations accordingly
    $deviceHasVariations = true;
    if( $variables['content']['product:field_model_variation'][0]['#options']['entity']->weight == 0 ) {
        $deviceHasVariations = false;
    }
    //...

당신은 심지어 계단식 여러 스위치를 원하는대로 당신은 기본적에 따라 특정 노드 전처리 파일을 백업 예를 더 분할을 위해, 많은 파일로이 작업을 수행 할 수 있습니다 #view_mode하나 개의 파일을 갖는, full에 대한보기 모드와 다른teaser

누군가 가이 질문을 다시 우연히 발견하면 이것이 도움이되기를 바랍니다 (:


1

call_user_func()매개 변수를 참조로 전달하지 않습니다. 그래서, 경우에 $variables당신 preprocess_foo()은 원래 배열의 복사본에 작동 기능; 나머지 렌더 프로세스 중에 오브젝트가 아닌 오브젝트에 대한 변경 사항은 적용되지 않습니다.


1

메인 hook_preprocess_node에서 끝에 다음 코드를 구현하십시오.

$preprocess_function = 'themename_node__' . $node->type . '__preprocess';
if (function_exists($preprocess_function)) {
 $preprocess_function($variables);
}

이제 노드 유형별로 전처리를했을 것입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.