.. _ckeditor: ======================= CKEditor integration ======================= The project uses `CKEditor 5 Premium `_ for :ref:`drafting documents` in :term:`MEG Docs` and other places where a rich text editor is required. The integration is implemented in ``editor`` app. Use of the integration required :envvar:`CKEDITOR_PREMIUM_TOKEN`. .. seealso:: | `CKEditor documentation `_ | Manage license in `CKEditor dashboard `_ Custom Fonts ============ .. important:: Before adding any fonts, make sure of the legality of hosting said fonts on our website. Custom fonts can be added by editing the :class:`options` inside of :class:`fontFamily` in the following file: :file:`meg_forms/editor/config.py` .. important:: Make sure the fonts are alphabetically ordered in :class:`fontFamily`. You will need to place the font static files in our repository and have it added as a :class:`@font-face` like so: .. code-block:: css @font-face { font-family: 'Noto Sans'; src: url('NotoSans/NotoSans-Regular.ttf') format('truetype'); font-weight: 400; font-style: normal; } This is in :file:`meg_forms/megdocs/static/css/fonts.css` and the fonts are placed into :file:`meg_forms/megdocs/static/fonts/`. You can place the font files at a different location, but you will have to point the :class:`@font-face` src url properly. Form widget =============== Replace the text field widget with :class:`~editor.widgets.CKeditorPremiumWidget` in the form to use the CKEditor as the input. .. automodule:: editor.widgets :members: .. automodule:: editor.fields :members: Form mix-in =========== Use :class:`~editor.forms.CKEditorFormMixin` mixin to use some of the advanced features of CKEditor such as :ref:`ckeditor revision history`. .. autoclass:: editor.forms.CKEditorFormMixin :members: .. _upgrade ckeditor: Upgrading CKEditor =================== CKEditor 5 and Premium Features are now self-hosted. The bundles live under: - :file:`meg_forms/editor/static/vendor/ckeditor5/` - :file:`meg_forms/editor/static/vendor/ckeditor5-premium-features/` To upgrade, replace the contents of these directories with the new version from the CKEditor customer portal. No code changes are required unless CKEditor introduces breaking import path changes. .. seealso:: | `Releases `_ lists available versions of CKEditor. | `Changelog `_ contains migration instructions for migrating between versions. | `Self-hosted ZIP downloads `_ customer portal download page. | `Installing from a ZIP file `_. .. _ckeditor plugins: CKEditor plugins ================== Bundled plugins ----------------- Some plugins are pre-bundled with CKEditor. These can be imported and added to the editor following the `documentation `_ .. _ckeditor megusers plugin: Users ------ :class:`MegUsers` implemented in :file:`meg-users.js`. Provides a list of users to CKEditor. Fetches data from :class:`~editor.views.api.CKEditorUserAPI` and provides list of all users visible to current user. This plugin is required for other integration plugins to display the correct user name beside each item. It also provides the id of the current user so that changes can be correctly attributed to the right user. .. important:: The user IDs in CKEditor correspond to the primary keys in :class:`~megforms.models.Auditor` model, not Django :class:`~django.contrib.auth.models.User` model .. _ckeditor revision history: Revision History ----------------- :class:`RevisionHistoryIntegration` in :file:`revision-integration.js` Revision history integration interfaces with :class:`~editor.models.DocumentRevision` model via :class:`~editor.views.api.CKEditorRevisionAPI`. It provides data about past revisions to CKEditor by querying :class:`~editor.views.api.CKEditorRevisionAPI` and details about changes in each revision. Any new changes introduced by user are stored in a text field and submitted to the view where the :class:`~editor.forms.CKEditorFormMixin` passes it on to :func:`~editor.revision_utils.update_revision_history`. .. uml:: diagrams/revision.puml :caption: Overview of the revision history integration .. seealso:: CKEditor documentation: `Revision History Integration `_ config options ^^^^^^^^^^^^^^^^^ enable: bool Whether to enable revision history. url: str url to get the revision history list from from for the current document (:class:`~editor.views.api.CKEditorRevisionAPI`). Also ``{url}{id}`` will be queried to get a single version details. revisionHistoryFieldId: str id name of the form field where CKEditor's revision history changes will be stored when submitting .. code-block:: json :caption: example config json { "enable": true, "url": "/editor/api/revisions/megdocs/documentdraft/5/" } Track changes (Suggest changes) -------------------------------- :class:`TrackChangesIntegration` in :file:`track-changes-integration.js` implemented in :task:`29902`. Enables :term:`track changes` mode. Changes suggested with using this feature are stored in :class:`~editor.models.DocumentSuggestion` model. .. seealso:: | CKEditor documentation: `Track Changes `_. | :ref:`track changes` in editor documentation. .. _ckeditor comments: Comments --------- :class:`CommentsIntegration` in :file:`comments-integration.js` implemented in :task:`30696`. Enables commenting on the document and it suggestions. A :class:`~editor.models.DocumentComment` is linked to :class:`~editor.models.DocumentCommentThread`, or :class:`~editor.models.DocumentSuggestion` if it's a suggestion comment. .. uml:: diagrams/comments.puml :caption: Overview of the Comments integration models. Each od the models in the ``Editor`` package also links to the relevant :term:`document draft` object. .. seealso:: | CKEditor documentation: | `Comments integration `_ | `Comments adapter spec `_ .. _ckeditor autosave: Mentions -------- Support for mentioning users in CKEditor comments was developed in #30715. ``MentionsIntegration`` is implemented in :file:`mentions-integration.js`. It relies on the :ref:`MegUsers` plugin to provide a list of users. This feature can be disabled by setting :envvar:`CKEDITOR_ENABLE_COMMENT_MENTIONS` variable. It is currently integrated only with :ref:`ckeditor comments` plugin. Data format ^^^^^^^^^^^^ Mentions are inserted in the comment as a ```` tag. This format should not be changed as the back-end relies on it being consistent to send mention notification. .. code-block:: html :caption: Example how mentioned user is represented in the comment code. @admin-full Autosave --------- A :term:`document draft` with save automatically at the interval defined by :envvar:`CKEDITOR_AUTOSAVE_DELAY` (typically few seconds), if user has made changes to the document. All subsequent auto-saved changes will be visible as a single change under the :ref:`ckeditor revision history`. To create a new Revision, press :guilabel:`Save`, or use "Save current revision" option. Similarly, individual auto saves are not tracked to reversion to reduce number of versions created. There will be a :guilabel:`SAVING…` indicator in the editor while the document is being saved, and :guilabel:`✔️ SAVED` if all changes are saved. Autosave feature can be disabled globally by setting :envvar:`CKEDITOR_AUTOSAVE_DELAY` to ``0``. Mutex ------- The Mutex plugin was implemented in :task:`30777` (:file:`mutex.js`). It ensures that only one person is editing the document at a time by making API calls to the :ref:`Mutex API` to acquire and maintain the lock on the document. While document is locked, other users will have a read-only view of the document. Developing plugins -------------------- Follow `the documentation `_ when developing a plugin, and store any plugins in :file:`/meg_forms/editor/static/ckeditor_premium/plugins` Slim editor ------------ A slim version of ckeditor was implemented for :task:`31387`. This enables the use of many light editors on one page (used for comment sections). The js file added (:file:`ckeditor.js``) searches for divs with the .ckeditor-instance class name and replaces them with editors.