schemadotorg_starterkit_layout-1.0.x-dev/schemadotorg_starterkit_layout.module
schemadotorg_starterkit_layout.module
<?php
/**
* @file
* Enables and configures the Layout Paragraphs Demo.
*/
declare(strict_types=1);
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
use Drupal\paragraphs\ParagraphInterface;
use Drupal\schemadotorg\SchemaDotOrgMappingInterface;
/**
* Implements hook_page_attachments().
*/
function schemadotorg_starterkit_layout_page_attachments(array &$page): void {
// Attach CSS and JavaScript, that fixes minor UI issues with
// minor UX enhancements.
$page['#attached']['library'][] = 'schemadotorg_starterkit_layout/schemadotorg_starterkit_layout';
}
/**
* Implements hook_style_options_data_alter().
*/
function schemadotorg_starterkit_layout_style_options_alter(array &$data): void {
// Add description to 'CSS class' style option.
$data['css_class']['description'] = $data['css_class']['description']
?? "Select CSS class to be applied to the entity's wrapper.";
}
/**
* Implements hook_schemadotorg_jsonld_schema_type_entity_alter().
*
* Loads a Thing of Thing's sameAs target entity and return its JSON-LD.
*/
function schemadotorg_starterkit_layout_schemadotorg_jsonld_schema_type_entity_alter(array &$data, EntityInterface $entity, ?SchemaDotOrgMappingInterface $mapping, BubbleableMetadata $bubbleable_metadata): void {
// Check that the entity has a mapping.
if (!$mapping) {
return;
}
// Check that the entity is mapped to https://schema.org/Thing.
if ($mapping->getSchemaType() !== 'Thing') {
return;
}
// Check that the https://schema.org/Thing has a https://schema.org/sameAs
// property
$same_as_field_name = $mapping->getSchemaPropertyFieldName('sameAs');
if (!$entity instanceof ParagraphInterface
|| !$same_as_field_name
|| !$entity->hasField($same_as_field_name)) {
return;
}
// Get the https://schema.org/sameAs property's target entity reference and
// make sure it a content entity.
// entity reference.
$target_entity = $entity->{$same_as_field_name}->entity ?? NULL;
if (!$target_entity instanceof ContentEntityInterface) {
return;
}
/** @var \Drupal\schemadotorg\SchemaDotOrgMappingStorageInterface $mapping_storage */
$mapping_storage = \Drupal::entityTypeManager()->getStorage('schemadotorg_mapping');
/** @var \Drupal\schemadotorg_jsonld\SchemaDotOrgJsonLdBuilderInterface $jsonld_builder */
$jsonld_builder = \Drupal::service('schemadotorg_jsonld.builder');
// Load the target entity and replace the https://schema.org/Thing with
// the target entity's JSON-LD.
$target_mapping = $mapping_storage->loadByEntity($target_entity);
if ($target_mapping) {
$data = $jsonld_builder->buildEntity($target_entity, $target_mapping, $bubbleable_metadata);
}
}
/**
* Implements hook_entity_view_alter().
*/
function schemadotorg_starterkit_layout_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display): void {
if ($entity->getEntityTypeId() !== 'node'
&& $entity->getEntityTypeId() !== 'paragraph') {
return;
}
$types = [
'collection_page' => 'schema_has_part_paragraph',
'media_gallery' => 'schema_has_part_media',
'image_gallery' => 'schema_has_part_media',
'audio_gallery' => 'schema_has_part_media',
'ctas' => 'schema_ctas_item_list_element',
];
$type = $entity->bundle();
$field_name = $types[$type] ?? NULL;
if (!$field_name || !isset($build[$field_name])) {
return;
}
$build[$field_name]['#attributes']['class'][] = 'schemadotorg-starterkit-layout-slick';
$build['#attached']['library'][] = 'schemadotorg_starterkit_layout/schemadotorg_starterkit_layout.slick';
}
/**
* Implements hook_entity_view_alter().
*/
function schemadotorg_starterkit_layout_paragraph_view_alter(array &$build, ParagraphInterface $paragraph, EntityViewDisplayInterface $display): void {
$default_paragraph_types = \Drupal::config('schemadotorg_layout_paragraphs.settings')
->get('default_paragraph_types');
if (!in_array($paragraph->bundle(), $default_paragraph_types)) {
return;
}
switch ($paragraph->bundle()) {
case 'quotation_custom':
case 'quotation_person':
if (isset($build['schema_text'][0])) {
$build['schema_text'][0]['#prefix'] = '<blockquote>';
$build['schema_text'][0]['#suffix'] = '</blockquote>';
}
if (isset($build['schema_creator'][0])) {
$build['schema_creator'][0]['#prefix'] = '<address>-- ';
$build['schema_creator'][0]['#suffix'] = '</address>';
}
break;
case 'item_list_text':
case 'item_list_string':
case 'item_list_link':
$item_type = str_replace('item_list_', '', $paragraph->bundle());
$field_name = 'schema_item_' . $item_type;
$items = [];
foreach (Element::children($build[$field_name]) as $key) {
$items[] = $build[$field_name][$key];
}
$build[$field_name] = [
'#theme' => 'item_list',
'#items' => $items,
'#weight' => $build[$field_name]['#weight'],
];
break;
case 'item_list_paragraph':
// Wrapper basic content paragraphs in <details> widgets.
foreach (Element::children($build['schema_item_paragraph']) as $key) {
/** @var \Drupal\paragraphs\ParagraphInterface $paragraph */
$paragraph = $build['schema_item_paragraph'][$key]['#paragraph'];
$build['schema_item_paragraph'][$key] = [
'#type' => 'details',
'#title' => $paragraph->hasField('schema_name')
? $paragraph->get('schema_name')->value
: '',
'content' => $build['schema_item_paragraph'][$key],
];
}
break;
case 'header':
if (isset($build['schema_headline'][0])) {
$build['schema_headline'][0]['#prefix'] = '<h2>';
$build['schema_headline'][0]['#suffix'] = '</h2>';
}
break;
case 'field':
$build['field_content_field']['#access'] = FALSE;
$parent_entity = $paragraph->getParentEntity();
$field_name = $paragraph->get('field_content_field')->value;
if (!$parent_entity || !$parent_entity->hasField($field_name)) {
break;
}
$entity_type_id = $parent_entity->getEntityTypeId();
$bundle = $parent_entity->bundle();
/** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository */
$entity_display_repository = Drupal::service('entity_display.repository');
$display_options = $entity_display_repository
->getViewDisplay($entity_type_id, $bundle, 'token')
->getComponent($field_name)
?: $entity_display_repository
->getViewDisplay($entity_type_id, $bundle, 'default')
->getComponent($field_name)
?: [];
$build[$field_name] = \Drupal::entityTypeManager()
->getViewBuilder($entity_type_id)
->viewField($parent_entity->get($field_name), $display_options);
// Wrap the title field in <h1> tags.
if ($field_name === 'title') {
$build[$field_name][0]['#prefix'] = '<h1>';
$build[$field_name][0]['#suffix'] = '</h1>';
}
break;
}
}
/* ************************************************************************** */
// Allowed values function callbacks.
/* ************************************************************************** */
/**
* Allowed values for content field.
*/
function schemadotorg_starterkit_layout_content_field_allowed_values(FieldStorageDefinitionInterface $definition, ?FieldableEntityInterface $entity = NULL): array {
$allowed_values = [
'title' => t('Title'),
];
// Fields.
if ($entity instanceof ParagraphInterface) {
if (\Drupal::routeMatch()
->getRouteName() === 'mercury_editor.builder.insert') {
/** @var \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout */
$layout_paragraphs_layout = \Drupal::routeMatch()
->getParameter('layout_paragraphs_layout');
$main_entity = $layout_paragraphs_layout->getEntity();
}
else {
$main_entity = $entity->getParentEntity();
}
}
else {
$main_entity = NULL;
}
$properties = ['entity_type' => 'node'];
if ($main_entity) {
$properties['bundle'] = $main_entity->bundle();
}
/** @var \Drupal\Core\Field\FieldConfigInterface[] $field_configs */
$field_configs = \Drupal::entityTypeManager()
->getStorage('field_config')
->loadByProperties($properties);
foreach ($field_configs as $field_config) {
$allowed_values[$field_config->getName()] = $field_config->getLabel();
}
asort($allowed_values);
return $allowed_values;
}
