Magento2 | PWA | GraphQL

Add simple promotional banner on all pages your website Magento


In this post you will learn about Magento 2 module which adds the ability to display a simple promotional banner throughout your website.

It also includes the ability to customize the styles of the promotional banner based on expired date selected from datepicker configuration.



You can find complete module on Github.

Create folder inside app/code/Magelearn/PromoBanner

Add registration.php file in it:

<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magelearn_PromoBanner', __DIR__);
Add composer.json file in it:
{
    "name": "magelearn/module-promobanner",
    "description": "Display a simple promotional banner throughout your website. It also includes the ability to customize the styles of the promotional banner based on expired date selected from datepicker configuration.",
    "type": "magento2-module",
    "license": "OSL-3.0",
    "authors": [
        {
            "email": "info@mage2gen.com",
            "name": "Mage2Gen"
        },
        {
            "email": "vijaymrami@gmail.com",
            "name": "vijay rami"
        }
    ],
    "minimum-stability": "dev",
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\PromoBanner\\": ""
        }
    }
}
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_PromoBanner" setup_version="1.0.0"/>
</config>
To give system configuration options, Add etc/adminhtml/system.xml file in it:
<?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>
		<section id="header" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label">
			<label>Header</label>
			<tab>general</tab>
			<resource>Magelearn_PromoBanner::config</resource>
			<group id="promo_banner" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label">
				<label>Promotional Banner</label>
				<field id="enable" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="0" translate="label" type="select">
					<label>Enable</label>
					<comment/>
					<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
				</field>
				<field id="message" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="text">
					<label>Banner Message</label>
					<validate>required-entry</validate>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
				</field>
                <field id="link" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="text">
                    <label>Banner Link</label>
                    <comment>When the banner is clicked the user will be directed to this page.</comment>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>
				<field id="expired_date" translate="label" type="date" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="4">
                    <label>Expire Date</label>
                    <frontend_model>Magelearn\PromoBanner\Block\Adminhtml\System\Config\Date</frontend_model>
                    <validate>required-entry</validate>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>
                <field id="custom_styles" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="15" translate="label" type="select">
                    <label>Use Custom Styles</label>
                    <comment>If you'd like to pick your own colors and font styles select yes. The default background is red, text color is white, and font size is 16px with a weight of 600.</comment>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>

                <field id="background" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="20" translate="label" type="text">
                    <label>Background</label>
                    <frontend_model>Magelearn\PromoBanner\Block\Adminhtml\System\Config\ColorPicker</frontend_model>
                    <comment>You can use the color picker that shows when clicking this field or you can add any style that is valid for the CSS background property. Defaults to red.</comment>
                    <depends>
                        <field id="enable">1</field>
                        <field id="custom_styles">1</field>
                    </depends>
                </field>
                <field id="font_size" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="30" translate="label" type="text">
                    <label>Font Size</label>
                    <comment>Add any style that is valid for the CSS font-size property. Defaults to 16px.</comment>
                    <depends>
                        <field id="enable">1</field>
                        <field id="custom_styles">1</field>
                    </depends>
                </field>
                <field id="font_color" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="30" translate="label" type="text">
                    <label>Font Color</label>
                    <frontend_model>Magelearn\PromoBanner\Block\Adminhtml\System\Config\ColorPicker</frontend_model>
                    <comment>You can use the color picker that shows when clicking this field or you can add any style that is valid for the CSS color property. Defaults to white.</comment>
                    <depends>
                        <field id="enable">1</field>
                        <field id="custom_styles">1</field>
                    </depends>
                </field>
                <field id="font_weight" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="30" translate="label" type="text">
                    <label>Font Weight</label>
                    <comment>Add any style that is valid for the CSS font-weight property. Defaults to 600.</comment>
                    <depends>
                        <field id="enable">1</field>
                        <field id="custom_styles">1</field>
                    </depends>
                </field>
			</group>
		</section>
	</system>
</config>

As per defined in this file, to give colorpicker and datepicker options we will create below two files.

Create ColorPicker.php file inside app/code/Magelearn/PromoBanner/Block/Adminhtml/System/Config folder.

<?php

namespace Magelearn\PromoBanner\Block\Adminhtml\System\Config;

use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;

class ColorPicker extends Field
{

    /**
     * Add script to html element
     *
     * @param  AbstractElement $element
     * @return string
     */
    protected function _getElementHtml(AbstractElement $element): string {
        $html = $element->getElementHtml();
        $value = $element->getData('value');

        $html .= '<script type="text/javascript">
            require(["jquery"], function ($) {
                $(document).ready(function (e) {
                    $("#' . $element->getHtmlId() . '").css("background-color","#' . $value . '");
                    $("#' . $element->getHtmlId() . '").colpick({
                        submit:0,
                        color: "#' . $value . '",
                        onChange:function(hsb,hex,rgb,el,bySetColor) {
                        $(el).css("background-color","#"+hex);
                        if(!bySetColor) $(el).val("#" + hex);
                    }
                    }).keyup(function(){
                        $(this).colpickSetColor(this.value);
                    });
                });
            });
            </script>';

        return $html;
    }
}

Create Date.php file inside app/code/Magelearn/PromoBanner/Block/Adminhtml/System/Config folder.

<?php

namespace Magelearn\PromoBanner\Block\Adminhtml\System\Config;

use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\Stdlib\DateTime;

class Date extends Field
{
    /**
     * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
     * @return void
     */
    public function render(AbstractElement $element)
    {
        $element->setDateFormat(DateTime::DATE_INTERNAL_FORMAT);
        $element->setTimeFormat('HH:mm:ss');
        $element->setShowsTime(true);
        return parent::render($element);
    }
}
Add etc/acl.xml file in it:
<?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_PromoBanner::config" title="Promotional Banner"/>
						</resource>
					</resource>
				</resource>
			</resource>
		</resources>
	</acl>
</config>
Add etc/config.xml file in it to give default options
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
	<default>
		<header>
			<promo_banner>
                <enable>0</enable>
                <custom_styles>0</custom_styles>
                <background>#e22626</background>
                <font_color>#ffffff</font_color>
                <font_size>16px</font_size>
                <font_weight>600</font_weight>
			</promo_banner>
		</header>
	</default>
</config>

Here, We will also add colorpicker library (CSS and JS) files by modifying adminhtml system config layout file.

Add adminhtml_system_config_edit.xml file in app/code/Magelearn/PromoBanner/view/adminhtml/layout folder:
<?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">
<head>
    <!-- This color picker library is also loaded by DotDigital_Email - I included these for stores that disable this module -->
    <script src="Magelearn_PromoBanner::js/colpick.js"/>
    <script src="Magelearn_PromoBanner::js/colorPickerInit.js"/>
    <css src="Magelearn_PromoBanner::css/colpick.css"/>
</head>
</page>
Now add colpick.css file in app/code/Magelearn/PromoBanner/view/adminhtml/web/css folder.

Add colorPickerInit.js file in app/code/Magelearn/PromoBanner/view/adminhtml/web/js folder. 

Add colpick.js file in app/code/Magelearn/PromoBanner/view/adminhtml/web/js folder. 

Now add front-end layout, block, template and viewmodel files.
Add app/code/Magelearn/PromoBanner/view/frontend/layout/default.xml file:
<?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">
	<head>
        <css src="Magelearn_PromoBanner::css/custom.css" rel="stylesheet" type="text/css"/>
    </head>
    <body>
		<referenceBlock name="header.container">
            <block name="promo.banner" template="Magelearn_PromoBanner::header/promo_banner.phtml">
                <arguments>
                    <argument name="viewModel" xsi:type="object">Magelearn\PromoBanner\ViewModel\Header\PromoBanner</argument>
                </arguments>
            </block>
		</referenceBlock>
	</body>
</page>
Add template file promo_banner.phtml file inside app/code/Magelearn/PromoBanner/view/frontend/templates/header :
<?php

use Magelearn\PromoBanner\ViewModel\Header\PromoBanner;
use Magento\Framework\View\Element\Template;

/** @var Template $block */
/** @var PromoBanner $viewModel */
$viewModel = $block->getData('viewModel');
$promoLink = $viewModel->getPromoLink();
?>
<?php if ($viewModel->isEnabled()): ?>
	<?php
	$date_now = date("Y-m-d h:i:s"); // this format is string comparable
	$date_expired = $viewModel->getExpiredDate();
	if ($date_expired > $date_now): ?>
    <?php if ($viewModel->isUseCustomStyles()): ?>
        <?php $customStyles = $viewModel->getCustomStyles(); ?>
        <style>
        <?php if ($customStyles['background']): ?>
        div.promo-banner-wrapper { background: <?= $block->escapeHtml($customStyles['background']) ?> }
        <?php endif; ?>
        <?php if ($customStyles['font_size'] || $customStyles['font_weight'] || $customStyles['font_color']): ?>
        div.promo-banner-wrapper div.promo-banner-message {
            <?php if ($color = $block->escapeHtml($customStyles['font_color'])): ?>
            color: <?= $block->escapeHtml($color) ?>;
            <?php endif; ?>
            <?php if ($fontSize = $customStyles['font_size']): ?>
            font-size: <?= $block->escapeHtml($fontSize) ?>;
            <?php endif; ?>
            <?php if ($fontWeight = $customStyles['font_weight']): ?>
            font-weight: <?= $block->escapeHtml($fontWeight) ?>;
            <?php endif; ?>
        }
        <?php endif; ?>
        </style>
    <?php endif; ?>
    <div class="promo-banner-wrapper">
        <div class="promo-banner-message">
            <?php if ($promoLink): ?>
            <a href="<?= $block->escapeUrl($promoLink) ?>">
            <?php endif; ?>
            <span><?= $block->escapeHtml($viewModel->getPromoText()) ?></span>
            <?php if ($promoLink): ?>
            </a>
            <?php endif; ?>
        </div>
    </div>
    <?php endif ?>
<?php endif ?>

Add ViewModel file PromoBanner.php inside app/code/Magelearn/PromoBanner/ViewModel/Header :

<?php
/**
 * Copyright © Chris Mallory All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Magelearn\PromoBanner\ViewModel\Header;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DataObject;
use Magento\Framework\View\Element\Block\ArgumentInterface;

class PromoBanner extends DataObject implements ArgumentInterface
{
    /**
     * System XML config path for ChrisMallory_PromoBanner
     */
    protected const PROMO_BANNER_XML_CONFIG_PATH = 'header/promo_banner/';

    /** @var ScopeConfigInterface */
    protected $scopeConfig;

    /**
     * PromoBanner constructor.
     *
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig
    ) {
        $this->scopeConfig = $scopeConfig;
        parent::__construct();
    }

    /**
     * Returns true if promotional banner is enabled
     * @return bool
     */
    public function isEnabled(): bool
    {
        return (bool)$this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'enable');
    }

    /**
     * Returns promotional banner text
     * @return string
     */
    public function getPromoText(): string
    {
        return $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'message');
    }
	
	 public function getExpiredDate()
    {
        return $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'expired_date');
    }
    /**
     * Returns promotional banner link
     * @return string
     */
    public function getPromoLink(): ?string
    {
        return $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'link');
    }

    /**
     * Returns true if promotional banner is configured to use custom CSS styles
     * @return bool
     */
    public function isUseCustomStyles(): bool
    {
        return (bool)$this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'custom_styles');
    }

    /**
     * Returns array of CSS styles
     * @return array
     */
    public function getCustomStyles(): array
    {
        $customStyles = [
            'background' => false,
            'font_size' => false,
            'font_weight' => false,
            'font_color' => false
        ];
		
		$background = $customStyles['background'];
		$color = $customStyles['font_color'];
		$fontSize = $customStyles['font_size'];
		$fontWeight = $customStyles['font_weight'];
		
        if ($background = $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'background')) {
            $customStyles['background'] = $background;
        }

        if ($color = $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'font_color')) {
            $customStyles['font_color'] = $color;
        }

        if ($fontSize = $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'font_size')) {
            $customStyles['font_size'] = $fontSize;
        }

        if ($fontWeight = $this->scopeConfig->getValue(self::PROMO_BANNER_XML_CONFIG_PATH . 'font_weight')) {
            $customStyles['font_weight'] = $fontWeight;
        }
		
        return $customStyles;
    }
}

After adding above files, just run Magento commands:

php bin/magento set:upg

php bin/magento set:d:c

php bin/magento set:s:d -f en_US

php bin/magento c:c

php bin/magento c:f

Now, you can see New configuration options at Store > Configuration > General > header

You can Enable/Disable the extension from system configuration option as well as can define custom styles.


0 Comments On "Add simple promotional banner on all pages your website Magento"

Back To Top