Создание ctools context plugin

04.03.2014
Share on FacebookShare on TwitterShare on GooglePlusShare on Linkedin
Ctools context plugin creation
Автор:

В одном из наших блогов уже поднималась тема создания плагинов для модуля Panels при разработке сайтов, которые можно реализовать с помощью Ctools. На этот раз речь пойдет о добавлении собственного контекста - это еще одна возможность, которую нам предоставляет Chaos tool suite.

Контекст в Panels - это своего рода обертка вокруг любого значимого объекта. Перечисленные ниже контексты уже внедрены в панель по умолчанию:

  • Comment;
  • File;
  • Node;
  • Node add form;
  • Node edit form;
  • String;
  • Taxonomy term;
  • Taxonomy vocabulary;
  • Token, User;
  • User edit form.

Список большой, однако иногда этих элементов бывает недостаточно. Поэтому здесь на помощь приходит механизм, с помощью которого возможно добавить в панель именно то, что нам нужно. Как видно из списка, существует такой контекст как "Node add form”, однако для терминов таксономии ничего подобного нет. Поэтому в этом примере мы опишем плагин, который позволит добавить форму создания терминов к любой панели.

Как и в случае с другими ctools плагинами, нам нужно прописать hook_ctools_plugin_directory():

/**
 * Implements hook_ctools_plugin_directory().
 */
function context_example_ctools_plugin_directory($module, $plugin) {
  if ($module == 'ctools' && !empty($plugin)) {
    return "plugins/{$plugin}";
  }
} 

Далее в директории с нашим модулем необходимо создать каталог под названием "plugins", в котором разместится папка "contexts". Следующим шагом будет создание файла плагина, в нашем случае он будет называться "taxonomy_term_add_form.inc".

Теперь можно перейти к написанию собственно плагина. В первую очередь, нужно объявить массив $plugin, который будет содержать всю необходимую информацию о нашем контексте.

/**
 * Plugins are described by creating a $plugin array which will be used
 * by the system that includes this file.
 */
$plugin = array(
  // Visible title.
  'title'             => t('Taxonomy term add form'),
  // Description of context.
  'description'       => t('A taxonomy term add form.'),
  // Function to create context.
  'context'           => 'context_example_create_taxonomy_term_add_form',
  // Plugin settings form.
  'edit form'         => 'context_example_taxonomy_term_add_form_settings_form',
  // Keyword to use for %substitution.
  'keyword'           => 'taxonomy_add',
  // The unique identifier for this context for use by required context checks.
  'context name'      => 'taxonomy_term_add_form',
  // Provides a list of items which are exposed as keywords.
  'convert list'      => array('vocabulary' => t('Taxonomy vocabulary')),
  // Convert keywords into data.
  'convert'           => 'context_example_taxonomy_term_add_form_convert',
  // Placeholder form is used in panels preview, for example.
  'placeholder form'  => array(
    '#type'         => 'textfield',
    '#description'  => t('Enter the taxonomy vocabulary.'),
  ),
);

Выше, в элементе массива с ключом 'edit form', мы объявили форму настроек, где мы сможем выбрать словарь таксономии, в котором будут храниться термины:

/**
 * Settings form for context plugin.
 */
function context_example_taxonomy_term_add_form_settings_form($form, &$form_state) {
  $conf         = $form_state['conf'];
  $vocabularies = taxonomy_vocabulary_get_names();
  $options      = array();

  // Provide the settings, where you will be able to select which of vocabularies will be used for taxonomy_term_add form.
  if (!empty($vocabularies)) {
    foreach ($vocabularies as $machine_name => $vocabulary) {
      $options[$machine_name] = $vocabulary->name;
    }

    $form['vocabulary'] = array(
      '#type'           => 'select',
      '#title'          => t('Taxonomy vocabulary'),
      '#description'    => t('Select the taxonomy vocabulary for this form.'),
      '#default_value'  => !empty($conf['vocabulary']) ? $conf['vocabulary'] : '',
      '#required'       => TRUE,
      '#options'        => $options,
    );
  }

  return $form;
}

Результаты этой формы нужно сохранять:

/**
 * Submit handler for plugin settings form.
 */
function context_example_taxonomy_term_add_form_settings_form_submit($form, &$form_state) {
  $form_state['conf']['vocabulary'] = $form_state['values']['vocabulary'];
}

Далее речь пойдет о функции, которая отвечает за, собственно, создание контекста:

/**
 * It's important to remember that $conf is optional here, because contexts
 * are not always created from the UI.
 */
function context_example_create_taxonomy_term_add_form($empty, $data = NULL, $conf = FALSE) {
  // We want to create the taxonomy add form, so we need to add the form contexts too.
  $context = new ctools_context(array('form', 'taxonomy_term_add_form'));
  // This is the plugin file name.
  $context->plugin = 'taxonomy_term_add_form';

  // Checking data from settings form.
  if (!empty($data['vocabulary'])) {
    // Get the The vocabulary object.
    $vocabulary = taxonomy_vocabulary_machine_name_load($data['vocabulary']);

    // Validate the taxonomy vocabulary exists and user has administrator access.
    if (!empty($vocabulary) && user_access('administer taxonomy')) {
      $form_state = array('build_info' => array('args' => array(array(), $vocabulary)));
      $form_id    = 'taxonomy_form_term';
      form_load_include($form_state, 'inc', 'taxonomy', 'taxonomy.admin');
      // Build a taxonomy_form_term form.
      $form       = drupal_build_form($form_id, $form_state);

      // All forms should place the form here.
      $context->form       = $form;
      $context->form_id    = $form_id;
      $context->form_title = t('Create a @name term', array('@name' => $vocabulary->name));
      // It's will be used in convert function.
      $context->data       = $data;

      return $context;
    }
  }
}

При объявлении плагина мы описали такие ключи массива как 'keyword', 'convert list' и 'convert'. Так как в нашем случае среди доступного контекста будет лишь машинное имя словаря таксономии (мы добавляем его в settings_form ), то в "convert list” можно сразу передать массив; но если переменных будет больше, или их значения нужно будет сгенерировать, то для этого можно использовать отдельную функцию с соответствующими настройками. Итак, описание этих параметров даст нам следующие аргументы в контексте:

taxonomy term add form

Например, стандартный контекст Node выглядит так:

node being viewed

Параметр 'convert' отвечает за преобразование ключевого слова в данные:

/**
 * Convert a context into a string.
 */
function context_example_taxonomy_term_add_form_convert($context, $type) {
  switch ($type) {
    // Convert a vocabulary keyword into the data.
    case 'vocabulary':
      return $context->data['vocabulary'];
  }
}

Вот и все, плагин полностью готов к использованию, наглядный пример его работы и архив с модулем можно найти в конце статьи.

Благодарим за внимание!

context.zip
1 vote, Rating: 5
Share on FacebookShare on TwitterShare on GooglePlusShare on Linkedin

Также по теме

1

Поддержка транзакций появилась уже в Drupal 7, включая те базы данных, которые самостоятельно их не поддерживают. Давайте рассмотрим как правильно их использовать,...

2

Модуль Migrate позволяет импортировать содержимое сайта в Drupal из других источников. Узнайте как установить и настроить этот инструмент для корректной работы.

3

В этой статье речь пойдёт о том, как установить ядро Drupal 8 как сабмодуль. Мы не будем рассматривать само понятие сабмодулей, их преимущества/недостатки, а лишь покажем в деталях, как подобную...

4

Не так давно мы рассматривали, как создать ctools тип контента для модуля Panels. На этот раз пришел черед другого...

5

Apps -  это модуль, который можно позиционировать как следующий шаг в развитии...

Need a quote? Let's discuss the project

Are you looking for someone to help you with your Drupal Web Development needs? Let’s get in touch and discuss the requirements of your project. We would love to hear from you.

Join the people who have already subscribed!

Want to be aware of important and interesting things happening? We will inform you about new blog posts on Drupal development, design, QA testing and more, as well news about Drupal events.

No charge. Unsubscribe anytime