Create CMS block in Magento 2 using data patch

In this tutorial we will show how simple it is to use data patches to create and update content on your Magento 2 store.

Using data patches is preferable for pipeline/version control teams because this way we can ensure that data will be updated on all environments. In addition data patches allow the possibility to revert the update by defining a function on what should happen once the module is uninstalled.

You can refer to the official documentation for a more complete explanation of all features. Generally data patches are used to either create or update data. This means that for database schema adjustments you would be better off going with schema patches. Important to note that patches will be applied only once. The database table patch_list contains a list of applied patches. The patch is applied during setup upgrade process when running in CLI.

TIP - You will sometimes need to either debug or run a patch multiple times. You can simply remove the entry from the patch_list table and run setup:upgrade.

Ok, lets get started. First thing we need is to create a module. I assume you are familiar with that. In our case the module is called Techflarestudio_Content. Next we need to define the Patch class. The class should be located in Setup/Patch/Data. We will name our block UpdateBlockData however you could name the class any way you want - just make sure the class name matches the file name.

Since we will need to create a new CMS block we will also include a block factory class and inject it in our class using dependency injection. We will define our block identifier and create the block using a fairly simple model creation strategy. Below is the code I am talking about:

<?php
/*
 *  @category  	Techflarestudio
 *  @author	Wasalu Duckworth
 *  @copyright Copyright (c) 2021 Techflarestudio, Ltd. 			(https://techflarestudio.com)
 *  @license http://opensource.org/licenses/OSL-3.0 The Open Software License 3.0 (OSL-3.0)
 */

namespace Techflarestudio\Content\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use \Magento\Cms\Model\BlockFactory;


/**
 * Class UpdateBlockData
 * @package Techflarestudio\Content\Setup\Patch\Data
 */
class UpdateBlockData
    implements DataPatchInterface,
    PatchRevertableInterface
{
    const BLOCK_IDENTIFIER = 'techflarestudio-header-notice';
    /**
     * @var BlockFactory
     */
    protected $blockFactory;

    /**
     * UpdateBlockData constructor.
     * @param BlockFactory $blockFactory
     */
    public function __construct(
        BlockFactory $blockFactory
    ) {
        $this->blockFactory = $blockFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        $headerNoticeData = [
            'title' => 'Header Notice',
            'identifier' => self::BLOCK_IDENTIFIER,
            'content' => '<div>Techflarestudio rules!</div>',
            'stores' => [0],
            'is_active' => 1,
        ];
        $headerNoticeBlock = $this->blockFactory
            ->create()
            ->load($headerNoticeData['identifier'], 'identifier');

        /**
         * Create the block if it does not exists, otherwise update the content
         */
        if (!$headerNoticeBlock->getId()) {
            $headerNoticeBlock->setData($headerNoticeData)->save();
        } else {
            $headerNoticeBlock->setContent($headerNoticeData['content'])->save();
        }
    }

    /**
     * {@inheritdoc}
     */
    public static function getDependencies()
    {
        /**
         * No dependencies for this
         */
        return [];
    }

    /**
     * Delete the block
     */
    public function revert()
    {
        $headerNoticeBlock = $this->blockFactory
            ->create()
            ->load(self::BLOCK_IDENTIFIER, 'identifier');

        if($headerNoticeBlock->getId()) {
            $headerNoticeBlock->delete();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getAliases()
    {
        /**
         * Aliases are useful if we change the name of the patch until then we do not need any
         */
        return [];
    }
}
Techflarestudio/Content/Setup/Patch/Data/UpdateBlockData.php

Inspecting the code we can see that the function apply takes care of the creation/updating of the content. The function will execute once when running setup:upgrade. The revert function will execute when uninstalling the module. You can do this by executing the following:

bin/magento module:uninstall Techflarestudio_Content

The uninstall command does not delete the module - it only reverts the data patches that have been previously installed. Keep in mind that after uninstalling the patch the entry is removed from the patch_list table which means that if the module is not removed the patch will apply again on next upgrade.

Assuming you have followed the instructions and created the above patch you can now run the setup:upgrade command and you should see the block in CMS->Blocks.

Extra tip - how to quickly add this block to header.

You may want to quickly add a CMS block somewhere in layout without doing any coding.

  • Go to Content->Widgets
  • Select CMS Static Block and your current design theme.
  • In Widget options choose the newly created CMS block.
  • Set the layout updates - for example All Pages and choose the container in which you would like to display this
Techflarestudio rules!

Notice the Techflarestudio rules! Magento in built content management system is very powerful and this is a very basic example on how you can control the content with no coding.