Drupal 7: Как создать блок программно

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

Процесс создания модуля я здесь описывать не буду, так как и без этого статья получилась обьемной, приступим сразу к созданию блока.

Для того, чтоб блок появился среди списка других блоков и его можно было настраивать, минимально необходимо определить два хука: hook_block_info() и hook_block_view(). Для полноценной-же реализации задуманных возможностей, надо реализовать следующие хуки:

  • hook_block_info() - отображение блока в списке доступных блоков
  • hook_block_configure() - настройка дополнительных параметров блока
  • hook_block_save() - сохранение информации, введенной в форме редактирования блока
  • hook_block_view() - Вывод содержимого блока

hook_block_info() - Отображение блока в списке блоков

Данный хук отвечает за появление создаваемого блока в административном меню. Возвращает он массив, состоящий из элементов, которые описывают создаваемые модулем блоки. Эти элементы, в  свою очередь, сами являются ассоциативными массивами. Информацию про допустимые ключи и их значения смотрите на странице hook_block_info(). Обратите внимание, что в имени функции слово hook заменено на имя модуля в данном случае test_block

/**
 * Implements hook_block_info().
 */
function test_block_block_info() {
  $blocks = array();
  $blocks['my_block'] = array(
    'info' => t('Test Block'),
  );
    
  return $blocks;
}

После сохранения изменений и обновления страницы, среди прочих, появится блок с именем ‘Test Block’:

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

hook_block_configure() - Форма настройки блока

С помомщью хука hook_block_configure() можно добавить дополнительные элементы, отображаемые при настройке блока. В данном случае это поле для загрузки изображения #managed_file и текстовое поле #text_format, но вы, если потребуется, можете добавить те поля, которые вам заблагорассудится. Список доступных типов полей вы можете найти на странице Form API Reference.

Примечание: #managed_file является не просто элементом ввода, а виджетом, который поддерживает AJAX, отображение превьюшек, проверку типа загружаемых файлов и многое другое.

Для описания элемента формы #text_format понадобятся #type, #title и #default_value - тип, заголовок и значение по умолчанию соответственно.

Для элемента формы #managed_file понадобятся #name, #type, #title, #description, #default_value, #upload_location и #upload_validators.

/**
 * Implements hook_block_configure().
 */
function test_block_block_configure($delta = '') {
  $form = array();

  switch ($delta) {
    case 'my_block' :
// Text field form element
      $form['text_body'] = array(
              '#type' => 'text_format',
              '#title' => t('Enter your text here in WYSIWYG format'),
              '#default_value' => variable_get('text_variable', ''),
      );

// Select file form element
      $form['file'] = array(
      '#name' => 'block_image',
      '#type' => 'managed_file',
      '#title' => t('Choose an Image File'),
      '#description' => t('Please select image. Only *.gif, *.png, *.jpg, and *.jpeg images allowed.'),
      '#default_value' => variable_get('test_block_image_fid', ''),
      '#upload_location' => 'public://',
      '#upload_validators' => array(
        'file_validate_extensions' => array('gif png jpg jpeg'),
      ),
      );
      break;
  }
  return $form;
}

После сохраненения изменений в модуле, форма редактирования блока должна содержать добавленные элементы:

hook_block_save() - Сохранение информации на сервере

для сохранения введенной информации, следует использовать хук hook_block_save(), который принимает на входе два агрумента $delta и $edit. Строковая переменная $delta содержит идентификатор блока, отправившего информацию, а в массиве $edit содержится сама отправляемая информация.

Для сохранения информации, введенной в текстовом поле, использована функция variable_set(), которой в качестве аргументов переданы имя переменной и ее значение,которое берется из переменной $edit['text_body']['value']

Для того, чтоб сохранить изображение, следует немного больше попрограммировать, а именно:

  1. Создать обьект $file для загруженного файла. Делается это с помощью функции file_load().
  2. Дальше нужно установить статус файла FILE_STATUS_PERMANENT (нонстанта, равная одному). Изначально, после загрузки файла через виджет #managed_file, файл имеет статус FILE_STATUS_TEMPORARY и удаляется по прошествии времени DRUPAL_MAXIMUM_TEMP_FILE_AGE.
  3. Далее, используя функцию file_save(), следует сохранить обновленный обьект $file в базе.
  4. Для того, чтоб указать системе, что файл используется блоком, следует воспользоваться функцией file_usage_add(). Это предотвратит удаление файла, в случае вызова функции file_delete(). В обычном режиме, удален может быть файл, который не имеет записей в таблице file_usage. Один из параметров, принимаемых функцией file_usage_add() является идентификатор блока, поэтому, чтоб получить этот идентификатор, следует вызвать функцию block_load(). Ну и напоследок, когда запись про использование файла сделана, используя функцию variable_set(), следует сохранить информацию про изображение.
/**
 * Implements hook_block_save().
 */
function test_block_block_save($delta  ='', $edit = array()) {
  switch ($delta) {
    case 'my_block' :
// Saving the text element value
      variable_set('text_variable' , $edit['text_body']['value']);

// Changing file to a permanent state
      $file = file_load($edit['file']);
      $file->status = FILE_STATUS_PERMANENT;
      file_save($file);
// Adding usage for file. Saving information about image.
      $block = block_load('test_block ', $delta);
      file_usage_add($file, 'test_block ', 'block ', $block->bid);
      variable_set('test_block_image_fid', $file->fid);
      break;
  }
}

hook_block_view() - Вывод содержимого блока

Последний этап - это при помощи хука hook_block_view(), вывести содержимое блока, в том числе и добавленные поля на экран.

Для повышения читаемости кода, логика данного этапа будет разбита на две функции: собственно сам хук hook_block_view() и вызываемая из него функция my_block_view(), в которой формируется массив.

 

/**
 * Implements hook_block_view().
 */
function test_block_block_view($delta = '') {
  $block = array();

  switch ($delta) {
    case 'my_block' :
      $block['content'] = my_block_view();
      break;
  }

  return $block;
}

/**   
 * Assemble renderable array for test block content.
 * @return
 * returns a renderable array of block content.
 */
function my_block_view() {
  $block = array();

// Capture the image file path and convert into HTML with some css attributes
  $image_file = file_load(variable_get('test_block_image_fid', ''));
  $image_path = '';

  if (isset($image_file->uri)) {
    $image_path = $image_file->uri;
  }
 
  $image = theme_image(array(
      'path' => ($image_path),
      'alt' => t('Image description.'),
      'title' => t('This is our block image title.'),
      'attributes' => array('class' => 'class_name'),
  ));
      
// Load text from variable
  $text = variable_get('text_variable', '');

// Block output in HTML with div wrappers around elements
  $block = array(
      'message' => array(
          '#prefix' => '<div>',
          '#type' => 'markup',
          '#markup' => $text,
          '#suffix' => '</div>',
      ),
      'image' => array(
          '#prefix' => '<div>',
          '#type' => 'markup',
          '#markup' => $image,
          '#suffix' => '</div>',
      ),
  );
      
  return $block;
}

Вот и все. Теперь блок готов к использованию:

Заключение

Как видите, для программного создания блока, нужно приложить совсем немного усилий, зато разобравшись во всех тонкостях работы Form API Drupal 7 для вас откроются неограниченные возможности создавать блоки самой различной сложности, а то, что вы все это делаете в виде отдельного модуля, позволит вам задействовать эти блоки повторно во всех ваших проектах. Во вложении к статье вы найдете готовый модуль, описанный выше.

Тэги: 
Прикрепленный файл: 

Добавить комментарий

Filtered HTML

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешённые HTML-теги: <a> <s> <u> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <hr> <dd> <sub> <sup>
  • Строки и параграфы переносятся автоматически.

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и параграфы переносятся автоматически.
CAPTCHA
Защита от СПАМ ботов. Подтвердите, пожалуйста, что вы человек.
7 + 1 =
Решите эту простую математическую задачу и введите результат. Например, для 1+3, введите 4.