Custom Elements

Create your own custom elements for the YOOtheme Pro page builder.

With a child theme you can add your own custom elements to the builder. Duplicate existing ones and change the markup and settings to your needs or create completely new elements that you can add to your projects.


Example Element

To get you started, we provide an example element that makes use of all the different field types and demonstrates the features described in the following chapter. Download and unzip the example files and place them in a /builder directory of your child theme, for example /yootheme-NAME/builder. Replace NAME with the name of our child theme.

Download Github


Adding Elements

Create a /builder folder in your child theme. All folders within /builder will be loaded as custom elements. Always make sure to give a unique element name (e.g. my_gallery) that is not taken by the default builder elements. You can find all elements in /vendor/yootheme/builder/elements, you can also copy an existing element and then customize it as you need to. Now let us go through the file structure of a element.

File Description
element.json Defines the element configuration and settings.
element.php Extends the element functionality. (optional)
templates/template.php Renders the actual frond-end markup. (partials are prefixed with template-*.php)
templates/content.php Renders the content which is saved in the page.
images/icon.svg The icon shown in the element picker.
images/iconSmall.svg The icon shown in the builder layout overview.

Configuration

The element.json defines the element's name, icons, fields and how the editing interface should look like inside the builder. The following example shows the element configuration and explains the purpose of each property.

//example/element.json
{
    // Name of the element
    "name": "example_element",

    // Label in the interface
    "title": "Example",

    // Icon in `New element` dialog
    "icon": "${url:images/icon.svg}",

    // Icon in builder overview
    "iconSmall": "${url:images/iconSmall.svg}",

    // Show in `New element` dialog
    "element": true,

    // Set default values for fields (field_name: default_value)
    "defaults": {
        "text": "John Doe"
    },

    // Define templates for the element
    "templates": {
        "render": "./templates/template.php",
        "content": "./templates/content.php"
    },

    // Define the available fields for the element (field_name: {field_definition})
    "fields": {

        "text": {
            "type": "text",
            "label": "Field text",
            "description": "A short description that will be displayed below the field."
        },

        // More fields of your element ...
    },

    // You can define different tabs for the element and assign the previous defined fields to tabs.
    // This is optional. When not defined, all fields will be displayed on one page.
    "fieldset": {
        "default": {
            "type": "tabs",
            "fields": [
                {
                    "title": "Tab 1",
                    "fields": ["text"]
                }
            ]
        }
    }
}

Templating

The template.php defines HTML markup of our element when it is displayed on the website. In the PHP template file you can access all element fields as properties using $props variable. Additionally, the template engine provides a helper to create HTML tags, using $this->el().

<?php //example/templates/template.php

// Create div tag
$el = $this->el('div', [

    'class' => [

        // Add `uk-alert`
        'uk-alert',

        // Add `uk-alert-{alert_style}`, only if $props['alert_style'] has a value and it will substitute the {alert_style}
        'uk-alert-{alert_style}',

        // Add `uk-padding`, only if $props['alert_size'] has a value and {@alert_size} will removed von the string
        'uk-padding {@alert_size}',
    ]

]);

?>
<?= $el($props, $attrs) // Output div tag ?>

    <?php if ($props['title']) : ?>
    <h3 class="el-title"><?= $props['title'] // Output title ?></h3>
    <?php endif ?>

    <div class="el-content"><?= $props['content'] // Output content ?></div>

</div>

Here is a overview of the variables which are available when rendering an element node in your templates.

Variable Description
$node The element node (stdClass)
$props The element properties ($node->props) set using the fields (array)
$children The element children ($node->children) like content items (array)
$builder The current builder instance used to render children (YOOtheme\Builder)

Extending

The element.php is an optional file which is used to extend element functionality with custom transforms or update functions. Just make sure to import the element.php by adding "@import": "./element.php" to your element.json file.

<?php //example/element.php

return [

    // Define transforms for the element node
    'transforms' => [

        // The function is executed before the template is rendered
        'render' => function ($node, array $params) {

            // Element object (stdClass)
            $node->type; // Type name (string)
            $node->props; // Field properties (array)
            $node->children; // All children (array)

            // Parameter array
            $params['path']; // All parent elements (array)
            $params['parent']; // Parent element (stdClass)
            $params['builder']; // Builder instance (YOOtheme\Builder)
            $params['type']; // Element definition (YOOtheme\Builder\ElementType)
            $params['app']; // Application instance (YOOtheme\Application)

        },

    ],

    // Define updates for the element node
    'updates' => [

        '1.18.0' => function ($node, array $params) {

            // Remove or modify deprecated properties
            unset($node->props['deprecated_prop']);

        },

    ],

];

You can now use the element inside the page builder. If it does not appear there, make sure you have enabled the child theme and your element is inside the /builder folder.

Example element in the element library


Fields

An element consists of a number of fields that are displayed in the page builder to enter content and change settings. These fields are then used to render the element inside YOOtheme Pro.

Each field has a type, by default it's type: text. The field will display an input field to enter text which can be rendered by the template. YOOtheme Pro provides a comprehensive collection of fields, e.g. for numbers and booleans as well as more complex ones, like an image, location or color picker.

You can define the fields in the element.json file. Add field name and field definition to the fields object, then you can optionally define different tabs where the fields should be shown in the fieldset definitions. Here is an example with a text, select and checkbox field.

...
"fields": {

    // Text (default, if type is not set), defines an input field
    "field_one": {
        "label": "Text",
        "type": "text"
    },

    // Select, defines an select box
    "field_two": {
        "label": "Select",
        "description": "Explanation that appears below the field",
        "type": "select",
        "text": "Field Text",
        "options": {
            "Option 1": 0,
            "Option 2": 1,
            "Option 3": 2
        }
    },

    // Checkbox, defines a checkbox
    "field_three": {
        "label": "Checkbox",
        "description": "Explanation that appears below the field",
        "type": "checkbox",
        "text": "Field Text"
    }
},

// Optional define tabs and assign fields
"fieldset": {
    "default": {
        "type": "tabs",
        "fields": [
            {
                "title": "Content",
                "fields": ["field_one", "field_two", "field_three"]
            },
            {
                "title": "Settings",
                "fields": []
            }
        ]
    }
}
...

Settings of the the example element

When rendering the template, the value of the field is of the according type, or null if the user has not entered a value yet.

<?php

    // Element properties
    $props['field_one'];   // string
    $props['field_two'];   // integer
    $props['field_three']; // boolean

?>

Field Attributes

Every field is defined by its type and its attributes. The following attributes are available for all field types.

Attribute Description
label The field label is displayed as a headline in the element settings on the left.
description The field description is displayed as muted text below the field.
attrs This adds additional HTML attributes to the rendered field.

Here is an example of a text field.

{
    "label": "Text",
    "description": "A description text that appears below the field",
    "type": "text",
    "attrs": {
        "placeholder": "Enter text..."
    }
}

Field Types

You can use a number of different fields to add content and settings to your element. Here is a list of all field types.

Name Type Description
Text text Define an input field. This is also the default if no field type is set.
Select select Define a select box – see example.
Number number Define a numerical input field.
Checkbox checkbox Define a checkbox – see example.
Radio radio Define a group of radio buttons – see example.
Range range Define an range slider with an addition input field – see example.
Textarea textarea Define a plain text area for multiple lines of text – see example.
Editor editor Define a visual and code editor (Depending on the WordPress settings) – see example.
Image image Define an image picker using the media library.
Video video Define a video picker using the media library.
Link link Define a link picker for WordPress system links and files in the media library.
Color color Define a color picker.
Font font Define a font picker.
Icon icon Define an icon picker for the UIkit icon library.
Location location Define an interactive map to pick a location.
Select-img select-img Define an image picker for a predefined set of images – see example.
Select-icon select-icon Define an icon picker for a predefined set of icons – see example.
Grid grid Arrange any field types in a grid next to each other – see example.

Select Example

Additional attributes are: default, options

{
    "label": "Select",
    "type": "select",
    "default": 0,
    "options": {
        "Option 1": 0,
        "Option 2": 1,
        "Option 3": 2
    }
}

Checkbox Example

Additional attributes are: text

{
    "label": "Checkbox",
    "type": "checkbox",
    "text": "The text behind the checkbox."
}

Radio Example

Additional attributes are: default, options, name

{
    "label": "Radio",
    "type": "radio",
    "name": "radio_group",
    "default": 0,
    "options": {
        "Option 1": 0,
        "Option 2": 1,
        "Option 3": 2
    }
}

Range Example

{
    "label": "Range",
    "type": "range",
    "attrs": {
        "min": 1,
        "max": 10,
        "step": 0.5
    }
}

Text area Example

{
    "label": "Textarea",
    "type": "textarea",
    "attrs": {
        "rows": 10,
        "placeholder": "Enter text..."
    }
}

Editor Example

Here is a list of additional attributes.

Attribute Description
editor Define which editor to load, i.e. code to disable the visual editor.
mode Explicitly define code language, e.g. css, js or text/html.

Note You often want to set a debounce attribute of around 500 milliseconds to prevent the live preview from updating while you are still typing in the editor.

Example for a visual and code editor.

{
    "label": "Editor",
    "type": "editor"
}

Example for a code editor only.

{
    "label": "Code editor",
    "type": "editor",
    "editor": "code",
    "mode": "css",
    "attrs": {
        "debounce": 500
    }
}

Select-img Example

Additional attributes are: title, default, options

{
    "label": "Select-img",
    "title": "Select an image",
    "type": "select-img",
    "default": "1-1",
    "options": {
        "1-1": {
            "label": "Whole",
            "src": "${url:images/whole.svg}"
        },
        "1-2": {
            "label": "Halves",
            "src": "${url:images/halves.svg}"
        },
        "1-3": {
            "label": "Thirds",
            "src": "${url:images/thirds.svg}"
        }
    }
}

Select-icon Example

Additional attributes are: options

{
    "label": "Select-icon",
    "type": "select-icon",
    "options": {
        "": {
            "label": "Always",
            "icon": "phone",
        },
        "s": {
            "label": "Small (Phone Landscape)",
            "icon": "phone-landscape",
        },
        "m": {
            "label": "Medium (Tablet Landscape)",
            "icon": "tablet-landscape",
        },
        "l": {
            "label": "Large (Desktop)",
            "icon": "laptop",
        },
        "xl": {
            "label": "X-Large (Large Screens)",
            "icon": "desktop",
        }
    }
}

Grid Example

Additional attributes are: fields

{
    "type": "grid",
    "fields": {
        "field_grid_one": {
            "label": "Text 1",
            "width": "1-2"
        },
        "field_grid_two": {
            "label": "Text 2",
            "width": "1-2"
        }
    }
}

Content Items

It’s possible to define repeatable content items in your element, like the default Grid and Slideshow elements do. Just like the element itself, a custom content item has its own element.json file. The following example is taken from the /example_item/element.json file that you’ll find in the example element:

//example_item/element.json
{
    "name": "example_item",
    "title": "Item",
    "width": 500,
    "templates": {
        "render": "./templates/template.php",
        "content": "./templates/content.php"
    },
    "fields": {

        "title": {
            "label": "Title",
            "type": "text"
        },

        "content": {
            "label": "Content",
            "type": "editor"
        },

        "image": {
            "label": "Image",
            "type": "image"
        }

    },
    "fieldset": {
        "default": {
            "fields": [
                "title",
                "content",
                "image"
            ]
        }
    }
}

This adds a field to your element that shows an interface to manage these custom content items.

//example/element.json
{
    ...

    "fields": {

        "content": {
            "label": "Items",
            "type": "content-items",
            "title": "content",
            "item": "example_item" // Name of the element item
        }

        ...
    },

    ...
}

Your element will then show a list of content elements the user can order and remove:

Content items field

YOOtheme Pro