Plugin Ctools (loại nội dung, quyền truy cập, v.v.) là gì và làm thế nào để tạo ra chúng?


Câu trả lời:


84

Thỉnh thoảng khi làm việc với trình quản lý TrangBảng điều khiển , rất hữu ích khi thêm các bổ trợ Ctools tùy chỉnh.

Ctools plugin đi kèm trong một số lượng lớn các hình thức, và các module khác, chẳng hạn như Feeds , AddressfieldOpenlayers tất cả tận dụng Ctools để cung cấp các plugin mở rộng bởi các module khác. Các dạng phổ biến nhất của plugin, có lẽ là "loại nội dung" và "quyền truy cập". Đầu tiên không được nhầm lẫn với "nội dung" thực thể và các gói của nó, còn được gọi là các loại nội dung.

Đầu tiên, bản tóm tắt :

Đối với bất kỳ mô-đun nào để cung cấp các plugin ctools, trước tiên họ nên cho Ctools biết nơi cần tìm chúng. Móc bên dưới, nói rằng chúng tôi cung cấp bổ trợ cho ctools, thuộc loại "content_types" và "access". Chức năng có thể được làm đơn giản hơn, nhưng bằng cách này, chúng tôi đảm bảo rằng chỉ có mô-đun đúng được thông báo về các plugin, cũng như chỉ quét đĩa để tìm tệp khi chúng tôi thực sự cung cấp loại plugin được yêu cầu.

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

Dưới đây là một cấu trúc thư mục ví dụ cho một mô-đun cung cấp hai plugin. Một loại nội dung và một plugin truy cập.

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

Plugin loại nội dung

Một loại nội dung trong từ vựng Ctools, thường được gọi là "Ngăn", như được cung cấp bởi Chế độ xem ví dụ. Trong câu hỏi này: Có cách nào để chặn danh sách NID được tạo bởi một chế độ xem và sử dụng chúng làm bộ lọc cho chế độ xem khác không? , tác giả hỏi về lập luận cho ăn lập trình để xem. Mặc dù bản thân nó không khó lắm, nhưng câu hỏi tiếp theo nhanh chóng trở thành: "Làm thế nào để tôi hiển thị kết quả?".

Một câu trả lời, sẽ là tạo ra một "loại nội dung" mới.

Bây giờ, plugin loại nội dung thực tế, một lần nữa sử dụng câu hỏi Lượt xem từ phía trên, có thể trông như thế này:

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

Khi mô-đun này được bật, giờ đây sẽ có một danh mục mới trong Bảng điều khiển, 'Danh mục tùy chỉnh của tôi', trong đó người ta sẽ tìm thấy một khung duy nhất, hiển thị mã từ phía trên.

Truy cập plugin

Plugin truy cập bên dưới sẽ cung cấp khả năng ghi lại các biến thể và / hoặc bảng dựa trên độ sâu của thuật ngữ được đo từ gốc của từ vựng.

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

Điều này thật tuyệt! Nhưng có tài liệu "chính thức" nào cho việc này không? (google tìm thấy rất nhiều bài đăng trên blog nhưng không có gì "chính thức" ..)
donquixote

1
Có rất nhiều ví dụ trong chính mô-đun ctools, chủ yếu là nơi tôi chọn đồ. Tôi đã cố gắng tự mình nhận nhiệm vụ viết tài liệu chính thức trong hơn một lần, nhưng luôn hết hơi.
Letharion

Tôi có một vấn đề khi thực hiện theo hướng dẫn này và đó là hình thức cấu hình không chỉ trống mà còn thiếu các nút.
beth

Tôi bằng cách nào đó đã bỏ lỡ câu hỏi / câu trả lời lần đầu tiên, tuyệt vời viết lên!
Clive

2
@beth Vấn đề là $ form trong module_content_type_edit_form () không nên được chuyển qua tham chiếu.
Justin

1

Các plugin CTools là các tệp nhỏ có thể là một phần của bất kỳ mô-đun nào như là cách để mở rộng chức năng của nó. Chúng có thể được sử dụng để cung cấp các thành phần (panes), thêm các tùy chọn kiểu bổ sung vào bảng của bạn, v.v.

Vui lòng kiểm tra các plugin CTools không có bảng điều khiển để biết tài liệu từng bước. Vì vậy, ngắn gọn nó đi như sau:

  1. Bạn cần thêm các phụ thuộc CTools vào .infotệp của mình dưới dạng:

    dependencies[] = ctools
    dependencies[] = panels
  2. Nói với CTools nơi plugin của bạn được đặt:

    <?php
    function MYMODULE_ctools_plugin_directory($module, $plugin) {
      if (($module == 'ctools') && ($plugin == 'content_types')) {
        return 'plugins/content_types';
      }
    }
    ?>
  3. Thực hiện plugin trong một .inctệp (theo mặc định là $module.$api.inc). Mã plugin ví dụ:

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

Vị trí mặc định của các plugin trông giống như:

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

Để biết thêm ví dụ, vui lòng kiểm tra ctools_plugin_examplemô-đun là một phần của mô-đun CTools hoặc kiểm tra trang Trợ giúp ( Ví dụ về Trình cắm CTools ) trong Giao diện người dùng Drupal sau khi bật mô-đun.


Trong Drupal 8, đây là một phần của lõi (xem: Drupal \ Element \ Plugin ) và nó cung cấp tính kế thừa đối tượng, giao diện đối tượng và đóng gói tệp đơn. Xem: Drupal 8 ngay bây giờ: Các plugin hướng đối tượng trong Drupal 7

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.