Ctools modal API. Пример использования

Версия Друпала:
7.x

Новые веяния моды таковы, что попапы обрели высокую популярность среди заказчиков и создается такое ощущение, что идеальный сайт, с их точки зрения, должен быть в попапе. Для шестого друпала был модуль Popups API. Для семерки его нет, но стараниями Эрла Майлза мы имеем замечательный инструмент - Ctools. Этот  модуль предоставляет мощный API для друпал-разработчика. В посте я рассмотрю малую часть возможностей тулзов, а именно modal API.

В качестве примера рассмотрим добавление отзывов к новостям. Новости и отзывы - это два типа контента. На странице новости есть блок с ссылкой "Добавить отзыв".

Для начала нам нужно объявить страницу в hook_menu, к которой будет обращаться ajax, затем пишем сам callback для объявленной страницы.  И в завершении блок с ссылкой "Добавить отзыв". Также не забываем в hook_form_alter() выставить дефолтное значение для поле "node reference".
Собственно, сам код:

<?php
/**
* Implements hook_menu().
*/
function examples_menu() {
 
$items['add/%ctools_js/review'] = array(
   
'page callback'    => 'examples_ctools_modal_review',
   
'page arguments'   => array(1),
   
'access arguments' => array('create review content'),
 );
 return 
$items;
}


/**
* Implements hook_block_info().
*/
function examples_block_info(){
 
$blocks['add_review'] = array(
   
'info' => t('Add review'),
 );
 return 
$blocks;
}


/**
* Implements hook_block_view().
*/
function examples_block_view($delta '') {
 switch (
$delta) {
   case 
'add_review':
     
ctools_include('ajax');
     
ctools_include('modal');
     
ctools_modal_add_js();
     
$news_id arg(1);
     if (
is_numeric($news_id)) {
       
// Link class must be "ctools-use-modal"    
       
$block['content'] = l(t('Add a review'), "add/nojs/review/{$news_id}", array('html' => TRUE'attributes' => array('class' => "ctools-use-modal")));
     }
     break;
 }
 return 
$block;
}


/**
* Implements hook_form_alter().
*/
function examples_form_alter(&$form, &$form_state$form_id) {
 switch (
$form_id) {
   case 
'review_node_form':
     
$news_id arg(3);
     if (
is_numeric(arg(3))) {
       
$lang field_language('node'$form['#node'], 'field_news');
       
// Declaration the default value for field on the comment creating form.
       
$form['field_news'][$lang][0]['nid']['#default_value'] = $news_id;
     }
 }
}


/**
* Page callback for modal review creation.
*/
function examples_ctools_modal_review($js FALSE) {
 
// loading libraries ctools'a 
 
ctools_include('node.pages''node''');
 
ctools_include('modal');
 
ctools_include('ajax');
 global 
$user;
 
$type 'review';
 
$node = (object) array(
   
'uid' => $user->uid,  
   
'name' => (isset($user->name) ? $user->name ''),  
   
'type' => $type,  
   
'language' => LANGUAGE_NONE);
  
// Loading node form with disabled scripts.
 
if (!$js) {
   return 
drupal_get_form($type '_node_form'$node);
 }
 
// Create array $form_state.
 
$form_state = array(
   
'title' => t('Add Review'),
   
'ajax'  => TRUE,
 );
 
$form_state['build_info']['args'] = array($node);
 
$output ctools_modal_form_wrapper($type '_node_form'$form_state);
 
// Actions after form submit. 
 
if (!empty($form_state['executed'])) {
   
$output = array();
   
// Close pop up.
   
$output[] = ctools_modal_command_dismiss();
   
$news_id arg(3);
   
// Insert  updated  view into a  page.
   
if (is_numeric(arg(3))) {
     
$output[] = ajax_command_html('.latest-reviews-full-style 'views_embed_view('reviews''block'arg(3)));
   }
 }
 print 
ajax_render($output);
}
?>

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

Примеры использования Ctools modal API можно посмотреть здесь(D7) и здесь(D6) .

Демо можно посмотреть здесь.

Тэги:
Ajax, Ctools, Forms API