Merge pull request #121 from yakky/feature/configuration

Allow ckeditor customization in HTMLField

thanks @yakky, closes #132
This commit is contained in:
Kim Thoenen 2014-06-04 17:13:02 +02:00
commit 02bc269dfd
6 changed files with 121 additions and 13 deletions

View File

@ -85,15 +85,84 @@ You can override the setting ``CKEDITOR_SETTINGS`` in your settings.py::
'skin': 'moono',
}
This is the default dict that holds all **CKEditor** settings. If you want to
use the CKEditor in your own models, then use the ``HTMLField`` from
``djangocms_text_ckeditor.fields`` and replace ``'toolbar': 'CMS'`` with
``'toolbar': 'HTMLField'`` in the above settings, in order to add an
This is the default dict that holds all **CKEditor** settings.
Customizing plugin editor
#########################
To customize the plugin editor, use `toolbar_CMS` attribute, as in::
CKEDITOR_SETTINGS = {
'language': '{{ language }}',
'toolbar_CMS': [
['Undo', 'Redo'],
['cmsplugins', '-', 'ShowBlocks'],
['Format', 'Styles'],
]
'skin': 'moono',
}
Customizing HTMLField editor
############################
If you use ``HTMLField`` from ``djangocms_text_ckeditor.fields`` in your own
models, use `toolbar_HTMLField` attribute::
CKEDITOR_SETTINGS = {
'language': '{{ language }}',
'toolbar_HTMLField': [
['Undo', 'Redo'],
['ShowBlocks'],
['Format', 'Styles'],
]
'skin': 'moono',
}
You can further customize each `HTMLField` field by using different
configuration parameter in your settings::
models.py
class Model1(models.Model):
text = HTMLField(configuration='CKEDITOR_SETTINGS_MODEL1')
class Model2(models.Model):
text = HTMLField(configuration='CKEDITOR_SETTINGS_MODEL2')
settings.py
CKEDITOR_SETTINGS_MODEL1 = {
'toolbar_HTMLField': [
['Undo', 'Redo'],
['ShowBlocks'],
['Format', 'Styles'],
['Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
]
}
CKEDITOR_SETTINGS_MODEL2 = {
'toolbar_HTMLField': [
['Undo', 'Redo'],
['Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
]
}
#. Add `configuration='MYSETTING'` to the `HTMLField` usage(s) you want to
customize;
#. Define a setting parameter named as the string used in the `configuration`
argument of the `HTMLField` instance with the desidered configuration;
Values not specified in your custom configuration will be taken from the global
``CKEDITOR_SETTINGS``.
For an overview of all the available settings have a look here:
http://docs.ckeditor.com/#!/api/CKEDITOR.config
Drag & Drop Images
------------------
@ -133,6 +202,7 @@ And use it in your models, just like a ``TextField``::
class MyModel(models.Model):
myfield = HTMLField(blank=True)
Extending the plugin
--------------------

View File

@ -5,6 +5,8 @@ from django.utils.translation import ugettext_lazy as _
from cms import __version__ as cms_version
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from djangocms_text_ckeditor.settings import TEXT_CKEDITOR_CONFIGURATION
from djangocms_text_ckeditor.widgets import TextEditorWidget
from djangocms_text_ckeditor.models import Text
from djangocms_text_ckeditor.utils import plugin_tags_to_user_html
@ -17,13 +19,17 @@ class TextPlugin(CMSPluginBase):
form = TextForm
render_template = "cms/plugins/text.html"
change_form_template = "cms/plugins/text_plugin_change_form.html"
ckeditor_configuration = TEXT_CKEDITOR_CONFIGURATION
def get_editor_widget(self, request, plugins, pk, placeholder, language):
"""
Returns the Django form Widget to be used for
the text area
"""
return TextEditorWidget(installed_plugins=plugins, pk=pk, placeholder=placeholder, plugin_language=language)
return TextEditorWidget(installed_plugins=plugins, pk=pk,
placeholder=placeholder,
plugin_language=language,
configuration=self.ckeditor_configuration)
def get_form_class(self, request, plugins, pk, placeholder, language):
"""

View File

@ -10,13 +10,26 @@ except ImportError:
class HTMLField(models.TextField):
configuration = None
def __init__(self, *args, **kwargs):
# This allow widget configuration customization from the model definition
if kwargs.get('configuration', False):
self.configuration = kwargs['configuration']
del(kwargs['configuration'])
super(HTMLField, self).__init__(*args, **kwargs)
def formfield(self, **kwargs):
defaults = {'widget': TextEditorWidget}
if self.configuration:
text_editor_widget = TextEditorWidget(configuration=self.configuration)
else:
text_editor_widget = TextEditorWidget
defaults = {'widget': text_editor_widget}
defaults.update(kwargs)
# override the admin widget
if defaults['widget'] == admin_widgets.AdminTextareaWidget:
defaults['widget'] = TextEditorWidget
defaults['widget'] = text_editor_widget
return super(HTMLField, self).formfield(**defaults)

View File

@ -20,4 +20,5 @@ else:
TEXT_SAVE_IMAGE_FUNCTION = getattr(settings, 'TEXT_SAVE_IMAGE_FUNCTION', save_function_default)
TEXT_ADDITIONAL_TAGS = getattr(settings, 'TEXT_ADDITIONAL_TAGS', ())
TEXT_ADDITIONAL_ATTRIBUTES = getattr(settings, 'TEXT_ADDITIONAL_ATTRIBUTES', ())
TEXT_ADDITIONAL_ATTRIBUTES = getattr(settings, 'TEXT_ADDITIONAL_ATTRIBUTES', ())
TEXT_CKEDITOR_CONFIGURATION = getattr(settings, 'TEXT_CKEDITOR_CONFIGURATION', None)

View File

@ -50,10 +50,9 @@ $(document).ready(function () {
init: function (container, options, settings) {
if ($('#' + container).length > 0) {
this.container = $('#' + container);
// add additional settings to options
this.options.toolbar = settings.toolbar;
this.options = $.extend(true, {
this.options = $.extend(false, {
'settings': settings
}, this.options, options);

View File

@ -1,5 +1,5 @@
import json
from copy import deepcopy
from django.conf import settings
from django.forms import Textarea
from django.template.loader import render_to_string
@ -10,7 +10,8 @@ import djangocms_text_ckeditor.settings as text_settings
class TextEditorWidget(Textarea):
def __init__(self, attrs=None, installed_plugins=None, pk=None, placeholder=None, plugin_language=None):
def __init__(self, attrs=None, installed_plugins=None, pk=None,
placeholder=None, plugin_language=None, configuration=None):
"""
Create a widget for editing text + plugins.
@ -31,17 +32,35 @@ class TextEditorWidget(Textarea):
self.pk = pk
self.placeholder = placeholder
self.plugin_language = plugin_language
if configuration and getattr(settings, configuration, False):
conf = deepcopy(text_settings.CKEDITOR_SETTINGS)
conf.update(getattr(settings, configuration))
self.configuration = conf
else:
self.configuration = text_settings.CKEDITOR_SETTINGS
def render_textarea(self, name, value, attrs=None):
return super(TextEditorWidget, self).render(name, value, attrs)
def render_additions(self, name, value, attrs=None):
language = get_language().split('-')[0]
configuration = deepcopy(self.configuration)
# We are in a plugin -> we use toolbar_CMS or a custom defined toolbar
if self.placeholder:
configuration['toolbar'] = configuration.get('toolbar', 'CMS')
# We are not in a plugin but toolbar is set to CMS (the default) ->
# we force the use of toolbar_HTMLField
elif configuration.get('toolbar', False) == 'CMS':
configuration['toolbar'] = 'HTMLField'
# Toolbar is not set or set to a custom value -> we use the custom
# value or fallback to HTMLField
else:
configuration['toolbar'] = configuration.get('toolbar', 'HTMLField')
context = {
'ckeditor_class': self.ckeditor_class,
'name': name,
'language': language,
'settings': language.join(json.dumps(text_settings.CKEDITOR_SETTINGS).split("{{ language }}")),
'settings': language.join(json.dumps(configuration).split("{{ language }}")),
'STATIC_URL': settings.STATIC_URL,
'installed_plugins': self.installed_plugins,
'plugin_pk': self.pk,