Bookモジュールのような次/前のページへのリンクを作成しようとしています。
ChapterとPageの2つのコンテンツタイプがあります。
Chapterコンテンツタイプには、ページのエンティティ参照フィールド(無制限)が含まれています。
したがって、各章には、エンティティ参照フィールド章のページに任意の数のページが含まれており、これらはページの順序を決定するために並べ替えられます。
ここで、各Pageで、親の値に基づいて前後のページへのリンクを作成しますChapterのエンティティ参照フィールドPages in章。
具体的には、ビューまたはブロックなどをPageで使用して、現在のPageを参照するChapterを取得し、値を反復処理する必要があります。エンティティ参照フィールド章のページの直前にあるPageと現在の直後にあるPageを検索Pageとし、これを単純な順不同リストとして出力します。
私は少しコーディングできますが、私はあまり上手ではないので、これを実装するアプローチを見つけるのに苦労しています。
私が試したこと
これをビューで構築しようとしました。私が遭遇した問題は、サブディビジョンエンティティ参照フィールドを反復処理して、前のリンクと次のリンクを除外するのが非常に難しいことでした。
これはDrupal 7 の場合と同様の質問ですが、Drupal 8はコア(ビューとエンティティ参照、例)、もう一度質問するのは公平だと思います。
Bookモジュールを使用しないのはなぜですか?
次/前のページの機能のみが必要です。理想的には、エンティティ参照フィールド章のページに基づいています。 Drupal 8のブックモジュールナビゲーションは、他のコアと同じパターンに従っていない(ブロックではなく、メニューでもない)。今日の午後、数時間を過ごした本の発行待ち行列と古い問題の整理、そしてモジュールを「近代化」するための努力はほとんどないように思えたので、この機能を自分で実装してみるのが良いだろうと思いました。
私は少しコーディングできますが、私はあまり上手ではないので、これを実装するためのアプローチを見つけるのに苦労しています。
7年前にゼロから始めましたが、HTMLとCSSしか知りませんでした。私はルールとビューを学び、習得しました。しかし、4、5年前のように、このようなシナリオに出くわし、既存のモジュールが必要なことをまったく実行しなかった、または既存のモジュールでオーバーキル/オーバーヘッドの回避策を実行する必要があると感じました。したがって、オンラインリソースからPHPを学び、Drupalのカスタムモジュールを作成する方法を学びました。
バックエンド/コーディングゲームを改善することを強くお勧めします。特にD8のルールはD7に比べて必要最低限なので、.
これをビューで作成しようとしました。私が遭遇した問題は、サブディビジョンエンティティ参照フィールドを反復処理して、前のリンクと次のリンクを除外することが非常に難しいことでした。
プログラムでビューでそれを解決することは可能ですが、前と次のリンクのためだけにビューでこれを行うのはやりすぎ/不必要だと感じます。より良いアプローチは、Twigのprev_url
およびnext_url
変数を作成することです。前処理関数を使用して、これらの変数を作成し、適切なテンプレートファイル(この場合はnode.html.twig)に渡すことができます。
私はたくさんのコメントを書いているので、あなたはフォローして、うまくいけば何かを学ぶことができます。
mytheme.theme(この特定のフックは、カスタムモジュールを作成するのではなく、テーマでも使用できるため)。
/**
* Implements hook_preprocess_HOOK() for node.html.twig.
*/
function mytheme_preprocess_node(&$variables) {
$node = $variables['elements']['#node']; // obtain current page node object
if ($node->getType() == 'page') { // check it's a "page" content type
$page_nid = $node->id(); // get the current page node id
// get Chapter nids using Entity Field Query
$query = \Drupal::entityQuery('node')
->condition('type', 'chapter')
->condition('field_reference', $page_nid); // check if current page NID is set on any Chapter's reference field
$chapter_nids = $query->execute(); // returns array of Chapter nids
if (!empty($chapter_nids)) { // check we have a result
$chapter_nid = reset($chapter_nids); // Extracts the first array value, since we assume current page can only belong to one Chapter.
$chapter_node = Drupal\node\Entity\Node::load($chapter_nid); // load chapter node
$referenced_page_nodes = $chapter_node->field_reference; // get referenced nodes
foreach ($referenced_page_nodes as $key => $referenced_item) { // loop though referenced nodes
if ($referenced_item->entity) {
if ($node->id() == $referenced_item->entity->id()) { // check if current page nid equals referenced nid
$prev_key = $key - 1; // we'll use these keys to access prev/next array values
$next_key = $key + 1;
if (!empty($referenced_page_nodes[$prev_key])) { // check if previous key exists
$prev_url = $referenced_page_nodes[$prev_key]->entity->toUrl()->toString(); // get prev URL
$variables['prev_url'] = $prev_url; // creates prev_url variable in node.html.twig
}
if (!empty($referenced_page_nodes[$next_key])) { // check if next key exists
$next_url = $referenced_page_nodes[$next_key]->entity->toUrl()->toString(); // get next URL
$variables['next_url'] = $next_url; // creates next_url variable in node.html.twig
}
break; // since we found it, exit from loop as no point in continuing to loop through.
}
}
}
}
}
}
注:field_reference
(2か所)の名前を、章コンテンツタイプの実際の参照フィールドのマシン名に変更します。
Mytheme/templates/node.html.twigでは、{{ content }}
パーツの後に配置できます
{% if prev_url is not empty %}
<span><a href="{{ prev_url }}">{{ 'Previous page'|t }}</a></span>
{% endif %}
{% if next_url is not empty %}
<span><a href="{{ next_url }}">{{ 'Next page'|t }}</a></span>
{% endif %}