Blocks
Relevant for platform versions 3.x.
For detailed information on using blocks for FL2.x, please read the link.
Purpose of Use
To add content to platform pages, you need to use blocks - view handler classes. Let's consider the general structure of a block, each stage of its creation, including integration on the page. Blocks can be created in modules as well as in add-ons.
namespace plugins\example\views;
use bff\view\Block;
class ExampleBlock extends Block
{
public function init()
{
// Block initialization
}
public function data()
{
// Processing block data used in the template
}
}
Initialization
The block class is created in the views
directory and inherits from the base block bff\view\Block
.
The init()
method is mandatory and initializes the block.
public function init()
{
// Call the base initialization
parent::init();
// Declare a template for rendering the block
$this->setTemplate('tpl/example', $controller);
// Set the multilingual block title
$this->setTitle($this->extension->lang('Example'));
}
The setTemplate($tpl, $controller)
method sets the template for the block, where
-
$tpl
-subdir/tpl_name
is the template name and location in thetpl
directory, for a block in a plugin, also specify the name of the template placement foldertpl/subdir/tpl_name
, for a block in a module - only the subdirectory and template namesubdir/tpl_name
; -
$controller
- the block controller, which can be a modulemodule_name
or a plugin.
$this->extension = $this->app->plugin('plugin_alias');
$this->setTemplate('tpl/subdir/tpl_name', $this->extension);
Block Data
The data()
method defines the data that will be passed to the template for displaying the block.
public function data()
{
// Base class data
$data = parent::data();
// Block data
$data['title'] = $this->lang('Example block');
$data['list'] = $this->model->getList();
return $data;
}
Block Template
In the view template plugins/example/tpl/example.php
, you can use the variables initialized in the data()
method.
/**
* Example block
* @see plugins\example\views\ExampleBlock
* @var $title string
* @var $list array
*/
?>
<div>
<h1><?= $title ?></h1>
<?php foreach($list as $item){ ?>
<?= $item['key'] ?>
<?php } ?>
</div>
Block Integration
To insert the block on the page, use the blocks()
method and specify the key and the class name of the ExamplePage
handler.
public function blocks()
{
$this->addBlock('example', ExampleBlock::class);
}
The addBlock($key, $block, $callback, $opts)
method adds the ExampleBlock
block to the current page handler object. It accepts the following parameters:
-
$key
: the block key. -
$block
: the class, block object, or aClosure
function. -
$callback
: optional parameter, a closure that will be called after the block initialization. The parameters are the added block object and the key. -
$opts
: optional parameter, an array of additional options.
During the rendering process of the page template, the block is displayed as a variable with the key example
.
Pages
To create pages, we use a view handler class that inherits from the base view page bff\view\Page
.
Pages can be created in both modules and addons.
Let's look at the page structure and main methods.
namespace plugins\example\views;
use bff\view\Page;
class ExamplePage extends Page
{
public function init()
{
// Initialize the page
}
public function data()
{
// Process the page data used in the template
}
public function blocks()
{
// Add blocks
}
public function settingsForm($form)
{
// Page settings in the admin panel
}
public function seo()
{
// Page SEO settings
}
}
Initialization and data of the page are similar to the init()
and data()
methods of blocks.
Page Blocks
In the blocks()
method, blocks of the page are added.
public function blocks()
{
// Add an existing block to the page
$this->addBlock('example', ExampleBlock::class, function (ExampleBlock $block) {
$block->itemId = $this->itemId;
}););
// Declare a block
$this->addTemplateBlock('filter', 'tpl/filter', $this->extension, function (bff\view\Block $block) {
$block->setTitle($this->extension->lang('Filter'));
...
})
}
Adding a block addBlock()
is described in detail in the "Blocks" section.
When adding a block, you can pass page parameters in $callback
.
In the page handler class, you can declare a block class in the method addTemplateBlock($key, $template, $controller, $callback)
:
- $key - block key,
- $template - template name and location in the
tpl
directory, - $controller - block controller,
- $callback - closure that will be called after the block is initialized, with the added block object as a parameter.
You can display blocks individually as variables in the template $example
and $filter
.
Page Settings
In the settingsForm($form)
method, a settings form for a page or block in the admin panel interface of the project is created.
$form
is an object constructor form bff/tpl/admin/Form that allows the display of all field types.
/** @var bool */
public $enabled = false;
/** @var string */
public $intro = '';
...
public function settingsForm($form)
{
$form->checkbox('enabled', $this->extension->lang('Enabled'), $this->enabled);
$form->wysiwyg('intro', $this->extension->lang('Page Text'));
}
In this case, the method creates a checkbox called enabled
and a wysiwyg editor called intro
. These settings are set as class parameters of the page handler. You can edit the field data in the admin panel under the "Design / Page Settings / Example Page" menu.
You can disable the block or change its placement on the page in the "Order" tab.
SEO parameters for the page are specified in the seo()
method.
Page Template
The page template page.php
is set in the init()
method during the initialization of the handler class:
public function init()
{
...
$this->setTemplate('tpl/page', $this->extension);
}
In the page template, the following are available for rendering:
- Page data from the
data()
method - Blocks as template variables, such as
$example
,$filter
- Page settings, such as
$enabled
,$intro
/**
* Example page
* @see plugins\example\views\ExamplePage
* @var $title string
* @var $enabled boolean
* @var $intro string
* @var $example plugins\example\views\ExampleBlock
* @var $filter string
*/
?>
<?php if($enabled){ // Class setting from settingsForm() ?>
<div>
<h1><?= $title // Class data from data() ?></h1>
<p><?= $intro ?></p>
<?= $exampleBlock // Example of outputting the ExampleBlock block ?>
<?= $filterBlock ?>
</div>
<?php } ?>
Displaying the Page
The display of the page is done by adding a route in a module or plugin.
In the start()
method of the /example/
route, specify the view class as the handler:
protected function start()
{
...
$this->routeAdd(
'plugin_alias-example', # route id
[
'pattern' => '/example/',
'callback' => ExamplePage::class,
]);
}
Extending Pages
You may notice that many pages implement a contract.
A contract is an interface, an abstract type of dependency that is registered in the application container
and allows for extension and replacement of the implementation of the original platform pages.
Let's consider this possibility with the example of the contacts page. The contacts contract is located in a module and looks like this:
namespace modules\contacts\views\contracts;
use bff\view\Page;
/**
* Contact page contract
* @mixin Page
*/
interface ContactPage
{
}
It is located in the views namespace in the contracts
directory and can use methods from the bff\view\Page
class.
In a theme or plugin, you can extend the platform's contacts page and create your own ContactPageExtended
contact page.
namespace plugins\contacts_extended\views;
use modules\contacts\views\ContactPage;
use modules\contacts\views\contracts\ContactPage as ContactPageContract;
class ContactPageExtended extends ContactPage implements ContactPageContract
{
...
}
You can override the specific implementation in the start
method.
use modules\contacts\views\contracts\ContactPage as ContactPageContract;
use plugins\contacts_extended\views\ContactPageExtended;
...
protected function start()
{
...
$this->app->singleton(
// Contract of the original contacts page in the platform
ContactPageContract::class,
// New class for the contacts page in the plugin
ContactPageExtended::class
);
}
...