다른 모듈의 필드 포맷터에 연결 하시겠습니까?


9

현재 Drupal 7 사이트에서 렌더링 직전의 프로그래밍 논리에 따라 '보기 모드'로 변경되는 노드 참조 이미지 필드를 구현하려고합니다. 이 필드는 현재 디스플레이 모드 설정을 통해 여러 컨텐츠 유형에서 렌더링되고 있으며 각각은 필드 포맷터 '렌더링 된 노드'를 사용합니다.

첫번째 시도

첫 번째 아이디어는 후크가 후크가 후크라는 것을 고려하여 다음을 구현하는 것이 었습니다.

function HOOK_field_formatter_view( $entity_type, $entity, $field ... ){
  switch ($display['type']) {
    case 'node_reference_node':
      /* Programatical logic here to modfy field render settings */
    break;
  }
}

분명히 내 모듈의 이름을 HOOK로 교환합니다.

출력을 완전히 무시하거나 렌더링하기 전에 값을 수정하기 때문에 위의 함수 node_reference_field_formatter_view가 원래 함수 전후에 발생하는지는 중요하지 않습니다 node_reference.module. 유일한 문제는 위의 후크가 모듈 단위로만 작동하는 것 같습니다. 즉, 사이트 전체가 아니므로 기본적으로 내 모듈에 대해 실행되지 않습니다.

이제 분명히 자신의 필드 포맷터를 작성하여 렌더링 된 노드를 출력 할 수 있습니다. 그러나 이미 존재하는 것을 고려하면 약간의 낭비처럼 보입니다.

다른 접근법

내 다른 접근 방법에왔다 HOOK_preprocess_node하고 HOOK_preprocess_field있지만 이전은 포함되지 않은 view_mode정보를, 후자는 모든이에 대한 참조가 있는지 적어도 5 개 가지 복잡한 구조를 포함 view_mode다른 수준에서 속성을 - 그리고 그것의 각을 수정해야 오히려 해키 느낌이 자신의 가치. 특정 view_mode속성을 변경해도 결과 이미지는 변경되지 않습니다.

질문

누구나 필드 포맷터가 (구속 모듈로) 렌더링하기 전에 페이지 단위로 요청을 변경하는 방법 (예 : 실제 컨텐츠 유형의 영구적 인보기 모드 설정을 변경할 필요가 없음)을 알고있는 확실한 방법을 알고 있습니까?


2
hook_field_formatter_view_alter()아마 지금 1 년 이상 또는 비슷한 것을 찾고 있었지만 불행히도 존재하지 않습니다. 참고로 hook_preprocess_node()확실히 않습니다view_mode그것을 사용할 수, 그것에서이다 $vars['view_mode'], 아니 $vars['node']->view_mode당신이 시도하는 유혹되었을 수있다.
Clive

@Clive 정보를 주셔서 감사합니다. 그리고 view_modeon 을 지적 해 주셔서 감사합니다 hook_preprocess_node. hook_field_formatter_view_alter()D8에 이런 것이 있는지 궁금합니다 .
Pebbl

아직 아무것도 보지 못했지만 ... D8에서 모든 것이 플러그인으로 변환되고 있습니다 (필드에 대해 잘 모르겠습니다). 따라서 기존 클래스를 재정 의하여 작업을 완료 할 수 있습니다. . 기대하고 있습니다!
Clive

1
@Clive, 여기 D7에 언급 된 마법의 변경 고리를 찾았습니까?
tyler.frankenstein

답변:


11

이 질문 hook_field_formatter_view()은 원래 모듈에서만 호출되지만을 통해 필드 포맷터의 소유권을 가질 수 있다고 언급합니다 hook_field_formatter_info_alter().

module다음과 같이 포맷터 의 키를 MYMODULE 로 설정할 수 있어야합니다 .

function MYMODULE_field_formatter_info_alter(&$info) {
  $info['some_field_formatter']['module'] = 'MYMODULE';
}

그런 다음MYMODULE_field_formatter_view() 선택적으로 구현할 수 있는 기존 모듈을 통해 피드를 구현 하여 요소를 변경할 수 있습니다.

function MYMODULE_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  // Your custom logic
  $element = OTHER_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display);
  // Any alterations
}

답을 자세히 설명해 주시겠습니까? 코드를 제공 하시겠습니까?
Scott Joudry

좋은 해결책, 나는 다른 모듈의 사업을 완전히 소유한다고 생각하지 않으며 (변경 후 다시 릴레이) ... 그냥 시도했지만 훨씬 간단한 코드로 끝납니다. 건배!
Pebbl

1
@ScottJoudry ~이 방법으로 인수하면 field_formatternode_reference의 모든 기능에 대한 메소드가 있는지 확인해야합니다 ( 즉 MYMODULE_field_formatter_settings_summary, MYMODULE_field_formatter_settings_form프록시 모듈이 원래 모듈로 돌아가더라도). end UI가 잘못된 모듈에서 이러한 메소드를 찾으려고하면 모든 디스플레이 모드 패널에서 중단됩니다.
Pebbl

Graham C의 접근 방식은 흥미롭지 만 너무 많은 재정의가 필요합니다.
milkovsky

2

좋아, 그래서 나는 왜 내 변경에 실현 #view_mode중 하나에서 hook_preprocess_nodehook_preprocess_fields작업하지 않았다. ( #view_mode에서 의 존재를 완전히 놓친 점을 지적한 Clive에게 감사합니다 hook_preprocess_node) .

내 문제 #view_mode는 이미 처리되어 올바른 #image_style속성으로 변환 되었다는 사실에서 비롯 되었습니다 .

그럼에도 불구 하고이 값을 변경하면 후크를 수정 한 후크에 너무 크게 의존하는 것 같습니다. 마침내 렌더링 된 이미지를 변경하는 코드가 생겼습니다.

function HOOK_preprocess_field( &$vars ){
  $element     = &$vars['element'];
  $entity_type = !empty($element['#entity_type']) ? $element['#entity_type'] : 'unknown';
  $bundle      = !empty($element['#bundle'])      ? $element['#bundle']      : 'unknown';
  $view_mode   = !empty($element['#view_mode'])   ? $element['#view_mode']   : 'unknown';
  $field_name  = !empty($element['#field_name'])  ? $element['#field_name']  : 'unknown';
  switch ( "$entity_type:$view_mode:$bundle/$field_name" ) {
    case 'node:full:mlandingpage/field_lead_image':
      if ( !empty($vars['items']) && 
           ($subelement = &$vars['items'][0]) ) {
        if ( !empty($subelement['field_image']) && 
             ($subfield = &$subelement['field_image'][0]) ) {
          /// this needs to be set to the image_style value, not the view_mode value.
          $subfield['#image_style'] = 'grid-normal-4-cols';
        }
      }
    break;
  }
}

위의 내용은 여전히 ​​웅장한 느낌은 아니지만 적어도 작동합니다. 필드 포맷터에는 이러한 _alter 메소드가 존재하지 않는다는 사실에 대해 Clive의 말을 들겠습니다. 부끄러운 일입니다. 포매터는 D7의 매우 강력한 기능이므로 더 많은 기능을 제공하는 것이 좋습니다.

어쨌든 미래의 사람들에게 더 나은 아이디어가 있다면 대답하십시오. :)


0

가장 쉬운 방법은 Panelizer를 사용하는 것 입니다.

Panelizer를 사용하지 않고 기본 Drupal보기 모드 또는 Display Suite를 사용하는 경우 hook_field_display_alter () 또는 hook_field_display_ENTITY_TYPE_alter ()를 시도 하십시오 .

엔티티, 표시 컨텍스트 및 모든 포맷터 설정이 있습니다. 또한 필드 렌더 설정을 쉽게 변경할 수 있습니다. 필드 포맷터를 다른 것으로 변경할 수도 있습니다.

이 접근법은 나에게 완벽하게 작동합니다. 유일한 단점은 "디스플레이 관리"UI에서 다른 설정과 혼동 될 수 있다는 것입니다.


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