I added a second footer block with links by adding the following code to my default.xml in my theme:
(app/design/frontend///Magento_Theme/layout/default.xml)
<referenceContainer name="footer">
<block class="Magento\Framework\View\Element\Html\Links" name="footer_links_custom">
<arguments>
<argument name="css_class" xsi:type="string">footer links</argument>
</arguments>
</block>
</referenceContainer>
<referenceBlock name="footer_links_custom">
<block class="Magento\Framework\View\Element\Html\Link\Current" name="2custom-link">
<arguments>
<argument name="label" xsi:type="string">Custom Links</argument>
<argument name="path" xsi:type="string">page-url</argument>
</arguments>
</block>
</referenceBlock>
What is the easiest way to add a title to the my footer_links_custom block, is there any way to do this in a simple manner? I've tried setting an argument "title" but that didn't work obviously. Is there any way we can know all the attributes there are for a certain block? (css_class, label, path, ...)
Is there no .phtml file for the footer links block?
Magento 2 leaves me behind with a lot of questions...
Thanks for the help!
In /magento/app/design/frontend/theme/theme/Magento_Theme/ You can set up the structure needed for this. and documentation to help can be found at:
http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/bk-frontend-dev-guide.html
In Magento_Theme/layout/default.xml you will find your block declarations, such as what you listed above already.
In Magento_Theme/Block/Html/Footer.php you can set up your controller with your Mage interface, such as...
class Footer extends \Magento\Framework\View\Element\Template implements \Magento\Framework\DataObject\IdentityInterface
{
protected $_copyright;
....
public function getCopyright()
{
if (!$this->_copyright) {
$this->_copyright = $this->_scopeConfig->getValue(
'design/footer/copyright',
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}
return $this->_copyright;
}
...
Magento_Theme/templates/html is where you can put your .phtml that your used to working with in Magento 1. Its not the exact same code obviously, but the idea is still the same here. for example, here is a footer that isn't code but stored in a db:
$om = \Magento\Framework\App\ObjectManager::getInstance();
$manager = $om->get('Magento\Store\Model\StoreManagerInterface');
$store = $manager->getStore(null)->getName();
$connection = $om->create('\Magento\Framework\App\ResourceConnection');
$conn = $connection->getConnection();
$select = $conn->select()
->from(
['o' => 'xyz_sitedata_items'],
['footer']
)
->where('o.storename=?', $store);
$data = $conn->fetchAll($select);
echo $data[0]['footer'];
for the record, using the object manager like this isn't recommended.
for a specific answer to the question posed, i would look to adding code to your footer.php. you can add data in with the construct, as well as reading all the data for the associated block there.
Related
I want to use a block in order to get some data in a template, but it's not working.
Here is my block
class Question extends \Magento\Framework\View\Element\AbstractBlock
{
protected $customerSession;
public function __construct(
Template\Context $context,
\Magento\Customer\Model\Session $customerSession
)
{
$this->customerSession = $customerSession;
parent::__construct($context);
}
public function test()
{
return "OK";
//return $this->customerSession->getCustomer()->getId();
}
}
And this is my catalog_product_view.xml
<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.details">
<block class="Magento\Catalog\Block\Product\View" name="question.tab" as="question" template="Semaine2_TP::product/delivery_info.phtml" group="detailed_info" >
<arguments>
<argument translate="true" name="title" xsi:type="string">Questions</argument>
</arguments>
<block name="question" class="Semaine2\TP\Block\Question" cacheable="false" template="Semaine2_TP::question/info.phtml" group="detailed_info"/>
</block>
</referenceBlock>
</body>
</page>
But with this, only the delivery_info.phtml is printed, and the info.phtml seems to be ignored.
Actually what I would like to be able to do is to use my test function from the block inside my delivery_info.phtml in order to get an action target URL for example or to get the customer if he is logged in.
But when I call $block in my phtml he always seems to search into the Magento\Catalog\Block\Product\View which is normal I guess.
New to magento 2 and no idea how to deal with this. Thanks for your assistance.
The right way is to use Magento View Models instead of Block classes to separate business logic
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/view-models.html
catalog_product_view.xml:
<referenceBlock name="product.info.details">
<block name="question.tab" as="question" template="Semaine2_TP::product/delivery_info.phtml" group="detailed_info" >
<arguments>
<argument translate="true" name="title" xsi:type="string">Questions</argument>
</arguments>
<block name="question" cacheable="false" template="Semaine2_TP::question/info.phtml" group="detailed_info">
<arguments>
<argument name="view_model" xsi:type="object">Semaine2\TP\ViewModel\Question</argument>
</arguments>
</block>
</block>
</referenceBlock>
app/code/Semaine2/TP/ViewModel/Question.php:
<?php
namespace Semaine2\TP\ViewModel;
use Magento\Framework\Registry;
use Magento\Catalog\Model\Product;
use Magento\Framework\View\Element\Block\ArgumentInterface;
/**
* Class Question.
*/
class Question implements ArgumentInterface
{
/**
* #var Registry
*/
private $registry;
/**
* #var Product
*/
private $product;
/**
* #param Registry $registry
*/
public function __construct(
Registry $registry
) {
$this->registry = $registry;
}
/**
* Get current product.
*
* #return Product
*/
public function getProduct(): Product
{
if ($this->product === null) {
$this->product = $this->registry->registry('current_product');
}
return $this->product;
}
}
Are you calling $block->getChildHtml() in your delivery_info.phtml file?
Since you have a custom block and template, I think you need to explicitly call a toHtml for your block. You can also pass in your custom block name to the function, if not I believe all child block HTMLs will be printed.
I was extending the wrong Block.
The block need to extends use Magento\Catalog\Block\Product\View;
Sadly this magento native block is using deprecated arguments, but I think we can't escape from this if we want to be able to call the construct.
I have two custom magento blocks called "exe2" and "example".
The exe2 block gets the contents of the example block using the getChildHtml function, but it keeps just returning empty strings to me and only the exe2 contents make it to the screen.
Here is my code my code:
exe2 xml file:
<layout version = "0.1.0">
<test_example_view>
<block type = "exemplum_mod2/exe2" name = "exemplum.mod2.exe2" template="exemplum/mod2/exe2.phtml">
<reference name = "exemplum.mod2.exe2">
<block type="exemplum/example" name="exemplum.example" template="exemplum/example1/example.phtml" />
</reference>
</block>
</test_example_view>
example xml file
<layout version="0.1.0">
<default>
<block type="exemplum/example" name="exemplum.example" template="exemplum/example1/example.phtml" />
</default>
Here is the exe2 phtml file that has the getChildHtml call in it:
<h1> 2nd </h1>
<?php
echo $this->getMessage();
echo $this->getChildHtml("exemplum.mod2.exe2");
?>
hello
example.phtml file:
<h1>Hello there</h1>
And finally heres the controller file that loads the blocks:
<?php
class exemplum_example1_ExampleController extends Mage_Core_Controller_Front_Action{
public function viewAction(){
$this->loadLayout();
$block = $this->getLayout()->createBlock('exemplum_mod2/exe2');
$block->setTemplate("exemplum/mod2/exe2.phtml");
$this->getLayout()->getBlock('content')->append($block);
$this->renderLayout();
}
}
What is the correct way to add one block as the child block of a another block in the xml file? Every solution that i found on google didn't seem to work in my case so what am i doing wrong here?
struggling getting access to an admin block ive created.
Ive created a module...it has many elements, all working. Ive got header includes added to certain admin pages no problem, using my adminhtml layout update xml file.
The issue seems to be it cant access/see my block...so muct be referencing wrong, even though ive been following the 'module creator' extension files.
Another silly issue i think, been at this too long! :)
First the code:
Mworkz/MyModuleName/Block/Adminhtml/MyBlock.php
class Mworkz_MyModuleName_Block_Adminhtml_MyModuleName extends Mage_Adminhtml_Block_Widget_Grid_Container
{
public function __construct()
{
var_dump('WE ARE IN THE ADMIN BLOCK!');exit;
$this->_controller = 'adminhtml_mymodulename';
$this->_blockGroup = 'mymodulename';
$this->_headerText = Mage::helper('mymodulename')->__('Item Manager');
$this->_addButtonLabel = Mage::helper('mymodulename')->__('Add Item');
parent::__construct();
}
}
My layout xml (this file works, and is referenced right, as my admin header includes work)
Should point out i have a custom tab and controller...all working.
<?xml version="1.0"?>
<layout version="0.1.0">
<mymodulename_adminhtml_mymodulename_index>
<reference name="head">
<action method="addJs"><script>Mworkz/MyModuleName.js</script></action>
</reference>
<reference name="content">
<block type="mymodulename/adminhtml_mymodulename" name="mymodulename" ></block>
</reference>
</mymodulename_adminhtml_mymodulename_index>
</layout>
I expect to see the var_dump stmt ive inserted....but it doesnt display.
Thanks in advance...
file naming! Simple caps issue...
My block file was called '...Adminhtml/MyModuleName.php',
My block identifier inside the file was '...Adminhtml_Mymodulename {'
Another set of working code snippets for adminhtml block users i suppose!
Thanks
I am creating a module that will have its own page at mysite.com/memymodule/index/index
I want to add functionality from a template file from at templates/me/template.phtml
I have an index controller like this:
<?php
class me_mymodule_IndexController extends Mage_Core_Controller_Front_Action {
public function indexAction() {
$this->loadLayout();
$this->renderLayout();
}
}
?>
I have a layout update mymodule.xml that looks like this:
<?xml version="1.0"?>
<layout version="0.1.0">
<mymodule_index_index>
<reference name="content">
<block type="core/template" name="me.mymodule" template="me/template.phtml" />
</reference>
</mymodule_index_index>
</layout>
The frontName of the module is mymodule
When the page renders the content block is completely empty and the content of template.phtml is completely ignored.
Help much appreciated :-)
Try this Code within your Controller's Action -
var_dump(Mage::getSingleton('core/layout')->getUpdate()->getHandles());
exit("Your Layout Path is ".__LINE__." in ".__FILE__);
This code tells you about the Tag which you need to create within Layout.xml.
Also check Config.xml that the Layout Update Section is correctly defined or not.
Hope it'll be beneficial for you.
THANKS
I would like to create a link on the My Account page that only get displays under certain conditions.
Right now I have the link display all the time by adding the following entry to my layout XML file:
<customer_account>
<reference name="customer_account_navigation">
<action method="addLink" translate="label" module="nie"><name>nie</name><path>nie</path><label>NIE Admin</label></action>
</reference>
</customer_account>
I am assuming there is a way to code this so that it only displays under certain circumstances.
The cart & checkout links already do something similar so their method can be copied.
Create a block. It won't be displaying directly so can be descended from the boring Mage_Core_Block_Abstract.
Give it a method where the conditional logic will go.
public function addNieLink()
{
if (($parentBlock = $this->getParentBlock()) && (CONDITION-GOES-HERE)) {
$parentBlock->addLink($this->_('NIE Admin'), 'nie', $this->_('NIE Admin'), true, array(), 50, null, 'class="top-link-cart"');
// see Mage_Page_Block_Template_Links::addLink()
}
}
protected function _prepareLayout()
{
// Add the special link automatically
$this->addNieLink();
return parent::_prepareLayout();
}
Put your check in place of CONDITION-GOES-HERE.
Add your block to the links block.
<customer_account>
<reference name="customer_account_navigation">
<block type="yourmodule/link" name="yourmodule.link" />
</reference>
</customer_account>
(Correct the block type here to your newly created link block)
The important bit is it calls getParentBlock() to find out where the link is to go.