Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll

API de formularios Drupal 7: creación de formularios en Drupal

11/05/2025, by Ivan

En lecciones anteriores nos familiarizamos con los hooks hook_block_info(), hook_block_view(), hook_menu(), hook_permission(), y ahora somos capaces de crear programáticamente tantas páginas y bloques como queramos. En esta lección, nos adentraremos en la Form API de Drupal 7 para la creación de formularios. Vamos a construir un formulario para la administración de funciones del módulo y trataremos de utilizar la mayor cantidad posible de hooks ya conocidos, para afianzar lo aprendido.

Para empezar, mostraremos 3 bloques. Creo que esto no será complicado para ti.

function sitemade_block_info(){
    $blocks = array(); // inicializamos un array vacío
    $blocks[1]['info'] = 'Lista de usuarios'; // título del bloque en la administración
    $blocks[2]['info'] = 'Lista de nodos';
    $blocks[3]['info'] = 'Lista de términos';
    return $blocks; // devolvemos la lista de bloques
}

function sitemade_block_view($delta = ''){
    $block = array(); // inicializamos un array vacío para el bloque
    switch ($delta){
        case 1: // mismo delta que devolvimos en hook_block_info()
            $block['subject'] = 'Usuarios'; // título del bloque
            $block['content'] = ''; // inicializamos variable de contenido
            $query = db_select('users', 'u') // consulta a la tabla users
                ->fields('u', array('uid', 'name')) // seleccionamos campos
                ->orderBy('u.uid', 'DESC') // ordenamos de forma descendente
                ->range(0, 5) // obtenemos 5 usuarios
                ->execute(); // ejecutamos la consulta
            $users = $query->fetchAll(PDO::FETCH_ASSOC); // obtenemos resultados como array
            foreach($users as $user){
                $block['content'] .= '

'; // base_path() devuelve la ruta base del sitio } break; case 2: $block['subject'] = 'Nodos'; $block['content'] = ''; $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->orderBy('n.nid', 'DESC') ->range(0, 10) ->execute(); $nodes = $query->fetchAll(PDO::FETCH_ASSOC); foreach($nodes as $node){ $block['content'] .= '

'; } break; case 3: $block['subject'] = 'Términos'; $block['content'] = ''; $query = db_select('taxonomy_term_data', 't') ->fields('t', array('tid', 'name')) ->orderBy('t.tid', 'DESC') ->range(0, 10) ->execute(); $terms = $query->fetchAll(PDO::FETCH_ASSOC); foreach($terms as $term){ $block['content'] .= '

'; } break; } return $block; }

Limpiamos la caché para que los nuevos bloques aparezcan en la administración. Mostramos estos bloques en la barra lateral izquierda:

Bloques de Drupal

Ahora crearemos una página en la administración donde después colocaremos un formulario para administrar estos tres bloques:

function sitemade_permission(){
    return array(
      'admin content blocks' => array(
        'title' => t('Administrar bloques de contenido'),
        'description' => t('Nodos, Usuarios, Términos'),
      ),
    );
}

function sitemade_menu(){
    $items = array(); // inicializamos array de ítems del menú
    $items['admin/config/content/content_blocks'] = array(
      'title' => 'Bloques de usuarios, nodos, términos',
      'description' => 'Administración de bloques',
      'page callback' => '_sitemade_content_blocks',
      'access arguments' => array('admin content blocks'),
    );
    return $items;
}

function _sitemade_content_blocks(){
    $content = '¡Lorem ipsum!';
    return $content;
}

Hemos creado la página, debería aparecer como una página vacía en la URL admin/config/content/content_blocks:

Página admin de Drupal

Y no olvidemos asignar permisos al rol de administrador para acceder a esta página (esto lo hicimos con hook_permission()):

Permisos en Drupal

Ahora modificaremos el código de nuestros hooks. Primero crearemos el formulario de administración. ¿Qué vamos a administrar en estos tres bloques? Propongo que sea el título del bloque y la cantidad de entidades mostradas (nodos, usuarios, términos).

Primero, cambiaremos la propiedad 'page callback' en el hook hook_menu:

function sitemade_menu(){
    $items = array();
    $items['admin/config/content/content_blocks'] = array(
      'title' => 'Bloques de usuarios, nodos, términos',
      'description' => 'Administración de bloques',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('_sitemade_content_blocks'),
      'access arguments' => array('admin content blocks'),
    );
    return $items;
}

drupal_get_form($form_id)

Un envoltorio para drupal_build_form() cuando no se necesita $form_state.

Parámetros

$form_id: identificador único de la función que genera el array del formulario. Si existe una función con este nombre, se invoca para construir el formulario. Si se requieren formularios similares con distintos identificadores, pueden declararse en hook_forms().

Cualquier argumento adicional pasado será transmitido a la función constructora del formulario. Por ejemplo, el formulario de edición de nodos node_edit requiere pasar el objeto nodo. Esto se puede lograr también con hook_form_alter() y hook_FORM_ID_alter() mediante $form_state['build_info']['args'].

Valor de retorno

Un array que representa el formulario.

Entonces reescribimos la función _sitemade_content_blocks() para que devuelva el array del formulario:

function _sitemade_content_blocks(){
    $form = array();

    $form['nodes-title'] = array(
      '#type' => 'textfield',
      '#title' => t('Título del bloque de nodos'),
      '#default_value' => variable_get('node_block', ''),
      '#size' => 60,
      '#maxlength' => 64,
      '#description' => t('Título para el bloque de nodos'),
    );

    $form['node-selected'] = array(
      '#type' => 'select',
      '#title' => t('Cantidad de nodos en el bloque'),
      '#options' => drupal_map_assoc(range(1,10)),
      '#default_value' => variable_get('node_block_range', 5),
      '#description' => t('Número de nodos mostrados en el bloque'),
    );

    $form['users-title'] = array(
      '#type' => 'textfield',
      '#title' => t('Título del bloque de usuarios'),
      '#default_value' => variable_get('user_block', ''),
      '#size' => 60,
      '#maxlength' => 64,
      '#description' => t('Título para el bloque de usuarios'),
    );

    $form['user-selected'] = array(
      '#type' => 'select',
      '#title' => t('Cantidad de usuarios en el bloque'),
      '#options' => drupal_map_assoc(range(1,10)),
      '#default_value' => variable_get('user_block_range', 5),
      '#description' => t('Número de usuarios mostrados en el bloque'),
    );

    $form['terms-title'] = array(
      '#type' => 'textfield',
      '#title' => t('Título del bloque de términos'),
      '#default_value' => variable_get('term_block', ''),
      '#size' => 60,
      '#maxlength' => 64,
      '#description' => t('Título para el bloque de términos'),
    );

    $form['term-selected'] = array(
      '#type' => 'select',
      '#title' => t('Cantidad de términos en el bloque'),
      '#options' => drupal_map_assoc(range(1,10)),
      '#default_value' => variable_get('term_block_range', 5),
      '#description' => t('Número de términos mostrados en el bloque'),
    );

    $form['actions'] = array('#type' => 'actions');
    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Guardar'),
    );

    return $form;
}

Ahora debemos implementar el submit handler para procesar y guardar estos valores en el sistema de variables de Drupal:

function sitemade_content_blocks_submit($form, &$form_state){
    variable_set('node_block', $form_state['values']['nodes-title']);
    variable_set('user_block', $form_state['values']['users-title']);
    variable_set('term_block', $form_state['values']['terms-title']);
    variable_set('node_block_range', $form_state['values']['node-selected']);
    variable_set('user_block_range', $form_state['values']['user-selected']);
    variable_set('term_block_range', $form_state['values']['term-selected']);
}

Con esto, al enviar el formulario se guardarán los valores y serán utilizados luego por los bloques para mostrar la información correctamente configurada.

Ahora solo queda modificar el hook hook_block_view() para que los títulos de los bloques y la cantidad de elementos mostrados se obtengan con variable_get(), es decir, desde los valores guardados en el formulario.

function sitemade_block_view($delta = ''){
  $block = array();
  switch ($delta){
    case 1:
      $block['subject'] = variable_get('user_block', 'Usuarios');
      $block['content'] = '';
      $query = db_select('users', 'u')
        ->fields('u', array('uid', 'name'))
        ->orderBy('u.uid', 'DESC')
        ->range(0, variable_get('user_block_range', 5))
        ->execute();
      $users = $query->fetchAll(PDO::FETCH_ASSOC);
      foreach($users as $user){
        $block['content'] .= '

'; } break; case 2: $block['subject'] = variable_get('node_block', 'Nodos'); $block['content'] = ''; $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->orderBy('n.nid', 'DESC') ->range(0, variable_get('node_block_range', 5)) ->execute(); $nodes = $query->fetchAll(PDO::FETCH_ASSOC); foreach($nodes as $node){ $block['content'] .= '

'; } break; case 3: $block['subject'] = variable_get('term_block', 'Términos'); $block['content'] = ''; $query = db_select('taxonomy_term_data', 't') ->fields('t', array('tid', 'name')) ->orderBy('t.tid', 'DESC') ->range(0, variable_get('term_block_range', 10)) ->execute(); $terms = $query->fetchAll(PDO::FETCH_ASSOC); foreach($terms as $term){ $block['content'] .= '

'; } break; } return $block; }

Con esto, los títulos y la cantidad de elementos mostrados en cada bloque dependerán de la configuración del formulario.

Y por supuesto: no olvides limpiar la caché después de realizar todos estos cambios para que Drupal registre las nuevas configuraciones.

Bloque Drupal personalizado

Como resultado, obtendrás una administración totalmente funcional para personalizar los bloques de usuarios, nodos y términos desde una página accesible en la administración. Esta lección demuestra cómo usar Form API junto con los hooks más importantes en el desarrollo de módulos personalizados para Drupal 7.