cancel
Showing results for 
Search instead for 
Did you mean: 

How do you override the lib/internal/Magento/Framework/View/Element/Html/Links.php class?

SOLVED
   Did you know you can see the translated content as per your choice?

Translation is in progress. Please check again after few minutes.

How do you override the lib/internal/Magento/Framework/View/Element/Html/Links.php class?

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

1 ACCEPTED SOLUTION

Accepted Solutions

Re: How do you override the lib/internal/Magento/Framework/View/Element/Html/Links.php class?

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;

    }
}

 

View solution in original post

3 REPLIES 3

Re: How do you override the lib/internal/Magento/Framework/View/Element/Html/Links.php class?

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;

    }
}

 

Re: How do you override the lib/internal/Magento/Framework/View/Element/Html/Links.php class?

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.

Re: How do you override the lib/internal/Magento/Framework/View/Element/Html/Links.php class?

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.