Skip to content
Snippets Groups Projects
Commit 6bb91b3f authored by Eric Bremner's avatar Eric Bremner
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
CONTENTS OF THIS FILE
---------------------
* Introduction
* Requirements
* Installation
* Configuration
INTRODUCTION
------------
Layout Builder Ids allows site builders to enter and ID to be used with either a section or block in layout builder. A "style" is just a representation of one or more CSS classes that will be applied. This will then allow for things like anchor links and javascript to target very specific blocks and sections.
* For a full description of the module, visit the project page:
https://www.drupal.org/project/layout_builder_ids/
* To submit bug reports and feature suggestions, or track changes:
https://www.drupal.org/project/issues/layout_builder_ids/
REQUIREMENTS
------------
* This module requires, at minimum, Drupal 8.8.0.
* This module requires that layout builder from core be enabled.
* This module requires hook_event_dispatcher (1.x branch) to be enabled.
INSTALLATION
------------
* Install as you would normally install a contributed Drupal module. Visit
https://www.drupal.org/docs/8/extending-drupal-8/installing-drupal-8-modules
for further information.
CONFIGURATION
-------------
When placing a block or section into a layout, this module will add an option for an ID, where only numbers, letters and hyphens are allowed.
name: Layout Builder Ids
description: Add an id to sections and blocks in Layout Builder.
core: 8.x
type: module
dependencies:
- drupal:layout_builder
- hook_event_dispatcher
<?php
/**
* Implements template_preprocess_layout
*/
function layout_builder_ids_preprocess_layout(&$variables) {
// If there is a layout builder id, set it in the attributes.
if (isset($variables['content']['#settings']['layout_builder_id'])) {
// Set the id attribute.
$variables['attributes']['id'] = $variables['content']['#settings']['layout_builder_id'];
}
}
services:
layout_builder_ids.render_block_component_subscriber:
class: Drupal\layout_builder_ids\EventSubscriber\LayoutBuilderIdsRenderSubscriber
tags:
- { name: event_subscriber }
layout_builder_ids.configure_section_form:
class: '\Drupal\layout_builder_ids\EventSubscriber\LayoutBuilderIdsConfigureSection'
tags:
- { name: 'event_subscriber' }
layout_builder_ids.configure_block_form:
class: '\Drupal\layout_builder_ids\EventSubscriber\LayoutBuilderIdsConfigureBlock'
tags:
- { name: 'event_subscriber' }
layout_builder_ids.route_subscriber:
class: Drupal\layout_builder_ids\EventSubscriber\LayoutBuilderIdsRouteSubscriber
tags:
- { name: 'event_subscriber' }
<?php
namespace Drupal\layout_builder_ids\EventSubscriber;
use Drupal\Core\Form\FormStateInterface;
use Drupal\hook_event_dispatcher\Event\Form\FormAlterEvent;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Component\Utility\Html;
/**
* Class LayoutBuilderIdsConfigureBlock.
*/
class LayoutBuilderIdsConfigureBlock implements EventSubscriberInterface {
/**
* Alter form.
*
* @param \Drupal\hook_event_dispatcher\Event\Form\FormAlterEvent $event
* The event.
*/
public function alterForm(FormAlterEvent $event) {
// Get the form from the event.
$form = &$event->getForm();
// If we are on a configure section form, alter it.
if ($form['#form_id'] == 'layout_builder_add_block' || $form['#form_id'] == 'layout_builder_update_block') {
// Get the form state.
$form_state = &$event->getFormState();
// Load in the form object.
$formObject = $form_state->getFormObject();
// Load in the component/block.
$component = $formObject->getCurrentComponent();
// Pull out the layout_builder_id from config.
$layout_builder_id = $component->get('layout_builder_id');
// Add the section id to the configure form.
$form['settings']['layout_builder_id'] = [
'#type' => 'textfield',
'#title' => 'Block ID',
'#weight' => 0,
'#default_value' => $layout_builder_id ? $layout_builder_id : NULL,
'#description' => t('Enter an ID for the section, must contain only letters and hyphens.'),
];
// Add our custom submit function.
array_unshift($form['#submit'], [$this, 'LayoutBuilderIdsSubmitForm']);
}
}
/**
* {@inheritdoc}
*/
public function LayoutBuilderIdsSubmitForm(array &$form, FormStateInterface $form_state) {
// Load in the layout_builder_id.
$layout_builder_id = $form_state->getValue(['settings', 'layout_builder_id']);
// If there is in id, save it in config.
if ($layout_builder_id !== NULL) {
// Load in the form object.
$formObject = $form_state->getFormObject();
// Load in the component/block.
$component = $formObject->getCurrentComponent();
// Set the layout_builder_id.
$component->set('layout_builder_id', Html::getId($layout_builder_id));
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
HookEventDispatcherInterface::FORM_ALTER => 'alterForm',
];
}
}
<?php
namespace Drupal\layout_builder_ids\EventSubscriber;
use Drupal\Core\Form\FormStateInterface;
use Drupal\hook_event_dispatcher\Event\Form\FormAlterEvent;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\RouteCollection;
use Drupal\Component\Utility\Html;
/**
* Class LayoutBuilderIdsConfigureSection.
*/
class LayoutBuilderIdsConfigureSection implements EventSubscriberInterface {
/**
* Alter form.
*
* @param \Drupal\hook_event_dispatcher\Event\Form\FormAlterEvent $event
* The event.
*/
public function alterForm(FormAlterEvent $event) {
// Get the form from the event.
$form = &$event->getForm();
// If we are on a configure section form, alter it.
if ($form['#form_id'] == 'layout_builder_configure_section') {
// Get the form state.
$form_state = $event->getFormState();
// Get the form object.
$formObject = $form_state->getFormObject();
// Get the config for the section.
$config = $formObject->getLayout()->getConfiguration();
// Add the section id to the configure form.
$form['layout_settings']['layout_builder_id'] = [
'#type' => 'textfield',
'#title' => 'Section ID',
'#weight' => 0,
'#default_value' => isset($config['layout_builder_id']) ? $config['layout_builder_id'] : '',
'#description' => t('Enter an ID for the section, must contain only letters and hyphens.'),
];
// Add our custom submit handler.
array_unshift($form['#submit'], [$this, 'LayoutBuilderIdsSubmitForm']);
}
}
/**
* {@inheritdoc}
*/
public function LayoutBuilderIdsSubmitForm(array &$form, FormStateInterface $form_state) {
// Get the layout builder id from the form.
$layout_builder_id = $form_state->getValue(['layout_settings', 'layout_builder_id'], NULL);
// If there is a layout builder id, store it.
if ($layout_builder_id !== NULL) {
// Get the layout.
$layout = $this->getLayout($form_state);
// Load in the config for this section.
$configuration = $layout->getConfiguration();
// Set the layout builder id in config variable.
$configuration['layout_builder_id'] = Html::getId($layout_builder_id);
// Set the config for this section.
$layout->setConfiguration($configuration);
}
}
/**
* Get the layout object
* @param FormStateInterface $form_state
* @return mixed
*/
private function getLayout(FormStateInterface $form_state) {
// Get the form object.
$formObject = $form_state->getFormObject();
return $formObject->getLayout();
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
HookEventDispatcherInterface::FORM_ALTER => 'alterForm',
];
}
}
<?php
namespace Drupal\layout_builder_ids\EventSubscriber;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\layout_builder\LayoutBuilderEvents;
/**
* Class BlockComponentRenderArraySubscriber.
*/
class LayoutBuilderIdsRenderSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
// Layout Builder also subscribes to this event to build the initial render
// array. We use a higher weight so that we execute after it.
$events[LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY] = ['onBuildRender', 50];
return $events;
}
/**
* Add each component's block styles to the render array.
*
* @param \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent $event
* The section component render event.
*/
public function onBuildRender(SectionComponentBuildRenderArrayEvent $event) {
// The render array.
$build = $event->getBuild();
// This shouldn't happen - Layout Builder should have already created the
// initial build data.
if (empty($build)) {
return;
}
// Get the layout builder id.
$layout_builder_id = $event->getComponent()->get('layout_builder_id');
// If there is a layout builder id, then set it in the attributes.
if ($layout_builder_id !== NULL) {
// Set the id attribute.
$build['#attributes']['id'] = $layout_builder_id;
// Now set the build for the event.
$event->setBuild($build);
}
}
}
<?php
namespace Drupal\layout_builder_ids\EventSubscriber;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Class RouteSubscriber.
*/
class LayoutBuilderIdsRouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
$configureSectionRoute = $collection->get('layout_builder.configure_section');
if ($configureSectionRoute) {
$configureSectionRoute->setDefault('_form', '\Drupal\layout_builder_ids\Form\ConfigureSectionForm');
}
}
}
<?php
namespace Drupal\layout_builder_ids\Form;
use Drupal\layout_builder\Form\ConfigureSectionForm as OriginalConfigureSectionForm;
/**
* Class ConfigureSectionForm.
*
* Extend the original form to expose the layout object.
* See https://www.drupal.org/i/3044117
*/
class ConfigureSectionForm extends OriginalConfigureSectionForm {
/**
* Get the layout plugin being modified.
*
* @return \Drupal\Core\Layout\LayoutInterface|\Drupal\Core\Plugin\PluginFormInterface
* The layout plugin object.
*/
public function getLayout() {
return $this->layout;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment