{"id":17463054,"url":"https://github.com/hvlads/django-ckeditor-5","last_synced_at":"2025-04-14T08:57:20.215Z","repository":{"id":37787040,"uuid":"212906102","full_name":"hvlads/django-ckeditor-5","owner":"hvlads","description":"Django CKEditor 5 integration.","archived":false,"fork":false,"pushed_at":"2025-02-11T19:38:00.000Z","size":10353,"stargazers_count":178,"open_issues_count":24,"forks_count":72,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-07T03:03:55.899Z","etag":null,"topics":["ckeditor5","django"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hvlads.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":"vladislav_khoboko","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2019-10-04T21:36:06.000Z","updated_at":"2025-04-03T09:01:24.000Z","dependencies_parsed_at":"2023-02-12T10:45:56.441Z","dependency_job_id":"712730b9-f317-4577-aba6-bf8c6a3f3e0f","html_url":"https://github.com/hvlads/django-ckeditor-5","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvlads%2Fdjango-ckeditor-5","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvlads%2Fdjango-ckeditor-5/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvlads%2Fdjango-ckeditor-5/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvlads%2Fdjango-ckeditor-5/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hvlads","download_url":"https://codeload.github.com/hvlads/django-ckeditor-5/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248852122,"owners_count":21171839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ckeditor5","django"],"created_at":"2024-10-18T10:07:58.287Z","updated_at":"2025-04-14T08:57:20.191Z","avatar_url":"https://github.com/hvlads.png","language":"Python","funding_links":["https://patreon.com/vladislav_khoboko"],"categories":["Integrations"],"sub_categories":[],"readme":"Django CKEditor 5 \n==================\n\n   CKEditor 5 for Django \u003e= 2.0\n\nQuick start\n-----------\n\n .. code-block:: bash\n \n        pip install django-ckeditor-5\n\n1. Add \"django_ckeditor_5\" to your INSTALLED_APPS in your `project/settings.py` like this:\n\n .. code-block:: python\n\n        INSTALLED_APPS = [\n            ...\n            'django_ckeditor_5',\n        ]\n\n\n2. Also, in your `project/settings.py` add:\n\n  .. code-block:: python\n\n      STATIC_URL = '/static/'\n      MEDIA_URL = '/media/'\n      MEDIA_ROOT = os.path.join(BASE_DIR, 'media')\n\n      customColorPalette = [\n            {\n                'color': 'hsl(4, 90%, 58%)',\n                'label': 'Red'\n            },\n            {\n                'color': 'hsl(340, 82%, 52%)',\n                'label': 'Pink'\n            },\n            {\n                'color': 'hsl(291, 64%, 42%)',\n                'label': 'Purple'\n            },\n            {\n                'color': 'hsl(262, 52%, 47%)',\n                'label': 'Deep Purple'\n            },\n            {\n                'color': 'hsl(231, 48%, 48%)',\n                'label': 'Indigo'\n            },\n            {\n                'color': 'hsl(207, 90%, 54%)',\n                'label': 'Blue'\n            },\n        ]\n\n      CKEDITOR_5_CUSTOM_CSS = 'path_to.css' # optional\n      CKEDITOR_5_FILE_STORAGE = \"path_to_storage.CustomStorage\" # optional\n      CKEDITOR_5_CONFIGS = { \n        'default': {\n            'toolbar': {\n                'items': ['heading', '|', 'bold', 'italic', 'link',\n                          'bulletedList', 'numberedList', 'blockQuote', 'imageUpload', ],\n                        }\n    \n        },\n        'extends': {\n            'blockToolbar': [\n                'paragraph', 'heading1', 'heading2', 'heading3',\n                '|',\n                'bulletedList', 'numberedList',\n                '|',\n                'blockQuote',\n            ],\n            'toolbar': {\n                'items': ['heading', '|', 'outdent', 'indent', '|', 'bold', 'italic', 'link', 'underline', 'strikethrough',\n                          'code','subscript', 'superscript', 'highlight', '|', 'codeBlock', 'sourceEditing', 'insertImage',\n                        'bulletedList', 'numberedList', 'todoList', '|',  'blockQuote', 'imageUpload', '|',\n                        'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'mediaEmbed', 'removeFormat',\n                        'insertTable',\n                        ],\n                'shouldNotGroupWhenFull': true\n            },\n            'image': {\n                'toolbar': ['imageTextAlternative', '|', 'imageStyle:alignLeft',\n                            'imageStyle:alignRight', 'imageStyle:alignCenter', 'imageStyle:side',  '|'],\n                'styles': [\n                    'full',\n                    'side',\n                    'alignLeft',\n                    'alignRight',\n                    'alignCenter',\n                ]\n    \n            },\n            'table': {\n                'contentToolbar': [ 'tableColumn', 'tableRow', 'mergeTableCells',\n                'tableProperties', 'tableCellProperties' ],\n                'tableProperties': {\n                    'borderColors': customColorPalette,\n                    'backgroundColors': customColorPalette\n                },\n                'tableCellProperties': {\n                    'borderColors': customColorPalette,\n                    'backgroundColors': customColorPalette\n                }\n            },\n            'heading' : {\n                'options': [\n                    { 'model': 'paragraph', 'title': 'Paragraph', 'class': 'ck-heading_paragraph' },\n                    { 'model': 'heading1', 'view': 'h1', 'title': 'Heading 1', 'class': 'ck-heading_heading1' },\n                    { 'model': 'heading2', 'view': 'h2', 'title': 'Heading 2', 'class': 'ck-heading_heading2' },\n                    { 'model': 'heading3', 'view': 'h3', 'title': 'Heading 3', 'class': 'ck-heading_heading3' }\n                ]\n            }\n        },\n        'list': {\n            'properties': {\n                'styles': 'true',\n                'startIndex': 'true',\n                'reversed': 'true',\n            }\n        }\n    }\n\n    # Define a constant in settings.py to specify file upload permissions\n    CKEDITOR_5_FILE_UPLOAD_PERMISSION = \"staff\"  # Possible values: \"staff\", \"authenticated\", \"any\"\n\n3. Include the app URLconf in your `project/urls.py` like this:\n \n  .. code-block:: python\n\n       from django.conf import settings\n       from django.conf.urls.static import static\n       \n       # [ ... ]\n       \n       urlpatterns += [ \n           path(\"ckeditor5/\", include('django_ckeditor_5.urls')),\n       ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)\n\n  Alternatively, you can use your own logic for file uploads. To do this, add the following to your `settings.py` file:\n\n  .. code-block:: python\n\n    # Define a constant in settings.py to specify the custom upload file view\n    CK_EDITOR_5_UPLOAD_FILE_VIEW_NAME = \"custom_upload_file\"\n\n  Then, in your `urls.py`, include the custom upload URL pattern:\n\n  .. code-block:: python\n\n     path(\"upload/\", custom_upload_function, name=\"custom_upload_file\"),\n\nThis allows users to customize the upload file logic by specifying their own view function and URL pattern.\n\n\n\n\n\n\n    \n    \n4. Add to your `project/models.py`:\n\n  .. code-block:: python\n\n\n        from django.db import models\n        from django_ckeditor_5.fields import CKEditor5Field\n        \n        \n        class Article(models.Model):\n            title=models.CharField('Title', max_length=200)\n            text=CKEditor5Field('Text', config_name='extends')\n            \n\nIncludes the following ckeditor5 plugins:\n\n            Essentials,\n            UploadAdapter,\n            CodeBlock,\n            Autoformat,\n            Bold,\n            Italic,\n            Underline,\n            Strikethrough,\n            Code,\n            Subscript,\n            Superscript,\n            BlockQuote,\n            Heading,\n            Image,\n            ImageCaption,\n            ImageStyle,\n            ImageToolbar,\n            ImageResize,\n            Link,\n            List,\n            Paragraph,\n            Alignment,\n            Font,\n            PasteFromOffice,\n            SimpleUploadAdapter,\n            MediaEmbed,\n            RemoveFormat,\n            Table,\n            TableToolbar,\n            TableCaption,\n            TableProperties,\n            TableCellProperties,\n            Indent,\n            IndentBlock,\n            Highlight,\n            TodoList,\n            ListProperties,\n            SourceEditing,\n            GeneralHtmlSupport,\n            ImageInsert,\n            WordCount,\n            Mention,\n            Style,\n            HorizontalLine,\n            LinkImage,\n            HtmlEmbed,\n            FullPage,\n            SpecialCharacters,\n            ShowBlocks,\n            SelectAll,\n            FindAndReplace,\n            FullScreen\n\n\nExamples\n-----------\n\nExample of using a widget in a form:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  .. code-block:: python\n\n      from django import forms\n\n      from django_ckeditor_5.widgets import CKEditor5Widget\n      from .models import Comment\n\n\n      class CommentForm(forms.ModelForm):\n            \"\"\"Form for comments to the article.\"\"\"\n\n            def __init__(self, *args, **kwargs):\n                super().__init__(*args, **kwargs)\n                self.fields[\"text\"].required = False\n\n            class Meta:\n                model = Comment\n                fields = (\"author\", \"text\")\n                widgets = {\n                    \"text\": CKEditor5Widget(\n                        attrs={\"class\": \"django_ckeditor_5\"}, config_name=\"comment\"\n                    )\n                }\n\nExample of using a widget in a template:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  .. code-block:: python\n\n    {% extends 'base.html' %}\n    {% block header %}\n        {{ form.media }} # Required for styling/js to make ckeditor5 work\n    {% endblock %}\n    {% block content %}\n        \u003cform method=\"POST\"\u003e\n            {% csrf_token %}\n            {{ form.as_p }}\n            \u003cinput type=\"submit\" value=\"Submit article\"\u003e\n        \u003c/form\u003e\n    {% endblock %}\n\nCustom storage example:\n^^^^^^^^^^^^^^^^^^^^^^^\n  .. code-block:: python\n\n      import os\n      from urllib.parse import urljoin\n\n      from django.conf import settings\n      from django.core.files.storage import FileSystemStorage\n\n\n      class CustomStorage(FileSystemStorage):\n          \"\"\"Custom storage for django_ckeditor_5 images.\"\"\"\n\n          location = os.path.join(settings.MEDIA_ROOT, \"django_ckeditor_5\")\n          base_url = urljoin(settings.MEDIA_URL, \"django_ckeditor_5/\")\n\n\nChanging the language:\n^^^^^^^^^^^^^^^^^^^^^^\nYou can change the language via the ``language`` key in the config\n\n .. code-block:: python\n\n      CKEDITOR_5_CONFIGS = {\n        'default': {\n            'toolbar': ['heading', '|', 'bold', 'italic', 'link',\n                        'bulletedList', 'numberedList', 'blockQuote', 'imageUpload', ],\n            'language': 'de',\n        },\n      }\n\n``language`` can be either:\n\n1. a string containing a single language\n2. a list of languages\n3. a dict ``{\"ui\": \u003ca string (1) or a list of languages (2)\u003e}``\n\nIf you want the language to change with the user language in django\nyou can add ``CKEDITOR_5_USER_LANGUAGE=True`` to your django settings.\nAdditionally you will have to list all available languages in the ckeditor\nconfig as shown above.\n\nCreating a CKEditor5 instance from javascript:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nTo create a ckeditor5 instance dynamically from javascript you can use the\n``ClassicEditor`` class exposed through the ``window`` global variable.\n\n  .. code-block:: javascript\n\n    const config = {};\n    window.ClassicEditor\n       .create( document.querySelector( '#editor' ), config )\n       .catch( error =\u003e {\n           console.error( error );\n       } );\n    }\n\nAlternatively, you can create a form with the following structure:\n\n  .. code-block:: html\n\n    \u003cform method=\"POST\"\u003e\n        \u003cdiv class=\"ck-editor-container\"\u003e\n            \u003ctextarea id=\"id_text\" name=\"text\" class=\"django_ckeditor_5\" \u003e\n            \u003c/textarea\u003e\n            \u003cdiv\u003e\u003c/div\u003e \u003c!-- this div or any empty element is required --\u003e\n            \u003cspan class=\"word-count\" id=\"id_text_script-word-count\"\u003e\u003c/span\u003e\n       \u003c/div\u003e\n       \u003cinput type=\"hidden\" id=\"id_text_script-ck-editor-5-upload-url\" data-upload-url=\"/ckeditor5/image_upload/\" data-csrf_cookie_name=\"new_csrf_cookie_name\"\u003e\n       \u003cspan id=\"id_text_script-span\"\u003e\u003cscript id=\"id_text_script\" type=\"application/json\"\u003e{your ckeditor config}\u003c/script\u003e\u003c/span\u003e\n    \u003c/form\u003e\n\nThe ckeditor will be automatically created once the form has been added to the\nDOM.\n\nTo access a ckeditor instance you can either get them through ``window.editors``\n\n  .. code-block:: javascript\n\n    const editor = windows.editors[\"\u003cid of your field\u003e\"];\n\nor by registering a callback\n\n  .. code-block:: javascript\n\n    //register callback\n    window.ckeditorRegisterCallback(\"\u003cid of your field\u003e\", function(editor) {\n      // do something with editor\n    });\n    // unregister callback\n    window.ckeditorUnregisterCallback(\"\u003cid of your field\u003e\");\n\n\nAllow file uploading as link:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nBy default only images can be uploaded and embedded in the content. To allow\nuploading and embedding files as downloadable links you can add the following\nto your config:\n\n .. code-block:: python\n\n      CKEDITOR_5_ALLOW_ALL_FILE_TYPES = True\n      CKEDITOR_5_UPLOAD_FILE_TYPES = ['jpeg', 'pdf', 'png'] # optional\n      CKEDITOR_5_CONFIGS = {\n        'default': {\n            'toolbar': ['heading', '|', 'bold', 'italic', 'link',\n                        'bulletedList', 'numberedList', 'blockQuote', 'imageUpload', 'fileUpload' ], # include fileUpload here\n            'language': 'de',\n        },\n\n**Warning**: Uploaded files are not validated and users could upload malicious\ncontent (e.g. a pdf which actually is an executable). Furthermore allowing file\nuploads disables any validation for the image upload as the backend can't\ndistinguish between image and file upload. Exposing the file upload to\nall/untrusted users poses a risk!\n\n\nRestrict upload file size:\n^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou can restrict the maximum size for uploaded images and files by adding\n\n .. code-block:: python\n\n      CKEDITOR_5_MAX_FILE_SIZE = 5 # Max size in MB\n\nto your config. Default is 0 (allow any file size).\n\n\nInstalling from GitHub:\n^^^^^^^^^^^^^^^^^^^^^^^\n  .. code-block:: bash\n\n    cd your_root_project\n    git clone https://github.com/hvlads/django-ckeditor-5.git\n    cd django-ckeditor-5\n    yarn install\n    yarn run prod\n    cd your_root_project\n    python manage.py collectstatic\n    \nExample Sharing content styles between front-end and back-end:\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nTo apply ckeditor5 styling outside of the editor, download content.styles.css from the official ckeditor5 docs and include it as a styleshet within your HTML template. You will need to add the ck-content class to the container of your content for the styles to be applied.\n`\u003chttps://ckeditor.com/docs/ckeditor5/latest/installation/advanced/content-styles.html#sharing-content-styles-between-frontend-and-backend\u003e`_\n\n.. code-block:: html\n\n   \u003clink rel=\"stylesheet\" href=\"path/to/assets/content-styles.css\" type=\"text/css\"\u003e\n   ...\n   \u003cdiv class=\"ck-content\"\u003e\n   \u003cp\u003eckeditor content\u003c/p\u003e\n   \u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhvlads%2Fdjango-ckeditor-5","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhvlads%2Fdjango-ckeditor-5","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhvlads%2Fdjango-ckeditor-5/lists"}