1

I want to add a new menu link in My Account page. Please see the below screenshot:

enter image description here

I want to add a new menu after to the menu link, Newsletter Subscriptions. In order to add the new menu and its fields, where I have to update the code.

Also, when a user clicks that new menu, I want to show the fields like Education, Occupation, etc., and those data should be store in database. This is my primary expectation.

Could anyone please point me out where to update the code?

Any help will be appreciated!

Code of UpgradeSchema:

<?php

namespace Vendor\CustomerNavigation\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{

    /**
     * {@inheritdoc}
     */
    public function upgrade(
        SchemaSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $installer = $setup;

        $installer->startSetup();
        if (version_compare($context->getVersion(), '0.1.1', '<')) {
        $installer->getConnection()->addColumn(
            $installer->getTable('customernavigation_customernavigation'),
            'field_1',
            [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                'length' => 255,
                'nullable' => true,
                'comment' => 'Field_1'
            ]

        );
        $installer->getConnection()->addColumn(
            $installer->getTable('customernavigation_customernavigation'),
            'field_2',
            [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                'length' => 255,
                'nullable' => true,
                'comment' => 'Field_2'
            ]
        );
    }
        $installer->endSetup();
    }
}
4

3 Answers 3

4

Check the below files to create a customer account navigation link and add a form for saving custom data as you want.

app/code/Vendor/CustomerNavigatio/registration.php

<?php

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

app/code/Vendor/CustomerNavigation/etc/module.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_CustomerNavigation" setup_version="1.0.0"/>
</config>

app/code/Vendor/CustomerNavigation/etc/frontend/routes.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="customernavigation" frontName="customernavigation">
            <module name="Vendor_CustomerNavigation" />
        </route>
    </router>
</config>

app/code/Vendor/CustomerNavigation/Setup/InstallSchema.php

<?php
/**
 * Copyright © 2015 Vendor. All rights reserved.
 */

namespace Vendor\CustomerNavigation\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

/**
 * @codeCoverageIgnore
 */
class InstallSchema implements InstallSchemaInterface
{
    /**
     * {@inheritdoc}
     */
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {

        $installer = $setup;

        $installer->startSetup();

        /**
         * Create table 'customernavigation_customernavigation'
         */
        $table = $installer->getConnection()->newTable(
            $installer->getTable('customernavigation_customernavigation')
        )
        ->addColumn(
            'id',
            \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'customernavigation_customernavigation'
        )
        ->addColumn(
            'education',
            \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            '64k',
            [],
            'education'
        )
        ->addColumn(
            'occupation',
            \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            '64k',
            [],
            'occupation'
        )


        ->setComment(
            'Vendor CustomerNavigation customernavigation_customernavigation'
        );

        $installer->getConnection()->createTable($table);

        $installer->endSetup();

    }
}

app/code/Vendor/CustomerNavigation/Model/ResourceModel/CustomerNavigation/Collection.php

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\CustomerNavigation\Model\ResourceModel\CustomerNavigation;

/**
 * CustomerNavigations Collection
 */
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    /**
     * Initialize resource collection
     *
     * @return void
     */
    public function _construct()
    {
        $this->_init('Vendor\CustomerNavigation\Model\CustomerNavigation', 'Vendor\CustomerNavigation\Model\ResourceModel\CustomerNavigation');
    }
}

app/code/Vendor/CustomerNavigation/Model/ResourceModel/CustomerNavigation.php

<?php
/**
 * Copyright © 2015 Vendor. All rights reserved.
 */
namespace Vendor\CustomerNavigation\Model\ResourceModel;

/**
 * CustomerNavigation resource
 */
class CustomerNavigation extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    /**
     * Initialize resource
     *
     * @return void
     */
    public function _construct()
    {
        $this->_init('customernavigation_customernavigation', 'id');
    }

}

app/code/Vendor/CustomerNavigation/Model/CustomerNavigation.php

<?php
/**
 * Copyright © 2015 Vendor. All rights reserved.
 */

namespace Vendor\CustomerNavigation\Model;

use Magento\Framework\Exception\CustomerNavigationException;

/**
 * CustomerNavigationtab customernavigation model
 */
class CustomerNavigation extends \Magento\Framework\Model\AbstractModel
{

    /**
     * @param \Magento\Framework\Model\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
    }

    /**
     * @return void
     */
    public function _construct()
    {
        $this->_init('Vendor\CustomerNavigation\Model\ResourceModel\CustomerNavigation');
    }
}

app/code/Vendor/CustomerNavigation/view/frontend/layout/customer_account.xml

<?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">
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-demo-link">
                <arguments>
                    <argument name="label" xsi:type="string">Demo Link</argument>
                    <argument name="path" xsi:type="string">customernavigation/customernavigation/index</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

app/code/Vendor/CustomerNavigation/Controller/CustomerNavigation/index.php

<?php
/**
 *
 * Copyright © 2015 Vendorcommerce. All rights reserved.
 */
namespace Vendor\CustomerNavigation\Controller\CustomerNavigation;

class Index extends \Magento\Framework\App\Action\Action
{

    /**
     * @var \Magento\Framework\App\Cache\TypeListInterface
     */
    protected $_cacheTypeList;

    /**
     * @var \Magento\Framework\App\Cache\StateInterface
     */
    protected $_cacheState;

    /**
     * @var \Magento\Framework\App\Cache\Frontend\Pool
     */
    protected $_cacheFrontendPool;

    /**
     * @var \Magento\Framework\View\Result\PageFactory
     */
    protected $resultPageFactory;

    /**
     * @param Action\Context $context
     * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
     * @param \Magento\Framework\App\Cache\StateInterface $cacheState
     * @param \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     */
    public function __construct(
       \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
        \Magento\Framework\App\Cache\StateInterface $cacheState,
        \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->_cacheTypeList = $cacheTypeList;
        $this->_cacheState = $cacheState;
        $this->_cacheFrontendPool = $cacheFrontendPool;
        $this->resultPageFactory = $resultPageFactory;
    }

    /**
     * Flush cache storage
     *
     */
    public function execute()
    {
        $this->resultPage = $this->resultPageFactory->create();  
        $this->resultPage->getConfig()->getTitle()->prepend(__('My Demo Link'));
        return $this->resultPage;

    }
}

app/code/Vendor/CustomerNavigation/view/frontend/layout/customernavigation_customernavigation_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <body>      
        <referenceContainer name="content">         
            <block class="Vendor\CustomerNavigation\Block\CustomerNavigation\Index" name="customernavigation_index" template="customernavigation/index.phtml">
            </block>
        </referenceContainer>      
    </body>
</page>

app/code/Vendor/CustomerNavigation/Block/CustomerNavigation/Index.php

<?php
/**
 * Copyright © 2015 Vendor . All rights reserved.
 */
namespace Vendor\CustomerNavigation\Block\CustomerNavigation;
class Index extends \Magento\Framework\View\Element\Template
{
    public function getEducation(){
        /*Your Custom logic here*/
    }
}

app/code/Vendor/CustomerNavigation/view/frontend/templates/customernavigation/index.phtml

<?php
/**
 * Copyright © 2015 vendorcommerce. All rights reserved.
 */
?>
<?php
/**
 * {{controller}} {{action}} template
 *
 * @var $block \Vendor\CustomerNavigation\Block\CustomerNavigation\Index
 */
?>
<form class="form contact"
      action="<?= $block->getUrl('customernavigation/customernavigation/save') ?>"
      id="contact-form"
      method="post"
      data-hasrequired="<?= $block->escapeHtmlAttr(__('* Required Fields')) ?>"
      data-mage-init='{"validation":{}}'>
    <fieldset class="fieldset">
        <div class="field education required">
            <label class="label" for="education"><span><?= $block->escapeHtml(__('Education')) ?></span></label>
            <div class="control">
                <input name="education" id="education" title="<?= $block->escapeHtmlAttr(__('Education')) ?>" value="" class="input-text" type="text" data-validate="{required:true}"/>
            </div>
        </div>
        <div class="field occupation required">
            <label class="label" for="occupation"><span><?= $block->escapeHtml(__('Occupation')) ?></span></label>
            <div class="control">
                <input name="occupation" id="occupation" title="<?= $block->escapeHtmlAttr(__('Occupation')) ?>" value="" class="input-text" type="text" data-validate="{required:true}"/>
            </div>
        </div>
    </fieldset>
    <div class="actions-toolbar">
        <div class="primary">
            <button type="submit" title="<?= $block->escapeHtmlAttr(__('Submit')) ?>" class="action submit primary">
                <span><?= $block->escapeHtml(__('Submit')) ?></span>
            </button>
        </div>
    </div>
</form>

app/code/Vendor/CustomerNavigation/Controller/CustomerNavigation/Save.php

<?php
namespace Vendor\CustomerNavigation\Controller\CustomerNavigation;

class Save extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Magento\Framework\View\Result\PageFactory
     */
    public function execute()
    {

        $data = $this->getRequest()->getParams();
        if ($data) {
            $model = $this->_objectManager->create('Vendor\CustomerNavigation\Model\CustomerNavigation');
            $id = $this->getRequest()->getParam('id');
            if ($id) {
                $model->load($id);
            }

            $model->setData($data);

            try {
                $model->save();
                $this->messageManager->addSuccess(__('The Customer Has been Saved.'));
                $this->_redirect('*/*/');
                return;
            } catch (\Magento\Framework\Model\Exception $e) {
                $this->messageManager->addError($e->getMessage());
            } catch (\RuntimeException $e) {
                $this->messageManager->addError($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addException($e, __('Something went wrong while saving the customer.'));
            }
            $this->_redirect('*/*/');
            return;
        }
        $this->_redirect('*/*/');
    }
}

Below are the screenshots of form and Saved data in Database.

enter image description here

enter image description here

Hope this will work for you.

11
  • I have updated the question, can you please have a look and tell me whether your code will works for that.
    – Mohammad
    Feb 13, 2020 at 12:35
  • 1
    I have updated my answer, Please check. Feb 14, 2020 at 5:15
  • 1
    Accept the answer if this will work for you, So it will help others in the community. Feb 14, 2020 at 5:25
  • 1
    I have updated the same. Thanks for your correction. Feb 14, 2020 at 10:24
  • 1
    You have to also change the module version on app/code/Vendor/CustomerNavigation/etc/module.xml to 0.1.1 as you have added in your UpgradeSchema. and then run the command php bin/magento setup:upgrade --keep-generated Feb 15, 2020 at 6:02
0

create new file customer_account.xml in your layout directory. then add this content

<body>
            <referenceBlock name="customer_account_navigation">
                <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-my-link" after="customer-account-navigation-account-link">
                    <arguments>
                        <argument name="path" xsi:type="string">test/customer/view</argument>
                        <argument name="label" xsi:type="string">My link</argument>
                    </arguments>
                </block>
            </referenceBlock>
        </body>

After adding this flush cachethen it show My link in customer account navigation.

1
  • I want to show the new fields when user clicks the new link. For example, the new link is 'Additional Information' and when the user clicks this link I want to show the fields called Education, Occupation, etc. How to show those fields.
    – Mohammad
    Feb 13, 2020 at 12:31
0

Here's what exactly you wanted.

enter image description here

First, create required files for creating and registering module,

1.Create registration.php on Vendor/Module/ directory

<?php
use \Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Invigorate_AddInfo', __DIR__);

2.Create composer.json

{
    "name": "invigorate/addinfo",
    "description": "Additinal Info Extension",
    "type": "magento2-module",
    "version": "1.0.0",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Invigorate\\AddInfo\\": ""
        }
    }
}
  1. Create module.xml on Vendor/Module/etc/
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Invigorate_AddInfo" setup_version="1.0.0" />
</config>
  1. Now to add menu you need to extend customer_account.xml file and add your menu code. Create customer_account.xml file on Vendor/Module/view/frontend/layout/ folder and add following code:
<?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">
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-addinfo">
                <arguments>
                    <argument name="path" xsi:type="string">addinfo</argument>
                    <argument name="label" xsi:type="string">Additional Information</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>
  1. Now create layout, block and controller files as per needed for your tab content, Create addinfo_index_index.xml inside Vendor/Module/view/frontend/layout/
<?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">
    <update handle="customer_account"/>
    <body>
        <referenceContainer name="content">
            <block class="Invigorate\AddInfo\Block\Addinfo" name="addinfo_content" template="Invigorate_AddInfo::addinfo.phtml" cacheable="false"></block>
        </referenceContainer>
    </body>
</page>
  1. Create addinfo.phtml on Vendor/Module/view/frontend/templates/
<?php echo "Hey I'm tab content"; ?>
  1. Create Index.php Controller file for route as Vendor/Module/Controller/Index/Index.php
<?php
namespace Invigorate\AddInfo\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action {
    private $pageFactory;
    public function __construct(
        Context $context,
        PageFactory $pageFactory
    )
    {
        parent::__construct($context);
        $this->pageFactory = $pageFactory;
    }
    public function execute()
    {
        $this->_view->loadLayout();
        $this->_view->getPage()->getConfig()->getTitle()->set(__('My Additional Info Content'));
        $this->_view->renderLayout();
    }
}
  1. Now add Block file Addinfo.php inside Vendor/Module/Block
<?php
namespace Invigorate\AddInfo\Block;
class AddInfo extends \Magento\Framework\View\Element\Template
{
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }
    public function _prepareLayout()
    {
        return parent::_prepareLayout();
    }
}

And you're done. Here's how it looks:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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