·

photo credit: Bricks via photopin (license)

Creating Blocks in Magento 2

Just like Magento 1, Magento 2 has blocks. For those who don’t know what Magento blocks are: they are classes that template (parts) can use to gain some specific functionality. Blocks are used throughout Magento and are a core part of it’s design and will most likely also be a part of your customisations.
So let’s just see how we can create and use these blocks to their fullest.


Please note that we use the boilerplate module from the article ‘Creating a module in Magento 2‘ as the entry point for this article.

Let’s talk a bit about Magento 2’s layout first

Before we get started with blocks, you need to be familiair with Magento 2’s layout mechanism. This will be discussed more thoroughly in an article later on, but for now there are some core principles you need to know:

  • Magento 2’s layout is determined by each individual module (look in the view/frontend/layout -folder of any given module for example).
  • In contrast with Magento 1, each Magento 2’s ‘page type’ is determined by it’s own layout XML-file. For example, layout updates that apply to all pages are set in default.xml , but layout updates that are only applied on product detail pages are set in catalog_product_view.xml .

Knowing these 2 rules, create a file called default.xml  in the folder view/frontend/layout  of your module and add the following content:

This will be the entry point for our layout updates.

Utilising existing blocks

As I said, Magento already has a whole bunch of blocks that you can already use out of the box. Take a look at any Magento module and look inside it’s Block -folder, and you’ll see the blocks that you can use. For example, if you want to render a static block with the identifier ‘example’ in the footer, we can add the following line inside our <body> -tag in our layout file:

Let me explain what happens here:

  • We reference the container called ‘footer’.
  • In this container we create a new block of the class Magento\Cms\Block\Block .
  • In this block, we pass a parameter called ‘block_id’, and we give it the value ‘example’ (If you want to know how this parameter is used in the block, I’d suggest that you take a look at the _toHtml() -method inside the class).

If you now flush your cache and reload your page, you’ll notice that we now have successfully added the static block to our footer. This method is great if you want to give your customer the possibility to be able to edit some chunks of text here and there.
But let’s take it one step further …

Writing your own block classes in Magento 2

Let’s create a block that – let’s say – shows us the current date. This can be done easily by creating a file called Date.php  inside the Block -folder of your module:

Now in our layout XML file, we can add the following block inside our <body> -tag:

Note that we don’t really need to re-declare our reference to the footer again, you could also add the block to the same container as our previous example.
Clear the cache and reload the page. Voila: we’ve inserted some text in our page. Note that we don’t have any HTML output, it’s just the raw output as declared in our _toHtml() -method.

What about template files?

Good question. Simple answer.
You’ve probably already seen a lot of .phtml -files throughout the codebase of Magento 2. Wouldn’t it be nice if we could just write those template files, but use the methods of our own blocks? Luckily for us, this is really simple.
Simply make your PHP class extend the class Magento\Framework\View\Element\Template  and declare your methods in the class (so don’t overwrite the _toHtml() -method):

And in your layout XML file, add a template attribute:

Create a file called example.phtml  inside view/frontend/templates :

Note that we call a variable called $block  inside our template. Whereas in Magento 1 we needed to use $this  to reference our block class, in Magento 2 it’s the $block -variable that references it. For completion: in Magento 2, $this  references to the template engines’ class, which is Magento\Framework\View\TemplateEngine\Php  by default.

All this trouble for such a simple method. Why not write PHP inside the template itself?

This is a fair question and I will discuss this one in more detail in a later article, but the main reason is to keep your code and your template separated. It’s true that .phtml -files are fully valid PHP-files and you could do stuff like access the file system or execute complete database queries in it. But this is very very bad practice (although I’ve seen plenty of third party modules do this and even Magento itself does this from time to time). When it comes to writing templates, always keep in mind that even a junior developer with very little PHP / HTML skills must be able to write templates. That means:

  • Only use very basic PHP functions (if/else, case, echo, etc.)
  • Let more complex task be done by blocks (this way you keep design and logic separated).

Like I said, more on this will be discussed later on, but it’s important to know this so you can better understand the position and the role of blocks in Magento.

This post is part of the series Magento 2 Development from Scratch.

Visitors give this article an average rating of 4.4 out of 5.

How would you rate this article?

4 thoughts on “Creating Blocks in Magento 2”

  1. Thank you very much!!!
    I have spent around 5 hours with trying to set my custom block to HEAD section with this way:

    but it only your solution helped me!!!!

  2. ayodio says:

    I can’t get the template part to work. I think it’s because of my _toHtml function what are we suppose to put in it ?

    1. Shavais says:

      Make sure your php class in your .php file extends Template rather then AbstractBlock, and make sure it doesn’t have any _toHtml function at all. (The system will use the _toHtml function of the Template class that you’re extending.)

  3. My block files must be in app/code/Vendor/Module/ … or it can be in app/design/Vendor/Theme/Module_Name/ … ?

Leave a Reply