Co to jest wtyczka Ctools (typ zawartości, dostęp itp.) I jak je tworzyć?


Odpowiedzi:


84

Od czasu do czasu podczas pracy z menedżerem stron Ctools i panelami przydatne jest dodawanie niestandardowych wtyczek Ctools.

Wtyczki Ctools występują w wielu formach, a inne moduły, takie jak Kanały , Pole Adresowe i Openlayers, wykorzystują Ctools do zapewnienia wtyczek rozszerzalnych o inne moduły. Najpopularniejsze formy wtyczek to prawdopodobnie „typ zawartości” i „dostęp”. Pierwszego nie należy mylić z bytem „treść” i jego pakietami, zwanymi także typami treści.

Najpierw płyta kotła :

Aby każdy moduł udostępniał wtyczki Ctools, powinien najpierw powiedzieć Ctools, gdzie ich szukać. Poniższy haczyk mówi, że zapewniamy wtyczki do narzędzi ctools typu „content_types” i „access”. Funkcję tę można uprościć, ale w ten sposób upewniamy się, że tylko odpowiedni moduł jest informowany o wtyczkach, a także skanujemy dysk w poszukiwaniu plików, gdy faktycznie zapewniamy żądany typ wtyczki.

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

Poniżej znajduje się przykładowa struktura katalogów modułu udostępniającego dwie wtyczki. Jeden typ zawartości i jedna wtyczka dostępu.

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

Wtyczka typu zawartości

Typ zawartości w słownictwie Ctools jest częściej znany jako „okienko”, na przykład w widokach. W tym pytaniu: Czy istnieje sposób na przechwycenie listy identyfikatorów NID utworzonych przez widok i użycie ich jako filtra dla innego widoku? , autor pyta o programowe podawanie argumentów do widoku. Chociaż nie jest to zbyt trudne, pytanie uzupełniające szybko brzmi: „Jak wyświetlić wyniki?”.

Jedną odpowiedzią będzie utworzenie nowego „typu zawartości”.

Teraz rzeczywista wtyczka typu zawartości, ponownie przy użyciu pytania Widoki z góry, może wyglądać tak:

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

Po włączeniu tego modułu w panelach powinna być teraz nowa kategoria „Moja niestandardowa kategoria”, w której należy znaleźć pojedynczy panel, renderujący kod z góry.

Wtyczka dostępu

Wtyczka dostępu poniżej zapewni możliwość wyodrębnienia wariantów i / lub paneli na podstawie głębokości terminu, mierzonej od źródła słownictwa.

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

To jest niesamowite! Ale czy istnieje na to „oficjalna” dokumentacja? (Google znajduje wiele postów na blogu, ale nic „oficjalnego” ..)
donquixote,

1
Istnieje wiele przykładów w samym module ctools, który przede wszystkim podniosłem. Próbowałem samodzielnie napisać oficjalne dokumenty więcej niż jeden raz, ale zawsze brakowało mi energii.
Letharion

Mam jeden problem podczas korzystania z tego samouczka, a mianowicie, że formularz konfiguracji jest nie tylko pusty, ale brakuje przycisków.
beth

Jakoś przegapiłem to pytanie / odpowiedź za pierwszym razem, niesamowite napisanie!
Clive

2
@beth Problemem jest formularz $ w module_content_type_edit_form () nie powinien być przekazywany przez odwołanie.
Justin

1

Wtyczki CTools to małe pliki, które mogą być częścią dowolnego modułu jako sposób na rozszerzenie jego funkcjonalności. Można ich używać do dostarczania komponentów (paneli), dodawania dodatkowych opcji stylów do paneli itp.

Sprawdź krok po kroku stronę Wtyczki CTools bez paneli . Tak krótko wygląda to tak:

  1. Musisz dodać zależności CTools do swojego .infopliku jako:

    dependencies[] = ctools
    dependencies[] = panels
  2. Powiedz CTools, gdzie znajduje się Twoja wtyczka:

    <?php
    function MYMODULE_ctools_plugin_directory($module, $plugin) {
      if (($module == 'ctools') && ($plugin == 'content_types')) {
        return 'plugins/content_types';
      }
    }
    ?>
  3. Zaimplementuj wtyczkę w .incpliku (domyślnie jako $module.$api.inc). Przykładowy kod wtyczki:

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

Domyślna lokalizacja wtyczek wygląda następująco:

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

Aby uzyskać więcej przykładów, sprawdź ctools_plugin_examplemoduł, który jest częścią modułu CTools, lub sprawdź stronę pomocy ( Przykłady wtyczek CTools ) w interfejsie Drupal po włączeniu modułu.


W Drupal 8 jest to teraz część rdzenia (patrz: Drupal \ Component \ Plugin ) i zapewnia dziedziczenie obiektów, interfejsy obiektów i enkapsulację pojedynczych plików. Zobacz: Drupal 8 Teraz: Wtyczki obiektowe w Drupal 7

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.