bnzk / django-ckeditor-link

link plugin for ckeditor, based on django modelforms/modeladmin, allowing direct linking to your models, or whatever
GNU General Public License v2.0
2 stars 2 forks source link
ckeditor django link

django-ckeditor-link

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

Installation

To get the latest stable release from PyPi

pip install django-ckeditor-link

Add ckeditor_link to your INSTALLED_APPS

INSTALLED_APPS = (
    ...,
    'ckeditor_link',
)

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/settings_test.py 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/models.py
    
    @python_2_unicode_compatible
    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" % self.target
    
        def get_link(self):
            # return link value, based on fields.
            return "http://www.dynamic.com"
    
    class LinkModel(LinkModelBase):
        pass
    
    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/admin.py
    ...
    from ckeditor_link.admin import DjangoLinkAdmin
    
    class LinkModelAdmin(DjangoLinkAdmin):
        pass
    
    admin.site.register(LinkModel, 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')
    
    CKEDITOR_CONFIGS = {
        'default': {
            'djangolinkIframeURL': CKEDITOR_LINK_IFRAME_URL,
            'djangolinkVerifyURL': CKEDITOR_LINK_VERIFY_URL,
            'djangolinkFallbackField': 'external',
            'extraPlugins': ','.join(
                [
                    # your extra plugins here
                    'djangolink',
    
                ]),
            'toolbar': 'Custom',
            'toolbar_Custom': [
                ['Bold', 'Underline'],
                ['DjangoLink', 'Unlink'],
    
            ]
        }
    }

    If you have existing content with normal <a href="https://github.com/bnzk/django-ckeditor-link/blob/develop/"> 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
CKEDITOR_LINK_ATTR_MODIFIERS = getattr(
    settings,
    'CKEDITOR_LINK_ATTR_MODIFIERS', {
        '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-).

Settings

CKEDITOR_LINK_MODEL (default: None)

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

CKEDITOR_LINK_USE_CMS_FILER (default: True if django-cms and django-filer in INSTALLED_APPS)

# when using the ckeditor_link.link_model app, enable cms and filer integration

CKEDITOR_LINK_MODEL_USE_FILER_ADDONS (default: False)

# when using filer integration, use django-filer-addons.filer_gui admin field

CKEDITOR_LINK_ATTR_MODIFIERS (default: {'cms_page': '{cms_page_2}'})

# 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
CKEDITOR_LINK_ATTR_MODIFIERS = {
    'multi_widget_field': '{multi_widget_field_1}--{multi_widget_field_whatever}'
    'cms_page': '{cms_page_2}'
}

Django Compatibility

Please refer to the CHANGELOG.txt for current supported django versions.

Contribute

Fork and code. Quickstart:

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

Testing

Either run tox for complete tests, or `python manage.py test

geckodriver install