Package: djangocms-text-ckeditor
NoteVersion 5 of this package does not include a move to CKEditor version 5CKEditor (v4) is a ready-for-use HTML text editor designed to simplify web content
creation. It’s a WYSIWYG editor that brings common word processor features
directly to your web pages. Enhance your website experience with our community
maintained editor. This package aims to integrate CKEditor into django CMS as
a text plugin.NoteThis project is endorsed by thedjango CMS Association.
That means that it is officially accepted by the dCA as being in line with our roadmap vision and development/plugin policy.
Join us onSlack.WarningFor django CMS 3.8.x+ usedjangocms-text-ckeditor>= 4.x.x (e.g.: version 4.0.0).For django CMS 3.4.x+ usedjangocms-text-ckeditor>= 3.2.x (e.g.: version 3.2.1).Contribute to this project and win rewardsBecause this is a an open-source project, we welcome everyone toget involved in the projectandreceive a rewardfor their contribution.
Become part of a fantastic community and help us make django CMS the best CMS in the world.We’ll be delighted to receive your
feedback in the form of issues and pull requests. Before submitting your
pull request, please review ourcontribution guidelines.We’re grateful to all contributors who have helped create and maintain this package.
Contributors are listed at thecontributorssection.One of the easiest contributions you can make is helping to translate this addon onTransifex.DocumentationSeeREQUIREMENTSin thesetup.pyfile for additional dependencies listed in theThe current integrated Version of CKEditor is:4.17.2For a full documentation visit:http://ckeditor.com/InstallationThis plugin requiresdjango CMS3.4.5 or higher to be properly installed.For a manual install:runpip installdjangocms-text-ckeditoradddjangocms_text_ckeditorto yourINSTALLED_APPSrunpython manage.py migrate djangocms_text_ckeditorUpgrading fromcms.plugins.textremovecms.plugins.textfromINSTALLED_APPSadddjangocms_text_ckeditortoINSTALLED_APPSrunpython manage.py migrate djangocms_text_ckeditor 0001--fakeConfigurationInline editing featureInline editing allows editors to directly click on a text plugin and change
the contents in django CMS’ edit mode. The CKEditor appears directly around
the text field and can be used normally. Changes are saved as soon as the
text field leaves focus.Inline editing requires to encapsulate the HTML text in a<div>in
edit mode. This might cause some side effects with a site’s CSS, e.g. direct
child rules.To activate inline editing add the following line in your project’ssettings.py:TEXT_INLINE_EDITING = TrueThis will add a toggle button to the toolbar to allow to switch inline editing
on and off for the current session.When inline editing is active the editor will save the plugin’s content each time it loses
focus. If only text has changed the user can immediately continue to edit. If
a text-enabled plugin was changed, added, or removed he page will refresh to
update the page tree and get the correctly rendered version of the changed
plugin.Default content in PlaceholderIf you use Django-CMS >= 3.0, you can useTextPluginin “default_plugins”
(see docs about theCMS_PLACEHOLDER_CONFsetting in Django CMS 3.0).TextPluginrequires just one value:bodywhere you write your default
HTML content. If you want to add some “default children” to your
automagically added plugin (i.e. aLinkPlugin), you have to put children
references in the body. References are"%(_tag_child_<order>)s"with the
inserted order of children. For example:CMS_PLACEHOLDER_CONF = {
    'content': {
        'name' : _('Content'),
        'plugins': ['TextPlugin', 'LinkPlugin'],
        'default_plugins':[
            {
                'plugin_type':'TextPlugin',
                'values':{
                    'body':'<p>Great websites : %(_tag_child_1)s and %(_tag_child_2)s</p>'
                },
                'children':[
                    {
                        'plugin_type':'LinkPlugin',
                        'values':{
                            'name':'django',
                            'url':'https://www.djangoproject.com/'
                        },
                    },
                    {
                        'plugin_type':'LinkPlugin',
                        'values':{
                            'name':'django-cms',
                            'url':'https://www.django-cms.org'
                        },
                    },
                ]
            },
        ]
    }
}CKEDITOR_SETTINGSYou can override the settingCKEDITOR_SETTINGSin your settings.py:CKEDITOR_SETTINGS = {
    'language': '{{ language }}',
    'toolbar': 'CMS',
    'skin': 'moono-lisa',
}This is the default dict that holds allCKEditorsettings.Customizing plugin editorTo customize the plugin editor, usetoolbar_CMSattribute, as in:CKEDITOR_SETTINGS = {
    'language': '{{ language }}',
    'toolbar_CMS': [
        ['Undo', 'Redo'],
        ['cmsplugins', '-', 'ShowBlocks'],
        ['Format', 'Styles'],
    ],
    'skin': 'moono-lisa',
}Customizing HTMLField editorIf you useHTMLFieldfromdjangocms_text_ckeditor.fieldsin your own
models, usetoolbar_HTMLFieldattribute:CKEDITOR_SETTINGS = {
    'language': '{{ language }}',
    'toolbar_HTMLField': [
        ['Undo', 'Redo'],
        ['ShowBlocks'],
        ['Format', 'Styles'],
    ],
    'skin': 'moono-lisa',
}You can further customize eachHTMLFieldfield 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'],
    ]
}Addconfiguration=’MYSETTING’to theHTMLFieldusage(s) you want to
customize;Define a setting parameter named as the string used in theconfigurationargument of theHTMLFieldinstance with the desired configuration;Values not specified in your custom configuration will be taken from the globalCKEDITOR_SETTINGS.For an  overview of all the available settings have a look here:http://docs.ckeditor.com/#!/api/CKEDITOR.configInline previewThe child plugins of TextPlugin can be rendered directly inside CKEditor iftext_editor_previewisn’tFalse. However there are few important points
to note:by default CKEditor doesn’t load CSS of your project inside the editing area
and has specific settings regarding empty tags, which could mean that things
will not look as they should until CKEditor is configured correctly.See examples:add styles and js configurationstop CKEditor from removing empty spans(useful for iconfonts)if you override widget default behaviour - be aware that it requires the
property “allowedContent”to containcms-plugin[*]as this custom tag is
what allows the inline previews to be renderedImportant note: please avoid html tags in__str__representation of text
enabled plugins - this messes up inline preview.If you’re adding a Text Plugin as a child inside another plugin and want to style it
conditionally based on the parent - you can addCMSPluginBase.child_ckeditor_body_css_classattribute to the parent class.Drag & Drop ImagesIn IE and Firefox based browsers it is possible to drag and drop a picture into the text editor.
This image is base64 encoded and lives in the ‘src’ attribute as a ‘data’ tag.We detect this images, encode them and convert them to picture plugins.
If you want to overwrite this behavior for your own picture plugin:There is a setting called:TEXT_SAVE_IMAGE_FUNCTION = 'djangocms_text_ckeditor.picture_save.create_picture_plugin'you can overwrite this setting in your settings.py and point it to a function that handles image saves.
Have a look at the functioncreate_picture_pluginfor details.To completely disable the feature, setTEXT_SAVE_IMAGE_FUNCTION = None.Usage as a model fieldIf you want to use the widget on your own model fields, you can! Just import the providedHTMLFieldlike so:from djangocms_text_ckeditor.fields import HTMLFieldAnd use it in your models, just like aTextField:class MyModel(models.Model):
    myfield = HTMLField(blank=True)This field does not allow you to embed any other CMS plugins within the text editor. Plugins can only be embedded
withinPlaceholderfields.If you need to allow additional plugins to be embedded in a HTML field, convert theHTMLFieldto aPlaceholderfieldand configure the placeholder to only accept TextPlugin. For more information on using placeholders outside of the CMS see:http://docs.django-cms.org/en/latest/how_to/placeholders.htmlAuto Hyphenate TextYou can hyphenate the text entered into the editor, so that the HTML entity&shy;(soft-hyphen)
automatically is added in between words, at the correct syllable boundary.To activate this feature,pip installdjango-softhyphen. Insettings.pyadd'softhyphen'to the list ofINSTALLED_APPS.django-softhyphenalso installs hyphening dictionaries for 25
natural languages.In case you already installeddjango-softhyphenbut do not want to soft hyphenate, setTEXT_AUTO_HYPHENATEtoFalse.Extending the pluginNoteAdded in version 2.0.1You can use this plugin as base to create your own CKEditor-based plugins.You need to create your own plugin model extendingAbstractText:from djangocms_text_ckeditor.models import AbstractText

class MyTextModel(AbstractText):
    title = models.CharField(max_length=100)and a plugin class extendingTextPluginclass:from djangocms_text_ckeditor.cms_plugins import TextPlugin
from .models import MyTextModel


class MyTextPlugin(TextPlugin):
    name = _(u"My text plugin")
    model = MyTextModel

plugin_pool.register_plugin(MyTextPlugin)Note that if you override therendermethod that is inherited from the baseTextPluginclass, any child text
plugins will not render correctly. You must call the superrendermethod in order forplugin_tags_to_user_html()to render out all child plugins located in thebodyfield. For example:from djangocms_text_ckeditor.cms_plugins import TextPlugin
from .models import MyTextModel


class MyTextPlugin(TextPlugin):
    name = _(u"My text plugin")
    model = MyTextModel

    def render(self, context, instance, placeholder):
        context.update({
            'name': instance.name,
        })
        # Other custom render code you may have
    return super().render(context, instance, placeholder)

plugin_pool.register_plugin(MyTextPlugin)You can furthercustomize your pluginas other plugins.Adding plugins to the “CMS Plugins” dropdownIf you have created a plugin that you want to use within Text plugins you can make them appear in the dropdown by
making themtext_enabled. This means that you assign the propertytext_enabledof a plugin toTrue,
the default value isFalse. Here is a very simple implementation:class MyTextPlugin(TextPlugin):
    name = "My text plugin"
    model = MyTextModel
    text_enabled = TrueWhen the plugin is picked up, it will be available in theCMS Pluginsdropdown, which you can find in the editor.
This makes it very easy for users to insert special content in a user-friendly Text block, which they are familiair with.The plugin will even be previewed in the text editor.Pro-tip: make sure your plugin provides its ownicon_altmethod.
That way, if you have manytext_enabled-plugins, it can display a hint about it. For example, if you created a plugin which displays prices of configurable product, it can display a tooltip with the name of that product.For more information about extending the CMS with plugins, readdjango-cms docon how to do this.Configurable sanitizerdjangocms-text-ckeditoruseshtml5libto sanitize HTML to avoid
security issues and to check for correct HTML code.
Sanitisation may strip tags usesful for some use cases such asiframe;
you may customize the tags and attributes allowed by overriding theTEXT_ADDITIONAL_TAGSandTEXT_ADDITIONAL_ATTRIBUTESsettings:TEXT_ADDITIONAL_TAGS = ('iframe',)
TEXT_ADDITIONAL_ATTRIBUTES = ('scrolling', 'allowfullscreen', 'frameborder')In case you need more control on sanitisation you can extend AllowTokenParser class and define
your logic into parse() method. For example, if you want to skip your donut attribute during
sanitisation, you can create a class like this:from djangocms_text_ckeditor.sanitizer import AllowTokenParser


class DonutAttributeParser(AllowTokenParser):

    def parse(self, attribute, val):
        return attribute.startswith('donut-')And add your class toALLOW_TOKEN_PARSERSsettings:ALLOW_TOKEN_PARSERS = (
    'mymodule.DonutAttributeParser',
)NOTE: Some versions of CKEditor will pre-sanitize your text before passing it to the web server,
rendering the above settings useless. To ensure this does not happen, you may need to add the
following parameters toCKEDITOR_SETTINGS:...
'basicEntities': False,
'entities': False,
...To completely disable the feature, setTEXT_HTML_SANITIZE = False.See thehtml5lib documentationfor further information.Searchdjangocms-text-ckeditor works well withaldryn-searchto make text content using Haystack.Developmentpre-commit hooksThe repo uses pre-commit git hooks to run tools which ensure code quality.To utilise this, runpip installpre-commitand thenpre-commitinstall.Building the JavaScriptdjangocms-text-ckeditordistributes a javascript bundle required for the
plugin to work, which contains CKEditor itself and all the necessary plugins for
functioning within CMS. To build the bundle you need to have to install
dependencies withnpm installand then to rungulp bundle.This command also updates the file name loaded based on the file contents.Updating the CKEditorMake sure to use the url inbuild config.Running TestsYou can run tests by executing:virtualenv env
source env/bin/activate
pip install -r tests/requirements.txt
python setup.py test