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.
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.
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>