Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll

Создание стиля отображения Views для Drupal

26/04/2020, by maria

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

Вы можете скачать готовый код здесь: TARDIS (хотя он все еще в dev). И если вам нужно введение в модули Drupal 8, вот практическое руководство по созданию базовых модулей Drupal 8.

.info.yml

Начните с создания папки под названием tardis для вашего модуля в /modules/custom. Поместите в него файл с именем tardis.info.yml со следующим кодом:

name: TARDIS
type: module
description: 'Provides a View display style that renders a list of year and month links to content in reverse chronological order.'
package: Views
core: '8.x'
dependencies:
  - drupal:views

Classy

Теперь пришло время создать класс плагина. Создайте файл с именем Tardis.php внутри src/Plugin/views/style и вставьте следующий код:

<?php

namespace Drupal\tardis\Plugin\views\style;

use Drupal\core\form\FormStateInterface;
use Drupal\views\Plugin\views\style\StylePluginBase;

/**
 * Style plugin to render a list of years and months
 * in reverse chronological order linked to content.
 *
 * @ingroup views_style_plugins
 *
 * @ViewsStyle(
 *   id = "tardis",
 *   title = @Translation("TARDIS"),
 *   help = @Translation("Render a list of years and months in reverse chronological order linked to content."),
 *   theme = "views_view_tardis",
 *   display_types = { "normal" }
 * )
 */
class Tardis extends StylePluginBase {

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['path'] = array('default' => 'tardis');
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);

    // Path prefix for TARDIS links.
    $form['path'] = array(
      '#type' => 'textfield',
      '#title' => t('Link path'),
      '#default_value' => (isset($this->options['path'])) ? $this->options['path'] : 'tardis',
      '#description' => t('Path prefix for each TARDIS link, eg. example.com<strong>/tardis/</strong>2015/10.'),
    );

    // Month date format.
    $form['month_date_format'] = array(
      '#type' => 'textfield',
      '#title' => t('Month date format'),
      '#default_value' => (isset($this->options['month_date_format'])) ? $this->options['month_date_format'] : 'm',
      '#description' => t('Valid PHP <a href="@url" target="_blank">Date function</a> parameter to display months.', array('@url' => 'http://php.net/manual/en/function.date.php')),
    );

    // Whether month links should be nested inside year links.
    $options = array(
      1 => 'yes',
      0 => 'no',
    );
    $form['nesting'] = array(
      '#type' => 'radios',
      '#title' => t('Nesting'),
      '#options' => $options,
      '#default_value' => (isset($this->options['nesting'])) ? $this->options['nesting'] : 1,
      '#description' => t('Should months be nested inside years? <br />
        Example:
        <table style="width:100px">
          <thead>
              <th>Nesting</th>
              <th>No nesting</th>
          </thead>
          <tbody>
            <td>
              <ul>
                <li>2016
                  <ul>
                    <li>03</li>
                    <li>02</li>
                    <li>01</li>
                  </ul>
                </li>
              </ul>
            </td>
            <td>
              <ul>
                <li>2016/03</li>
                <li>2016/02</li>
                <li>2016/01</li>
              </ul>
            </td>
          </tbody>
        </table>
      '),
    );

    // Extra CSS classes.
    $form['classes'] = array(
      '#type' => 'textfield',
      '#title' => t('CSS classes'),
      '#default_value' => (isset($this->options['classes'])) ? $this->options['classes'] : 'view-tardis',
      '#description' => t('CSS classes for further customization of this TARDIS page.'),
    );
  }

}

Давайте рассмотрим некоторые из них:

 * @ViewsStyle(
 *   id = "tardis",
 *   title = @Translation("TARDIS"),
 *   help = @Translation("Render a list of years and months in reverse chronological order linked to content."),
 *   theme = "views_view_tardis",
 *   display_types = { "normal" }
 * )

Эти комментарии важны. Они закладывают основу для нашего плагина. Если вы не забудете добавить их, код не будет работать должным образом.

class Tardis extends StylePluginBase {

Базовое определение плагина. Опять же, это необходимо.

  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['path'] = array('default' => 'tardis');
    return $options;
  }

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

  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);

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

. file

Файл .module не является обязательным в Drupal 8, но именно там должна быть информация о темах:

<?php

/**
 * @file
 * TARDIS Views module help and theme functions.
 */

/**
 * Implements hook_theme().
 */
function tardis_theme($existing, $type, $theme, $path) {
  // Store TARDIS preprocess theme functions in a separate .inc file.
  \Drupal::moduleHandler()->loadInclude('tardis', 'inc', 'tardis.theme');

  return array(
    'tardis' => array(
      'file' => 'tardis.theme.inc',
    ),
  );
}

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

файл .theme.inc

Создайте файл с именем tardis.theme.inc в каталоге нашего модуля и включите следующий код:

<?php

/**
 * @file
 * Theme for TARDIS views.
 */
function template_preprocess_views_view_tardis(&$variables) {
  // View options set by user.
  $options = $variables['view']->style_plugin->options;

  // Build a two-dimension array with years and months.
  $time_pool = array();

  foreach ($variables['view']->result as $id => $result) {
    $created = $result->node_field_data_created;
    $created_year = date('Y', $created);
    // Month date format.
    $month_date_format = (isset($options['month_date_format'])) ? $options['month_date_format'] : 'm';
    $created_month_digits = date('m', $created);
    $created_month = date($month_date_format, $created);
    $time_pool[$created_year][$created_month_digits] = "$created_month";
  }

  $options['time_pool'] = $time_pool;

  // Update options for twig.
  $variables['options'] = $options;
}

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

Twig it out

Теперь для вывода модуля создайте файл views-view-tardis.html.twig в папке с именем templates. Но почему это имя? Помните комментарии в начале этого урока?

* theme = "views_view_tardis",

Это означает, что шаблон должен быть найден в расположении по умолчанию (/ templates) с этим именем, только с черточками вместо подчеркивания и .html.twig в конце.

Что касается кода:

{#
/**
 * Default theme implementation for Views to output a TARDIS archive.
 *
 * Available variables:
 * - options: View plugin style options:
 *   - classes: CSS classes.
 *   - nesting: Whether months should be nested inside years.
 *   - path: Link path. Eg.: example.com/TARDIS/2016/03
 *   - time_pool: Two-dimension array containing years and months with content.
 *
 * @see template_preprocess_views_view_tardis()
 *
 * @ingroup themeable
 */
#}
{%
  set classes = [
    'views-view-tardis',
    options.classes
  ]
%}
<div{{ attributes.addClass(classes) }}>
  <ul>
    {% for key, item in options.time_pool %}
      {% if options.nesting == 1 %}
        <li><a href="/{{ options.path }}/{{ key }}">{{ key }}</a><ul>
        {% for subkey, subitem in item %}
          <li><a href="/{{ options.path }}/{{ key }}/{{ subkey }}">{{ subitem }}</a></li>
        {% endfor %}
        </ul></li>
      {% else %}
        {% for subkey, subitem in item %}
          <li><a href="/{{ options.path }}/{{ key }}/{{ subkey }}">{{ subitem }}</a></li>
        {% endfor %}
      {% endif %}
    {% endfor %}
  </ul>
</div>

Сначала рекомендуется извлечь все переменные, переданные ассоциативным массивом $variable в начале файла. Они аккуратно хранятся в $variable['options'] - или, как было бы у twig, variables.options.

Затем мы устанавливаем некоторые классы для нашего представления, как определено в форме параметров:

{%
  set classes = [
    'views-view-tardis',
    options.classes
  ]
%}

И вспомните их:

<div{{ attributes.addClass(classes) }}>

Остальная часть кода посвящена извлечению месяцев и лет, в которых есть записи, и отображению списка HTML. Здесь важно отметить цикл for:

{% for key, item in options.time_pool %}

Что делает каждую ссылку правильно. Например:

<li><a href="/{{ options.path }}/{{ key }}/{{ subkey }}">{{ subitem }}</a></li>

Еще кое-что

И последнее, но не менее важное: мы должны создать представление по умолчанию и экспортировать его, чтобы ускорить его для пользователей. Вы должны заметить, что в /config/install/views.view.tardis.yml уже есть представление по умолчанию. Это представление по умолчанию доступно с того момента, как пользователи активируют модуль.

Я создал его и экспортировал через единую форму экспорта в admin/config/development/configuration/single/export, следуя превосходному учебнику Субходжита Пола.

Это оно!

Теперь вы сможете написать свой собственный плагин для просмотра Views для Drupal 8! Оставьте свой комментарий ниже. Удачного кодирования!

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.