Question

Is it possible to create blocks as part of a theme, and have those blocks visible without actually having to create the block manually in the admin panel? I want to ship a theme with the blocks automatically created.

For my client they would simply select their page and select what blocks they want on the page. All of the blocks in this instance are static HTML blocks.

I would also like to note a development issue. If the above problem can be solved it would also work for my development issue ...

Writing code for blocks is done in my text editor and I copy and paste the code over into the block while developing. Often times I forget to copy over the code and waste time wondering why I'm seeing no changes.

To be able to write blocks in my text editor and have them appear on pages without having to copy and paste.

Any idea how I can do this?

Was it helpful?

Solution

Yes you can do this, but it will require that you have a companion theme module bundled with your theme since you can only create static blocks via a module:

Theme:

  • Component Name: frontend/BugHunter/bughunter
  • Composer Slug: bug-hunter/theme-bug-hunter
  • Composer Dependency On: bug-hunter/module-theme-bug-hunter
    • If this was composer installed, it would ensure you're module gets installed with your theme
    • Another option via composer would be to have a meta package with requirements of both the theme and module

Module:

  • Name: BugHunter_ThemeBugHunter
  • Composer Slug: bug-hunger/module-theme-bug-hunter

Data patch

  • You could group the creation of all the static blocks into one data patch
  • Alternatively, it might be more natural to create a data patch per static block as you are developing/updating the theme.
  • Once a data patch runs once, a record of it being applied gets stored in the patch_list db table so that it will not be run again on subsequent setup:upgrades
  • The code below assumes it's a new block and that the block is applied to all stores

app/code: app/code/BugHunter/ThemeBugHunter/Setup/Patch/Data/CreateBlocks.php composer: vendor/bug-hunter/module-theme-bug-hunter/Setup/Patch/Data/CreateBlocks.php

<?php

namespace BugHunter\ThemeBugHunter\Setup\Patch\Data;

use Magento\Cms\Api\BlockRepositoryInterface;
use Magento\Cms\Api\Data\BlockInterface;
use Magento\Cms\Api\Data\BlockInterfaceFactory;
use Magento\Cms\Model\Block;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class CreateBlocks implements DataPatchInterface
{
    /**
     * @var ModuleDataSetupInterface
     */
    protected $moduleDataSetup;

    /**
     * @var BlockInterfaceFactory
     */
    protected $blockFactory;

    /**
     * @var BlockRepositoryInterface
     */
    protected $blockRepository;

    /**
     * CreateBlocks constructor.
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param BlockInterfaceFactory $blockFactory
     * @param BlockRepositoryInterface $blockRepository
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        BlockInterfaceFactory $blockFactory,
        BlockRepositoryInterface $blockRepository
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->blockFactory = $blockFactory;
        $this->blockRepository = $blockRepository;
    }

    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        $this->moduleDataSetup->startSetup();

        /** @var BlockInterface $newBlock */
        $newBlock = $this->blockFactory->create();
        $newBlock
            ->setTitle('Block Name')
            ->setIdentifier('unique_blog_identifier')
            ->setIsActive(Block::STATUS_ENABLED)
            ->setContent('<div class="something">content</div>')
            ->setStoreId([0]);

        try {
            $this->blockRepository->save($newBlock);
        } catch (\Exception $e) {
            throw $e;
        }

        $this->moduleDataSetup->endSetup();
    }

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

    /**
     * {@inheritdoc}
     */
    public function getAliases()
    {
        return [];
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top