You have a couple of options. The simplest is using the Text content type to include the widget using the standard TinyMCE widget feature.
Your other option is to create a new content type which wraps your widget in a Page Builder content type. Our Products content type does exactly this, it's just an interface for the Catalog Product List widget.
products.xml
contains a mass converter to create the widget directive:
view/adminhtml/pagebuilder/content_type/products.xml
<converters>
<converter component="Magento_PageBuilder/js/content-type/products/mass-converter/widget-directive" name="widget_directive">
<config>
<item name="html_variable" value="html"/>
</config>
</converter>
</converters>
Which in turn within widget-directive.ts
(or JS depending on which source you're viewing) we create the standard product list widget directive:
view/adminhtml/web/ts/js/content-type/products/mass-converter/widget-directive.ts
:
public toDom(data: ConverterDataInterface, config: ConverterConfigInterface): object {
const attributes = {
type: "Magento\\CatalogWidget\\Block\\Product\\ProductsList",
template: "Magento_CatalogWidget::product/widget/content/grid.phtml",
anchor_text: "",
id_path: "",
show_pager: 0,
products_count: data.products_count,
type_name: "Catalog Products List",
conditions_encoded: this.encodeWysiwygCharacters(data.conditions_encoded || ""),
};
if (attributes.conditions_encoded.length === 0) {
return data;
}
set(data, config.html_variable, this.buildDirective(attributes));
return data;
}
You can read more about mass converters here: https://devdocs.magento.com/page-builder/docs/reference/configurations.html#mass-converter
You can look to duplicate the Products content type and modify it to your needs. On a high level, it just feeds it's configured form fields into the directive's parameters.
Alongside the above, we have a great step by step tutorial on how to create a new content type available here: https://devdocs.magento.com/page-builder/docs/create-custom-content-type/overview.html
I threw this answer together after (temporarily) solving the issue, please forgive me if my explanation is not concise.
When inserting images via Media Gallery, an ajax request is sent to Magento\MediaGalleryUi\Model\InsertImageData\GetInsertImageData.php
, which returns the images URL path, but does not include the domain.
The result is something like /media/wysiwyg/myimage.jpg
I use a CDN where the media path is /
instead of /media
. On the backend, the preview loads fine in the Media Gallery, but when the image is inserted, the CDNs domain is removed from the URL, leaving /path/to/image.jpg
, which causes the image to load from the hostname of my store https://example.com/path/to/image.jpg
, and https://media.mycdn.com/media/path/to/image.jpg
on the frontend.
To solve this, I have modified Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent.php
, changing:
if ($forceStaticPath) {
// phpcs:ignore Magento2.Functions.DiscouragedFunction
return parse_url($this->imagesHelper->getCurrentUrl() . $filename, PHP_URL_PATH);
}
To
if ($forceStaticPath) {
// phpcs:ignore Magento2.Functions.DiscouragedFunction
return $this->imagesHelper->getCurrentUrl() . $filename;
}
This is because parse_url
with the PHP_URL_PATH
component removes the host from the URL, leaving only the path. By removing parse_url
, the full URL is used on both the frontend and backend.
I will work on a cleaner solution and (hopefully) post it at a later date.
Best Answer
Using the following class
Magento\Framework\App\Config\ScopeConfigInterface
You can access any config for any scope.
The scope can also be store for example.