Create a visibility condition for CMS Blocks
Edit on GitHubVisibility Condition is a Templates & Slots feature functionality that lets you define when a CMS block is displayed on a page. The Spryker CMS Blocks content provider for slots has the following visibility conditions by default:
- Category condition for the Category page.
- Product and category conditions for the product details page.
- CMS page condition for the CMS page.
Each page type has a dedicated template with several slot widgets. The visibility conditions of each template are defined in module configuration.
namespace Pyz\Zed\CmsSlotBlock;
use Spryker\Zed\CmsSlotBlock\CmsSlotBlockConfig as SprykerCmsSlotBlockConfig;
class CmsSlotBlockConfig extends SprykerCmsSlotBlockConfig
{
/**
* @return string[][]
*/
public function getTemplateConditionsAssignment(): array
{
return [
'@CatalogPage/views/catalog-with-cms-slot/catalog-with-cms-slot.twig' => [
'category',
],
'@ProductDetailPage/views/pdp/pdp.twig' => [
'productCategory',
],
'@Cms/templates/placeholders-title-content-slot/placeholders-title-content-slot.twig' => [
'cms_page',
],
];
}
}
As shown in the preceding example, the visibility condition configuration is an array, so you can have a combination of visibility conditions in a template. For example, the product details page template can have productCategory
and customer
visibility conditions. It means that the CMS block for which these conditions are defined is only displayed when both of the defined conditions are fulfilled. In particular, the CMS block is displayed in the following cases:
- On the product details pages belonging to a defined categories and products.
- When the user login status is equal to the defined login status.
- When user account details are equal to the defined account details.
Visibility condition for a template
To show the procedure, the following steps walk you through the creation of the customer
visibility condition for the product details page template:
- Assign the new condition to the template in
src/Pyz/Zed/CmsSlotBlock/CmsSlotBlockConfig.php
:
/**
* @return string[][]
*/
public function getTemplateConditionsAssignment(): array
{
return [
'@ProductDetailPage/views/pdp/pdp.twig' => [
'productCategory',
'customer'
],
];
}
- From the properties available on the product details page, choose the properties to pass to the slot widget. For example, property values related to user account details (like
age
orcity
) can be fetched from the session. A slot widget withidProductAbstract
,isGuest
,age
, andcity
properties looks as follows:
{% cms_slot 'slt-key' required ['idProductAbstract'] with {
idProductAbstract: data.product.idProductAbstract,
isGuest: customer is null, {# user logged in or session is empty #}
age: cutomer ?? customer.age,
city: cutomer ?? customer.location.city,
} %}
-
Insert it into the product details page template—
@ProductDetailPage/views/pdp/pdp.twig
. -
Define new properties for
CmsSlotBlockConditionTransfer
andCmsSlotParamsTransfer
insrc/Pyz/Shared/CmsSlotBlockCustomer/Transfer/cms_slot_block_customer.transfer.xml
:
<transfer name="CmsSlotParams">
<property name="isGuest" type="bool"/>
<property name="age" type="int"/>
<property name="city" type="string"/>
</transfer>
<transfer name="CmsSlotBlockCondition">
<property name="isGuest" type="bool"/>
<property name="fromAge" type="int"/>
<property name="toAge" type="int"/>
<property name="city" type="string"/>
</transfer>
Visibility condition form plugin for the Back Office
- Implement the following plugin for the Back Office using
\Spryker\Zed\CmsSlotBlockGuiExtension\Communication\Plugin\CmsSlotBlockGuiConditionFormPluginInterface
:
CustomerSlotBlockConditionFormPlugin
namespace Pyz\Zed\CmsSlotBlockCustomerGui\Communication\Plugin\CmsSlotBlockGui;
use Generated\Shared\Transfer\CmsSlotTemplateConfigurationTransfer;
use Spryker\Zed\CmsSlotBlockGuiExtension\Communication\Plugin\CmsSlotBlockGuiConditionFormPluginInterface;
use Spryker\Zed\Kernel\Communication\AbstractPlugin;
use Symfony\Component\Form\FormBuilderInterface;
/**
* @method \Spryker\Zed\CmsSlotBlockCmsGui\Communication\CmsSlotBlockCmsGuiCommunicationFactory getFactory()
* @method \Spryker\Zed\CmsSlotBlockCmsGui\CmsSlotBlockCmsGuiConfig getConfig()
*/
class CustomerSlotBlockConditionFormPlugin extends AbstractPlugin implements CmsSlotBlockGuiConditionFormPluginInterface
{
/**
* @param \Generated\Shared\Transfer\CmsSlotTemplateConfigurationTransfer $cmsSlotTemplateConfigurationTransfer
*
* @return bool
*/
public function isApplicable(CmsSlotTemplateConfigurationTransfer $cmsSlotTemplateConfigurationTransfer): bool
{
return in_array('customer', $cmsSlotTemplateConfigurationTransfer->getConditions(), true);
}
/**
*
* @param \Symfony\Component\Form\FormBuilderInterface $builder
*
* @return void
*/
public function addConditionForm(FormBuilderInterface $builder): void
{
$customerSlotBlockConditionForm = $this->getFactory()->createCustomerConditionForm();
$customerSlotBlockFormDataProvider = $this->getFactory()->createCustomerConditionFormDataProvider();
$customerSlotBlockConditionForm->buildForm($builder, $customerSlotBlockFormDataProvider->getOptions());
}
}
-
Put
CustomerSlotBlockConditionFormPlugin
into thesrc/Pyz/Zed/CmsSlotBlockCustomerGui
module. -
Create
CustomerSlotBlockConditionForm
. It is a regular Symfony Form class that implements\Symfony\Component\Form\FormBuilderInterface
. For details, see the following:- Forms for more information about Symfony forms.
- Creating Forms to learn about form creation procedure in Spryker.
- A form example in
\Spryker\Zed\CmsSlotBlockProductCategoryGui\Communication\Form\ProductCategorySlotBlockConditionForm
.
The name of the first form element must correspond to the condition name you create. In this case, it looks like $builder->add('customer', FormType::class)
.
Child form elements can have any names and subsequent child form elements.
In this case, the created form has five elements:
customer
parent form with four children:isGuest
radio button.fromAge
numeric input field.toAge
numeric input field.city
dropdown with the city list fetched from database.
/**
* @param \Symfony\Component\Form\FormBuilderInterface $builder
* @param array $options
*
* @return void
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('customer', FormType::class, [
'label' => false,
'error_mapping' => [
'.' => static::FIELD_ALL,
]
]);
$builder->get('customer')->add('isGuest', ChoiceType::class, [
'choices' => ['For logged-in Users' => false, 'For Guests' => true],
'multiple' => false,
]);
$builder->get('customer')->add('fromAge', IntegerType::class);
$builder->get('customer')->add('toAge', IntegerType::class);
$builder->get('customer')->add('city', Select2ComboBoxType::class, [
'choices' => $options['city_list'], // from CustomerSlotBlockFormDataProvider
]);
}
- Add the new plugin to the
\Pyz\Zed\CmsSlotBlockGui\CmsSlotBlockGuiDependencyProvider::getCmsSlotBlockFormPlugins()
plugin list inCustomerSlotBlockConditionFormPlugin
.
-
In the Back Office, go to Content Management > Slots.
-
For List of Templates, select a product details page template.
-
In the List of Slots for
{name}
Template, Select a slot . -
Add or choose one CMS block in the List of Blocks for the
{name}
slot.You must be able to see a rendered form of the customer visibility condition.
-
Select any visibility conditions and take note of them.
-
Click Save.
-
In the database, check the last added rows in the
spy_cms_slot_block.conditions
andspy_cms_slot_block_storage.data
columns.
spy_cms_slot_block.conditions
and spy_cms_slot_block_storage.data
must contain the customer condition data that you have set in the Back Office.
Visibility condition resolver plugin for a slot widget
- Implement the following plugin using
\Spryker\Client\CmsSlotBlockExtension\Dependency\Plugin\CmsSlotBlockVisibilityResolverPluginInterface
:
CustomerSlotBlockConditionResolverPlugin
namespace Pyz\Client\CmsSlotBlockCustomer\Plugin\CmsSlotBlock;
use Generated\Shared\Transfer\CmsSlotBlockTransfer;
use Generated\Shared\Transfer\CmsSlotParamsTransfer;
use Spryker\Client\CmsSlotBlockExtension\Dependency\Plugin\CmsSlotBlockVisibilityResolverPluginInterface;
use Spryker\Client\Kernel\AbstractPlugin;
class CustomerSlotBlockConditionResolverPlugin extends AbstractPlugin implements CmsSlotBlockVisibilityResolverPluginInterface
{
/**
* @param \Generated\Shared\Transfer\CmsSlotBlockTransfer $cmsSlotBlockTransfer
*
* @return bool
*/
public function isApplicable(CmsSlotBlockTransfer $cmsSlotBlockTransfer): bool
{
return $cmsSlotBlockTransfer->getConditions()
->offsetExists('customer');
}
/**
* @param \Generated\Shared\Transfer\CmsSlotBlockTransfer $cmsSlotBlockTransfer
* @param \Generated\Shared\Transfer\CmsSlotParamsTransfer $cmsSlotParamsTransfer
*
* @return bool
*/
public function isCmsBlockVisibleInSlot(
CmsSlotBlockTransfer $cmsSlotBlockTransfer,
CmsSlotParamsTransfer $cmsSlotParamsTransfer
): bool {
/** @var \Generated\Shared\Transfer\CmsSlotBlockConditionTransfer $cmsSlotBlockConditionTransfer */
$cmsSlotBlockConditionTransfer = $cmsSlotBlockTransfer->getConditions()
->offsetGet('customer');
if ($cmsSlotBlockConditionTransfer->getIsGuest() && $cmsSlotParamsTransfer->getIsGuest()) {
return true;
}
$isBlockVisible = false;
if ($cmsSlotParamsTransfer->getAge()) {
$age = $cmsSlotParamsTransfer->getAge();
if ($cmsSlotBlockConditionTransfer->getFromAge() && $age < $cmsSlotBlockConditionTransfer->getFromAge()) {
return false;
}
if ($cmsSlotBlockConditionTransfer->getToAge() && $age > $cmsSlotBlockConditionTransfer->getToAge()) {
return false;
}
$isBlockVisible = true;
}
if ($cmsSlotParamsTransfer->getCity()) {
if (
$cmsSlotBlockConditionTransfer->getCity()
&& $cmsSlotParamsTransfer->getCity() !== $cmsSlotBlockConditionTransfer->getCity()
) {
return false;
}
}
return $isBlockVisible;
}
}
-
Insert it into the
src/Pyz/Client/CmsSlotBlockCustomer
module. -
Enable
CustomerSlotBlockConditionResolverPlugin
in\Pyz\Client\CmsSlotBlock\CmsSlotBlockDependencyProvider::getCmsSlotBlockVisibilityResolverPlugins()
.
On the Storefront, open the product details page that contains the CMS block for which you have selected the visibility conditions.
- Make sure that you fulfill the visibility conditions and see the CMS block content.
- Make sure that you do not fulfill the visibility conditions and do not see the CMS block content.
For example, you can select and check the content against the following visibility conditions:
- Login status
- Location
- Age
Thank you!
For submitting the form