So I have been trying to learn Magento 2.3 and so far I have not gotten very far. I have successfully created a theme and replaced the logo. My theme is extending Magento/blank theme. I want to replace the HTML structure used for the header.links section. I have done some searching and so far have not been able to figure out what steps I need to do to override the default behavior of inserting the links inside of a ul tag.
inside of the Links class in the framework there is a method _toHtml() which has some hard coded HTML that it uses to create the header.links section/block. That code looks like:
protected function _toHtml() { if (false != $this->getTemplate()) { return parent::_toHtml(); } $html = ''; if ($this->getLinks()) { $html = '<ul' . ($this->hasCssClass() ? ' class="' . $this->escapeHtml( $this->getCssClass() ) . '"' : '') . '>'; foreach ($this->getLinks() as $link) { $html .= $this->renderLink($link); } $html .= '</ul>'; } return $html; }
Notice the <ul and closing </ul> tags? I don't want them. I want to use a bootstrap 4 dropdown which has a structure of:
<div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown button </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </div>
Notice no UL or li.
So my question is how do I override this method? I have read in posts that since this is a protected method it cannot be overridden. I find that very disturbing because this method is forcing me to use HTML that I do not want. Shouldn't the HTML come from a template and not a class method?
Thanks for your help,
Bruce
Solved! Go to Solution.
you can try using plugin
<type name="Magento\Framework\View\Element\Html"> <plugin name="some-unique-name-here" type="Your\Class\Name\Here" sortOrder="1" /> </type>
then,
<?php namespace Your\Class\Name; class Here { //'after' is reserved word. //`ToHtml` is the name of the method your want to intercept, capitalized //in this case you want to intercept the toHtml method of a certain block //the first parameter is always the name of the class you intercept with the reserved word `Inteceptor` at the end. This will give you access at the class instance //the second parameter is what the original toHtml method returns. This is the html you want public function afterToHtml( \NameOfClass\You\Intercept\Here\Interceptor $original, $html ) { //do something with $html //make sure you return a value of the same type as the original method return $html; } }
you can try using plugin
<type name="Magento\Framework\View\Element\Html"> <plugin name="some-unique-name-here" type="Your\Class\Name\Here" sortOrder="1" /> </type>
then,
<?php namespace Your\Class\Name; class Here { //'after' is reserved word. //`ToHtml` is the name of the method your want to intercept, capitalized //in this case you want to intercept the toHtml method of a certain block //the first parameter is always the name of the class you intercept with the reserved word `Inteceptor` at the end. This will give you access at the class instance //the second parameter is what the original toHtml method returns. This is the html you want public function afterToHtml( \NameOfClass\You\Intercept\Here\Interceptor $original, $html ) { //do something with $html //make sure you return a value of the same type as the original method return $html; } }
I tried this but must not have it set up correctly it doesn't seem to call my plugin code. I will review my steps and try this approach again and let you know.
Thanks for the response.
I missed the step of enabling the module. Every post I found seemed to not mention this step, I guess when you think about it it makes sense but being a noob I'm bound to miss somethings.
Thanks again for your awesome response it helped me tremendously.