Remove the wrapping paragraph around a widget in Magento 2

I already wrote a post about how to do this in Magento 1, but it seems that the ‘wrapping paragraphs around widgets‘-problem still exists in Magento 2. That’s why in this article I’ll show you how to fix this problem in Magento 2.

Create a module first

First things first, we need to create a new module in which we can manifest our awesome functionality. If you don’t know how to create a module in Magento 2, I’d suggest you read this article first.

Create a helper

The next thing we do, is create a helper class that has our method to remove the wrapping paragraphs. We call this file Data.php and we place it in the Helper -folder of our module:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<?php

namespaceGielberkers\Example\Helper;

useMagento\Framework\App\Helper\AbstractHelper;

/**

* Class Data

* @package Gielberkers\Example\Helper

*/

classDataextendsAbstractHelper

{

/**

* Remove wrapping <p></p> tags around widgets

*

* @param $content

* @return mixed

*/

publicfunctionremoveWrappingParagraphs($content)

{

// Remove wrapping paragraphs around widgets:

$content=preg_replace('/<p>{{(.*?)}}<\/p>/','{{$1}}',$content);

// Remove div around widgets

$content=preg_replace('/<div>{{(.*?)}}<\/div>/','{{$1}}',$content);

// Remove empty paragraphs:

$content=preg_replace('/<p>(|s*|&nbsp;|n)<\/p>/','',$content);

return$content;

}

}

The removeWrappingParagraphs() -method is pretty straight forward: it uses some regular expressions to check if there are widgets that are wrapped in paragraphs or <div> -elements.

Register for the proper events

Now, there are 2 events that we want to listen for in our module:

cms_page_render , which is fired as soon as a CMS page is rendered.

cms_block_load_after , which is fired after a CMS block is loaded.

We only need to listen to these events on the frontend of our site, so create a file called events.xml in etc/frontend of your modules’ folder and add the following content:

Create the observers

In Magento 2, you need to create a separate observer file for each event that you register to. If you look at the XML above, you’ll note that we need to create 2 observers in Model/Observer/Cms :

PageRender.php

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<?php

namespaceGielberkers\Example\Model\Observer\Cms;

useGielberkers\Example\Helper\Data;

useMagento\Framework\Event\ObserverInterface;

/**

* Class PageRender

* @package Gielberkers\Example\Model

*/

classPageRenderimplementsObserverInterface

{

/** @var Data */

protected$helper;

/**

* Observer constructor.

* @param Data $helper

*/

publicfunction__construct(Data$helper){

$this->helper=$helper;

}

/**

* @param \Magento\Framework\Event\Observer $observer

*/

publicfunctionexecute(\Magento\Framework\Event\Observer$observer)

{

/** @var \Magento\Cms\Model\Page $page */

$page=$observer->getPage();

$content=$page->getContent();

$content=$this->helper->removeWrappingParagraphs($content);

$page->setContent($content);

}

}

Note the execute() -method of this class, because that’s where the magic happens. It gets the page from our observer and manipulates it’s content by using the helper we created earlier.
At this point we’re already done for widgets in CMS pages. But as said, we want to remove them wrapping paragraphs in static blocks as well. That’s where the next file comes in:

BlockLoadAfter.php

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<?php

namespaceGielberkers\Example\Model\Observer\Cms;

useGielberkers\Example\Helper\Data;

useMagento\Cms\Model\Block;

useMagento\Framework\Event\ObserverInterface;

/**

* Class BlockLoadAfter

* @package Gielberkers\Example\Model

*/

classBlockLoadAfterimplementsObserverInterface

{

/** @var Data */

protected$helper;

/**

* Observer constructor.

* @param Data $helper

*/

publicfunction__construct(Data$helper){

$this->helper=$helper;

}

/**

* @param \Magento\Framework\Event\Observer $observer

*/

publicfunctionexecute(\Magento\Framework\Event\Observer$observer)

{

/** @var Block $block */

$block=$observer->getObject();

$content=$block->getContent();

$content=$this->helper->removeWrappingParagraphs($content);

$block->setContent($content);

}

}

The execute() -method of this class is more or less the same as that of PageRender , with the only difference that it manipulates the content of a block instead of a page.

This is the blog Giel Berkers,
a fulltime web developer from The Netherlands with a passion for the web.
I want to share ideas, knowledge, but also learn from
my readers. If you got any questions, or need help with something, feel free to drop me a
line.If I think that more people can benefit from the answer on your question, I'll write a blog post about it.