В одному з наших блогів вже висвітлювалася тема створення плагінів для модуля 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' можна одразу передати масив; але якщо змінних буде більше, або їх значення потрібно згенерувати, то для цього можна використати окрему функцію з відповідними налаштуваннями. Отже, описання цих параметрів дасть нам наступні аргументи в контексті:
Для прикладу, стандартний контекст Node виглядає так:
Параметр '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']; } }
Ось і все, плагін повністю готовий до використання, наглядний приклад його роботи та архів з модулем можна знайти в кінці статті.
Дякую за увагу.