Creating Block Extension
Creating block extensions is pretty darn easy but can provide complex solutions to your content needs too. Let's dive in!
Create Your Extension
First things first, we need to create our extension:
php artisan make:addon my_company.extension.awesome_block
Next open up the AwesomeBlockExtension
class and make sure it extends \Anomaly\BlocksModule\Block\BlockExtension
and defines it's $provides
and $category
properties so we know what it does:
<?php namespace MyCompany\AwesomeBlockExtension;
use Anomaly\BlocksModule\Block\BlockExtension;
class AwesomeBlockExtension extends BlockExtension
{
protected $category = 'content';
protected $provides = 'anomaly.module.blocks::block.awesome';
}
Categories
protected $category = 'content';
You can use any of these built in sections by default:
content
information
component
media
module
social
layout
other
You can also resolve the \Anomaly\BlocksModule\Block\BlockCategories
classes register
function in the boot method of your service provider to add a category of your own:
$categories->register('example-category', [
'name' => 'Name or translatable string.',
'description' => 'Description or translatable string.',
]);
Adding Configuration Fields
The easiest way to get user input into a block is by using the Configuration Module which is already pre-setup for you. All you need to do is define your configuration fields in a resources/config/configuration.php
file.
<?php
return [
'cover_image' => [
'type' => 'anomaly.field_type.file',
'config' => [
'folders' => ['images'],
],
],
'content' => [
'type' => 'anomaly.field_type.wysiwyg',
'config' => [
'configuration' => 'basic',
],
],
];
Customizing Form Sections
You can define optional form sections
for your entire block (aside from the mandatory title field) by defining a resources/config/sections.php
file.
Your block, configuration, and stream entry fields are available to you already prefixed.
<?php
return [
'example' => [
'fields' => [
'configuration_cover_image',
'configuration_content',
],
],
];
By default fields will stack on top of each other in the order in which they are defined. {.tip}
Creating A Block Stream
Some data is best stored in a stream rather than in configuration. It's easy to create a stream for your block:
php artisan make:stream blocks awesome_block
blocks
is a name I tend to use here but you can name the stream whatever you like. {.tip}
Just like building other addons - all you have to do now is populate your extension's migrations
as needed.
If only using one stream we can now simply define the $model
property of our AwesomeBlockExtension
class and the stream will be merged into the block automatically for you.
<?php namespace MyCompany\AwesomeBlockExtension;
use Anomaly\BlocksModule\Block\BlockExtension;
use MyCompany\AwesomeBlockExtension\Block\BlockModel;
class AwesomeBlockExtension extends BlockExtension
{
protected $provides = 'anomaly.module.blocks::block.awesome';
protected $model = BlockModel::class;
}
If you would like the above stream entry fields in your block's form simply add them to your sections.php
using the entry_
prefix:
<?php
return [
'example' => [
'fields' => [
'entry_gallery_repeater',
'configuration_cover_image',
'configuration_content',
],
],
];
Displaying Block Content
To define your block's content view we need to define the $view
property of our AwesomeBlockExtension
:
<?php namespace MyCompany\AwesomeBlockExtension;
use Anomaly\BlocksModule\Block\BlockExtension;
use MyCompany\AwesomeBlockExtension\Block\BlockModel;
class AwesomeBlockExtension extends BlockExtension
{
protected $provides = 'anomaly.module.blocks::block.awesome';
protected $view = 'anomaly.extension.awesome_block::content';
protected $model = BlockModel::class;
}
Now create your resources/views/content.twig
file in the extension directory and create your view using block
as the BlockInterface
:
<div class="hero">
{{ file(block.cover_image).make.resize(1200)|raw }}
{% for item in block.gallery_repeater %}
{{ item.image.make.resize(48, 48).class('img-rounded')|raw }}
{% endfor %}
{{ block.content.render|raw }}
</div>
Looking at the above you can see that configuration and custom entry data are both accessible directly off of the block.
Should you need to access configuration in a non-magic way you can use {{ block.configuration($key) }}
. You can also grab settigns
, if your extension defines any, the same way {{ block.settings($key) }}
.
You can access your block's custom stream entry directly as well using {{ block.entry.$field }}
where entry
is a polymorphic relation.
Advanced Development
Block Instance Form Builder
Should you need to interact with the multiple form builder responsible for building blocks directly you can override the extend
method on your block extension:
public function extend(BlockInstanceFormBuilder $builder)
{
parent::extend($builder);
// Do more stuff!
}
Dynamic Views
The getView
method is responsible for telling the blocks system what view to use for your block's content.
You could easily override the method and use $block
property to return a view dynamically or even a user generated view from the editor field type.
public function getView()
{
if ($this->block->configuration('something_special')) {
return 'my_company.extension.awesome_block::alternate_view';
}
return $this->view;
}