Jak osadzić widok w określonym węźle?

13

Próbuję osadzić widok w określonym węźle. Znalazłem tutoriale do robienia tego za pomocą szablonów Drupal 7 i PHP:

<?php print views_embed_view('view_name'); ?>

Ale szukam sposobu w Drupal 8 z szablonami gałązek. Próbowałem wywołać views_embed_view()funkcję w hook_node_view()i przypisać ją do węzła, aby wydrukować ją w szablonie gałązki. Ale wygląda na to, że ten hak nigdy nie zostanie wywołany.

Wszelkie wskazówki / rozwiązania, jak to zrobić w Drupal 8?

TiMESPLiNTER
źródło

Odpowiedzi:

19

Osadzone widoki gałązek

Moduł ten pozwala osadzać widoki z funkcją gałązki.

{{ views_embed_view('view_name', 'view_id') }}

Powyższy moduł został amortyzowany na korzyść

Twig Tweak

Moduł Twig Tweak zapewnia rozszerzenie Twig z kilkoma przydatnymi funkcjami i filtrami, które mogą poprawić doświadczenia programistów.

Dawny: <dd>{{ drupal_view('view_name', 'view_machine_name') }}</dd>

Możesz znaleźć view_machine_name tutaj

Bez sssweat
źródło
@ TiMESPLiNTER po prostu daje ci głowę.
Bez Sssweat
Od kiedy? Wersja?
Vishal Kumar Sahu
1
@VishalKumarSahu odkąd moja odpowiedź została opublikowana, 18 marca 16. Myślę, że moduł nadal działa, po prostu nie jest już utrzymywany ani rozwijany.
Bez Sssweat
Doskonale doskonały. Działa świetnie i mam z tym dobre doświadczenie. Dzięki
Vishal Kumar Sahu
Twig Tweak! Dobry moduł
Harish ST
5

Tak to działało w pod-temacie Drupal 8 beta 12 Classy.

W pliku your_theme.info.theme

function stjameskidsclub_preprocess_node(&$variables){
  $stuff  = views_embed_view('policy_documents', 'embed_1', 28);
  $variables["my_view"] = \Drupal::service('renderer')->renderRoot($stuff);
}  

Skopiowałem plik node.html.twig i otoczyłem tagi artykułu (lub obszar, który chcesz zastąpić) blokiem gałązki. Umieściłem to w folderze / template / content.

{% block replace_area %}
  <article{{ attributes.addClass(classes) }}>

    ...

  </article>  
{% endblock replace_area %}

Następnie utworzyłem węzeł - 2.html.twig (zamień 2 na żądany węzeł) w folderze / template / content z następującym kodem.

{% extends "node.html.twig" %}

{% block replace_page %}
  {{ my_view }}
{% endblock %}
Jerzy
źródło
4

Pierwszym problemem, z którym walczysz, jest to, że renderowane jednostki, takie jak węzły, są teraz domyślnie buforowane, więc hook_node_view () jest wywoływany tylko raz po wyczyszczeniu pamięci podręcznej / zapisaniu tego węzła.

Jest to jednak dość łatwe do wyłączenia, patrz settings.local.php.

Następnie umieszczenie wyjścia widoku w $ build jest dość łatwe i mniej więcej działa jak w 7.x. Zamiast korzystać z funkcji osadzania, rozważ użycie $ views = Views :: getView (), a następnie $ views-> buildRenderable ()

Dwie wskazówki:

  • Udostępnij klucz, którego używasz do kompilacji $, jako dodatkowe pole w hook_entity_extra_field_info () , a następnie sprawdź wyświetlacz, czy składnik jest włączony (zobacz, jak robi to user_user_view () . To pozwala skonfigurować wagę / położenie widoku w Interfejs użytkownika, a także ukryć go w niektórych trybach widoku.
  • Jeśli twój widok ma stronę, jest to nieco bardziej skomplikowane, ponieważ dane wyjściowe węzła są buforowane. Musisz wtedy uświadomić kluczowi pamięci podręcznej pager, na przykład patrz comment_entity_build_defaults_alter () (nie widok, ale jest to najbliższy przykład, jaki ma rdzeń).
Berdir
źródło
Przede wszystkim dziękuję za tę wspaniałą odpowiedź. Dobrze „włączyłem” settings.local.phpi wyczyściłem wszystkie pamięci podręczne. Ale mój hak themename_node_view()w themename.themedalszym ciągu nie jest wywoływana. Czy masz pojęcie, dlaczego tak może być?
TiMESPLiNTER,
1
W pliku settings.php znajduje się fragment kodu, którego należy odkomentować (na końcu). aby upewnić się, że plik settings.local.php jest załadowany, dodaj niepoprawny PHP, który powoduje błąd krytyczny. jeśli witryna nie zawiedzie, plik nie zostanie załadowany.
Berdir,
2

Ponieważ Berdir nawiązywał do widoku-> buildRenderable, właśnie tego szukasz, ale aby dać więcej kontekstu w module, musisz wykonać następujące czynności.

//use core libraries
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;

//use views class
use \Drupal\views\Views;

function hook_node_view(&$build, $node, $display, $view_mode){

 $thisView = Views::getView('view_name');

 $build['arbitrary_render_array_key_here'] = $thisView->buildRenderable('block_1',array($your_arguments));

}

Następnie w szablonie strony możesz uzyskać do niego dostęp za pomocą

{{ page.content.theme_name_content }}
ummdorian
źródło
1
Wszystko to było jednym linerem w Drupal 7. Ciekawe.
WM
0

W widokach możesz utworzyć blok z odpowiednimi danymi.

Po utworzeniu bloku możesz przypisać blok, aby pojawił się w żądanym obszarze zawartości (stopka / nagłówek / treść / itp.). Przypisz go, a następnie kliknij „konfiguruj”. Powinieneś być w stanie „Pokazać blok na określonych stronach”. Wybranie opcji „Tylko wymienione strony” i dodanie / node / your-node-number do specyfikacji strony powinno ograniczyć ten widok / blok do wyświetlania tylko z wybranym węzłem.

Twoje zdrowie!

Luke Rehmann
źródło
Dziękuję za odpowiedź :-). Ale potem muszę utworzyć obszar zawartości dla każdej sprawy. Więc jeśli chcę mieć pierwszy tekst, potem widok, a potem znowu tekst. Lub jeśli chcę mieć pierwszy tekst, a następnie widok lub najpierw widok, a następnie tekst. Następnie muszę utworzyć 3 różne obszary treści, które renderuję w określonych węzłach temapltes. Ale views_embed_view()podejście jest chyba znacznie łatwiejsze i czystsze.
TiMESPLiNTER
0

Wiem, że wspomniałeś, że chcesz używać szablonów gałązek, ale możesz użyć modułu Widoki Odniesienia , aby uniknąć konieczności przeszukiwania szablonów. Daje również tę zaletę, że można go dodać do dowolnego obiektu z możliwością zmiany pola, dzięki czemu redaktorzy treści mogą skonfigurować widok / wynik.

joekers
źródło