FriendsOfOro / hackoro-cms-grapejs

Integration of GrapgeJS into CMS edit fields
Other
3 stars 0 forks source link

Implementation of GrapesJS Editor #1

Closed chrisaligent closed 4 years ago

chrisaligent commented 5 years ago

It's going to take me a few days to submit a PR for this, but for now I've extracted the changes I made during the Hackathon to get GrapesJS working in the Landing Pages Editor.

Caveats

  1. Due to time constraints I made my changes directly in the vendor directory, these will need to be extracted out into the new GrapesJS Bundle (shouldn't be too difficult).
  2. Are we happy with the licensing for GrapesJS? It seems to be BSD-3. Would need to be checked before anything can be released.
  3. This demo used the Quick Start "GrapesJS Plugin Webpage Preset" demo as a starting point, much of this won't be needed in the real implementation. It also uses the Aviary Image Editor plugin, I'm not sure how to remove this.

Required Components

  1. Replace WYSIWYG Textarea widget (currently TinyMCE) with GrapesJS
  2. Inject the frontend styles from the current website into the editor
  3. On Save, persist the HTML and CSS from GrapesJS (this was incomplete)
  4. On Load (editing existing content), split the HTML and CSS and pass them back to GrapesJS

Screenshots

Selection_223 Selection_224 Selection_225

Code Changes

vendor/oro/platform/src/Oro/Bundle/UIBundle/Resources/views/Default/index.html.twig This file required the CSS/JS assets to be injected, but in the real world it should be pushed into the correct script block (like any other Bundle assets).

<link href="https://unpkg.com/grapesjs/dist/css/grapes.min.css" rel="stylesheet">
<!--<link href="dist/grapesjs-preset-webpage.min.css" rel="stylesheet">-->
<script src="https://dme0ih8comzn4.cloudfront.net/imaging/v3/editor.js"></script>
<script src="https://static.filestackapi.com/v3/filestack-0.1.10.js"></script>
<script src="https://unpkg.com/grapesjs"></script>
<script src="/js/grapesjs-preset-webpage.min.js"></script>

As far as I can tell these assets are only needed in the backend/admin area, except for the grapes.min.css file to render the frontend content. NOTE: On the last line is a grapesjs-preset-webpage.min.js file, you'll need to download this from the demo repo linked above and drop it into your public/js directory for now

vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig This is where the bulk of the code is (currently). We are replacing the default Symfony Textarea widget:

{%- block textarea_widget -%}
    <textarea {{ block('widget_attributes') }}>{{ value }}</textarea>
{%- endblock textarea_widget -%}

with GrapesJS:

{%- block textarea_widget -%}
    <div id="gjs" style="height:0px; overflow:hidden"></div>

    <textarea id="postBody" style="visibility: hidden;">{{ value }}</textarea>
    <textarea id="postCSS" style="visibility: hidden;">
        {# CSS will need to be injected here #}
    </textarea>

    <script type="text/javascript">
        var initGrapes = function() {
            var editor = grapesjs.init({
                height: '800px',
                width: '100%',
                showOffsets: 1,
                noticeOnUnload: 0,
                components: '',
                storageManager: {autoload: 0},
                container: '#gjs',
                fromElement: false,
                plugins: ['gjs-preset-webpage'],
                pluginsOpts: {
                    'gjs-preset-webpage': {}
                },
                canvas: {
                    styles: [
                        'https://demo.orocommerce.com/css/layout/default/styles.css?version=815a2ec3'
                    ]
                }
            });

            // Passes the contents of the two hidden Textareas (HTML Body + CSS) back to the Editor instance
            editor.setComponents(document.getElementById('postBody').value);
            editor.setStyle(document.getElementById('postCSS').value);
        }
        window.onload = initGrapes;
    </script>
{%- endblock textarea_widget -%}

This code can easily be refactored, but this was the minimum code needed to get the demo working during the Hackathon. During the Hackathon I would manually copy the CSS from the "Edit" button back into the Twig source for the postCSS Textarea (where there is currently a Comment). I would also manually store the HTML and CSS into the database table, as a single value so that the frontend render could be tested. Realistically this may need to be stored as a separate DB column.

I was not able to use the "JSON" storage option that was discussed on the day, I couldn't find any way to implement this which made sense to me (based on rushing through the documentation). It didn't seem necessary to me, as the GrapesJS Editor was perfectly capable of re-rendering/editing existing content as long as the HTML and CSS were passed back to it as separate values (using setComponents() and setStyle() respectively).

chrisaligent commented 5 years ago

It would be great to eventually merge this with @anyt 's code for inserting Oro Widgets (such as the Contact Us form demo he managed to hack together).

chrisaligent commented 4 years ago

This bundle is no longer needed as Oro have taken over development of GrapesJS, it is included as part of Oro 4.1:

https://oroinc.com/b2b-ecommerce/blog/updates-to-orocommerce-4-1-rc