1

I am trying to add two link to my account "link 1" "link 2". links that will load just a simple "testing" message. I got the link to display but if i click the link i get an oops error page.

The following is an example: How to add a new page to the new link in the Customer Account page

How do i do about fixing this in detail.


1. Create customer_account layout XML file

app/code/YourNamespace/YourModule/view/frontend/layout/customer_account.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_account_navigation">
            <!-- Add menu to the end of the sidebar -->
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-your-first-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourmodule/yourfirstlink/index</argument>
                    <argument name="label" xsi:type="string">Your First Link</argument>
                </arguments>
            </block>
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-your-second-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourmodule/yoursecondlink/index</argument>
                    <argument name="label" xsi:type="string">Your Second Link</argument>
                </arguments>
            </block> 
        </referenceBlock>
    </body>
</page>

2. Create your module’s layout XML file

app/code/YourNamespace/YourModule/view/frontend/layout/yourmodule_yourfirstlink_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <title>
            Your First Link
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="YourNamespace\YourModule\Block\YourBlock" name="yourmodule.firstlink.index" template="YourNamespace_YourModule::yourfirstlink/index.phtml" cacheable="false" />
        </referenceContainer>
    </body>
</page>

app/code/YourNamespace/YourModule/view/frontend/layout/yourmodule_yoursecondlink_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <title>
            Your Second Link
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="Magento\Framework\View\Element\Template" name="yourmodule.secondlink.index" template="YourNamespace_YourModule::yoursecondlink/index.phtml" cacheable="false" />
        </referenceContainer>
    </body>
</page>

3. Create Controller class files

app/code/YourNamespace/YourModule/Controller/YourFirstLink/Index.php

<?php
namespace YourNamespace\YourModule\Controller\YourFirstLink;
 
class Index extends \Magento\Framework\App\Action\Action
{
        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
 
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}
?>

app/code/YourNamespace/YourModule/Controller/YourSecondLink/Index.php

<?php
namespace YourNamespace\YourModule\Controller\YourSecondLink;
 
class Index extends \Magento\Framework\App\Action\Action
{
        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
 
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}
?>

4. Create Block class file

app/code/YourNamespace/YourModule/Block/YourBlock.php

<?php
namespace YourNamespace\YourModule\Block;
class YourBlock extends \Magento\Framework\View\Element\Template
{        
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,        
        array $data = []
    )
    {        
        parent::__construct($context, $data);
    }
    
    public function getHelloWorld()
    {
        return 'Hello World';
    }
    
}
?>

5. Create Template files

app/code/YourNamespace/YourModule/view/frontend/templates/firstlink/index.phtml

<h1> first page </h1>

app/code/YourNamespace/YourModule/view/frontend/templates/secondlink/index.phtml

<h1> second Page </h1>

6. Create registration.php

app/code/YourNamespace/YourModule/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'YourNamespace_YourModule',
    __DIR__
);

6/30/2020 Updates ( Changed YourNamespace/YourModule to MyAccount_Links

app/code/YourNamespace/YourModule/view/frontend/layout/customer_account.xml

Changed Path to "yourroute/yourfirstlink/index"

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_account_navigation">
            <!-- Add menu to the end of the sidebar -->
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-your-first-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourroute/yourfirstlink/index</argument>
                    <argument name="label" xsi:type="string">Link 1</argument>
                </arguments>
            </block>
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-your-second-link" after="customer-account-navigation-your-first-link" >
                <arguments>
                    <argument name="path" xsi:type="string">yourroute/yoursecondlink/index</argument>
                    <argument name="label" xsi:type="string">link 2</argument>
                </arguments>
            </block> 
        </referenceBlock>
    </body>
</page>

app/code/YourNamespace/YourModule/view/frontend/layout/yourroute_yourfirstlink_index.xml

Changed file name to lowercase "yourroute_yourfirstlink_index.xml"

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <update handle="customer_account"/>
    <head>
        <title>
            Your First Link
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="MyAccount\Links\Block\yourblock" name="yourroute/yourfirstlink/index" template="MyAccount_Links::yourfirstlink/index.phtml" cacheable="false" />
        </referenceContainer>
    </body>
</page>

app/code/YourNamespace/YourModule/view/frontend/layout/yourroute_yoursecondlink_index.xml

Changed file name yoursecondlink to lowercase and changed file="yourroute/yoursecondlink/index"

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <title>
            Your Second Link
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="Magento\Framework\View\Element\Template" name="yourroute/yoursecondlink/index" template="MyAccount_Links::yoursecondlink/index.phtml" cacheable="false" />
        </referenceContainer>
    </body>
</page>

app/code/YourNamespace/YourModule/Controller/yourfirstlink/Index.php

Changed folder "yourfirstlink" to lowercase

<?php
namespace MyAccount\Links\Controller\yourfirstlink;
 
class Index extends \Magento\Framework\App\Action\Action
{
        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
 
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}
?>

app/code/YourNamespace/YourModule/Controller/yoursecondlink/Index.php

Changed folder to lowercase "yoursecondlink"

<?php
namespace MyAccount\Links\Controller\yoursecondlink;
 
class Index extends \Magento\Framework\App\Action\Action
{
        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
 
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}
?>

app/code/YourNamespace/YourModule/Block/yourblock.php

Change file name to lovercase "yourblock.php"

<?php
namespace MyAccount\Links\Block;
class yourblock extends \Magento\Framework\View\Element\Template
{        
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,        
        array $data = []
    )
    {        
        parent::__construct($context, $data);
    }
    
    public function getHelloWorld()
    {
        return 'Hello World';
    }
    
}
?>

app/code/YourNamespace/YourModule/etc/module.xml

Added a Module

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="MyAccount_Links" setup_version="0.0.1">
        <sequence>
            <module name="Magento_Customer"/>
        </sequence>
    </module>
</config>

app/code/YourNamespace/YourModule/etc/frontend/routes.xml

Added routes.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route frontName="yourroute" id="yourmodule">
            <module name="MyAccount_Links"/>
        </route>
    </router>
</config>
  • You need to check the case of the paths. Magento resolves the capital at the start of the file as lower case but not any of the others. So it all otherwise needs to match. If the folder is YourFirstLink then it's entry in your paths is yourFirstLink – Mark Rees Jun 28 '20 at 12:28
  • Thank you for the response. i really appreciate it... although it did not work on my end. Are you willing to try to use this code and see if there are any issues with it. As i'm getting nowhere. ive changed path names up to the point to all lowercase. – Demasys Jun 29 '20 at 19:48
  • What is in your etc/frontend/routes.xml? Did you put one in your module? – Mark Rees Jun 29 '20 at 20:08
  • Thank you kindly for the response. I do not have one in my module. how would i go about setting the up?. I only have what is listed above. – Demasys Jun 29 '20 at 20:23
0

After some discussion in the question's comments your problem appears to be a lack of a routes.xml combined with not managing the case of your links. Following the filenames and directories in the original question.

You need a file called routes.xml in YourNamespace/YourModule/etc/frontend

YourNamespace/YourModule/etc/frontend/routes.xml

This would be an example content:

    <?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route frontName="yourroute" id="yourmodule">
            <module name="YourNamespace_YourModule"/>
        </route>
    </router>
</config>

Then your links would be yourroute/yourFirstLink/index and yourroute/yourSecondLink/index

You would also need to rename your layout files.

YourNamespace/YourModule/view/frontend/layout/yourroute_yourFirstLink_index.xml
YourNamespace/YourModule/view/frontend/layout/yourroute_yourSecondLink_index.xml

If all of these match each other then your link should resolve, I would recommend after altering your files that you proceed to use the bin/magento setup:upgrade and bin/magento setup:di:compile commands, so that you can ensure you are not affected by a cached or generated file.

To give some background, in Magento many things have a strict naming convention that it expects so that it can resolve the correct action. For basic or index controllers it is as follows.

Your routes.xml defines the name to find your module. So a module being YourModule could have a route of moduleroute. Then if you need to get to the controller Index.php which is in the ./Controller/Awesome folder your second element to the url becomes awesome. So you're file structure is YourVendor/YourModule/Controller/Awesome/Index.php and you want to send a link so that it can display the great layout file you want to create. That means your link is created of the three sections you've just defined, the route, the subfolder and the file name. So that becomes moduleroute/awesome/index

You then have to create a layout file whose name mirrors the url key for the controller. You just replace the / with _. This is case sensitive. Magento only sets the first letter of each section (as described before) to lowercase. So if your folder under Controller is ThisIsMyAwesomeModuleAction the url section would be thisIsMyAwesomeModuleAction.

All of this is how Magento currently loads it's own contollers. The same reason if you want to add a special section to the homepage you alter cms_index_index.xml as the homepage is resolved to ./vendor/magento/module-cms/Controller/Index/Index.php which then calls the layout file mentioned.

  • Thank you again for your time and help. Very much Appreciated. I have changed a few things as instructed and a bit more as well. I no longer see an error message when clicking my custom links. I’m currently getting a blank page without the my messages links showing on the left yet the two Compare Products and My Wish List below are showing on the right side as if the layout is set to 1 columns. I did change the columns to see if it makes a difference and it does not. I don't think the block of test text is loading... Again Thank you very much for the help and your time. – Demasys Jun 30 '20 at 20:27
  • Any advice on how i could get this block to load. i went over the code again. The solution seems to be escaping me. – Demasys Jul 1 '20 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.