How to Create a Template Block in Magento 2

Want to learn something new? Check out my most recent Egghead course:

Build a Twelve-Factor Node.js App with Docker - WATCH NOW on!

Cheers -Mark

Thu, 08/20/2015 - 12:31

Submitted by markoshust Thu, 08/20/2015 - 12:31

Note that this blog post was originally written by myself on Mage Inferno's blog, which no longer exists. Many old user comments have been lost, but this post won't be!

Hopefully you've already read Setting Up Your Magento 2 Module the Right Way with Composer & Packagist, so we can start creating our module. We won't use Composer or Packagist in this tutorial to save some time, as we are just writing code to test out functionality. Let's get right into things.

Create module skeleton

First, we'll create a our module skeleton:

mkdir -p app/code/Foo/Bar/etc

Next, we'll create the module definition file at app/code/Foo/Bar/etc/module.xml:

<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Foo_Bar" setup_version="0.0.0"/>

With Magento 2, modules are not automatically picked up until they are enabled by command line. So let's enable the module. The setup:upgrade line is needed right now because of a bug in Magento 2, but this should only be needed in the future if there are database installer scripts in your module.

./bin/magento module:enable Foo_Bar
./bin/magento setup:upgrade
Note that if you are running Magento through a Docker container, you should "bash" into the container first before executing shell commands:

docker exec -it CONTAINER_ID bash

And with that, we're off to the races, as enabling a module also flushes the cache for us.

Block class and Layout XML

Magento 2 is now aware of our module, so let's create our block class. We'll do this by extending the \Magento\Framework\View\Element\Template class, and create a custom getName function:

namespace Foo\Bar\Block;

* Baz block
class Baz
    extends \Magento\Framework\View\Element\Template
    public function getTitle()
        return "Foo Bar Baz";

Note the changes from Magento 1; specifically setting a custom namespace and the new format for extending a block template, along with the new class.

Now that we have programmed our block, we want to display it on the home page. The naming of the file is important as this is the new way of using layout handles. The cms_index_index.xml name will make our block only appear on the home page (module_controller_action.xml).

Create our folder location:

mkdir -p app/code/Foo/Bar/view/frontend/layout

Then create a layout XML file at app/code/Foo/Bar/view/frontend/layout/cms_index_index.xml containing:

<page xmlns:xsi="" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
        <referenceContainer name="main">
            <block class="Foo\Bar\Block\Baz" template="Foo_Bar::default/baz.phtml"/>

The referenceContainer element is referencing the layout container for our block. To read more about layout containers, please visit the official documentation on layouts. We also recommend reading thoroughly through the XML instructions for layouts to get a deeper understanding of the changes to the layout layer of Magento 2.

Explore the core base container and block layout definitions by checking out the layout and page_layout folders in app/code/Magento/Theme/view/frontend.

Template HTML and Caching

Next we'll create our folders for the template:

mkdir -p app/code/Foo/Bar/view/frontend/templates/default

Then the actual template HTML at app/code/Foo/Bar/view/frontend/templates/default/baz.phtml containing:

<h1><echo $block->getTitle() ></h1>

If you need to flush the cache for any reason (if the block isn't showing or was previously cached), you can do so with one of the following command lines depending on what cache you want to clear. Any changes to the layout XML will always require a cache flush with the layout param, while the new full page cache will need to be flushed on most PHP code changes.

./bin/magento cache:flush --all # Flush all cache types
./bin/magento cache:flush layout  # Flush Layout XML
./bin/magento cache:flush full_page  # Flush Full Page Cache


And with a cache flush, refresh your home page and you should see Foo Bar Baz shown at the top of the main content area!

We've created a GitHub repository with this sample module code, which will also be updated in the future with other code samples.


Thanks for sharing this awesome guide, I was creating a module in Magento 2. Your post is awesome that helped me a lot while fixing declaration and registration of module!

Add new comment