Ctools тип контенту для Panels

12.10.2012
Ctools content type for Panels
Автор:

Наша компанія веб розробників дуже часто використовує модуль Panels при створенні сайтів. Хоча це рішення додає чимало HTML-структури, але натомість ми отримуємо гнучкий, зручний, простий в обслуговуванні механізм. В той же час іноді вбудованих можливостей модуля буває недостатньо (нестандартні вимоги замовника або внутрішнє бажання зробити щось так само, та ще й краще). Ctools типи контенту чимось схожі на стандартні блоки в Drupal, але у них є свої переваги:

  • можливість виведення будь-якої інформації - в'юшки, форми, HTML
  • ці сутності добре структуруються - темінг, препроцес і форма налаштувань для кожного ctools content type описується всередині нього самого
  • вони працюють з контекстами панелей
  • легко реалізувати форму налаштувань відображення.

Розглянемо процес створення ctools типу контенту. Для цього створимо модуль "ctools_example". У модулі викликаємо hook_ctools_plugin_directory (), який повідомляє ctools розташування папки з плагінами зазначеного типу. У хука є два параметри:

  • $ Plugin_type - назва параметра говорить сама за себе - це назва типу плагіна ('Panels', 'layouts', 'styles' і т.д.)
  • $ Owner - обов'язковий параметр, так як ctools дотримується простору імен по плагінам в залежності від того якому модулю вони належать. Зазвичай використовується шлях "plugins/$ plugin_type".
/*
 * Implements hook_ctools_plugin_directory -
 */
function ctools_example_ctools_plugin_directory($owner, $plugin_type) {
  if ($owner == 'ctools' && $plugin_type == 'content_types') {
    return 'plugins/content_types';
  }
}

Далі створюємо папку "plugins / content_types" і поміщаємо туди файл з нашим плагіном, наприклад "ctools_example_content_type.inc". У цьому файлі насамперед описуєм плагін. Доступні параметри:

  • 'title' - назва нашого типу контенту
  • 'description' - його детальний опис
  • 'single' - якщо тут TRUE, то в цьому типі контенту немає підтипів 
  • 'content_types' - масив, що визначає властивості типу контента або функції, яка повертає цей масив
  • 'render callback' - назва функції, яка буде відповідати за виведення блока
  • 'defaults' - контекст за замовчуванням
  • 'edit form' - назва функції, яка буде відповідати за виведення форми редагування типу контенту
  • 'icon' - іконка, що буде відображатися в адмін інтерфейсі. Іконка повинна знаходитися в папці з плагіном
  • 'category' - категорія, до якої буде належати новостворений тип контенту

Весь перелік параметрів можна подивитися встановивши модуль Advanced help.

 /**
 * Plugins are described by creating a $plugin array which will be used
 * by the system that includes this file.
 */
$plugin = array(
  'title' => t('Example block'),
  'description' => t('Example block.'),
  // 'single' => TRUE means has no subtypes.
  'single' => TRUE,
  // Constructor.
  'content_types' => array('no_context_content_type'),
  // Name of a function which will render the block.
  'render callback' => 'ctools_example_static_block_render',
  // The default context.
  'defaults' => array(),

  // This explicitly declares the config form. Without this line, the func would be
  // ctools_plugin_example_no_context_content_type_edit_form.
  'edit form' => 'ctools_example_example_block_edit_form',
  'icon' => 'favicon.ico',
  'category' => array(t('Example'), -9),
);

Думаю, ви вже зрозуміли, що далі нам потрібно оголосити функції виведення і редагування нашого об’єкту. Створимо простий тип контенту, який буде за допомогою автозаповнення підтягувати якусь ноду і виводити її заголовок та текст. Виведення заголовка, виведення його посиланням / не посиланням і виведення тексту буде опцією. А ось власне і сама форма:

/**
 * Generates example block edit form.
 */
function ctools_example_example_block_edit_form($form, &$form_state) {
  $conf = $form_state['conf'];

  // We don't want to use standart pane title functionallity.
  $form['override_title']['#access'] = FALSE;
  $form['override_title_text']['#access'] = FALSE;
  $form['override_title_markup']['#access'] = FALSE;
  $form['title_nid'] = array(
    '#type' => 'textfield',
    '#title' => t('Enter content title'),
    '#autocomplete_path' => 'ctools_example/autocomplete',
    '#default_value' =>  $conf['title_nid'] ? $conf['title_nid'] : '',
  );
  $form['show_body'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show body'),
    '#default_value' =>  $conf['show_body'] ? TRUE : FALSE,
  );
  $form['display_title'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display title'),
    '#default_value' =>  $conf['display_title'] ? TRUE : FALSE,
  );
  $form['title_as_link'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display title as link'),
    '#default_value' =>  $conf['title_as_link'] ? TRUE : FALSE,
    '#states' => array(
      'visible' => array(
        ':input[name="display_title"]' => array('checked' => TRUE),
      ),
    ),
  );

  return $form;
}

До форми редагування ctools типу контенту можна додавати submit / validate - обробники також як і до стандартних форм в Drupal.  У нашому випадку validate - обробник буде перевіряти правильність введення в поле автозаповнення, а submit - обробник буде зберігати налаштування для конкретного блоку:

/**
 * Validate handler for example block edit form.
 */
function ctools_example_example_block_edit_form_validate($form, &$form_state) {
  $text = $image = $video = $audio = FALSE;
  if (!preg_match('/.*\[nid:([\d]+)\]/', $form_state['values']['title_nid'], $m)) {
    form_set_error('title_nid', t('Title should be in format "Title [nid:xxx]"'));
  }
}

/**
 * Submit handler for example block edit form.
 */
function ctools_example_example_block_edit_form_submit($form, &$form_state) {
  foreach (array('title_nid', 'display_title', 'title_as_link', 'show_body') as $key) {
    $form_state['conf'][$key] = $form_state['values'][$key];
  }
}

Ну і на завершення функція, що відповідає за виведення  контенту нашого блоку. Як видно з коду, логіка виведення нагадує логіку, що використовується в hook_block_view() . При цьому нам потрібно сформувати об'єкт з наступними можливими властивостями:

  • 'title' - заголовок блоку
  • 'content' - контент блоку
  • 'links' - масив посилань, що відносяться до контенту. Формат масиву повинен бути в такому ж форматі як і для функції theme_links
  • 'more' - посилання за опцією, на зразок "Читати далі"

Повний перелік властивостей можна подивитися встановивши той таки ж модуль Advanced help.

/**
 * Run-time rendering of the body of the block.
 *
 * @param $subtype
 * @param $conf
 *   Configuration as done at admin time.
 * @param $args
 * @param $context
 *   Context - in this case we don't have any.
 *
 * @return
 *   An object with at least title and content members.
 */
function ctools_example_example_block_render($subtype, $conf, $args, $context) {
  $block = new stdClass();
  $block->content = '';
  if (!empty($conf)) {
    preg_match('/(.*) \[nid:([\d]+)\]/', $conf['title_nid'], $m);
    if (isset($m[1]) && is_numeric($m[2])) {
      $nid = $m[2];
      $node = node_load($nid);
      if ($conf['display_title']) {
        $block->title = $conf['title_as_link'] ? l($node->title, "node/{$node->nid}") : $node->title;
      }
      $lang = field_language('node', $node, 'body');
      if ($conf['show_body']) {
        $block->content .= $node->body[$lang][0]['value'];
      }
    }
  }
  return $block;
}

Весь код модуля дивіться у прикріплених файлах, приблизний вигляд адмін інтерфейсу - на скріншотах.

 

Дякую за увагу.

2 votes, Рейтинг: 5

Також по темі

1

 Із розвитком соціальних мереж замовники все частіше хочуть інтегрувати сайт з Facebook, Twitter, Google+ і т.д. На одному з проектів, потрібно було, реалізувати кроспостінг у...

2

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

3

В статті буде розповідатись про те, як швидко налаштувати модуль Search API та...

4

Трапляються завдання, для вирішення котрих необхідно створювати свою таблицю в базі даних і потім власними ж запитами взаємодіяти із цією таблицею. За таких обставин написання численних запитів...

Subscribe to our blog updates