magento2: Magento 2.2: Unable to change order top.links

Preconditions

Magento 2.2 PHP 7.0

Issue description

Since upgrading to Magento 2.2 I’m unable to change the order of the top.links since the introduction of the getSortOrder function in Link.php. The SortLinkInterface breaks any way to set the order of the top.links.

Steps to reproduce

I have tried the following steps to move the top links in my default.xml file:

  • Moving the link before or after another link: <move element="my-account-link" destination="top.links" after="register-link"/>

  • Setting the link order by adding an argument with setOrder number: <argument name="sortOrder" xsi:type="number">xxx</argument>

Expected result (screenshot from Magento 2.1)

screen shot 2017-10-13 at 15 08 51

Actual result (screenshot from Magento 2.2)

screen shot 2017-10-13 at 15 08 32

Can somebody tell me if this is a bug in Magento 2.2 or is there another way to set the top.links order since the Magento 2.2 upgrade??

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 21 (2 by maintainers)

Most upvoted comments

I have been fighting with the top.links container all morning, and have managed to track down the issue that is preventing the links from being ordered.

I found the issue lies in the class Magento\Customer\Block\Account\Navigation. The getLinks() function will, ahem, get the links added to the top.links container, and then proceed to parse them. The first step is to extract any links that implement the SortLinkInterface class. They get copied to a new array, and then unset from the initial array of links. After looping all of the links, there are now 2 arrays: 1 with SortLinkInterface links, and the other with “regular” links. These two arrays are then merged, with the SortLInkInterface array being the first parameter. This means that any link that implements that interface will be placed before any links that don’t implement it, regardless of the before/after values in the XML.

The fix is to make sure that your Link class implements the interface, and also implements the required getSortOrder() function. Once these two changes are made, in the layout XML, a sortOrder attribute can be added to each new block that is added to top.links, which will control the order of the links. before and after attributes no longer required there.

// app/code/Vendor/Theme/Block/Html/Link.php

namespace Vendor\Theme\Block\Html;

use Magento\Customer\Block\Account\SortLinkInterface;

class Link extends \Magento\Framework\View\Element\Html\Link implements SortLinkInterface {
  //...

  getSortOrder() {
    return $this->getData(self::SORT_ORDER);
  }

  //...
}
// app/design/frontend/Vendor/Module/Magento_Theme/layout/default.xml

<referenceBlock name="top.links">
  <block class="Vendor\Theme\Block\Html\Link" name="my.vendor.link">
    <arguments>
      <argument name="sortOrder" xsi:type="number">10></argument>
    </arguments>
  </block>
</referenceContainer>

In working through this, I’ve managed to come across a bug in the sorting of the links, which I’ve created a pull request for. The pull request doesn’t “solve” this ticket, but it will solve an issue that will be faced once the directions above are followed https://github.com/magento/magento2/pull/14726

@engcom-backlog-nazar , do you have a commit ID so we can apply the fix to the 2.2 line?