Search code examples
magento2getterpublic-method

in magento 2 which block methods are available in a template?


m2 is much different than m1.

When I'm writing code (programming public methods) in the template they don't seem to be working. Are all methods allowed like protected and private as well? or getters or only public getters? I'm confused.

I believe it's only public getters right?

Any help would be greatly appreciated.


Solution

  • All public methods from the block context are available in the template.

    Block context is the block class you've assigned to the template in layout XML. It's equivalent to block type in Magento 1. By default it is \Magento\Framework\View\Element\Template, which is equivalent to Mage_Core_Block_Template in Magento 1.

    This block context is assigned to the template as the $block variable during rendering. This is different from Magento 1, where $this refers to the block context in the template. In Magento 2, $this refers to the template engine responsible for rendering the template. You can see this all play out in the render method of the template engine, where the $dictionary parameter (containing $block among others) is extracted just before including the phtml file. This allows all extracted variables, notably $block, to be used in the template.

    Example block usage

    Say you've created a custom block class in your module as app/code/MyNamespace/MyModule/Block/MyBlock.php like this.

    <?php 
    
    namespace MyNamespace\MyModule\Block;
    
    use Magento\Framework\View\Element\Template;
    
    class MyBlock extends Template
    {
        public const FOO = 'foo';
        private const BAR = 'bar';
    
        public function isFoo(string $str): bool 
        {
            return $str === self::FOO;
        }
    
        private function isBar(string $str): bool
        {
            return $str === self::BAR;
        }
    }
    

    You'd include this block to, let's say every product page by creating a file in app/code/MyNamespace/MyModule/view/frontend/layout/catalog_product_view.xml like this.

    <?xml version="1.0"?>
    
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceContainer name="content">
                <block class="MyNamespace\MyModule\Block\MyBlock" name="myblock" template="MyNamespace_MyModule::mytemplate.phtml" />
            </referenceContainer>
        </body>
    </page>
    

    This will add MyBlock to the content-container on every product page. Containers will auto-render their child blocks, so they are similar to the core/text_list block type in Magento 1.

    Then in the template configured in the layout XML, app/code/MyNamespace/MyModule/view/frontend/templates/mytemplate.phtml, you can use public methods and properties, including isFoo, but not private or protected ones like isBar. Doc-comments in the beginning of the template file make it clear what $this and $block are.

    <?php
    /** @var $this \Magento\Framework\View\TemplateEngine\Php */
    /** @var $block \MyNamespace\MyModule\Block\MyBlock */
    $thing1 = 'foo';
    $thing2 = 'bar';
    ?>
    <div class="my-thing">
        <?php if ($block->isFoo($thing1)): ?>
            <!-- isFoo works since it's a public method -->
        <?php endif; ?>
        <?php if ($block->isBar($thing2)): ?>
            <!-- isBar doesn't work since it's a private method -->
        <?php endif; ?>
        
        <!-- You can access public properties and constants from the $block object, too -->
        <span><?php echo $block::FOO; ?></span>
    </div>