How to create a custom element
If you are a developer, you can create your own elements. Custom elements can have a form and output defined by the developer. Once created, they will be available as elements under the "Custom elements" section within the Sidebar browser.
Use the "Site Studio example custom element" module to understand how custom elements are used and then follow the guide below, which walks through the process of creating your own Custom element.
Use the "Site Studio example custom element"
The "Site Studio example custom element" module is an example of how a developer can create a custom element.
To enable it:
- Navigate to Extend and search for "Site Studio example element"
- Enable the Site Studio example custom element module
- Navigate to a Site Studio component or template
- Open the sidebar browser, and scroll down to the Custom elements section
- Drag "Example element" or "Example container element" on to your layout canvas
- Double click to edit the Example element
- Fill out the form and click Save
- Save the template/component and view the output.
Creating your own element
The steps below explain how you can take the example module and create your own element that integrates seamlessly with Site Studio.
Each element inside Site Studio has two parts:
- the form - this is the element form which contains the defined fields
- the template - the rendered output of the custom element.
Data the user or site builder adds to the form is fed to a twig template to render the output. For internal Site Studio elements, these templates exist on the Site Studio API. They are combined to make a single aggregated template that is used to drive the output of entire nodes, pages, views, etc.
Your custom element is a bit different as it will be rendered at runtime instead of aggregated on the API.
You will need to create a form definition, and instead of a Site Studio template, you will create a render function that will render the output of the form at runtime. That render function can use a .twig template file to render the output, but this is not a requirement. As an example, Site Studio example element module uses a local .twig template file for the output.
1. Creating your form
Site Studio uses a custom form definition format that is not related to the Drupal form system. You have several field types you can use, and these will be displayed to the site builder in the "Settings" tab of the element.
Create a new module and add a class under the CustomElement plugin namespace, e.g. [module_path]/src/Plugin/CustomElement/Generic.php
The plugin class must extend Drupal\cohesion_elements\CustomElementPluginBase and be annotated with CustomElement, for example:
namespace Drupal\module_name\Plugin\CustomElement;
use Drupal\cohesion_elements\CustomElementPluginBase;
/**
* Generic HTML element plugin for Site Studio.
*
* @CustomElement(
* id = "generic_html_tag",
* label = @Translation("Generic HTML tag with text content")
* )
*/
class Generic extends CustomElementPluginBase {
The label key is the name of your custom element, and this is what will appear within the sidebar browser, both id and label are required.
The class must implement both getFields() and render() methods, render() is discussed below in step #2.
getFields() function returns an array defining the form structure of the custom element. Each entry should be a keyed array in the following format:
public function getFields() {
return [
'tag' => [
'htmlClass' => 'col-xs-12',
'type' => 'select',
'title' => 'HTML tag',
'nullOption' => false,
'options' => [
'p' => 'p',
'span' => 'span',
'div' => 'div',
]
],
'text' => [
'htmlClass' => 'col-xs-12',
'title' => 'Text content',
'type' => 'textfield',
'placeholder' => 'e.g. Site Studio is great',
],
];
}
The available field types that can be used in a custom element are:
- textfield
- select
- checkbox
- image
- textarea
- wysiwyg
Below is an example of how to use each type of field within the getFields() function:
public function getFields() {
return [
// This is an example text field.
'mytextfield' => [
'htmlClass' => 'col-xs-12',
'title' => 'Text content',
'type' => 'textfield',
'placeholder' => 'e.g. Site Studio is great',
],
// This is an example select field.
'myselectfield' => [
'htmlClass' => 'col-xs-12',
'type' => 'select',
'title' => 'HTML tag',
'nullOption' => false,
'options' => [
'p' => 'p',
'span' => 'span',
'div' => 'div',
]
],
// This is an example checkbox field.
'mycheckboxfield' => [
'htmlClass' => 'col-xs-6',
'type' => 'checkbox',
'title' => 'Title of my checkbox field',
// These fields are specific to this form field type.
'notitle' => false,
'defaultValue' => true,
],
// This is an example image field.
'myimagefield' => [
'htmlClass' => 'col-xs-12',
'title' => 'Title of my image field',
'type' => 'image',
// This field is specific to this form field type.
'buttonText' => 'Some button',
],
// This is an example text area field.
'mytextareafield' => [
'htmlClass' => 'col-xs-12',
'type' => 'textarea',
'title' => 'Title of my text area field.',
],
// This is an example WYSIWYG field.
'mywysiwygfield' => [
'htmlClass' => 'col-xs-12',
'type' => 'wysiwyg',
'title' => 'Title of my WYSIWYG field.',
'defaultValue' => [
'text' => '<p>This is some default content.</p>',
'textFormat' => 'cohesion'
]
],
];
}
Fields must be defined within the getFields function or your custom element will not be visible in the sidebar browser.
Depending on the type of field you select, you will be required to add additional fields.
See the examples in src/Plugin/CustomElement/Example.php for further details.
2. Creating your render method
Your render method is passed three parameters and should return a render array:
public function render($settings, $markup, $class) {
return [
'#theme' => 'generic_element',
'#settings' => $settings,
'#markup' => $markup,
'#class' => $class,
];
}
$settings is an array containing the form data input by the user/site builder along with the element name.
Note, the element name is provided as a convenience in case you want to use the same render function for multiple elements.
(
"element" => "module_example_1",
"mycheckboxfield" => true,
"myothercheckboxfield" => true,
"mytextfield" => "Test 'data'.",
"myselectfield" => "option2",
"mytextareafield" => "Test data 2.",
"mywysiwygfield"= > "<p>Test data 3.</p>n"
)
$markup is an array containing data added to the "Markup" tab within the custom element
Here is an example of that markup data:
(
[attributes] => Array
(
[0] => Array
(
[attribute] => "data-something"
[value] => "somevalue"
)
)
[prefix] => "someprefix"
[suffix] => "somesuffix"
)
$class is a string containing the class that targets your element. Anything added to the styles tab will be built into the Site Studio stylesheets and available under this class name.
It has the format: 'coh-ce-xxxxxxx' with NO preceding dot/period character.
Your function should return a renderable array. An example of this (using a .twig template) can be found on the Drupal.org theming documentation.
Creating your own custom container element
To create your own custom container element, much of the code is exactly the same as creating a custom element.
1. Custom Element plugin
To create a container custom element the CustomElement plugin annotation should have 'container = true' like so:
namespace Drupal\example_element\Plugin\CustomElement;
use Drupal\cohesion_elements\CustomElementPluginBase;
/**
* Container HTML element plugin for Site Studio.
*
* @package Drupal\cohesion\Plugin\CustomElement
*
* @CustomElement(
* id = "example_container_element",
* label = @Translation("Example container element"),
* container = true
* )
*/
class ContainerExample extends CustomElementPluginBase {
Next within the render function of the plugin add #elementChildren to the return array like so:
public function render($element_settings, $element_markup, $element_class, $element_context = [], $element_children = '') {
// Render the element.
return [
'#theme' => 'example_container_element',
'#template' => 'example-container-element-template',
'#elementSettings' => $element_settings,
'#elementMarkup' => $element_markup,
'#elementContext' => $element_context,
'#elementClass' => $element_class,
'#elementChildren' => $element_children
];
}
2. Custom element module
Within your custom element module, hook_theme function add elementChildren to the variables array like so, this provides the variable elementChildren to the twig template:
/**
* Implements hook_theme().
*/
function example_element_theme($existing, $type, $theme, $path) {
return [
'example_container_element' => [
'template' => 'example-container-element-template',
'variables' => [
'elementSettings' => NULL,
'elementMarkup' => NULL,
'elementContext' => NULL,
'elementClass' => NULL,
'elementChildren' => NULL,
],
'render element' => 'children',
],
];
}
Then within the custom element twig template you can add to render out the child elements/components within the custom element.
The Site Studio example element module is a good starting point to look at when creating your own custom element and contains examples for both a regular element and container element. Another example of a custom element is the AddToAny Site Studio integration module which is available on Drupal.org.