Skip to content

Block config and type

Here we are diving a bit deeper understand what the luya\cms\base\PhpBlock -> config() method of a block contains and which kind of types can be used. First we have to explain the available types of configurations and which are used to be configured by the user or the developer.

Block input / Output configuration

The config() method returns an array with all defined types for this current block, the first level defines the block types:

php
return [
    'vars' => [],
    'cfgs' => [],
    'placeholders' => [],
];

You only have to return the types you like to use in your block, if do not have placeholders your do not have to return it at all.

NameFunction
varsVariables where to user can enter data according to your type (select, text, radio, etc.).
cfgsThose options are shown as well in the admin UI and are meant to be used optional options which could be use for developers.
placeholdersDefined placeholders allows you to mark an area where other blocks can be dropped and rendered. A common use case could be a div with given class where dropping nested blocks is allowed. It's very common to enable luya\cms\base\InternalBaseBlock -> $isContainer property when working with placeholders, this will render the block nicely with cols and rows (if configured).

Now you can add a field into the above defined type, this is like a configuration of a field which must contain var, label and type:

php
[
    'var' => 'userInputText',
    'label' => 'Form Label for the User',
    'type' => self::TYPE_TEXT, // or as class constant: self::TYPE_TEXT
]

Required Input

Since version 3.4 of LUYA Module CMS it's possible to define a required property in order to ensure can not be empty.

Above, this would create an input variable with a text input field and a label From Label for the User. The type of the field can be added into a group you like:

php
return [
    'vars' => [
        ['var' => 'userInputText', 'label' => 'Description of userInputText', 'type' => self::TYPE_TEXT, 'required' => true]
    ]
];

Input block types

There are several types you can use to generate your block controllers. Each class which support those types implements the luya\admin\base\TypesInterface where you can use the type names as constant.

Type NameConstantsDescription
zaa-textTYPE_TEXTCreates a simple string input text value field.
zaa-textareaTYPE_TEXTAREACreates a multi-row text input element known as textarea
zaa-passwordTYPE_PASSWORDCreates a input password field which hides the input value behind * signs
zaa-numberTYPE_NUMBERCreates a numeric value
zaa-decimalTYPE_DECIMALCreates decimal input field with option: options="{'steps':0.0001}" to define step size. Default = 0.001.
zaa-linkTYPE_LINKCreate a link field for internal and external URLs
zaa-wysiwygTYPE_WYSIWYGCreates a small wysiwyg editor
zaa-selectTYPE_SELECTCreates a select drop down with options based on the options parameter. The options item must contain a value and label key, e.g. [["value" => "v1", "label" => "Value 1"], ["value" => "v2", "label" => "Value 2"]].
zaa-radioTYPE_RADIOCreates a radio button selection based on the options parameter. The Options item must contain a value and label key, e.g. [["value" => "v1", "label" => "Value 1"], ["value" => "v2", "label" => "Value 2"]].
zaa-dateTYPE_DATECreates a date picker where the user can choose a date, the response inside the block will be a Unix timestamp.
zaa-datetimeTYPE_DATETIMECreates a date picker where the user can choose a date and provide an additional time, the response inside the block will be a Unix timestamp.
zaa-checkboxTYPE_CHECKBOXCreates a single checkbox (e.g. to define on/off states).
zaa-checkbox-arrayTYPE_CHECKBOX_ARRAYCreate an array with checkboxes.
zaa-file-uploadTYPE_FILEUPLOADCreates a file upload form and returns the fileId on success.
zaa-file-array-uploadTYPE_FILEUPLOAD_ARRAYCreates an array with file id and caption string.
zaa-image-uploadTYPE_IMAGEUPLOADCreates an image upload form and return the imageId on success.
zaa-image-array-uploadTYPE_IMAGEUPLOAD_ARRAYCreates an array with image id and caption string.
zaa-list-arrayTYPE_LIST_ARRAYCreates an array with a key variable value.
zaa-multiple-inputsTYPE_MULTIPLE_INPUTSCreates an expandable list with plugins for each row.
zaa-colorTYPE_COLORA color wheel to choose a color which will return the hex code of the selected color.
zaa-slugTYPE_SLUGInput field which will generate URL safe strings where only a-z, 0-9 and - is allowed.
zaa-tableTYPE_TABLEGenerates a table generator where you can create cols and rows.

Examples with block types

Example for file download (file upload) and Markdown text for textarea inputs, where the text is required.

php
public function config()
{
    return [
        'vars' => [
             ['var' => 'image', 'label' => 'Image', 'type' => self::TYPE_IMAGEUPLOAD, 'options' => ['no_filter' => true]],
             ['var' => 'text', 'label' => 'Text', 'type' => self::TYPE_TEXTAREA, 'required' => true],
             ['var' => 'download', 'label' => 'Download', 'type' => self::TYPE_FILEUPLOAD],
        ],
    ];
}

public function getText()
{
    return TagParser::convertWithMarkdown($this->getVarValue('text'));
}

public function extraVars()
{
    return [
        'text' => $this->getText(),
        'image' => BlockHelper::imageUpload($this->getVarValue('image'), false, true),
        'download' => BlockHelper::fileUpload($this->getVarValue('download'), true),
    ];
}

In the view you can access the values as followed:

php
<?php if ($this->extraValue('download') && $this->extraValue('image')): ?>
    <img src="<?= $this->extraValue('image')->source; ?>" />
    <?= $this->extraValue('text'); ?>
    <a href="<?= $this->extraValue('download')->href; ?>">Download File</a>
<?php endif; ?>

Placeholders

This is very strong feature of LUYA CMS block system. It allows you to create an infinite amount of recursions. Thinking of GRID system like Bootstrap, the placeholders are like cols where you can put other blocks. An example of a block configuration with placeholders:

php
public function config()
{
    return [
        'placeholders' => [
            [
                ['var' => 'left', 'cols' => 8, 'label' => 'Left'],
                ['var' => 'right', 'cols' => 4, 'label' => 'Right'],
            ]
        ],
    ];
}

The above example would generate 1 row with 2 columns. As Bootstrap 4 has at max 12 cols the first column would be larger then the second. Now you can enable luya\cms\base\InternalBaseBlock -> $isContainer which will render the placeholders nicely and different to casual blocks.

$isContainer has no admin view

When enabling the luya\cms\base\InternalBaseBlock -> $isContainer the luya\cms\base\InternalBaseBlock -> admin() output wont have no effect and is not rendered!

block with placeholders

When enabling the cache for layout blocks, the full placeholder content will be cached to. So it's very common to disable caching for blocks with placeholders.

An example of how a view file for this layout block with placeholders could look like:

php
<?php
/**
 * @var $this \luya\cms\base\PhpBlockView
 */
?>
<div class="row">
    <div class="col-md-8">
        <?= $this->placeholderValue('left'); ?>
    </div>
    <div class="col-md-4">
        <?= $this->placeholderValue('right'); ?>
    </div>
</div>

Block injectors

A very common scenario is to collect data from an ActiveRecord model, display the items and select them (e.g. via select or checkbox) and then access the selected model rows via luya\cms\base\PhpBlock -> extraVars(). To achieve this a lot of code is required inside your blocks, which is good to understand what and why things happens, but if you need to get results quickly injectors are going to help you manage this kind of tasks.

Injectors can, as the name already says, inject data into your luya\cms\base\PhpBlock -> config() method and assign custom data to luya\cms\base\PhpBlock -> extraVars().

Lets assume we have news articles from an ActiveRecord model which you want to select inside the admin UI area and return the selected model rows. This can be defined via the luya\cms\base\PhpBlock -> injectors() method as a new injector as in the example below:

php
class MyBlock extends \luya\cms\base\PhpBlock
{
    // ...
    
    public function injectors()
    {
        return [
            'newsData' => new \luya\cms\injectors\ActiveQueryCheckboxInjector([
                'query' => \luya\news\models\Article::find(),
                'label' => 'title', // This attribute from the model is used to render the admin block dropdown selection.
                'type' => self::INJECTOR_VAR,
                'varLabel' => 'Select Articles', // The Block form label
            ])
        ];
    }
}

Now the generated injector ActiveQueryCheckboxInjector is going to grab all information from the defined query and assign them into the extra var newsData. Now you can access $extras['newsData'] which returns all selected rows from the checkbox you have assigned.

In order to append the injected variable to the end of the form use 'append' => true.

For example your view file could now look like this:

php
foreach ($this->extraValue('newsData') as $model) {
    echo $model->title; // assuming the title is an attribute of the Article model defined in the query part of the injector.
}

The following Injectors are currently available:

ClassDescription
luya\cms\injectors\ActiveQueryCheckboxInjector Generates as checkbox selection from an ActiveRecord and assign the selected model rows into the extraVars section. In order to select only a specific fields add the select() to the ActiveRecord find ActiveQuery.
luya\cms\injectors\ActiveQueryRadioInjector Generates a radio list
luya\cms\injectors\ActiveQuerySelectInjector Generates a dropdown select
luya\cms\injectors\LinkInjector Generates an ability to select a link and returns the correct URL to the link based on the user selection.
luya\cms\injectors\TagInjector Generates a checkbox to select all available admin tags and provides API to return those selected tags.

Injector API

Each injector object generate trough the luya\cms\base\InternalBaseBlock -> injectors() method can be access trough the magical array access. Let's assume you are registering the TagInjector:

php
public function injectors()
{
    return ['tags' => new TagInjector()];
}

Now you are able to access the TagInjector object trough the $this['tags'] ArrayAccess getter method.

Custom Types

In order to develop custom directive types you need to create a few things are required:

  1. A module which is registered and loaded (the module will provide the registration of the asset files). [[/guide/admin/intro]]
  2. An asset file which holds the AngularJS directive code. [[/guide/admin/assets]]]
  3. The AngularJS directive itself which is compatible with LUYA injector API.

An example code for a directive which is compatible with the injector API directive:

js
zaa.directive("myInput", function(){
    return {
        restrict: "E",
        scope: {
            "model": "=",
            "options": "=",
            "label": "@label",
            "i18n": "@i18n",
            "id": "@fieldid",
            "placeholder": "@placeholder"
        },
        template: function() {
            return '<div>Here you can add your code where `$model` is the value to change for your input.</div>';
        }
    }
});

Now after creating the module with the asset file and the JavaScript. You can use my-input directive (example code above) inside your block config as type.