Since widgets are created in the admin panel, you first need to write some Magento logic for the backend part of the widget.
<aside> ✅ The Magento Developer Docs have a great guide for creating a widget. Let's walk through what you need to do to create a new widget to later make it work with Scandi.
</aside>
Create a Block class for the widget. It needs to extend Template
and implement the BlockInterface
. Other than that, the only thing you need to do is specify the _template
the widget uses.
// app/code/ScandiTutorials/CustomWidget/Block/Widget/NewsletterWidget.php
<?PHP
declare(strict_types=1);
namespace ScandiTutorials\\CustomWidget\\Block\\Widget;
use Magento\\Framework\\View\\Element\\Template;
use Magento\\Widget\\Block\\BlockInterface;
class NewsletterWidget extends Template implements BlockInterface
{
protected $_template = "widget/newsletter_widget.phtml";
}
But you haven't created the template yet! So do that next. If you were writing the template for Magento, you would need to render all the elements needed for the widget.
However, since all the ScandiPWA rendering logic happens on the frontend using React, the template can be much simpler. The template merely needs to render a single element to specify the widget type.
This is also where you "send" all the widget parameters to the frontend. Let's say your widget will have a single String parameter, the title. You can get that parameter with $block->escapeHtml($block->getData('title'))
and assign it to the data-title
attribute:
//app/code/ScandiTutorials/CustomWidget/view/frontend/templates/widget/newsletter_widget.phtml
<?php
/** ScandiTutorials\\\\CustomWidget\\\\Block\\\\Widget\\\\NewsletterWidget $block */
?>
<widget type="newsletter" data-title="<?= $block->escapeHtml($block->getData('title')) ?>"></widget>
You may realize that widget
is not a real element type, and both attributes are custom too. This is ok, because all the HTML will get parsed on the frontend to render a custom React element.
For now, you haven't implemented any rendering on the frontend yet. So if you create a test page with this widget and view it, you won't see it. However, if you check the CMS content response received from the server, you'll see that the widget is there!
{
"data": {
"cmsPage": {
"title": "test",
"content": "<widget type=\\\\"newsletter\\\\" data-title=\\\\"hello world\\\\"></widget>\\\\n",
"page_width": "default",
"content_heading": "",
"meta_title": "",
"meta_description": "",
"meta_keywords": ""
}
}
}