/block-style-plugins

Development for Drupal module https://www.drupal.org/project/block_style_plugins

Primary LanguagePHP

About

Block Style Plugins is an API module that allows a module or theme to add style options to block configuration by creating a custom plugin. It is advisable to do this primarily in themes since the majority of styles should be specific to a theme.

The new core Layout Builder is supported and will offer a new contextual link for "Style settings". This way your styles will work for blocks regardless as to whether you place them via the new Layout Builder or the traditional Blocks UI.

Tutorial Video: https://youtu.be/Y0t8owlV2_4

Dependencies

  • block
  • block_content

Basic Setup

Creating plugins and form fields in a Yaml file

The easiest way to get started is to use a single yaml file to declare each plugin and the fields to display. This can go into either a module or better yet, a theme. Name it mymodule.blockstyle.yml or mytheme.blockstyle.yml replacing the first part with the name or your module or theme.

sample_block_style:
  label: 'Sample Block Style'
  form:
    field_name:
      '#type': 'textfield'
      '#title': 'Add a custom css class'
      '#default_value': 'my-class'
  template: block__my_custom_template

Notice: Form fields need to be on the same level and cannot currently be nested.

By adding a template you may specify a template theme suggestion of your choosing for the block.

By default, each field value will be set as a CSS class on the block. The one exception will be checkboxes. The checkbox data is passed along (with other style data) to the theme layer and can be accessed in a preprocess function at $variables['configuration']['block_styles'] or in a Twig template at {{ configuration.block_styles }}

Example Plugins

The tests directory has a module which demonstrates how to build your own plugins tests/modules/block_style_plugins_test.

Example Block Style plugins can be found in the tests directory tests/modules/block_style_plugins_test/src/Plugin/BlockStyle/SimpleClass.php tests/modules/block_style_plugins_test/src/Plugin/BlockStyle/DropdownWithInclude.php tests/modules/block_style_plugins_test/src/Plugin/BlockStyle/CheckboxWithExclude.php

Also, check out the example Yaml file for easily declaring plugins at tests/modules/block_style_plugins_test/block_style_plugins_test.blockstyle.yml

Advanced Usage

Setting up a block style in a module with a PHP class

Even more power is available if a custom plugin is created in PHP.

Create a new plugin class extending the BlockStyleBase class. Be sure to add in proper plugin Annotations such as:

/**
 * Provides a 'SimpleClass' block style for adding a class in a text field.
 *
 * @BlockStyle(
 *  id = "simple_class",
 *  label = @Translation("Simple Class"),
 * )
 */

Override the BlockStyleBase::buildConfigurationForm method to extend the $form array with your own custom style options using the Form API.

$styles = $this->getConfiguration();

$form['sample_class'] = array(
  '#type' => 'textfield',
  '#title' => $this->t('Add a custom class to this block'),
  '#description' => $this->t('Do not add the "period" to the start of the class'),
  '#default_value' => $styles['sample_class'],
);

Adding a block style to a theme with a custom PHP class

Instead of defining form fields in Yaml, a theme can use a PHP class just like a module. Just add a class and path to the class name in the yaml file.

Standard class Annotations are not discoverable in a theme. Thus the need to use a themename.blockstyle.yml file

sample_block_style:
  label: 'Sample Block Style'
  class: '\Drupal\themename\Plugin\BlockStyle\SampleBlockStyle'

Then add a BlockStyle plugin class into themename\Plugin\BlockStyle\SampleBlockStyle.php which will extend the BlockStyleBase class

Visibility rules for restricting style options to specific blocks

"include" and "exclude" attributes are available to only include certain blocks or to exclude certain blocks from accessing your custom block styles. Choose one or the other. Don't use both "include" and "exclude" at the same time.

Pass in a "block plugin id" or a custom block content "block content type" bundle name into the "include" or "exclude" attributes.

Include only specific block content types

sample_block_style:
  label: 'Sample Block Style'
  include:
    - 'block_content_type'

Exclude specific blocks

sample_block_style:
  label: 'Sample Block Style'
  exclude:
    - 'block_plugin_id'

Match all derivatives of a base plugin id

You can also match any derivatives of a base plugin id by adding :* such as system_menu_block:* which will match all derivatives of the menu blocks such as system_menu_block:main.

How to discover a 'block plugin id'

It might be frustrating at first trying to figure out how to get a block's plugin id. In a theme's themename.theme file just preprocess a block. One of the variables available is the plugin_id.

/**
 * Implements hook_preprocess_block().
 */
function themename_preprocess_block(array &$variables) {
  // Get the plugin id.
  $plugin_id = $variables['plugin_id'];
  print '<pre>' . $plugin_id . '</pre>';
}

How to discover the name of a "block content type"

All blocks created from block content types show the same base plugin id block_content. Thus, a the block's content type is it's machine name. Go to /admin/structure/block/block-content/types and Edit one of the block types shown. To the right of the label will be a "Machine name". For example the "Basic block" type created by the Standard profile has a machine name basic.