Ctools 플러그인 (컨텐츠 유형, 액세스 등)이란 무엇이며 어떻게 작성합니까?


답변:


84

Ctools Page managerPanels 작업을 할 때마다 사용자 정의 Ctools 플러그인을 추가하는 것이 유용합니다.

Ctools의 플러그인 형태의 다수로 제공하고, 같은 다른 모듈, 피드 , AddressfieldOpenlayers는 다른 모든 모듈로 확장 플러그인을 제공하기 위해 Ctools를 사용합니다. 플러그인의 가장 일반적인 형태는 아마도 "content type"과 "access"일 것입니다. 첫 번째는 있어야 하지 엔티티 "내용"과 번들과 혼동, 또한 콘텐츠 형식을했다.

먼저, 상용구 :

ctools 플러그인을 제공하는 모든 모듈의 경우 먼저 Ctools에 찾을 위치를 알려야합니다. 아래 훅은 ccontent를위한 "content_types"및 "access"유형의 플러그인을 제공한다고 말합니다. 이 기능은 더 간단하게 만들 수 있지만, 이렇게하면 플러그인에 대해 올바른 모듈 만 알 수있을뿐만 아니라 실제로 요청되는 플러그인 유형을 제공 할 때 디스크에서 파일을 검색 할 수 있습니다.

function HOOK_ctools_plugin_directory($owner, $plugin_type) {
  // We'll be nice and limit scandir() calls.
  if ($owner == 'ctools' && ($plugin_type == 'content_types' || $plugin_type == 'access')) {
    return 'plugins/' . $plugin_type;
  }
}

다음은 두 개의 플러그인을 제공하는 모듈의 디렉토리 구조 예입니다. 하나의 컨텐츠 유형과 하나의 액세스 플러그인.

module/
module/module.info
module/module.module
module/plugins/
module/plugins/content_types/
module/plugins/content_types/two_views_in_one.inc
module/plugins/access/
module/plugins/access/term_depth.inc

컨텐츠 유형 플러그인

Ctools 어휘의 컨텐츠 유형은보기와 같이 제공되는 "패널"로 더 자주 알려져 있습니다. 이 질문에서 : 보기에 의해 생성 된 NID 목록을 가로 채고 다른보기의 필터로 사용하는 방법이 있습니까? 저자는 프로그래밍 방식으로 인수를 뷰에 제공하는 방법에 대해 묻습니다. 그 자체로는 그리 어렵지는 않지만 후속 질문은 "결과를 어떻게 표시합니까?"가 빨리됩니다.

한 가지 대답은 새로운 "콘텐츠 유형"을 만드는 것입니다.

이제 실제 콘텐츠 유형 플러그인은 위에서 다시보기 질문을 사용하여 다음과 같이 보일 수 있습니다.

$plugin = array(
  'title' => t('Render a View with arguments from another'),
  'single' => TRUE,
  'category' => array(t('My custom category'), -9),
  // Despite having no "settings" we need this function to pass back a form, or we'll loose the context and title settings.
  'edit form' => 'module_content_type_edit_form',
  'render callback' => 'module_content_type_render',
);

function module_content_type_render($subtype, $conf, $args, $context = NULL) {
  $block = new stdClass;
  $block->title = 'My View';

  $view = views_get_view('get_nids');
  $view->preview('display_machine_name', array($arg1, $arg2));

  $nids = '';
  foreach($view->result as $node) {
    $nids += $node->nid . ',';
  }
  $nids = rtrim($nids, ',');
  $view = views_get_view('get_related');
  $view->execute_display('display_machine_name', array($nids));
  $block->content = $view->render();

  return $block;
}

/**
 * 'Edit form' callback for the content type.
 */
function module_content_type_edit_form($form, &$form_state) {
  // No settings beyond context, which has already been handled.
  return $form;
}

이 모듈을 사용하면 패널에 '내 사용자 정의 카테고리'라는 새 카테고리가 생겨 하나의 창을 찾아 위에서 코드를 렌더링해야합니다.

액세스 플러그인

아래의 액세스 플러그인은 어휘의 루트에서 측정 된 용어의 깊이에 따라 변형 및 / 또는 창을 정리할 수있는 기능을 제공합니다.

<?php
/**
 * @file
 * Plugin to provide access control based upon a parent term.
 */

/**
 * Plugins are described by creating a $plugin array which will be used
 * by the system that includes this file.
 */
$plugin = array(
  'title' => t("Taxonomy: term depth"),
  'description' => t('Control access by the depth of a term.'),
  'callback' => 'term_depth_term_depth_ctools_access_check',
  'default' => array('vid' => array(), 'depth' => 0),
  'settings form' => 'term_depth_term_depth_ctools_access_settings',
  'settings form validation' => 'term_depth_term_depth_ctools_access_settings_validate',
  'settings form submit' => 'term_depth_term_depth_ctools_access_settings_submit',
  'summary' => 'term_depth_term_depth_ctools_access_summary',
  'required context' => new ctools_context_required(t('Term'), array('taxonomy_term', 'terms')),
);

/**
 * Settings form for the 'term depth' access plugin.
 */
function term_depth_term_depth_ctools_access_settings($form, &$form_state, $conf) {
  // If no configuration was saved before, set some defaults.
  if (empty($conf)) {
    $conf = array(
      'vid' => 0,
    );
  }
  if (!isset($conf['vid'])) {
    $conf['vid'] = 0;
  }

  // Loop over each of the configured vocabularies.
  foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
    $options[$vid] = $vocabulary->name;
  }

  $form['settings']['vid'] = array(
    '#title' => t('Vocabulary'),
    '#type' => 'select',
    '#options' => $options,
    '#description' => t('Select the vocabulary for this form. If there exists a parent term in that vocabulary, this access check will succeed.'),
    '#id' => 'ctools-select-vid',
    '#default_value' => $conf['vid'],
    '#required' => TRUE,
  );

  $form['settings']['depth'] = array(
    '#title' => t('Depth'),
    '#type' => 'textfield',
    '#description' => t('Set the required depth of the term. If the term exists at the right depth, this access check will succeed.'),
    '#default_value' => $conf['depth'],
    '#required' => TRUE,
  );

  return $form;
}

/**
 * Submit function for the access plugins settings.
 *
 * We cast all settings to numbers to ensure they can be safely handled.
 */
function term_depth_term_depth_ctools_access_settings_submit($form, $form_state) {
  foreach (array('depth', 'vid') as $key) {
    $form_state['conf'][$key] = (integer) $form_state['values']['settings'][$key];
  }
}

/**
 * Check for access.
 */
function term_depth_term_depth_ctools_access_check($conf, $context) {
  // As far as I know there should always be a context at this point, but this
  // is safe.
  if (empty($context) || empty($context->data) || empty($context->data->vid) || empty($context->data->tid)) {
    return FALSE;
  }

  // Get the $vid.
  if (!isset($conf['vid'])) {
    return FALSE;
  }
  $depth = _term_depth($context->data->tid);

  return ($depth == $conf['depth']);
}

/**
 * Provide a summary description based upon the checked terms.
 */
function term_depth_term_depth_ctools_access_summary($conf, $context) {
  $vocab = taxonomy_vocabulary_load($conf['vid']);

  return t('"@term" has parent in vocabulary "@vocab" at @depth', array(
    '@term' => $context->identifier,
    '@vocab' => $vocab->name,
    '@depth' => $conf['depth'],
  ));
}

/**
 * Find the depth of a term.
 */
function _term_depth($tid) {
  static $depths = array();

  if (!isset($depths[$tid])) {
    $parent = db_select('taxonomy_term_hierarchy', 'th')
      ->fields('th', array('parent'))
      ->condition('tid', $tid)
      ->execute()->fetchField();

    if ($parent == 0) {
      $depths[$tid] = 1;
    }
    else {
      $depths[$tid] = 1 + _term_depth($parent);
    }
  }

  return $depths[$tid];
}

대단해! 그러나 이것에 대한 "공식적인"문서가 있습니까? (Google은 블로그 게시물이 많지만 "공식"은 아닙니다.)
donquixote

1
ctools 모듈 자체에는 많은 예제가 있습니다. 이곳은 주로 물건을 집어 들었습니다. 공식 문서를 두 번 이상 작성하는 작업을 수행하려고했지만 항상 증기가 부족합니다.
Letharion 2016 년

이 튜토리얼을 따라갈 때 한 가지 문제가 있는데, 이는 구성 양식이 비어있을뿐만 아니라 버튼이 없다는 것입니다.
be 27-06-27

어떻게 든이 질문 / 답변을 처음으로 놓쳤습니다.
Clive

2
@beth 문제는 module_content_type_edit_form ()의 $ form은 참조로 전달해서는 안됩니다.
Justin

1

CTools 플러그인은 기능을 확장하는 방법으로 모든 모듈의 일부가 될 수있는 작은 파일입니다. 구성 요소 (패널)를 제공하고 패널에 추가 스타일 옵션을 추가하는 데 사용할 수 있습니다.

단계별 설명서는 패널이없는 CTools 플러그인 페이지를 확인하십시오 . 간단히 말하면 다음과 같습니다.

  1. 다음 .info과 같이 파일에 CTools 종속성을 추가해야합니다 .

    dependencies[] = ctools
    dependencies[] = panels
    
  2. 플러그인이있는 위치를 CTools에 알려주십시오.

    <?php
    function MYMODULE_ctools_plugin_directory($module, $plugin) {
      if (($module == 'ctools') && ($plugin == 'content_types')) {
        return 'plugins/content_types';
      }
    }
    ?>
    
  3. .inc파일에 플러그인을 구현 하십시오 (기본적으로 $module.$api.inc). 플러그인 코드 예 :

    <?php
    $plugin = array(
      'title' => t('Twitter feed'),
      'description' => t('Twitter feed'),
      'category' => 'Widgets',
      'icon' => '',
      'render callback' => 'twitter_block',
      'defaults' => array(),
    );
    
    // render callback
    function twitter_block() {
      // Add twitter widget javascript
      $url = TWITTER_USER
      $widget_id = TWITTER_WIDGET_ID;
      $data = array();
    
      $data['url'] = $url;
      $data['widget_id'] = $widget_id;
    
      $content = array(
        '#theme' => 'my_block',
        '#content' => $data,
      );
    
      $block = new stdClass();
      $block->content = $content;
      $block->title = '';
      $block->id = 'twitter_block';
    
      return $block;
    }
    ?>
    

플러그인의 기본 위치는 다음과 같습니다.

MYMODULE/
    plugins/
        content_types/
        templates/
    MYMODULE.info
    MYMODULE.module  

더 많은 예제를 보려면 ctools_plugin_exampleCTools 모듈의 일부인 모듈을 확인하거나 모듈 을 활성화 한 후 Drupal UI에서 도움말 페이지 ( CTools 플러그인 예제 )를 확인하십시오.


Drupal 8에서는 이제 코어의 일부이며 ( Drupal \ Component \ Plugin 참조 ) Object 상속, Object 인터페이스 및 단일 파일 캡슐화를 제공합니다. 참조 : 드루팔 8 자 : 객체 지향 플러그인을 드루팔 7

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