Skip to main content

Alternative link dialog for ckeditor 4, using django modeladmin forms.

Project description


Build status fails sometimes - selenium and iframes and ... sleep. Passes with local tox, believe me.

CI Version Licence PyPI Downloads

link plugin for ckeditor, based on django modelforms/modeladmin, allowing direct linking to your models, or to whatever your want.

Table of contents


To get the latest stable release from PyPi

pip install django-ckeditor-link

Add ckeditor_link to your INSTALLED_APPS


ckeditor_link does not need it's own database tables, so no need to migrate.

If you want an out of the box solution for linking, you can add ckeditor_link.link_model to your INSTALLED_APPS. Warning, EXPERIMENTAL feature.

Usage / Examples

Have a look at ckeditor_link/tests/test_app/ for a complete example.

Following steps are needed.

  1. Define a link model. Proposed way: Create an abstract base model, that you can extend from for example when having a teaser model. And a CKLink model, whose purpose is only to provide a modelform and validation. No data is ever written to that table, if used with DjangoLinkAdmin.

    # your_app/
    class LinkModelBase(models.Model):
        target = models.CharField(max_length=255, blank=True, default='', )
        external_url = models.CharField(max_length=255, blank=True, default='',)
        email = models.EmailField(blank=True, default='',)
        testmodel = models.ForeignKey(TestModel, null=True, default=None, blank=True)
        class Meta:
            abstract = True
        def __str__(self):
            # do it better
            return "LINK! %s" %
        def get_link(self):
            # return link value, based on fields.
            return ""
    class LinkModel(LinkModelBase):
    class Teaser(LinkModelBase):
        image = models.ImageField()
        title = models.CharField()
        text = models.TextField()

    For your convinience, we provide a basic abstract link model, and a django-cms / django-filer compatible version, under ckeditor_link.link_model.models. They are named LinkBase and CMSFilerLinkBase, and thought to inherit from. To use them, you would need to add ckeditor_link.link_model to INSTALLED_APPS in your settings. To use the cms / filer version, you'll need to set CKEDITOR_LINK_USE_CMS_FILER to True in your settings. You can provide your own LINK_TYPE_CHOICES, if you add some more fields, with settings.CKEDITOR_LINK_TYPE_CHOICES.

  2. Register your model with DjangoLinkAdmin.

    # your_app/
    from ckeditor_link.admin import DjangoLinkAdmin
    class LinkModelAdmin(DjangoLinkAdmin):
        pass, LinkModelAdmin)
  3. Configure your django-ckeditor (or whatever ck you use).

    # config for django-ckeditor
    CKEDITOR_LINK_MODEL = 'my_app.models.LinkModel'
    CKEDITOR_LINK_IFRAME_URL = reverse_lazy('admin:my_app_linkmodel_add')
    CKEDITOR_LINK_VERIFY_URL = reverse_lazy('admin:my_app_linkmodel_verify')
        'default': {
            'djangolinkIframeURL': CKEDITOR_LINK_IFRAME_URL,
            'djangolinkVerifyURL': CKEDITOR_LINK_VERIFY_URL,
            'djangolinkFallbackField': 'external',
            'extraPlugins': ','.join(
                    # your extra plugins here
            'toolbar': 'Custom',
            'toolbar_Custom': [
                ['Bold', 'Underline'],
                ['DjangoLink', 'Unlink'],

    If you have existing content with normal <a href=""> style links, you can migrate them into ckeditor-link mode: In the ckeditor configs, specify your model field as djangolinkFallbackField (see above), existing href values will show up in that field (and stay there).

  4. In your template, use the django-ckeditor-link templatetag. This adds lxml and cssselect as dependencies - you must install those yourself.

    {% load ckeditor_link_tags %}
    {% object.html_field|ckeditor_link_add_link %}

If your linkmodel has a multi widget (as the django-cms's PageField), you can use the CKEDITOR_LINK_ATTR_MODIFIERS setting, to modify attributes as you like. Example:

# a default, working with the provided contrib link_model and django-cms
        'cms_page': '{cms_page_2}'

The actual value of cms_page will be formatted with the python format(**kwargs) function, where kwargs are the link's data attributes and it's values (without data-).



# needed when using the ckeditor_link_add_links template filter, otherwise not
CKEDITOR_LINK_MODEL = 'my_app.models.LinkModel'


# needed when using the ckeditor_link_add_links template filter
# used to combine multi widgets values, to be in a valid form. 
# django-cms own "PageField" needs this
    'multi_widget_field': '{multi_widget_field_1}--{multi_widget_field_whatever}'
    'cms_page': '{cms_page_2}'

Django Compatibility

Officialy supported is django 1.11 LTS and 2.0, 2.1 and 2.2 LTS. As there is no magic, it will probably work with older django versions.

Add a chart with compatibility, one day.


Fork and code. Quickstart:

    pip install -r test_requirements.txt
    ./ migrate  # create local sqlite db
    ./ createsuperuser  # you want that
    ./ loaddata test_app  # same data that is used for running tests
    ./ runserver  # goto localhost:8000/admin/ or localhost:8000/testmodel/2/


Either run tox for complete tests, or `python test

geckodriver install

  • visit
  • download the latest version of "geckodriver-vX.XX.X-linux64.tar.gz"
  • unarchive the tarball (tar -xvzf geckodriver-vX.XX.X-linux64.tar.gz)
  • give executable permissions to geckodriver (chmod +x geckodriver)
  • move the geckodriver binary to /usr/local/bin or any location on your system PATH.

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

django-ckeditor-link-0.4.3.tar.gz (70.3 kB view hashes)

Uploaded source

Built Distribution

django_ckeditor_link-0.4.3-py2.py3-none-any.whl (81.7 kB view hashes)

Uploaded py2 py3

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page