Magento2 | PWA | GraphQL

Configuring CMS Pages as Dynamic Rows in Magento 2 Store Settings


The Magento 2 Dynamic CMS Page List module provides a seamless way to manage and display CMS pages directly from the store configuration settings.

This module enables you to dynamically add CMS pages with customizable labels within a configurable dropdown list, allowing for easy management of page-specific details at the store level.

Perfect for administrators, this tool simplifies the customization of CMS page lists and descriptions through a user-friendly interface in the configuration settings.

You can find the complete module on GitHub at Magelearn_DynamicPageList

Or Check the below images for a better understanding of the functionality of this module.





Let's start it by creating a custom extension. 

Create a folder inside app/code/Magelearn/DynamicPageList

Add registration.php file in it:

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

Add composer.json file in it:

{
    "name": "magelearn/magento2-module-dynamic-page-list",
    "description": "The Dynamic Row Image Upload Magento module enables administrators to upload and manage multiple images directly in Admin System Configuration with dynamic rows.",
    "type": "magento2-module",
    "license": "Apache-2.0",
    "authors": [
        {
            "name": "Vijay Rami",
            "email": "vijaymrami@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "prefer-stable": true,
    "version":"1.0",
    "require": {
        "php": ">=8.0.0"
    },
    "repositories": [
    {
        "type": "package",
        "package": {
            "name": "magelearn/magento2-module-dynamic-file-upload",
            "version": "1.0",
            "source": {
                "url": "https://github.com/vijayrami/Magelearn_DynamicFileUpload.git",
                "type": "git",
                "reference": "main"
            }
        }
    }
    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\DynamicPageList\\": ""
        }
    }
}

Add etc/module.xml file in it:

<?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="Magelearn_DynamicPageList" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Backend"/>
            <module name="Magento_Config"/>
            <module name="Magento_Cms"/>
        </sequence>
    </module>
</config>

Add etc/acl.xml file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magento_Backend::stores">
                    <resource id="Magento_Backend::stores_settings">
                        <resource id="Magento_Config::config">
                            <resource id="Magelearn_DynamicPageList::config" title="Magelearn DynamicPageList Section" sortOrder="50" />
                        </resource>
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

Now to give the CMS Page list options at System configuration at admin,

we will add etc/adminhtml/system.xml file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="magelearn" translate="label" sortOrder="10">
            <label>Magelearn Modules</label>
        </tab>
        <section id="dynamic_list" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>Dynamic CMS Page List</label>
            <tab>magelearn</tab>
            <resource>Magelearn_DynamicPageList::config</resource>
            <group id="selection" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>General Configuration</label>
                <field id="cms_pages" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>CMS Page Mapping</label>
                    <frontend_model>Magelearn\DynamicPageList\Block\Adminhtml\Form\Field\DynamicRows</frontend_model>
                    <backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
                    <class>required-entry validate-select</class>
                </field>
            </group>
        </section>
    </system>
</config>

Now as per highlighted code above, we will add
app/code/Magelearn/DynamicPageList/Block/Adminhtml/Form/Field/DynamicRows.php file

<?php

declare(strict_types=1);

namespace Magelearn\DynamicPageList\Block\Adminhtml\Form\Field;

use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\LocalizedException;

class DynamicRows extends AbstractFieldArray
{
    /**
     * @var CmsPageOptions
     */
    private $cmsPageRenderer;
    
    /**
     * Prepare rendering the new field by adding all the needed columns
     */
    protected function _prepareToRender()
    {
        $this->addColumn('cms_page', [
            'label' => __('CMS Page'),
            'renderer' => $this->getCmsPageRenderer()
        ]);
        $this->addColumn('custom_text', [
            'label' => __('Custom Text'),
            'class' => 'required-entry'
        ]);
        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add Row');
    }
    
    /**
     * Get CMS Page renderer
     *
     * @return CmsPageOptions
     * @throws LocalizedException
     */
    private function getCmsPageRenderer()
    {
        if (!$this->cmsPageRenderer) {
            $this->cmsPageRenderer = $this->getLayout()->createBlock(
                CmsPageOptions::class,
                '',
                ['data' => ['is_render_to_js_template' => true]]
                );
        }
        return $this->cmsPageRenderer;
    }
    
    /**
     * Prepare existing row data object
     *
     * @param DataObject $row
     * @throws LocalizException
     */
    protected function _prepareArrayRow(DataObject $row)
    {
        $options = [];
        $cmsPage = $row->getCmsPage();
        if ($cmsPage) {
            $options['option_' . $this->getCmsPageRenderer()->calcOptionHash($cmsPage)] = 'selected="selected"';
        }
        $row->setData('option_extra_attrs', $options);
    }
}

And as per highlighted above, we will add
app/code/Magelearn/DynamicPageList/Block/Adminhtml/Form/Field/CmsPageOptions.php file.

<?php
declare(strict_types=1);

namespace Magelearn\DynamicPageList\Block\Adminhtml\Form\Field;

use Magento\Framework\View\Element\Html\Select;
use Magento\Framework\View\Element\Context;
use Magento\Cms\Model\ResourceModel\Page\CollectionFactory;

class CmsPageOptions extends Select
{
    /**
     * @var CollectionFactory
     */
    private $collectionFactory;

    /**
     * @param Context $context
     * @param CollectionFactory $collectionFactory
     * @param array $data
     */
    public function __construct(
        Context $context,
        CollectionFactory $collectionFactory,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->collectionFactory = $collectionFactory;
    }

    /**
     * Set "name" for <select> element
     *
     * @param string $value
     * @return $this
     */
    public function setInputName($value)
    {
        return $this->setName($value);
    }

    /**
     * Set "id" for <select> element
     *
     * @param string $value
     * @return $this
     */
    public function setInputId($value)
    {
        return $this->setId($value);
    }

    /**
     * Render block HTML
     *
     * @return string
     */
    public function _toHtml(): string
    {
        $this->setClass('required-entry validate-select');
        if (!$this->getOptions()) {
            $this->setOptions($this->getCmsPageOptions());
        }
        return parent::_toHtml();
    }

    /**
     * Get CMS pages options
     *
     * @return array
     */
    private function getCmsPageOptions(): array
    {
        $collection = $this->collectionFactory->create();
        $options = [];
        
        $options[] = ['label' => __('-- Please Select --'), 'value' => ''];
        
        foreach ($collection as $page) {
            $options[] = [
                'label' => $page->getTitle(),
                'value' => $page->getId()
            ];
        }
        
        return $options;
    }
}
0 Comments On "Configuring CMS Pages as Dynamic Rows in Magento 2 Store Settings"

Back To Top