Svelte is an open-source JavaScript framework that helps to create interactive web pages. The Svelte plugin enables users to embed its components seamlessly into their content.
In this blog, we will consider how to create a custom plugin to integrate Svelte components into CKEditor 5, a powerful and extensible rich text editor that allows developers to tailor it to their specific needs.
To begin with, check out the directory structure that houses the essential components of the Svelte plugin.
Directory structure
Essential components of the Svelte plugin
1. package.json
Download the necessary CKEditor5 node modules for compiling custom plugins.
2. webpack.config.js
The Webpack.config.js file is a script designed to automate the build process for CKEditor 5 plugins located in the js/ckeditor5_plugins directory. It employs the webpack module bundler to produce plugin files that are ready for production.
This configuration script is structured to bundle CKEditor 5 plugins individually, leveraging the capabilities of the getDirectories function. This function dynamically retrieves all subdirectories within the specified path (./js/ckeditor5_plugins). For each identified directory, a distinct Webpack configuration is generated and seamlessly integrated into the module.exports array.
3. index.js
This file exports an object as the default export of the ‘index.js’ file. The object possesses a property named Svelte, and its value is the imported Svelte plugin. This is how CKEditor 5 will identify and uncover the Svelte plugin during the execution of the build process. The exported object functions as a map of available plugins that CKEditor 5 can utilize.
4. svelte.js
The Svelte class serves as the glue that integrates the editing and UI components of the plugin. It extends CKEditor's Plugin class and specifies its dependencies.
The static get requires() method in this context specifies that the Svelte master plugin requires both SvelteEditing and SvelteUI. Although these components extend the Plugin class, CKEditor 5 will not consider them as individual plugins unless explicitly exported in index.js. This emphasizes the importance of explicit export to ensure that CKEditor 5 recognizes these components as plugins.
5. SvelteEditing - Handling the model
The SvelteEditing class defines the data model for the Svelte element and the converters for handling its conversion to and from DOM markup.
The init method initializes the plugin, calling two helper methods: _defineSchema and _defineConverters, to set up the schema and converters for the Svelte model. Additionally, it adds the 'insertSvelte' command to the editor, associating it with the InsertSvelteCommand class.
The _defineSchema method sets up the schema for the Svelte model, registering the model type and specifying that it behaves like a self-contained object (isObject: true). It also defines where the model is allowed (allowWhere), where its content is allowed (allowContentOf), and the allowed attributes (allowAttributes), in this case, the 'src' attribute.
The _defineConverters method sets up the converters for the Svelte model, using the CKEditor conversion object to register converters for upcasting and downcasting.
This section registers an upcast converter, determining how existing HTML is interpreted by the editor when it loads. It specifies that when encountering an HTML iframe element with the class '-svelte-embed,' it should be upcasted to a Svelte model element.
This section registers a downcast converter for data, defining how the Svelte model should be converted to DOM markup. If the model has a 'src' attribute, it uses that value; otherwise, it defaults to 'https://www.google.com'. It creates an iframe element with the specified class and source, which is then returned.
This section registers an editing downcast converter, defining how the Svelte model should be converted to editable DOM markup. It creates an iframe element similar to the data downcast converter and then uses toWidgetEditable to wrap it as a widget in the editable view.
6. SvelteUI - User interface integration
The SvelteUI class registers the toolbar button for Svelte embeds, complete with an icon and dropdown functionality. It listens for user interactions and triggers the insertion of Svelte components into the editor.
This section adds the Svelte component to the CKEditor UI, creating a dropdown view using the createDropdown function. It sets its button view with an icon and associates it with the specified locale.
Here, a collection of items is created, representing the Svelte components to be displayed in the dropdown. It iterates through the directories obtained from the editor's configuration and adds each Svelte component as a button to the collection.
This line adds the list of Svelte components to the previously created dropdown view using the addListToDropdown function.
This section sets up an event listener using 'this.listenTo' to listen for the 'execute' event on the dropdown view. When an item is selected, it extracts the src and label from the selected item, modifies the src path, and then executes the 'insertSvelte' command on the editor with the modified src.
Finally, the init method returns the configured dropdown view, completing the initialization of the SvelteUI plugin.
7. insertsveltecommand
The heart of our plugin lies in the InsertSvelteCommand class. This command executes when the toolbar button for embedding Svelte components is pressed, utilizing CKEditor's model to insert the desired content into the editor.
This line declares the InsertSvelteCommand class, extending the CKEditor 5 Command class. This class encapsulates the logic executed when the toolbar button is pressed.
The execute method is part of the Command class and contains the logic to be executed when the command is invoked. It takes a src parameter, representing the source content to be inserted.
The createSvelte function generates a CKEditor 5 model element representing the Svelte component. It uses the writer.createElement method to create an element with the specified name ('Svelte') and attributes (in this case, the src attribute). The created element is then returned.
The final look
After enabling the module in Drupal, you should see the screen below:
In this requirement, we are passing the folders inside a specific directory from Drupal to the CKEditor5 plugin. When you access any content-type page with full HTML, you will start seeing this:
On clicking the "View Source" option, the type casting of CKEditor5 will display the iframe tag with the src attribute set to the folder's index.html.
Conclusion
Creating a custom CKEditor 5 plugin to embed Svelte components adds a new dimension to content creation. The Svelte plugin seamlessly integrates into the editor, providing users with a streamlined experience for incorporating dynamic Svelte content.
If you want to know how to integrate CKEditor 5 in Drupal 9, you can find all the important steps here.
Happy editing with Svelte !