Skip to content

Building Blocks

Blocks are elements used in the CMS module to display and configure data. Blocks are dropped into the placeholders of a CMS Layout. An example of a block could be a paragraph tag where the user can add the content. LUYA CMS module is shipped with some default blocks, but you can create your own elements.

Block Admin

Create a new block

TIP

Use ./vendor/bin/luya cms/block/create console command to generate a block.

You can add blocks to your application or to a module. In either case, the folder where the blocks are stored must be named as blocks. Additionally blocks should have the suffix Block in their filename.

For example, we create a block TextTransformBlock and store it in app/blocks or app/modules/yourmodule/blocks.

This is how the TextTransformBlock could look like in your code:

php
<?php
namespace app\blocks;

class TextTransformBlock extends \luya\cms\base\PhpBlock
{
    public function icon()
    {
        return 'extension'; // https://material.io/resources/icons/
    }
    
    public function name()
    {
        return 'Transformed Text';
    }
    
    public function config()
    {
        return [
            'vars' => [
                ['var' => 'mytext', 'label' => 'The Text', 'type' => self::TYPE_TEXT],
            ],
        ];
    }

    public function extraVars()
    {
        return [
            'textTransformed' => strtoupper($this->getVarValue('mytext')),
        ];
    }

    public function admin()
    {
        return 'Administrations View: ` vars.mytext `';
    }
}

Define help information for the admin view:

php
public function getFieldHelp()
{
    return [
        'content' => 'An explain example of what this var does and where it is displayed.',
    ];
}

Block Types

Read more about details regarding luya\cms\base\InternalBaseBlock -> config() in Block Types

As we have switched to luya\cms\base\PhpBlock by default you now have to create also a view file, which is located in the view folder of your application: app/views/blocks/. The view itself must have the same name as the class name of your block, e.g. TextTransformBlock.php.

In the example above, the view file should look like this:

php
<?php
/* @var $this \luya\cms\base\PhpBlockView */
?>

<?php if ($this->varValue('mytext')): ?>
    <h1><?= $this->extraValue('textTransformed'); ?></h1>
<?php endif; ?>

In order to retrieve values from configurations ($this->[METHOD]):

TypeMethod
varluya\cms\base\PhpBlockView -> varValue()
cfgluya\cms\base\PhpBlockView -> cfgValue()
extraluya\cms\base\PhpBlockView -> extraValue()
placeholderluya\cms\base\PhpBlockView -> placeholderValue()

Check the luya\cms\base\PhpBlockView for full method reference to use inside the PHP block view.

Register and import

After creating a block, you have to import it into your application. The reason behind the import process is to avoid rely on database structure (which cant be tracked in a VCS or SVN easily) and to work with PHP files you can manage in version control system (e.g. GitHub or BitBucket). Run the Import Command:

sh
./vendor/bin/luya import

This will add or update the block into the CMS system. If you rename or remove a Block from your application, the old block will be deleted from your database.

Module blocks

When you add a block inside of a module you have to define the luya\cms\base\PhpBlock -> $module properties, this will ensure the view file will be found in the correct folder. This way, you can redistributed blocks with your own package to other users:

php
class TestBlock extends \luya\cms\base\PhpBlock
{
    public $module = 'mymodule';
}

Caching

To speed up your system you can enable the cache for each block by the definition of a caching component in your configs. Block caching is disabled by default for all blocks luya\cms\base\PhpBlock -> $cacheEnabled

php
class MyTestBlock extends \luya\cms\base\PhpBlock
{
    public $cacheEnabled = true;
}

This will cache the block for 60 minutes but you can adjust the number of seconds the block should be cached by defining the luya\cms\base\PhpBlock -> $cacheExpiration property:

php
public $cacheExpiration = 60;

You can enable block caching for a block event if the caching component is not registered, so you can redistribute blocks and the behavior of them.

Env / Context Information

Each block is placed in an environment (env). You can access those information inside your block with luya\cms\base\PhpBlock -> getEnvOption() logic:

php
$this->getEnvOption($key, $defaultValue);

The following keys are available:

  • id: Returns the unique identifier from the CMS context.
  • blockId: Returns the id of this block (unique identifier).
  • context: Returns 'frontend' or 'admin' to find out in which context you are.
  • pageObject: Returns the luya\cms\models\NavItemPage object where the block is located.
  • isFirst: Returns whether this block is the first in its placeholder or not.
  • isLast: Returns whether this block is the last in its placeholder or not.
  • index: Returns the index number/position within this placeholder.
  • itemsCount: Returns the number of items inside this placeholder.
  • isPrevEqual: Returns whether the previous item is of the same origin (block type, like text block) as the current.
  • isNextEqual: Returns whether the next item is of the same origin (block type, like text block) as the current.
  • equalIndex: Returns the current index number/position of this element within the list of same elements.

Thereof you can also retrieve the related luya\cms\models\NavItem and luya\cms\models\Nav objects via luya\cms\models\NavItemPage -> getNavItem() and luya\cms\models\NavItem -> getNav() as follows:

php
$this->getEnvOption('pageObject')->navItem->nav;

Inside a PHP block view call instead:

php
$this->block->getEnvOption($key, $defaultValue);

Or you can easily access these properties through convenient shortcuts, e.g. $this->isPrevEqual.

For example, they are useful to make a container layout block which auto close/open the row when working with a grid system like the one from Bootstrap:

php
<?php if (!$this->isPrevEqual): ?>
<div class="row">
<?php endif; ?>

    <div class="col-md-3">
       <h1>The Block Content.</h1>
    </div>

<?php if (!$this->isNextEqual): ?>
</div>
<?php endif; ?>

The above example would only open the row element once and closes the row container when the next element is not an element of the current block.

Properties from CMS page

If there are any CMS properties defined you can access them like this:

php
$this->getEnvOption('pageObject')->navItem->nav->getProperty('myCustomProperty');

If there is a property defined you will get the property object otherwise returning false.

Register Assets and JavaScript/CSS

Sometimes your block should also register some CSS or JavaScript files, therefore you can access the global luya\web\View object inside of your PHP view template. It is quite similar to registering other assets with the difference that you are accessing the global scope view instead of the view on $this.

Assuming the below code is the PHP view of your block:

php
MyBlockAsset::register($this);

Now the Asset is registered in the application view object.

It's also possible to just register certain JavaScript or CSS code, therefore use registerJs() or registerCss() directly in the view files of the block.

Registering some JavaScript code:

php
$this->registerJs("
    console.log('hello world');
");

Or register a variable:

php
$this->registerJsVar("foo", "bar"); // var foo = 'bar'

And for CSS inline styles use:

php
$this->registerCss("
    .data { color: red; }
");

AJAX Requests in Block

To implement AJAX inside a block the following concept is used:

Create a callback and define all parameters. The callback is what the URL returns to your JavaScript which can be HTML or JSON.

php
public function callbackHelloWorld($time)
{
    return 'hallo world ' . $time;
}

The above callback requires the parameter $time and must be called trough an AJAX call inside of the JavaScript, to create the URL for this specific callback we are going to use createAjaxLink():

php
$this->createAjaxLink('HellWorld', ['time' => time()]);

You could store this created link from above inside your extras vars and pass it to the JavaScript.

You can pass additional values to the callback by using the post AJAX method and collect them in your callback via Yii::$app->request->post(). The get parameters are used to resolve the callback.

Block groups

There is the ability to manage the block groups via classes. You can add new blockgroups to your application on which your block depends, when you run the import command LUYA will add/update the blocks into the provided groups.

To add new block groups create folder in your @app namespace, or inside a module with the name blockgroups, to add a folder create class like this app\blockgroups\MySuperGroup:

php
<?php
namespace app\blockgroups;

class MySuperGroup extends \luya\cms\base\BlockGroup
{
    public function identifier()
    {
        return 'my-super-group';
    }
    
    public function label()
    {
        return 'My Super Group Elements';
    }
    
    public function getPosition()
    {
        return 30;
    }
}

The position of the block will start from lower to higher, means 1 will be at the top of the groups list in the administration and even higher will be more at the bottom.

The folder will be created on import. Now blocks can belong to this folder, to do so override the luya\cms\base\BlockInterface -> blockGroup() method of your block:

php
public function blockGroup()
{
    return \app\blockgroups\MySuperGroup::className();
}

You can also use one of the predefined group block class:

  • \luya\cms\frontend\blockgroups\MainGroup (this is default group for all blocks)
  • \luya\cms\frontend\blockgroups\LayoutGroup
  • \luya\cms\frontend\blockgroups\ProjectGroup
  • \luya\cms\frontend\blockgroups\DevelopmentGroup
  • \luya\cms\frontend\blockgroups\MediaGroup
  • \luya\cms\frontend\blockgroups\TextGroup

Block variations

In order to extend a block with a special behaviour the luya\cms\admin\Module -> $blockVariations property of the cmsadmin module can be configured inside your general config like in the example below:

php
'cmsadmin' => [
    'class' => 'luya\cms\admin\Module',
    'blockVariations' => [
        TextBlock::variations()
            ->add('bold-flavor', 'Bold font with Markdown')->cfgs(['cssClass' => 'bold-font'])->vars(['textType' => 1])
            ->add('italic-flavor', 'Italic Font')->cfgs(['cssClass' => 'italic-font'])
            ->register(),
    ]
],

Maybe the application block is not known inside the config files, then there is an alternative option to define block variations:

php
'cmsadmin' => [
    'class' => 'luya\cms\admin\Module',
    'blockVariations' => [
         'app\blocks\TextBlock' => [
             'variation1' => [
                 'title' => 'Super Bold Text',
                 'vars' => ['cssClass' => 'bold-font-css-class'],
                 'cfgs' => [], // will be ignore as it's empty, so you can also just remove this part.
                 'extras' => [], // will be ignore as it's empty, so you can also just remove this part.
                 'is_default' => 0,
             ],
         ]
    ]
]

Block preview

To give the user a better understanding how you block could looks like you can store a JPEG image under app/images/blocks or app/modules/yourmodule/images/blocks with same name as the block e.g. TextTransformBlock.jpg. This image will be display on hover over a block name in the navigation. Make sure that this file size is so small as possible (maybe use a image optimizer) and image size is under 400x400 pixel.