Crear Campos Personalizados usando Drupal 7 Fields API

Definir el Campo:


Establecer el campo como una opción seleccionable en un tipo de contenido requiere tres pasos:

1. Defina el esquema de su campo Implementando hook_field_schema() en tu archivo  .install . 
Mi tipo de campo solo tiene una columna para la "opción", ya que las otras columnas, para la configuración de funciones o flujo de trabajo, se agregan mediante submódulos.

Snippet
function my_module_field_schema($field) {
 schema = array();
 schema['columns']['option'] = array(
      'type' => 'varchar',
      'length' => 25,
      'not null' => FALSE
  );
  return $schema;
}


2. Definir el campo al Field API implementando hook_field_schema() en el archivo .module Cuando se implemente, el nombre será "Mi campo". Todas las instancias de este campo tendrán una longitud máxima predeterminada de 255. Puede colocar cualquier configuración predeterminada aquí si lo desea o eliminar esta línea por completo si no se aplica a su implementación.

Snippet
function my_module_field_info() {
  return array(
    'mi_campo_name' => array(
      'label' => t('Mi Campo'),
      'description' => t('Description of Mi Campo.'),
      'settings' => array('max_length' => 255),
      'instance_settings' => array(
        'text_processing' => 0,
      ),
      'default_widget' => 'options_select',
      'default_formatter' => 'states_field_options',
    ),
  );
}

3. Defina el widget que utilizará para representar su campo. Si su campo usa un widget personalizado, puede definirlo implementando hook_field_widget_info () y hook_field_widget_form(). El módulo de ejemplos proporciona información sobre estas funciones.

Si su campo utilizará un widget existente, incluya ese widget como una opción para su campo al incluirlo hook_field_widget_info_alter() en su archivo .module. Si quiero que mi campo se represente usando solo una lista de selección (widget options_select), así que así es como se vería mi implementación:

Snippet
function my_module_field_widget_info_alter(&$info) {
  $widgets = array(
    'options_select' => array('mi_campo_type'),
  );
  foreach ($widgets as $widget => $field_types) {
    $info[$widget]['field types'] = array_merge($info[$widget]['field types'], $field_types);
  }
}

Configuración del Campo:


Ahora tiene un campo listo para ser seleccionado desde Manage Fields. Ahora necesita definir la configuración para su campo.

Primero debe definir el formulario para la configuración de su campo. Los campos admiten tanto la configuración de campo como la configuración de instancia. En caso de que no esté familiarizado, la configuración de campo se aplica a todos los lugares donde se usa ese campo y la configuración de instancia se aplica solo a esa instanciación de ese campo. Algunos tipos de campo solo admiten configuraciones de campo, otros solo admiten configuraciones de instancia y algunos admiten ambos.

Cree su formulario

Utilizando hook_field_settings_form()y hook_field_instance_settings_form() según corresponda. Ambas funciones toman el campo y la instancia como variables. Cree el formulario utilizando las convenciones estándar de Drupal. Cabe señalar que Fields API espera que los elementos del formulario se ordenen de la misma manera que la definición de su esquema. Los nombres de los elementos del formulario pueden diferir, pero el orden es importante para el módulo Field SQL Storage.

Debido a la forma en que se creó e implementó mi campo, se hara la validación del elemento (usando la propiedad #element_validate de un elemento de formulario) en lugar de usar hook_field_validate(). Lo hice porque quería validar la configuración del campo y no la implementación, y se llama a hook_field_validate cada vez que se representa el campo, tanto para la configuración del campo como para la creación / edición de nodos. Esto también me permitió mantener mi controlador de validación más limpio y más eficiente.

Snippet
function my_module_element_validate($element, &$form_state) {
  switch ($element['#type']) {
    case 'textfield':
      if ($element['#value'] == '') {
        form_error($element, t('Case Name may not be blank.'));
      }
      break;
    case 'checkboxes':
      if (empty($element['#value'])) {
        form_error($element, t('You must give at least one role access to this state.'));
      }
      break;
  }
}

Como Fields API maneja el envío y el almacenamiento de los elementos de su formulario, no necesita implementar un controlador de envío personalizado a menos que sea para alterar los datos antes de guardarlos.

Si su campo proporcionará múltiples opciones o si necesita representar una lista de cualquier tipo, debe implementar hook_options_list()para devolver la matriz de opciones a la Fields API para completar su widget.

Snippet
function my_module_options_list($field, $instance, $entity_type, $entity) {
  return array('option_1', 'option_2');
}

Crea tu Display


El último elemento necesario para crear su campo es definir cómo se representará. Puede crear múltiples configuraciones de pantalla si lo desea, solo una era necesaria para mi implementación. Drupal usará el nombre de su campo como etiqueta para que no tenga que preocuparse por eso, solo devuelva el valor apropiado para el campo. 

1. Defina el Display de su campo usando hook_field_formatter_info().

Snippet
function states_field_field_formatter_info() {
  return array(
    'my_field_default' => array(
      'label' => t('Default'),
      'field types' => array('my_field_name'),
    ),
  );
}

2. Devuelve los datos para mostrarlos cuando se procesan con hook_field_formatter_view().

Snippet
function my_module_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  //Currently we only have one display option, use switch
  //to prepare for future options.
  switch ($display['type']) {
    case 'mi_campo_default':
      foreach ($items as $delta => $item) {
        if (isset($options[$item['option']]['option'])) {
          $output = field_filter_xss($options[$item['option']]['option']);
        }
        else {
          $output = "Not Supplied";
        }
        $element[$delta] = array('#markup' => $output);
      }
      break;
    default:
  }
  return $element;
}

Comments