Het maken van een Views-weergavestijl voor Drupal
Het maken van een Views-weergavestijlplugin kan ingewikkeld lijken, maar het is eenvoudiger dan het eruitziet. Hier is een stapsgewijze handleiding over hoe dit te doen, inclusief broncode.
U kunt de kant-en-klare code hier downloaden: TARDIS (hoewel deze nog in dev is). En als u een introductie nodig heeft in Drupal 8-modules, bekijk dan dit praktische handboek voor het maken van basis Drupal 8-modules.
.info.yml
Begin met het aanmaken van een map met de naam tardis voor uw module in /modules/custom. Plaats daarin een bestand met de naam tardis.info.yml met de volgende code:
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
Nu is het tijd om de pluginclass te maken. Maak een bestand met de naam Tardis.php in src/Plugin/views/style en voeg de volgende code in:
<?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.'),
);
}
}
Laten we een paar zaken bekijken:
* @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" }
* )
Deze commentaarregels zijn belangrijk. Ze vormen de basis voor onze plugin. Als u ze vergeet toe te voegen, werkt de code niet correct.
class Tardis extends StylePluginBase {
De basisdefinitie van de plugin. Ook dit is noodzakelijk.
protected function defineOptions() {
$options = parent::defineOptions();
$options['path'] = array('default' => 'tardis');
return $options;
}
Mogelijkheid om basisopties te definiëren, plus een belangrijke standaardwaarde voor onze plugin. Dit is nodig omdat de plugin configureerbaar moet zijn.
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
Verder bouwen we een eigen instellingenformulier met velden, bijna zoals gewone configuratieformulieren. Voor meer informatie, zie de Forms API-referentie.
.module-bestand
Het .module-bestand is niet verplicht in Drupal 8, maar hier hoort de themainformatie thuis:
<?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',
),
);
}
In feite delegeren we de preprocessfunctie naar een apart bestand om alles netjes te organiseren.
.theme.inc-bestand
Maak een bestand met de naam tardis.theme.inc in de map van onze module en voeg de volgende code in:
<?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;
}
Deze code neemt in feite alle aangemaakte datums van nodes en bouwt er een associatieve array van, die samen met andere instellingen uit het formulier naar het sjabloon wordt doorgegeven voor de uiteindelijke rendering.
Twig it out
Voor de output van de module maakt u een bestand views-view-tardis.html.twig in de map templates. Maar waarom die naam? Denk aan de commentaarregels aan het begin van deze les:
* theme = "views_view_tardis",
Dit betekent dat het sjabloon in de standaardlocatie (/templates) moet staan met die naam, alleen met streepjes in plaats van underscores en .html.twig erachter.
De code ziet er zo uit:
{#
/**
* 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>
Het is aan te raden om eerst alle variabelen uit de associatieve array $variables bovenaan het bestand uit te lezen. Ze worden netjes opgeslagen in $variables['options'] – of in Twig als variables.options.
Daarna stellen we enkele klassen in voor onze view, zoals gedefinieerd in het instellingenformulier:
{%
set classes = [
'views-view-tardis',
options.classes
]
%}
En voegen we die toe:
<div{{ attributes.addClass(classes) }}>
De rest van de code haalt de maanden en jaren met inhoud op en toont die in een HTML-lijst. Hier is de belangrijke for-lus:
{% for key, item in options.time_pool %}
Die zorgt ervoor dat elke link correct wordt aangemaakt. Bijvoorbeeld:
<li><a href="/{{ options.path }}/{{ key }}/{{ subkey }}">{{ subitem }}</a></li>
Nog iets
En last but not least: we moeten een standaardweergave maken en exporteren om het voor gebruikers sneller beschikbaar te maken. U zult zien dat er al een standaardweergave is in /config/install/views.view.tardis.yml. Deze standaardweergave is beschikbaar zodra gebruikers de module activeren.
Ik heb deze gemaakt en geëxporteerd via het formulier voor enkele export in admin/config/development/configuration/single/export, volgens de uitstekende tutorial van Subhojit Paul.
Dat is het!
Nu kunt u uw eigen Views-weergavestijlplugin voor Drupal 8 schrijven! Laat hieronder een reactie achter. Veel plezier met coderen!