Skip to main content

A Django library to integrate the Editor.js editor with image handling and custom tools.

Project description

Django Editor.js

PyPI version Build Status Coverage Status

A modern, extensible, and self-contained Django app for integrating the block-style Editor.js into your projects.

This library provides a custom EditorJSField for your models and a sandboxed iframe widget for the Django admin, ensuring a clean, conflict-free editing experience. It comes with powerful features like automatic image management, dynamic tool configuration, and a customizable HTML renderer.

Key Features

  • Iframe Sandboxing: The editor is rendered within an iframe to prevent CSS and JavaScript conflicts with the Django admin or your site's styles.
  • Dynamic Tool Configuration: Configure all Editor.js tools directly from your project's settings.py. Add, remove, or override the default toolset, including your own custom-built plugins.
  • Automatic Image Management: Integrated image upload endpoint with configurable storage. Automatically deletes unused images from storage when a model instance is updated or deleted.
  • Extensible HTML Renderer: A server-side Python class converts the saved JSON data into clean HTML, with methods for each block type that can be easily extended or overridden.
  • Built-in Template Filter: Render your content with a simple {% load ... %} and filter call, no need to write your own rendering logic.
  • Sensible Defaults: Works out-of-the-box with a rich set of common Editor.js tools.
  • Admin-Friendly UI: Features include automatic iframe resizing and a fullscreen editing mode for a better user experience.

Installation

  1. Install the package from PyPI:

    pip install dj-editor-js
    
  2. Add 'editor_js' to your INSTALLED_APPS in settings.py:

    # settings.py
    INSTALLED_APPS = [
        # ...
        'django.contrib.admin',
        'django.contrib.auth',
        # ...
        'editor_js',
    ]
    

Configuration

  1. Include the URLs: Add the library's URLs to your project's urls.py. These are required for the iframe and the image upload endpoint.

    # your_project/urls.py
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('editor-js/', include('editor_js.urls')),
        # ... your other urls
    ]
    
  2. Configure Settings (Optional): You can customize the library by adding an EDITOR_JS dictionary to your settings.py. If you don't provide this, the library will use its sensible defaults.

    # settings.py
    EDITOR_JS = {
        # Define a custom storage backend for uploaded images.
        "STORAGE_BACKEND": "app.storage.PrivateMediaStorage",
    
        # Specify the custom CSS files to be loaded inside the editor's iframe.
        "CSS_FILES": ["my_app/css/style.css", "other_app/css/style.css"],
    
        # Specify a custom Python class to render the JSON data to HTML.
        "RENDERER_CLASS": "my_app.renderers.MyCustomRenderer",
    
        # Configure the tools available to the editor.
        "TOOLS": {
            # Add a new custom tool
            'my_custom_tool': {
                'class': 'MyCustomTool',
                'script': 'my_app/js/my-custom-tool.js',
                'static': True, # True if the script is a local static file
                'config': {
                    'placeholder': 'Enter your custom text...'
                }
            },
            # Remove a default tool
            'quote': None,
        }
    }
    

Usage

In Your Models

Use the EditorJSField in your models as you would any other Django model field. It stores the editor's content as JSON.

  • To use a custom set of Editor.js tools for a field, pass a tools dictionary to the field.
  • To use the global (default) tool configuration, define the field without the tools argument.

Since EditorJSField inherits from Django's models.JSONField, you can also pass any of its standard attributes, such as blank=True or null=True.

Example:

# my_app/models.py
from django.db import models
from editor_js.fields import EditorJSField

class Post(models.Model):
    title = models.CharField(max_length=200)

    # This field will only have Header and List tools
    summary = EditorJSField(tools={
        'header': {
            'class': 'Header',
            'script': 'https://cdn.jsdelivr.net/npm/@editorjs/header@latest',
        },
        'list': {
            'class': 'EditorjsList',
            'script': 'https://cdn.jsdelivr.net/npm/@editorjs/list@latest',
        }
    })

    # This field will use the default or global tool configuration
    body = EditorJSField()
    # ...

The field will automatically render the iframe widget in the Django admin.

Rendering Content in Templates

The library includes a built-in template filter to easily render your EditorJSField data as HTML.

  1. Load the filter in your template:

    {% load editor_js_filters %}
    
  2. Apply the filter to your field's data:

    <!-- post_detail.html -->
    {% load editor_js_filters %}
    
    <article>
        <h1>{{ post.title }}</h1>
        <div class="content">
            {{ post.body|render_editor_js }}
        </div>
    </article>
    

The filter will automatically use your custom renderer class if you have specified one in your settings.


Demo Application

A fully functional demo application is included to showcase the features of this library. To try it out:

1. Clone the repository:

git clone https://github.com/otto-torino/django-editor-js.git
cd django-editor-js

2. Run the demo:

  • On Windows:

    run_demo.bat
    
  • On macOS / Linux:

    ./run_demo.sh
    

This will set up a minimal Django project, create a database, and start the development server so you can explore the editor in action.


Customization

This library is designed to be highly extensible.

Adding & Removing Tools

You can fully control the tools available in the editor via the EDITOR_JS['TOOLS'] dictionary in settings.py.

  • To remove a default tool, set its key to None:

    "TOOLS": { 'raw': None, 'table': None }
    
  • To add a new tool, add a new key with its configuration:

    "TOOLS": {
        'my_checklist': {
            'class': 'Checklist', # The JS class name
            'script': '[https://cdn.jsdelivr.net/npm/@editorjs/checklist@latest](https://cdn.jsdelivr.net/npm/@editorjs/checklist@latest)', # URL or static path
            'static': False, # Is it a local static file?
        }
    }
    

The library comes with the following default tools: Header, List, Quote, Table, Raw HTML, Embed, Image, Button, and Divider.

Custom HTML Rendering

If you add a custom tool, you'll need to tell Django how to render it.

  1. Subclass the provided EditorJsRenderer and add a render_my_tool_name method.
  2. Update settings.py to point to your new class.
# my_app/renderers.py
from editor_js.renderers import EditorJsRenderer

class MyCustomRenderer(EditorJsRenderer):
    def render_my_custom_tool(self, data):
        # Logic to convert the tool's data to HTML
        items = data.get('items', [])
        html = "<ul>"
        for item in items:
            checked = 'checked' if item.get('checked') else ''
            text = self.escape(item.get('text', ''))
            html += f'<li><input type="checkbox" {checked} disabled> {text}</li>'
        html += "</ul>"
        return html

# settings.py
EDITOR_JS = {
    "RENDERER_CLASS": "my_app.renderers.MyCustomRenderer",
    # ...
}

Custom Storage & Styling

  • Storage: To use a different storage system (like Amazon S3), set the STORAGE_BACKEND setting to the dotted path of your storage class (e.g., 'storages.backends.s3boto3.S3Boto3Storage').
  • Styling: To match the editor's appearance with your frontend, provide a path to a custom CSS file in the CSS_FILE setting. This file will be loaded inside the editor's iframe.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dj_editor_js-0.1.1.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dj_editor_js-0.1.1-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

Details for the file dj_editor_js-0.1.1.tar.gz.

File metadata

  • Download URL: dj_editor_js-0.1.1.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.0

File hashes

Hashes for dj_editor_js-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d610648c180b8c75397e470918442167112f2e8d4a6271bc678faab51d7166ff
MD5 8b58e262cfd538f6ccc467eff631ceef
BLAKE2b-256 fd28a8f964a7701dd00b4428321e974f4972898bb09ff3040c51093810fa3e33

See more details on using hashes here.

File details

Details for the file dj_editor_js-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: dj_editor_js-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 22.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.0

File hashes

Hashes for dj_editor_js-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 edd46151ae9f552ca2351d9b15484ddc05a99a6e37a114c5b7fb902a7d9357b7
MD5 a398686c1d265140cde08320bad86c36
BLAKE2b-256 9f15cc03d137d908dbc4c1103ccc5e7814762bdee87d3c0f8043c52f2a252434

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page