Создание стиля отображения Views для Drupal
Создание плагина стилей отображения 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! Оставьте свой комментарий ниже. Удачного кодирования!