NetgenRemoteMediaBundle
NetgenRemoteMediaBundle copied to clipboard
SPLAT-1442 ckeditor5 plugin
N.B. documentation/installation instructions have not been written yet
Changes
JS plugin
- code is versioned alongside the Vue production build, but is not built itself
- why?: cke5 cannot register pre-built plugins into an editor, the files are built at the same time as the editor itself due to a lot of dependency on singletons. Building independently creates several of the same singleton classes
- sklepex was a sort of issue with their pre-built editor, and will be addressed in their PR. tl;dr I dug through the classes and exported what the plugin needs
- ibexa is a non-issue because their editor has to be built with webpack anyway, which is pretty much the only way to make it configurable (
yarn ibexa
)
- exports
- plugin class for the editor
- function to render the ngrm fields contained in the cke5 output to front (it's cast and saved to database, and rendered as-is, so this was necessary for proper templating)
- plugin key for config - not super necessary, but does not hurt since we already have more than 1 export
- plugin flow
- in the editor, it embeds the entire Vue application as is, but with
mode: embed
for the extra fields needed - when saving, it saves a div with a few data attributes needed for casting back to the editor model
- when loading back into the editor, there is a delay in showing the selected images due to asynchronous calls being made to fill up Vue's attributes. The editor itself does not allow any form of asynchronous behaviour, so it has to be rendered as empty first
- in the editor, it embeds the entire Vue application as is, but with
- plugin configuration
-
endpoints
- most of these are functions that takelocationId
as a parameter, referring to the remote resource location-
createLocation
-
updateLocation(locationId)
-
deleteLocation(locationId)
-
getSelectedImage(locationId)
- retrieve selectedImage data for the Vue app in the editor -
viewResource(locationId)
- render a location on the front web, saved as data param. Additionally receive query params:css_class
,variation_group
,variation_name
,alignment
-
-
fieldId
- to keep Vue instances on the page unique -
config
- Vue config, merged with defaults in the plugin -
variationGroup
- necessary for rendering
-
- rendering on the web
- in cke5's data, the embedded media is saved as a div with some data attributes
- the front render function provided alongside the plugin uses the
viewEndpoint
alongside some other attributes to get the rendered field from the backend
Issues to address
- asynchronous behaviour when loading into the editor - consider a loader/disabled state while waiting?
- asynchronous behaviour when rendering on front - width/height on div so content doesn't jump around if it's an image? Will it ever be something that's not an image?
- in general - non-image behaviour?
PHP + config
Configuration
- added Configuration controller to fetch Vue's
config
attribute for the editor, is currently done within project code to fetch it only once - added bundle configuration for templates with key
view_resource
- this template is rendered by a controller that is called from JS
Controllers
All of these have been registered under ajax routes
- aforementioned Configuration controller
- new RemoteResourceLocation controllers:
- Create - creates a new location, based on form transformer
- Delete - deletes a location
- Update - updates values on a location (if it's not a resource change), also based on form transformer
- SelectedImage - gets selectedImage data for Vue, logic based on existing templates and twig functions that build the attribute for a full remote media field
- new RemoteResource controller (might be better under Location?)
- View - renders configured
netgen_remote_media.templates.view_resource
template. Default template in bundle is based on some existing rendering template
- View - renders configured
Services etc.
- added RemoteResourceService that handles the boilerplate data updating on location and resource objects
- using that service in the Transformer, can be reverted if needed, but that code was used for extraction and reuse
Vue
- new
selectedImage
fields-
selectedVariation
- one ofvariations
-
cssClass
- free text input
-
- config option
mode
for extra fields- value
embed
is used to render additional fields that fill in newselectedImage
fields
- value
-
ngrm-change
event detail has additional info-
changedField
property that tells the listener what input caused the event to fire- value
modal
is used for changes triggered by something in a modal - other values are input
name
attributes -
why?: the editor rerenders on every value change and this is mostly used to refocus a text field after
ngrm-change
is fired
- value
-
Webpack
- moved the file copying thing into a webpack plugin
- added watch script in package.json (plugin is run every time, copying the new built files on every rebuilt change)
Still needed changes/actions
- ~check for actual uniqueness of the field id when loaded into the editor (currently using command value, can likely cause issues)~ - done
- ~make
endpoints
config partially configurable (fallback to default) similarly to Vue config~ - done - ~recheck
config
merge~ - done
Usage
Using the plugin requires certain node modules to be available so it can be built. This is easily possible when building the editor alongside other project assets because all of those should already be included as dependencies, but if using a pre-built editor (sklepex, might be updated to building the editor with webpack instead of this though), the necessary classes should be exported from the source file and needed aliases set in the webpack config.
- webpack
- aliasing @ckeditor paths to where the exports can be found if they are not already in the project's JS dependencies
- plugin registration
- ibexa - has own rules of registering, might be possible to add the config to the remote-media-ibexa bundle
- other - find specific framework rules if they already have ckeditor included, like how ibexa has its own
- or have a file where the editor is initialised, import plugin class from bundle assets and add it to plugins, following ckeditor's documentation
- rendering on the web
- import the render file in a JS file that will be included on pages with ckeditor5 output, will likely need a build system
Testing
Currently testable on a Sylius project. Can be tested on sklepex where it's configured already for that project - https://bitbucket.org/forlagshuset/sklepex/pull-requests/819
Manual testing requires adding the plugin to the Ckeditor upon initialisation in the project and following the Usage section above, and various configuration information given
Issues
Does not currently work with ibexa - needs some xslt file preparation for ibexa's rich text handling