Source code for djangocodemirror.widgets

# -*- coding: utf-8 -*-
"""
Form field widget
=================

"""
import json

from django import forms
from django.conf import settings
from django.utils.text import slugify

from djangocodemirror.manifest import CodeMirrorManifest


[docs]class CodeMirrorWidget(forms.Textarea): """ Widget to add a CodeMirror or DjangoCodeMirror instance on a textarea Take the same arguments than ``forms.Textarea`` and accepts one suplementary optionnal arguments : Arguments: config_name (string): A Codemirror config name available in ``settings.CODEMIRROR_SETTINGS``. Default is ``empty``. embed_config (bool): If ``True`` will add Codemirror Javascript config just below the input. Default is ``False``. Attributes: config_name (string): For given config name. template_name (string): Template path for widget rendering. """ codemirror_field_js = settings.CODEMIRROR_FIELD_INIT_JS template_name = "djangocodemirror/widget.html" def __init__(self, *args, **kwargs): self.config_name = kwargs.pop("config_name", "empty") self.embed_config = kwargs.pop("embed_config", False) super(CodeMirrorWidget, self).__init__(*args, **kwargs)
[docs] def init_manifest(self, name): """ Initialize a manifest instance Arguments: name (string): Config name to register. Returns: CodeMirrorManifest: A manifest instance where config (from ``config_name`` attribute) is registred. """ manifesto = CodeMirrorManifest() manifesto.register(name) return manifesto
[docs] def get_codemirror_field_js(self): """ Return CodeMirror HTML template from ``CodeMirrorWidget.codemirror_field_js``. Returns: string: HTML template string. """ return self.codemirror_field_js
[docs] def codemirror_config(self): """ Shortcut to get Codemirror parameters. Returns: dict: CodeMirror parameters. """ return self.editor_manifest.get_codemirror_parameters(self.config_name)
[docs] def codemirror_script(self, inputid): """ Build CodeMirror HTML script tag which contains CodeMirror init. Arguments: inputid (string): Input id. Returns: string: HTML for field CodeMirror instance. """ varname = slugify("{}_codemirror".format(inputid)).replace("-", "_") html = self.get_codemirror_field_js() opts = self.codemirror_config() return html.format(varname=varname, inputid=inputid, settings=json.dumps(opts, sort_keys=True))
def get_context(self, name, value, attrs): context = super(CodeMirrorWidget, self).get_context(name, value, attrs) # Widget allways need an id to be able to set CodeMirror Javascript # config if 'id' not in context['widget']['attrs']: context['widget']['attrs']['id'] = 'id_{}'.format(name) # Append HTML for CodeMirror Javascript config just below the textarea if self.embed_config: context['widget'].update({ 'script': self.codemirror_script(context['widget']['attrs']['id']), # noqa: E501 }) return context
[docs] def render(self, name, value, attrs=None, renderer=None): """ Returns this Widget rendered as HTML, as a Unicode string. """ if not hasattr(self, "editor_manifest"): self.editor_manifest = self.init_manifest(self.config_name) config = self.editor_manifest.get_config(self.config_name) if config.get('embed_config'): self.embed_config = True context = self.get_context(name, value, attrs) return self._render(self.template_name, context, renderer)
@property def media(self): """ Adds necessary files (Js/CSS) to the widget's medias. Returns: django.forms.Media: Media object with all assets from registered config. """ if not hasattr(self, "editor_manifest"): self.editor_manifest = self.init_manifest(self.config_name) return forms.Media( css={"all": self.editor_manifest.css()}, js=self.editor_manifest.js() )
[docs]class CodeMirrorAdminWidget(CodeMirrorWidget): """ CodeMirror widget suited for usage in models admins. Act like CodeMirrorWidget but allways embed Codemirror Javascript config. """ def __init__(self, *args, **kwargs): kwargs['embed_config'] = True super(CodeMirrorAdminWidget, self).__init__(*args, **kwargs)