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

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.