Drupal用Views表示スタイルの作成
Views表示スタイルプラグインの作成は難しいように思えるかもしれませんが、思ったより簡単です。ソースコード付きのステップバイステップガイドを紹介します。
完成したコードはこちらからダウンロードできます:TARDIS(まだdev版ですが)。Drupal 8モジュールの入門が必要な場合は、Drupal 8の基本モジュール作成の実践ガイドがあります。
.info.yml
/modules/customに、モジュール用のtardisというフォルダーを作成することから始めます。その中に、次のコードを含む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
次はプラグインクラスの作成です。src/Plugin/views/style内にTardis.phpという名前のファイルを作成し、次のコードを貼り付けます:
<?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);
さらに進んで、通常の設定フォームとほぼ同じように、フィールドを持つ実際のオプションフォームを作成します。詳細については、Forms APIリファレンスを参照してください。
.moduleファイル
.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で仕上げる
次に、モジュールの出力用に、templatesというフォルダーにviews-view-tardis.html.twigファイルを作成します。しかし、なぜこの名前なのでしょうか?このレッスンの最初のコメントを覚えていますか?
* 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>
まず、ファイルの先頭で、$variables連想配列によって渡されたすべての変数を抽出することをお勧めします。それらは$variables['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>
もう1つ
最後に重要なことですが、ユーザー向けに便利にするために、デフォルトのビューを作成してエクスポートする必要があります。/config/install/views.view.tardis.ymlにデフォルトのビューが既にあることに気づくはずです。このデフォルトビューは、ユーザーがモジュールを有効化した時点で利用可能になります。
私はSubhojit Paulの優れたチュートリアルに従って、admin/config/development/configuration/single/exportのシングルエクスポートフォームで作成し、エクスポートしました。
これで終わり!
これで、Drupal 8用の独自のViews表示プラグインを書けるようになりました!下にコメントを残してください。楽しいコーディングを!