monsieurbiz/sylius-rich-editor-plugin

A Rich Editor plugin for Sylius.

Installs: 4 004

Dependents: 2

Suggesters: 0

Security: 0

Stars: 11

Watchers: 4

Forks: 4

Open Issues: 3

Type:sylius-plugin


README

68747470733a2f2f6d6f6e736965757262697a2e636f6d2f6c6f676f2e706e67      68747470733a2f2f64656d6f2e73796c6975732e636f6d2f6173736574732f73686f702f696d672f6c6f676f2e706e67

Rich Editor

Rich Editor Plugin license Build Status Scrutinizer Code Quality

This plugin add a rich editor on fields to be able to drag and drop elements and edit it.

Example of rich editor field

Installation

composer require monsieurbiz/sylius-rich-editor-plugin

Change your config/bundles.php file to add the line for the plugin :

<?php

return [
    //..
    MonsieurBiz\SyliusRichEditorPlugin\MonsieurBizSyliusRichEditorPlugin::class => ['all' => true],
];

Then create the config file in config/packages/monsieurbiz_sylius_rich_editor.yaml :

imports:
  - { resource: "@MonsieurBizSyliusRichEditorPlugin/Resources/config/config.yaml" }

Finally import the routes in config/routes/monsieurbiz_sylius_rich_editor.yaml :

monsieur_biz_rich_editor_plugin:
    resource: "@MonsieurBizSyliusRichEditorPlugin/Resources/config/routing.yaml"

Use the Rich Editor

Update your form type

To make a field use the rich editor, you have to use RichEditorType on it.

Here is a simple example with the description field of the ProductTranslationType form :

<?php

// [...]

use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use MonsieurBiz\SyliusRichEditorPlugin\Form\Type\RichEditorType;

final class ProductTranslationType extends AbstractResourceType
{
    // [...]
    
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', TextType::class, [
                'label' => 'sylius.form.product.name',
            ])
            ->add('slug', TextType::class, [
                'label' => 'sylius.form.product.slug',
            ])
            ->add('description', RichEditorType::class, [
                'required' => false,
                'label' => 'sylius.form.product.description',
            ])
            ->add('metaKeywords', TextType::class, [
                'required' => false,
                'label' => 'sylius.form.product.meta_keywords',
            ])
            ->add('metaDescription', TextType::class, [
                'required' => false,
                'label' => 'sylius.form.product.meta_description',
            ])
        ;
    }

    // [...]
}

You will have the input display as a zone in which you can drag and drop some elements :

The product description field with rich editor

Call twig render

In your template, to display the content of the rich editor as HTML, you have to call the twig filter :

{{ content | mbiz_rich_editor_render }}

Available elements

The plugin contains some simple elements

Image element

The image element

Double Image element

The double image element

Quote element

The quote element

Text element

The text element

Video element

The video element

Title element

The title element

Button link element

The title element

Separator element

The title element

Taxon Product element

The taxon product element

It will be displayed as a carousel

Products element

The products element

It will be displayed as a carousel

Carousel view

It uses the Slick carousel used by Sylius. You can customize the templates if you want another one.

An example of a carousel

Create your own elements

In this example, we will add a Google Maps element.

Create the UiElement class

Your element NEEDS to implement the \MonsieurBiz\SyliusRichEditorPlugin\UiElement\UiElementInterface interface.

<?php

declare(strict_types=1);

namespace App\UiElement;

use MonsieurBiz\SyliusRichEditorPlugin\UiElement\AbstractUiElement;
use MonsieurBiz\SyliusRichEditorPlugin\UiElement\UiElementInterface;
use App\Form\Type\UiElement\GmapType;

class Gmap extends AbstractUiElement implements UiElementInterface
{
    protected $type = 'gmap';

    // We have an image for our element, if you don't specify it, we will use a default one
    public function getImage(): string
    {
        return '/assets/shop/images/ui_elements/gmap.svg';
    }
    
    public function getFields(): array
    {
        return [
            'gmap_link',
        ];
    }

    public function getFormClass(): string
    {
        return GmapType::class;
    }
}

You can use the trait \MonsieurBiz\SyliusRichEditorPlugin\UiElement\YoutubeVideoTrait which gives you access to the method getVideoIframeURLFromPublicURL(string $url) in your UiElement.

Create the UiElement form type

<?php

declare(strict_types=1);

namespace App\Form\Type\UiElement;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;

class GmapType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('gmap_link', TextType::class, [
                'label' => 'monsieurbiz_richeditor_plugin.ui_element.gmap.field.gmap_link',
                'required' => true,
                'constraints' => [
                    new NotBlank(),
                ],
            ])
        ;
    }
}

Declare your class as UI Element

Use your services.yaml for that:

App\UiElement\Gmap:
    tags: ['monsieurbiz_rich_editor.ui_element']

You can also use a resource for all your UiElements, example:

App\UiElement\:
    resource: '../../UiElement/'
    tags: ['monsieurbiz_rich_editor.ui_element']

Add translations

Don't forget to add the translations. Keys are autogenerated by the plugin or you can customize it in overriding the AbstractUiElement methods in your element.

Here is an example of possible translation for the GMap element :

monsieurbiz_richeditor_plugin:
    ui_element:
        gmap:
            title: 'GMap Element'
            short_description: 'Include a GMap'
            description: 'An element with a GMap URL'
            field:
                gmap_link: 'GMap Link'

Create the template to render it

The plugin will try to find a template in @MonsieurBizSyliusRichEditorPlugin/UiElement/gmap.html.twig.
You can provide a custom path in overriding the AbstractUiElement::getTemplate method in your element.

Here is an example of simple render for this element :

<iframe id="gmap_canvas" src="{{ element.gmap_link }}" scrolling="no" marginheight="0" marginwidth="0" width="600" height="500" frameborder="0"></iframe>

Tip! You can access the UiElement itself via the uiElement variable in your template!
Very useful if you use the YoutubeVideoTrait as example: {{ uiElement.getVideoIframeURLFromPublicURL(element.video_url) }}.

The result !

The element is on the toolbar

The GMap element

You have a form in the modal to edit it

The GMap form

It will use your template to render it

The GMap display

Contributing

You can open an issue or a Pull Request if you want! 😘
Thank you!