放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

Chapter 08: Working with Fields Drupal字段

感觉这一章没什么用,用UI为Drupal增加字段看起来的确很酷,但是没什么实用性。个人网站还好,商业网站程序卖出去给客户让客户按照说明书帮你创建字段?很明显还是用Field API写代码来创建字段更有实际意义,在你安装模块后,这个字段就在你的节点编辑表单里,已准备好为你的模块使用。

color_example.info

name = Color Example
description = "Creates a custom field for inputting and displaying text in a colorful
fashion."
package = Pro Drupal Development
core = 7.x
files[] = color_example.module
php = 5.2

color_example.module

<?php
/**
* @file
* An example field using the Field API.
*
*/
 
/**
 * Implements hook_field_info().
 *
 * Provides the description of the field.
 * 描述字段名
 */
function color_example_field_info()
{
    return array(
            'color_example_rgb' => array(
                    'label' => t('Example Color RGB'),
                    'description' => t('Demonstrates a field composed of an RGB color.'),
                    'default_widget' => 'color_example_3text',
                    'default_formatter' => 'color_example_simple_text'
            ) 
    );
}
 
/**
 * Implements hook_field_schema().
 * 建立数据表
 */
function color_example_field_schema($field)
{
    $columns = array(
            'rgb' => array(
                    'type' => 'varchar',
                    'length' => 7,
                    'not null' => FALSE 
            ) 
    );
    $indexes = array(
            'rgb' => array(
                    'rgb'
            ) 
    );
    return array(
            'columns' => $columns,
            'indexes' => $indexes
    );
}
 
/**
 * Implements hook_field_validate().
 *
 * Verifies that the RGB field as combined is valid
 * (6 hex digits with a # at the beginning).
 * 校验rgb是否合法必须是#xxxxxx的形式
 */
function color_example_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors)
{
    foreach($items as $delta=>$item)
    {
        if(!empty($item['rgb']))
        {
            if(!preg_match('@^#[0-9a-f]{6}$@', $item['rgb']))
            {
                $errors[$field['field_name']][$langcode][$delta][] = array(
                        'error' => 'color_example_invalid',
                        'message' => t('Color must be in the HTML format #abcdef.') 
                );
            }
        }
    }
}
 
/**
 * Implements hook_field_is_empty().
 * 描述什么样的字段是空字段
 */
function color_example_field_is_empty($item, $field)
{
    return empty($item['rgb']);
}
 
/**
 * Implements hook_field_formatter_info().
 * 定义字段是如何被描述的,只是定义,下一个函数才渲染
 */
function color_example_field_formatter_info()
{
    return array(
            // This formatter just displays the hex value in the color indicated.
            'color_example_simple_text' => array(
                    'label' => t('Simple text-based formatter'),
                    'field types' => array(
                            'color_example_rgb'
                    ) 
            ),
            // This formatter changes the background color of the content region.
            'color_example_color_background' => array(
                    'label' => t('Change the background of the output text'),
                    'field types' => array(
                            'color_example_rgb'
                    ) 
            ) 
    );
}
 
/**
 * Implements hook_field_formatter_view().
 * 渲染
 */
function color_example_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display)
{
    $element = array();
    switch ($display['type'])
    {
        // This formatter simply outputs the field as text and with a color.
        // 简单地将rgb值以对应的颜色输出
        case 'color_example_simple_text' :
            foreach($items as $delta=>$item)
            {
                $element[$delta]['#markup'] = '<p style="color: ' . $item['rgb'] . '">' . t('The color for this event is @code', array(
                        '@code' => $item['rgb'] 
                )) . '</p>';
            }
            break;
        // This formatter adds css to the page changing the '.region-content' area's
        // background color. If there are many fields, the last one will win.
        // 通过css改变'.region-content'
        case 'color_example_color_background' :
            foreach($items as $delta=>$item)
            {
                drupal_add_css('div.region-content { background-color:' . $item['rgb'] . ';}', array(
                        'type' => 'inline'
                ));
                $element[$delta]['#markup'] = '<p>' . t('The color for this event has been changed to @code', array(
                        '@code' => $item['rgb'] 
                )) . '</p>';
            }
            break;
    }
    return $element;
}
 
/**
 * Implements hook_field_widget_info().
 * 定义三个挂件
 */
function color_example_field_widget_info()
{
    return array(
            'color_example_text' => array(
                    'label' => t('RGB value as #ffffff'),
                    'field types' => array(
                            'color_example_rgb'
                    ) 
            ),
            'color_example_3text' => array(
                    'label' => t('RGB text fields'),
                    'field types' => array(
                            'color_example_rgb'
                    ) 
            ),
            'color_example_colorpicker' => array(
                    'label' => t('Color Picker'),
                    'field types' => array(
                            'color_example_rgb'
                    ) 
            ) 
    );
}
 
/**
 * Implements hook_field_widget_form().
 */
function color_example_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element)
{
    $value = isset($items[$delta]['rgb']) ? $items[$delta]['rgb'] : '';
    $element += array(
            '#delta' => $delta
    );
    $element['rgb'] = array();
    switch ($instance['widget']['type'])
    {
        case 'color_example_colorpicker' :
            $element['rgb'] += array(
                    '#suffix' => '<div class="field-example-colorpicker"></div>',
                    '#attributes' => array(
                            'class' => array(
                                    'edit-field-examplecolorpicker'
                            ) 
                    ),
                    '#attached' => array(
                            // Add Farbtastic color picker.
                            'library' => array(
                                    array(
                                            'system',
                                            'farbtastic'
                                    ) 
                            ),
                            // Add javascript to trigger the colorpicker.
                            'js' => array(
                                    drupal_get_path('module', 'color_example') . '/color_example.js'
                            ) 
                    ) 
            );
        // DELIBERATE fall-through: From here on the color_example_text and
        // color_example_colorpicker are exactly the same.
        case 'color_example_text' :
            $element['rgb'] += array(
                    '#title' => t('Event\’s RGB Color'),
                    '#type' => 'textfield',
                    '#default_value' => $value,
                    // Allow a slightly larger size than the field length to allow for some
                    // configurations where all characters won't fit in input field.
                    '#size' => 7,
                    '#maxlength' => 7 
            );
            break;
        case 'color_example_3text' :
            // Convert rgb value into r, g, and b for #default_value.
            if(isset($items[$delta]['rgb']))
            {
                preg_match_all('@..@', substr($items[$delta]['rgb'], 1), $match);
            }
            else
            {
                $match = array(
                        array() 
                );
            }
            // A fieldset to hold the three text fields.
            $element += array(
                    '#type' => 'fieldset',
                    '#element_validate' => array(
                            'color_example_3text_validate'
                    ),
                    // The following is set so that the validation function will be able
                    // to access external value information that otherwise would be
                    // unavailable.
                    '#delta' => $delta,
                    '#attached' => array(
                            'css' => array(
                                    drupal_get_path('module', 'color_example') . '/color_example.css'
                            ) 
                    ) 
            );
            // Create a textfield for saturation values for Red, Green, and Blue.
            foreach(array(
                    'r' => t('Red'),
                    'g' => t('Green'),
                    'b' => t('Blue') 
            ) as $key=>$title)
            {
                $element[$key] = array(
                        '#type' => 'textfield',
                        '#title' => $title,
                        '#size' => 2,
                        '#default_value' => array_shift($match[0]),
                        '#attributes' => array(
                                'class' => array(
                                        'rgb-entry'
                                ) 
                        ),
                        '#description' => t('The 2-digit hexadecimal representation of the
                            @color saturation, like "a1" or "ff"', array(
                                '@color' => $title
                        )) 
                );
            }
            break;
    }
    return $element;
}
 
/**
 * Validate the individual fields and then convert them into a single HTML RGB
 * value as text.
 */
function color_example_3text_validate($element, &$form_state)
{
    $delta = $element['#delta'];
    $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
    $field_name = $field['field_name'];
    if(isset($form_state['values'][$field_name][$element['#language']][$delta]))
    {
        $values = $form_state['values'][$field_name][$element['#language']][$delta];
        foreach(array(
                'r',
                'g',
                'b'
        ) as $colorfield)
        {
            $val = hexdec($values[$colorfield]);
            // If they left any empty, we'll set the value empty and quit.
            if(strlen($values[$colorfield]) == 0)
            {
                form_set_value($element, array(
                        'rgb' => NULL 
                ), $form_state);
                return;
            }
            // If they gave us anything that's not hex, reject it.
            if((strlen($values[$colorfield]) != 2) || $val < 0 || $val > 255)
            {
                form_error($element[$colorfield], t("Saturation value must be a 2-digit hexadecimal
value between 00 and ff."));
            }
        }
        $value = sprintf('#%02s%02s%02s', $values['r'], $values['g'], $values['b']);
        form_set_value($element, array(
                'rgb' => $value
        ), $form_state);
    }
}
 
/**
 * Implements hook_field_error().
 */
function color_example_field_widget_error($element, $error, $form, &$form_state)
{
    switch ($error['error'])
    {
        case 'color_example_invalid' :
            form_error($element, $error['message']);
            break;
    }
}

color_example.js

/**
 * @file
 * Javascript for Color Example.
 */
/**
 * Provide a farbtastic colorpicker for the fancier widget.
 */
(function ($) {
    Drupal.behaviors.color_example_colorpicker = {
            attach: function(context) {
                $(".edit-field-example-colorpicker").live("focus", function(event) {
                    var edit_field = this;
                    var picker = $(this).closest('tr').find(".field-example-colorpicker");
//                  Hide all color pickers except this one.
                    $(".field-example-colorpicker").hide();
                    $(picker).show();
                    $.farbtastic(picker, function(color) {
                        edit_field.value = color;
                    }).setColor(edit_field.value);
                });
            }
    }
})(jQuery);

color_example.css

/**
* @file
* CSS for Color Example.
*/
div.form-item table .form-type-textfield,div.form-item table .form-type-textfield *
    {
    display: inline-block;
}

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » Chapter 08: Working with Fields Drupal字段

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》