10

I need to display newsletter subscribe form on my CMS page.

Default form has only email field but I need to display with additional fields.

Additional fields like : Gender, First-name, and Last-name.

How I can add these fields in the table, display it on the form, save values in the table.

2 Answers 2

14

The below worked fine for me. There is plenty of room for improvement. The form needs styling help and this adds additional first/last name fields to the admin grid rather than merging them with the existing customer name columns. Add this to your CMS page to include the form with the additional fields {{block class="Magento\Newsletter\Block\Subscribe" template="Vendor_Module::subscribe.phtml"}}

Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
  <type name="Magento\Newsletter\Model\Subscriber">
    <plugin name="vendor_module_newsletter_model_subscriber" type="Vendor\Module\Plugin\Newsletter\Subscriber"/>
  </type>
</config>

Vendor/Module/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_Module" setup_version="0.0.1">
    <sequence>
      <module name="Magento_Newsletter" />
    </sequence>
  </module>
</config>

Vendor/Module/Plugin/Newsletter/Subscriber.php

<?php

namespace Vendor\Module\Plugin\Newsletter;

use Magento\Framework\App\Request\Http;

class Subscriber {
  protected $request;

  public function __construct(
    Http $request
  ) {
    $this->request = $request;
  }

  public function aroundSubscribe($subject, \Closure $proceed, $email) {
    $result = $proceed($email);
    if ($this->request->isPost() && $this->request->getPost('firstname')) {
      $firstname = $this->request->getPost('firstname');
      $lastname = $this->request->getPost('lastname');
      $gender = $this->request->getPost('gender');

      $subject->setCFirstname($firstname);
      $subject->setCLastname($lastname);
      $subject->setGender($gender);

      try {
        $subject->save();
      }catch (\Exception $e) {
        throw new \Exception($e->getMessage());
      }
    }

    return $result;
  }
}

Vendor/Module/Setup/InstallSchema.php

<?php

namespace Vendor\Module\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{
  public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
    $setup->startSetup();

    $table = $setup->getTable('newsletter_subscriber');

    $setup->getConnection()->addColumn(
      $table,
      'c_firstname',
      [
        'type' => Table::TYPE_TEXT,
        'nullable' => true,
        'comment' => 'First Name'
      ]
    );
    $setup->getConnection()->addColumn(
      $table,
      'c_lastname',
      [
        'type' => Table::TYPE_TEXT,
        'nullable' => true,
        'comment' => 'Last Name'
      ]
    );
    $setup->getConnection()->addColumn(
      $table,
      'gender',
      [
        'type' => Table::TYPE_INTEGER,
        'nullable' => true,
        'comment' => 'Gender'
      ]
    );

    $setup->endSetup();
  }
}

If you are using Magento ˆ2.3 you should use this db_schema.xml below instead of InstallSchema.php above.

Vendor/Module/etc/db_schema.xml

<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="newsletter_subscriber" resource="default" engine="innodb" comment="Newsletter Subscriber">
        <column xsi:type="int" name="gender" unsigned="false" nullable="false" comment="Gender"/>
        <column xsi:type="varchar" name="c_firstname" nullable="false" comment="First Name"/>
        <column xsi:type="varchar" name="c_lastname" nullable="false" comment="Last Name"/>
    </table>
</schema>

Vendor/Module/view/adminhtml/layout/newsletter_subscriber_block.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="adminhtml.newslettrer.subscriber.grid.columnSet">
      <block class="Magento\Backend\Block\Widget\Grid\Column" as="custom_firstname">
        <arguments>
          <argument name="header" xsi:type="string" translate="true">First Name</argument>
          <argument name="index" xsi:type="string">c_firstname</argument>
          <argument name="header_css_class" xsi:type="string">col-firstname</argument>
          <argument name="column_css_class" xsi:type="string">ccol-firstname</argument>
        </arguments>
      </block>
      <block class="Magento\Backend\Block\Widget\Grid\Column" as="custom_lastname">
        <arguments>
          <argument name="header" xsi:type="string" translate="true">Last Name</argument>
          <argument name="index" xsi:type="string">c_lastname</argument>
          <argument name="header_css_class" xsi:type="string">col-lastname</argument>
          <argument name="column_css_class" xsi:type="string">ccol-lastname</argument>
        </arguments>
      </block>
      <block class="Magento\Backend\Block\Widget\Grid\Column">
        <arguments>
          <argument name="header" xsi:type="string" translate="true">Gender</argument>
          <argument name="index" xsi:type="string">gender</argument>
          <argument name="type" xsi:type="string">options</argument>
          <argument name="options" xsi:type="array">
            <item name="gender_male" xsi:type="array">
              <item name="value" xsi:type="string">1</item>
              <item name="label" xsi:type="string" translate="true">Male</item>
            </item>
            <item name="gender_female" xsi:type="array">
              <item name="value" xsi:type="string">2</item>
              <item name="label" xsi:type="string" translate="true">Female</item>
            </item>
            <item name="gender_not_specified" xsi:type="array">
              <item name="value" xsi:type="string">3</item>
              <item name="label" xsi:type="string" translate="true">Not Specified</item>
            </item>
          </argument>
          <argument name="header_css_class" xsi:type="string">col-gender</argument>
          <argument name="column_css_class" xsi:type="string">ccol-gender</argument>
        </arguments>
      </block>
    </referenceBlock>
  </body>
</page>

Vendor/Module/view/frontend/templates/subscribe.phtml

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

/** @var \Magento\Newsletter\Block\Subscribe $block */

?>
<div class="block newsletter">
  <div class="title"><strong><?php /* @escapeNotVerified */ echo __('Newsletter') ?></strong></div>
  <div class="content">
    <form class="form subscribe"
          novalidate
          action="<?php echo $block->escapeUrl($block->getFormActionUrl()) ?>"
          method="post"
          data-mage-init='{"validation": {"errorClass": "mage-error"}}'
          id="newsletter-validate-detail">
      <div class="field firstname">
        <label class="label" for="firstname"><span><?php echo $block->escapeHtml(__('First Name')) ?></span></label>
        <div class="control">
          <input name="firstname" type="text" id="firstname"
                 placeholder="<?php echo $block->escapeHtmlAttr(__('First Name')) ?>"
                 data-validate="{required:true}"/>
        </div>
      </div>
      <div class="field lastname">
        <label class="label" for="lastname"><span><?php echo $block->escapeHtml(__('Last Name')) ?></span></label>
        <div class="control">
          <input name="lastname" type="text" id="lastname"
                 placeholder="<?php echo $block->escapeHtmlAttr(__('Last Name')) ?>"
                 data-validate="{required:true}"/>
        </div>
      </div>
      <?php $_gender = $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Gender') ?>
      <?php echo $_gender->toHtml() ?>
      <div class="field newsletter">
        <label class="label" for="newsletter"><span><?php echo $block->escapeHtml(__('Sign Up for Our Newsletter:')) ?></span></label>
        <div class="control">
          <input name="email" type="email" id="newsletter"
                 placeholder="<?php echo $block->escapeHtmlAttr(__('Enter your email address')) ?>"
                 data-validate="{required:true, 'validate-email':true}"/>
        </div>
      </div>
      <div class="actions">
        <button class="action subscribe primary" title="<?php echo $block->escapeHtmlAttr(__('Subscribe')) ?>" type="submit">
          <span><?php echo $block->escapeHtml(__('Subscribe')) ?></span>
        </button>
      </div>
    </form>
  </div>
</div>

Vendor/Module/registration.php please make proper file all

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
  \Magento\Framework\Component\ComponentRegistrar::MODULE,
  'Vendor_Module',
  __DIR__
);
3
  • Hi Pmclain, I tried your solution but it did not work in my end. I have a question about this one Vendor/Module/Plugin/Newsletter/Subscriber.php <-- is this a block or something? and about in the di.xml this line of codes: <type name="Magento\Newsletter\Model\Subscriber"> <plugin name="vendor_module_newsletter_model_subscriber" type="Vendor\Module\Plugin\Newsletter\Subscriber"/> </type> It will result in error also. Feb 28, 2017 at 2:36
  • The plugin class you are referencing is a plugin/interceptor. Describing in detail here would be a bit long winded, but the official documentation is devdocs.magento.com/guides/v2.1/extension-dev-guide/… The class is responsible for adding the additional field information to the subscriber model before saving. The di.xml is telling Magento the plugin class exists. Without details of error you are experiencing I can't really speak intelligently to the problem. Did you try deleting the var/generation directory?
    – Pmclain
    Mar 4, 2017 at 13:47
  • backend working properly but front end not working for me
    – matinict
    Mar 20, 2019 at 12:14
0

add newsletter_manage_index.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_newsletter">
            <container name="customer.form.newsletter.extra" htmlTag="div">
                <block class="Magento\Framework\View\Element\Template" name="name_of_your_block" template="Vendor_ModuleName::your_template_path.phtml" />
            </container>
        </referenceBlock>
    </body>
</page>

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.