ckan / ckanext-pages

A simple builtin CMS for CKAN sites
GNU General Public License v3.0
51 stars 99 forks source link

Error: CKEditor not loaded when updating blog #125

Closed ondics closed 1 year ago

ondics commented 1 year ago

Error description:

Debugging (using Docker image openknowledge/ckan-base:2.9) results in:

The two files cannot be loaded:

https://<production-ckan-hostname>/blog_edit/skins/moono-lisa/editor_gecko.css?t=L0QD
https://<production-ckan-hostname>/blog_edit/lang/de.js?t=L0QD

When using this extension as developer everything works (Docker image openknowledge/ckan-dev:2.9):

The two files are loaded with a different URLs:

https://<developer-ckan-hostname>/skins/moono-lisa/editor_gecko.css?t=L0QD
https://<developer-ckan-hostname>/lang/de.js?t=L0QD

In .env this extension is configured using

CKANEXT__PAGES__ABOUT_MENU=False
CKANEXT__PAGES__ALLOW_HTML=True
CKANEXT__PAGES__EDITOR=ckeditor

Is that a bug in the extension? Am I missing something? Config error?

pdelboca commented 1 year ago

I'm having the exact same issue. I tried to debug it today but couldn't find any reasonable solution. Looks like there is something wrong on how ckanext-pages is serving/accessing webassets.

I also don't understand why is appending /pages_edit/ when debug=False.

@smotornyuk any idea what is going on here?

smotornyuk commented 1 year ago

Sure. Don't blame webassets, ckanext-pages just didn't configure CKEditor properly.

CKEditor is an enterprise solution. It comes with themes, plugins, and modules. How can CKEditor load modules in runtime? Probably, using some assumptions. For example, CKEditor may assume that plugin xxx will be available as public xxx.js file. Does it mean, that CKEditor should append the following tag to the page, whenever it enables the xxx plugin in runtime?:

<script src="/xxx.js">Cannot load xxx plugin for CKEditor</script>

Answer: almost. Not every system serves public files from the site root. From my experience, some /public/, /static/, /assets/ prefix is usually used. That's why CKEditor is trying to be smart(and it usually works). It checks the origin of ckeditor.js. It's almost safe to assume, that ckeditor.js is loaded from a public source, thus all its plugins can be loaded from the same path.

For example. if ckeditor.js is loaded from /x/y/z/ckeditor.js, it will try to load xxx.js from the same place - /x/y/z/ceditor.js.

And it works in debug mode because every file is loaded separately. ckeditor.js loaded from the public folder, available at the site root(/ckeditor.js), so do all the plugins.

What happens in production mode? All files are compiled into a single huge main.js. There are no more cketior.js. CKEditor cannot identify a public folder for the current portal. It searches for the source of the script that initialized CKEditor instead. Is it /webassets/ckanext-pages/main.js? Yes. Probably, it should load xxx plugins from /webassets/ckanext-pages/xxx.js then? No. All the plugins, translations, etc are not included in webassets and are not served by them. CKEditor has to load them from the public path(in your case unless you are using custom site root) it's /.

How we can tell CKEditor to use a custom public path? By setting global variable CKEDITOR_BASEPATH. For example, in this case, something like this will solve the problem:

<script>window.CKEDITOR_BASEPATH = "/"</script>   

You may want to use ckan.SITE_ROOT instead of hardcoding /, but in this case, you have to make sure, that CKAN's JS is loaded before your script.

pdelboca commented 1 year ago

Thanks for your answer @smotornyuk .

I'm just trying to understand what changed since this feature stop working when updating from 2.9 to 2.10. That's why I'm pointing to ckanext-pages registering or loading assets differently than before.

CKAN 2.9 with ckanext-pages v0.3.7: Screenshot from 2023-06-07 12-05-07

CKAN 2.10 with ckanext-pages v0.5.1:

Screenshot from 2023-06-07 12-13-17

That's why I'm trying to get more insights on how webassets are handled. I'll keep looking into this!

smotornyuk commented 1 year ago

I suspect, somebody has overriden this hack