Istnieją dwa rodzaje bloków, a metoda renderowania tych dwóch jest nieco inna:
Bloki treści
Bloki treści to bloki tworzone w interfejsie. Przypominają one konfigurowalne struktury danych węzłów z polami itp. Jeśli chcesz renderować jedną z nich, możesz zrobić to, co normalnie zrobiłbyś z jednostkami, załadować je i renderować za pomocą kreatora widoków:
$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
getViewBuilder('block_content')->view($block);
return $render;
Bloki wtyczek
Bloki mogą być również wtyczkami zdefiniowanymi w różnych modułach. Przykładem może być blok nawigacyjny. Jeśli chcesz je wyrenderować, musisz użyć menedżera wtyczek blokowych.
$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
// You might need to add some cache tags/contexts.
return [];
}
$render = $plugin_block->build();
// In some cases, you need to add the cache tags/context depending on
// the block implemention. As it's possible to add the cache tags and
// contexts in the render method and in ::getCacheTags and
// ::getCacheContexts methods.
return $render;
Konfiguruj encje
Wspólne dla tych dwóch typów są bloki. Po wstawieniu ich do regionu utworzysz element konfiguracji, który ma wszystkie ustawienia bloku. W niektórych przypadkach bardziej użyteczna będzie obsługa encji konfiguracyjnych. Ponieważ ten sam blok może być umieszczony w wielu regionach z inną konfiguracją i może być trudniejszy przy użyciu jednostek konfiguracji bloku. Fajną rzeczą jest to, że możesz chcieć renderować blok z określoną konfiguracją, złą rzeczą jest to, że identyfikatory konfiguracji mogą się zmieniać przez bałagan w interfejsie, więc kod może nie działać po umożliwieniu użytkownikom korzystania z interfejsu bloku.
$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
->getViewBuilder('block')
->view($block);
return $render;
Najlepszym sposobem do wyświetlania tylko bloków w szablonach z wstępnym przetwarzaniem
Iw swoim
page.html.twig
lubnode.html.twig
czyxxx.html.twig
użyć zmiennej My_region takiego:I w tablicy do renderowania (moduł niestandardowy), na przykład, w kontrolerze niestandardowym w content ():
Za pomocą
nie jest użyteczny, ponieważ Drupal już zakłada renderowanie w D8 i jest to przestarzałe . Zamiast tego powinieneś użyćdrupal_render
\Drupal::service('renderer')->renderRoot()
.Jest trochę ciężki, lepiej jest użyć systemu maksymalnego obszaru i nie dodaje bloku obciążenia z procesu wstępnego. W przypadku użycia kontrolera w modułach wydaje się to uzasadnione.
źródło
element-content
właściwości w tablicy renderowania. Czy wiesz, gdzie jest to udokumentowane?\Drupal\block\Entity\Block::load
nie zwraca bloku cały czas. Zwraca coś tylko wtedy, gdy ładowany blok jest umieszczony w widoku w układzie bloku . Jeśli nie jest umieszczony, zwraca null.\Drupal::entityTypeManager()->getViewBuilder('block')->view($block);
Oprócz najważniejszej odpowiedzi ... Jeśli chcesz renderować blok z widoku, być może będziesz musiał zrobić coś nieco inaczej.
(nazwa wyświetlana np. -> blok_1)
Ponieważ zamierzamy przekazać go gałązce, nie musimy renderować (używając usługi renderowania).
Możesz więc po prostu przekazać ją jako zmienną do gałązki (w tym przykładzie jest to zwrot kontrolera):
w swoim module potrzebujesz hook_theme () dla swojej zmiennej:
I wreszcie w szablonie twig:
źródło
Musiałem pobrać kod HTML niestandardowego bloku i użyć go:
źródło
__toString()
.źródło
drupal_render
z usługi renderowania.drupal_render
jest zaniedbany, ale zachowanie renderowania tablicy z renderowaną zawartością jest dość złe, powinieneś$block_content
zamiast tego powrócić , tablica renderowania może zostać zmieniona przed rzeczywistym renderowaniem i powinieneś pozwolić Drupalowi wykonać rendering w miarę możliwości lub zrobić to sam.Zasadniczo istnieją dwa typy renderów.
Gdy w układzie istnieje instancja bloku. blok może być renderowany w gałązce przy użyciu wstępnego przetwarzania jako
$ block = Block :: load ('BLOCK_ID'); $ variable ['social_links'] = \ Drupal :: entityTypeManager () -> getViewBuilder ('block') -> view ($ block);
Nie ma instancji ani konfiguracji bloku. Następnie w preprocesorze musimy utworzyć instancję, zbudować blok, a następnie go wyrenderować
$ block_manager = \ Drupal :: service ('plugin.manager.block'); $ config = []; $ plugin_block = $ block_manager-> createInstance ('farmjournal_social_sharing', $ config); $ render = $ plugin_block-> build (); zmienne $ ['farmjournal_social_sharing'] = render ($ render);
źródło
Wygląda na to, że działa to w przypadku bloków wtyczek.
źródło
Otrzymujesz wyjście bloku:
Następnie możesz zwrócić dane wyjściowe na różne sposoby:
lub:
źródło
\Drupal::service ('renderer')->render ($block_content)
można to zrobić,drupal_render ($block_content)
jednak ten ostatni jest przestarzały w Drupal 8.drupal_render
z usługi renderowania.drupal_render
jest zaniedbany, ale zachowanie renderowania tablicy z renderowaną zawartością jest dość złe, powinieneś$block_content
zamiast tego powrócić , tablica renderowania może zostać zmieniona przed rzeczywistym renderowaniem i powinieneś pozwolić Drupalowi wykonać rendering w miarę możliwości lub zrobić to sam. To, coNa podstawie moich badań możesz oprzeć kod z Jak renderować blok programowo w Drupal 8 . Możesz także zmienić
w coś tak prostego jak:
aby dołączyć go na przykład do zmiennej zwrotnej strony.
źródło
drupal_render
z usługi renderowania.drupal_render
jest zaniedbany, ale zachowanie renderowania tablicy z renderowaną zawartością jest dość złe, powinieneś$block_content
zamiast tego powrócić , tablica renderowania może zostać zmieniona przed rzeczywistym renderowaniem i powinieneś pozwolić Drupalowi wykonać rendering w miarę możliwości lub zrobić to sam.