springload / draftail

📝🍸 A configurable rich text editor built with Draft.js
https://www.draftail.org/
MIT License
613 stars 64 forks source link

Using Draftail outside of a Wagtail Admin page is a nightmare #450

Closed boatcoder closed 1 year ago

boatcoder commented 3 years ago

Is your proposal related to a problem?

I've got a wagtail site with this awesome RichText Editor (called Draftail) but trying to use it on a non Wagtail Admin page makes me feel dirty. I wanted a biography field that people could write about themselves and I wanted the blog authors to be able to use it as well. BUT to do that I've had to do some things that make me cringe.

Not bad:

{% block extra_css %}
  <link href="{% static 'wagtailadmin/css/panels/draftail.css' %}" type="text/css" media="all" rel="stylesheet">
{% endblock extra_css %}

WTF???? why aren't we just using Favicons for things like Bold

    <div data-sprite></div>
    <script>
        function loadIconSprite() {
            var spriteURL = '{% url "wagtailadmin_sprite" %}';
            var revisionKey = 'wagtail:spriteRevision';
            var dataKey = 'wagtail:spriteData';
            var isLocalStorage = 'localStorage' in window && typeof window.localStorage !== 'undefined';

            var insertIt = function (data) {
                var spriteContainer = document.body.querySelector('[data-sprite]');
                spriteContainer.innerHTML = data;
            }

            var insert = function (data) {
                if (document.body) {
                    insertIt(data)
                } else {
                    document.addEventListener('DOMContentLoaded', insertIt.bind(null, data));
                }
            }

            if (isLocalStorage && localStorage.getItem(revisionKey) === spriteURL) {
                var data = localStorage.getItem(dataKey);
                if (data) {
                    insert(data);
                    return true;
                }
            }

            try {
                var request = new XMLHttpRequest();
                request.open('GET', spriteURL, true);
                request.onload = function () {
                    if (request.status >= 200 && request.status < 400) {
                        data = request.responseText;
                        insert(data);
                        if (isLocalStorage) {
                            localStorage.setItem(dataKey, data);
                            localStorage.setItem(revisionKey, spriteURL);
                        }
                    }
                }
                request.send();
            } catch (e) {
                console.error(e);
            }
        }
        loadIconSprite();
    </script>

Because wagtail comments somehow needs wagtailConfig.ADMIN_API and draftail won't initialize without comments.js

      <script>
        (function(document, window) {
            window.wagtailConfig = window.wagtailConfig || {};
            wagtailConfig.ADMIN_API = {
                PAGES: '',
                DOCUMENTS: '',
                IMAGES: '',
                {# // Use this to add an extra query string on all API requests. #}
                {# // Example value: '&order=-id' #}
                EXTRA_CHILDREN_PARAMETERS: '',
            };

            {% i18n_enabled as i18n_enabled %}
            {% locales as locales %}
            wagtailConfig.I18N_ENABLED = {% if i18n_enabled %}true{% else %}false{% endif %};
            wagtailConfig.LOCALES = {{ locales|safe }};

            wagtailConfig.STRINGS = {% js_translation_strings %};

            wagtailConfig.ADMIN_URLS = {
                PAGES: ''
            };
        })(document, window);
    </script>
    <script src="{% static 'wagtailadmin/js/vendor/jquery-3.5.1.min.js' %}"></script>
    <!-- <script src="{% static 'wagtailadmin/js/core.js' %}"></script> strangely not needed -->
    <script src="{% static 'wagtailadmin/js/vendor.js' %}"></script>
    <script src="{% static 'wagtailadmin/js/comments.js' %}"></script>
    {{ form.media.js }}

All of this just to get the draftail editor on a non wagtailadmin page!

Describe the solution you’d like

{% block extra_css %}
  <link href="{% static 'wagtailadmin/css/panels/draftail.css' %}" type="text/css" media="all" rel="stylesheet">
{% endblock extra_css %}
...
    {{ form.media.js }}

This would mean that draftail needs to be standalone, not using vendor.js or comments.js so it would need to be rolled up separately. Pretty sure this was just an oversight in how things are built but I've spent about 3 hours reversing this to figure out the minimum subset of dirty I had to get to get it to work at all, and I must say the sprite loading what a HUGE surprise.

Describe alternatives you’ve considered

I haven't tried any other alternatives because I don't want 2 editors on the site, I'd like to use that really cool draftail but also be able to use it outside of the wagtail admin pages.

Additional context

https://stackoverflow.com/questions/52848686/add-rtf-rich-text-editor-to-customusercreationform-customusereditform

I don't think this guy ever got it to work, but I'm not the only one that thinks it would be nice to use it outside of the wagtail admin

zerolab commented 2 years ago

Hey @boatcoder, have you seen https://github.com/timonweb/non-admin-draftail? Maybe that can help a bit?

kiwiheretic commented 2 years ago

@zerolab 's solution only works for a website which is using Wagtail forms but what if the form is manually crafted from HTML? Or is this project incompatible with such an approach?

boatcoder commented 2 years ago

That seems like a huge step in the right direction

krystianmagdziarz commented 1 year ago

Hi, any update?

thibaudcolas commented 1 year ago

Hi, I’m going to close this now.

I’m not sure how clear this is to anyone in this thread but Draftail is a standalone editor that’s used in lots of projects that aren’t Wagtail. I think the documentation is clear on what steps are needed to use it on a given project. The editor implementation in this repository springload/draftail will never contain any Wagtail-specific code.

This issue is about Wagtail’s setup of Draftail not being usable outside the Wagtail CMS admin interface – and that’s all due to how the editor is set up specifically inside the CMS,

In addition Wagtail’s link chooser, document chooser, etc – are all specific to the CMS and would also be a pain to get working outside of the CMS admin interface.


If anyone wants to take this forward – I think being able to use some of Wagtail’s UI outside the admin UI would make for a great feature request on the Wagtail repository. I’d recommend being specific about the current issues (icons, comments, etc), and keeping it professional (avoid things like "I've had to do some things that make me cringe").

As far as the approach, the most likely way to make this work in my opinion would be to have a <wagtail-draftail></wagtail-draftail> Web Component in the CMS, which packages up the admin styles and necessary icons.