作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
我们这章,就主要讲Views了。刚才提到,我们受Field collection views模块的启发,我们这里介绍一个这个模块的代码。这个模块的用法,我们在Think in Drupal的第二集,里面已经介绍过了,是对Field Collection模块的一个很好的补充。Field collection views模块的主要功能,就是为Field collection类型的字段,提供一个formatter(格式化器),使用Views来呈现Field collection items。
我们来看一下module文件里面的代码:
/**
* Implements hook_field_formatter_info().
*/
function field_collection_views_field_formatter_info() {
return array(
'field_collection_views_view' => array(
'label' => t('Views field-collection items'),
'field types' => array('field_collection'),
'settings' => array(
'name' => 'field_collection_view',
'display_id' => 'default',
'add' => t('Add'),
),
),
);
}
/**
* Implements hook_field_formatter_view().
*/
function field_collection_views_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $display['settings'];
switch ($display['type']) {
case 'field_collection_views_view':
//debug($items);
$args = '';
$i = 1;
foreach ($items as $delta => $item) {
if ($i == 1) {
$args .= $item['value'];
}
else {
$args .= '+' . $item['value'];
}
$i++;
}
$view_name = isset($settings['name']) ? $settings['name'] : 'field_collection_view';
$display_id = isset($settings['display_id']) ? $settings['display_id'] : 'default';
$content = views_embed_view($view_name, $display_id, $args);
$element[0] = array(
'#markup' => $content,
);
if (empty($items)) {
field_collection_field_formatter_links($element, $entity_type, $entity, $field, $instance, $langcode, $items, $display);
}
break;
}
return $element;
}
/**
* Implements hook_field_formatter_settings_form().
*/
function field_collection_views_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$elements['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#default_value' => $settings['name'],
'#description' => t('The machine name of the view to embed.'),
);
$elements['display_id'] = array(
'#type' => 'textfield',
'#title' => t('Display id'),
'#default_value' => $settings['display_id'],
'#description' => t('The display id to embed.'),
);
$elements['add'] = array(
'#type' => 'textfield',
'#title' => t('Add link title'),
'#default_value' => $settings['add'],
'#description' => t('Leave the title empty, to hide the link.'),
);
return $elements;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function field_collection_views_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$links = array_filter(array_intersect_key($settings, array_flip(array('name', 'display_id'))));
if ($links) {
return '<em>Embed View:</em> ' . check_plain(implode(', ', $links));
}
else {
return t('Not showing any view.');
}
}
/**
* Implements hook_views_api().
*/
function field_collection_views_views_api() {
return array(
'api' => '3.0-alpha1',
'path' => drupal_get_path('module', 'field_collection_views') . '/views',
);
}
我们在Think in Drupal的第1集里面,讲字段API的时候,讲过,如何为已有字段定制格式器,我们这里做的就是这个工作,hook_field_formatter_info,hook_field_formatter_view,hook_field_formatter_settings_form,hook_field_formatter_settings_summary,这四个钩子函数,是定制格式器时,需要实现的四个钩子函数。
在field_collection_views_field_formatter_view里面,注意粗体字部分,这里面的逻辑是,我们获取所有的field collection item的ids,然后把它们作为参数传递给对应的视图(view)。views_embed_view,这个函数,我们已经非常熟悉了,注意这里的参数传递方式,我们这里使用了“+”号,来传递多个参数。这是实际当中,经常用的一个技巧。
最后,我们实现了hook_views_api,这里注意的是'api',我们这里用的是'3.0-alpha1',是Views的最初版本,如果把它改为'3.0',也是可以的。