Skip to content
Snippets Groups Projects

Add generateMultiple(); remove some methods.

Files
2
@@ -158,26 +158,140 @@ class CustomElementGenerator {
@@ -158,26 +158,140 @@ class CustomElementGenerator {
}
}
/**
/**
* Generates a custom element tag for the given entity and view mode.
* Generates a custom element from entity, possibly after translation.
*
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* Entity to process.
* Entity to process.
* @param string $viewMode
* @param string $viewMode
* View mode used for rendering field values into slots.
* View mode used for rendering field values into slots.
* @param string|null $langcode
* @param string|null $langcode
* (optional) For which language the entity should be rendered, defaults to
* (optional) For which language the entities should be rendered. Defaults
* the current content language.
* to the current content language.
 
* @param \Drupal\Core\Session\AccountInterface|null $account
 
* (optional) The user for which to check access when rendering fields.
 
* Defaults to the current user.
*
*
* @return \Drupal\custom_elements\CustomElement
* @return \Drupal\custom_elements\CustomElement
* Extracted custom elements containing data attributes and slots.
* Custom element containing entity properties as attributes and slots.
*/
*/
public function generate(ContentEntityInterface $entity, string $viewMode, string $langcode = NULL) {
public function generate(ContentEntityInterface $entity, string $viewMode, string $langcode = NULL, AccountInterface $account = NULL) {
// Get desired entity translation.
$custom_elements = $this->generateMultiple([$entity], $viewMode, $langcode, $account);
$entity = $this->entityRepository->getTranslationFromContext($entity, $langcode);
return current($custom_elements);
$custom_element = $this->getEntityDefaults($entity, $viewMode);
}
$this->buildEntityContent($entity, $custom_element, $viewMode);
$this->moduleHandler->alter('custom_element_entity', $custom_element, $entity, $viewMode);
/**
return $custom_element;
* Generates custom elements from entities, possibly after translation.
 
*
 
* @param \Drupal\Core\Entity\ContentEntityInterface[] $entities
 
* Entities to process.
 
* @param string $viewMode
 
* View mode used for rendering field values into slots.
 
* @param string|null $langcode
 
* (optional) For which language the entities should be rendered. Defaults
 
* to the current content language.
 
* @param \Drupal\Core\Session\AccountInterface|null $account
 
* (optional) The user for which to check access when rendering fields.
 
* Defaults to the current user.
 
*
 
* @return \Drupal\custom_elements\CustomElement[]
 
* Custom elements containing entities' properties as attributes and slots,
 
* keyed by the same value as the corresponding entities.
 
*/
 
public function generateMultiple(array $entities, string $viewMode, string $langcode = NULL, AccountInterface $account = NULL): array {
 
foreach ($entities as &$entity) {
 
$entity = $this->entityRepository->getTranslationFromContext($entity, $langcode);
 
}
 
 
return $this->buildEntityContent($entities, $viewMode, $account);
 
}
 
 
/**
 
* Generates custom elements from entities.
 
*
 
* @param \Drupal\Core\Entity\ContentEntityInterface[] $entities
 
* Entities to process.
 
* @param string $viewMode
 
* View mode used for rendering field values into slots.
 
* @param \Drupal\Core\Session\AccountInterface|null $account
 
* (optional) The user for which to check access, or NULL to check access
 
* for the current user.
 
*
 
* @return \Drupal\custom_elements\CustomElement[]
 
* Custom elements containing entities' properties as attributes and slots,
 
* keyed by the same value as the corresponding entities.
 
*/
 
public function buildEntityContent(array $entities, string $viewMode, AccountInterface $account = NULL): array {
 
// Process custom elements by bundle, because most CE displays require
 
// components to be prepared by bundle. Retain original order of entities
 
// in the return value.
 
$custom_elements = [];
 
foreach ($entities as $key => $entity) {
 
$entities_by_type_bundle_key[$entity->getEntityTypeId()][$entity->bundle()][$key] = $entity;
 
 
$custom_elements[$key] = $this->getEntityDefaults($entity, $viewMode);
 
}
 
 
foreach ($entities_by_type_bundle_key as $entity_type_id => $entities_by_bundle_key) {
 
foreach ($entities_by_bundle_key as $bundle => $entities) {
 
$ce_display = $this->getEntityCeDisplay($entity_type_id, $bundle, $viewMode);
 
$ce_display->setOriginalMode($viewMode);
 
 
if ($entity_view_display = $this->checkLayoutBuilderDisplay($ce_display, current($entities))) {
 
// Skip processing of display components and let layout builder
 
// render everything.
 
foreach ($entities as $key => $entity) {
 
$custom_elements[$key]->addCacheableDependency($ce_display);
 
$this->buildLayoutBuilderContent($entity, $custom_elements[$key], $entity_view_display);
 
}
 
}
 
else {
 
$ce_name = $ce_display->getCustomElementName();
 
if ($ce_display->getForceAutoProcessing()) {
 
// Only do auto-processing on entity-level; skip processing of
 
// display components. This was default behaviour in 2.x.
 
foreach ($entities as $key => $entity) {
 
$custom_elements[$key]->addCacheableDependency($ce_display);
 
$custom_elements[$key]->setTag($ce_name);
 
$this->process($entity, $custom_elements[$key], $viewMode);
 
}
 
}
 
else {
 
// Build entity components, one by one, for this bundle's entities.
 
foreach ($entities as $key => $entity) {
 
$custom_elements[$key]->addCacheableDependency($ce_display);
 
$custom_elements[$key]->setTag($ce_name);
 
}
 
 
foreach ($ce_display->getComponents() as $component_name => $display_component) {
 
if ($formatter = $ce_display->getRenderer($component_name)) {
 
$grouped_items = [];
 
$field_name = $display_component['field_name'];
 
foreach ($entities as $key => $entity) {
 
if ($this->fieldIsAccessible($entity, $field_name, $custom_elements[$key], $account)) {
 
$items = $entity->get($field_name);
 
$items->filterEmptyItems();
 
$grouped_items[$key] = $items;
 
}
 
}
 
if ($grouped_items) {
 
$formatter->prepareBuild($grouped_items);
 
 
foreach ($grouped_items as $key => $items) {
 
$formatter->build($items, $custom_elements[$key]);
 
}
 
}
 
}
 
}
 
}
 
}
 
 
foreach ($entities as $key => $entity) {
 
$this->moduleHandler->alter('custom_element_entity', $custom_elements[$key], $entity, $viewMode);
 
}
 
}
 
}
 
 
return $custom_elements;
}
}
/**
/**
@@ -205,18 +319,21 @@ class CustomElementGenerator {
@@ -205,18 +319,21 @@ class CustomElementGenerator {
}
}
/**
/**
* Builds an entity's content as custom element.
* Checks if both CE and Core display enable Layout Builder;.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity.
* @param \Drupal\custom_elements\CustomElement $element
* The custom element to add to.
* @param string $viewMode
* The current view mode.
*/
*/
public function buildEntityContent(ContentEntityInterface $entity, CustomElement $element, $viewMode) {
private function checkLayoutBuilderDisplay(EntityCeDisplayInterface $ceDisplay, ContentEntityInterface $entity): ?CustomElementsLayoutBuilderEntityViewDisplay {
$entity_ce_display = $this->getEntityCeDisplay($entity->getEntityTypeId(), $entity->bundle(), $viewMode);
if ($ceDisplay->getUseLayoutBuilder()) {
$this->buildCeDisplay($entity, $element, $entity_ce_display, $viewMode);
// 'Use layout builder' must also be enabled on the corresponding core
 
// display (for view mode or default).
 
$entity_view_displays = EntityViewDisplay::collectRenderDisplays([$entity], $ceDisplay->getOriginalMode());
 
$entity_view_display = $entity_view_displays[$entity->bundle()];
 
if ($entity_view_display->getThirdPartySetting('layout_builder', 'enabled')) {
 
assert($entity_view_display instanceof CustomElementsLayoutBuilderEntityViewDisplay);
 
return $entity_view_display;
 
}
 
}
 
 
return NULL;
}
}
/**
/**
@@ -256,63 +373,6 @@ class CustomElementGenerator {
@@ -256,63 +373,6 @@ class CustomElementGenerator {
$custom_element->addCacheableDependency($display);
$custom_element->addCacheableDependency($display);
}
}
/**
* Builds an entity's content as custom element using a CE display.
*
* Not accessible or empty fields are not built.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity.
* @param \Drupal\custom_elements\CustomElement $custom_element
* The custom element.
* @param \Drupal\custom_elements\Entity\EntityCeDisplayInterface $display
* Entity custom element display entity.
* @param string $viewMode
* The view mode being built.
* @param \Drupal\Core\Session\AccountInterface|null $account
* (optional) The user for which to check access, or NULL to check access
* for the current user. Defaults to NULL.
*/
public function buildCeDisplay(ContentEntityInterface $entity, CustomElement $custom_element, EntityCeDisplayInterface $display, string $viewMode, AccountInterface $account = NULL) {
$custom_element->addCacheableDependency($display);
// If 'use layout builder' is enabled, and if it's enabled on the
// corresponding core display (for view mode or default), skip processing
// of the fields in the CE display, and let layout builder render it all.
if ($display->getUseLayoutBuilder()) {
$entity_view_displays = EntityViewDisplay::collectRenderDisplays([$entity], $viewMode);
$entity_view_display = reset($entity_view_displays);
if ($entity_view_display->getThirdPartySetting('layout_builder', 'enabled')) {
assert($entity_view_display instanceof CustomElementsLayoutBuilderEntityViewDisplay);
$this->buildLayoutBuilderContent($entity, $custom_element, $entity_view_display);
return;
}
}
$display->setOriginalMode($viewMode);
$custom_element->setTag($display->getCustomElementName());
// When configured, only do auto-processing on entity-level and skip the
// config of individual components. This is the same behaviour as it was
// default in 2.x.
if ($display->getForceAutoProcessing()) {
$this->process($entity, $custom_element, $viewMode);
return;
}
// Else render using the individual display components.
foreach ($display->getComponents() as $component_name => $display_component) {
if ($formatter = $display->getRenderer($component_name)) {
$field_name = $display_component['field_name'];
if ($this->fieldIsAccessible($entity, $field_name, $custom_element, $account)) {
// @todo Move prepareBuild to prepareView phase.
$formatter->prepareBuild([$entity->get($field_name)]);
$formatter->build($entity->get($field_name), $custom_element);
}
}
}
}
/**
/**
* Gets a Custom Elements display for the entity type, bundle and view mode.
* Gets a Custom Elements display for the entity type, bundle and view mode.
*
*
Loading