Merge pull request #100 from minusf/richtext

fobi rich text content plugin based on summernote
This commit is contained in:
Artur Barseghyan 2017-11-30 14:55:48 +01:00 committed by GitHub
commit 18e579b9f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 254 additions and 0 deletions

View file

@ -145,6 +145,9 @@ cat README.rst \
src/fobi/contrib/plugins/form_elements/content/content_text/README.rst \
docs/empty.rst.distrib \
\
src/fobi/contrib/plugins/form_elements/content/content_richtext/README.rst \
docs/empty.rst.distrib \
\
src/fobi/contrib/plugins/form_elements/content/content_video/README.rst \
docs/empty.rst.distrib \
\

View file

@ -0,0 +1,93 @@
fobi.contrib.plugins.form_elements.content.content_richtext
-----------------------------------------------------------
A ``Fobi`` Rich text form element plugin based on
`Summernote <https://summernote.org/>`_.
Installation
~~~~~~~~~~~~
(1) Install ``django-summernote``.
.. code-block:: sh
pip install django-summernote
(2) Add ``django_summernote`` to ``INSTALLED_APPS`` in ``settings.py``.
.. code-block:: python
INSTALLED_APPS = (
...
'django_summernote',
...
)
(3) Add ``django_summernote.urls`` to ``urls.py``.
.. code-block:: python
urlpatterns = [
...
url(r'^summernote/', include('django_summernote.urls')),
...
]
(4) Add ``fobi.contrib.plugins.form_elements.content.content_richtext`` to
``INSTALLED_APPS`` in ``settings.py``.
.. code-block:: python
INSTALLED_APPS = (
...
'fobi.contrib.plugins.form_elements.content.content_richtext',
...
)
(5) In the terminal type:
.. code-block:: sh
./manage.py fobi_sync_plugins
(6) Assign appropriate permissions to the target users/groups to be using
the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to ``True``.
Controlling HTML tags and attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(1) Install ``bleach``.
.. code-block:: sh
pip install bleach
(2) Specify ``FOBI_PLUGIN_CONTENT_RICHTEXT_ALLOWED_TAGS`` and
``FOBI_PLUGIN_CONTENT_RICHTEXT_ALLOWED_ATTRIBUTES`` in
``settings.py``. The default values are:
.. code-block:: python
FOBI_PLUGIN_CONTENT_RICHTEXT_ALLOWED_TAGS = [
'a',
'abbr',
'acronym',
'b',
'blockquote',
'code',
'em',
'i',
'li',
'ol',
'strong',
'ul',
]
FOBI_PLUGIN_CONTENT_RICHTEXT_ALLOWED_ATTRIBUTES = {
'a': ['href', 'title'],
'abbr': ['title'],
'acronym': ['title'],
}
For frontend-only control one could alternatively use
a ``summernote`` plugin like ``summernote-cleaner``.

View file

@ -0,0 +1,10 @@
__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext'
__author__ = 'Frantisek Holop <fholop@ripe.net>'
__copyright__ = 'RIPE NCC'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('default_app_config', 'UID')
default_app_config = 'fobi.contrib.plugins.form_elements.content.' \
'content_richtext.apps.Config'
UID = 'content_richtext'

View file

@ -0,0 +1,18 @@
__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext.apps'
__author__ = 'Frantisek Holop <fholop@ripe.net>'
__copyright__ = 'RIPE NCC'
__license__ = 'GPL 2.0/LGPL 2.1'
try:
__all__ = ('Config',)
from django.apps import AppConfig
class Config(AppConfig):
"""Config."""
name = 'fobi.contrib.plugins.form_elements.content.content_richtext'
label = 'fobi_contrib_plugins_form_elements_content_content_richtext'
except ImportError:
pass

View file

@ -0,0 +1,47 @@
from __future__ import absolute_import
from collections import OrderedDict
from uuid import uuid4
from django.utils.encoding import smart_str
from django.utils.translation import ugettext_lazy as _
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin
from . import UID
from .forms import ContentRichTextForm
__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext.base'
__author__ = 'Frantisek Holop <fholop@ripe.net>'
__copyright__ = 'RIPE NCC'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentRichTextPlugin',)
class ContentRichTextPlugin(FormElementPlugin):
uid = UID
name = _('Content rich text')
group = _('Content')
form = ContentRichTextForm
def post_processor(self):
self.data.name = '{0}_{1}'.format(self.uid, uuid4())
def get_raw_data(self):
return OrderedDict(
(
('text', self.data.text),
)
)
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
field_kwargs = {
'initial': smart_str(self.data.text),
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]

View file

@ -0,0 +1,15 @@
from __future__ import absolute_import
from fobi.base import form_element_plugin_registry
from .base import ContentRichTextPlugin
__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext.' \
'fobi_form_elements'
__author__ = 'Frantisek Holop <fholop@ripe.net>'
__copyright__ = 'RIPE NCC'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentRichTextPlugin',)
form_element_plugin_registry.register(ContentRichTextPlugin)

View file

@ -0,0 +1,68 @@
from django import forms
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django_summernote.widgets import SummernoteInplaceWidget
from fobi.base import BasePluginForm, get_theme
try:
import bleach
BLEACH_INSTALLED = True
except ImportError as err:
BLEACH_INSTALLED = False
__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext.forms'
__author__ = 'Frantisek Holop <fholop@ripe.net>'
__copyright__ = 'RIPE NCC'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentRichTextForm',)
theme = get_theme(request=None, as_instance=True)
class ContentRichTextForm(forms.Form, BasePluginForm):
plugin_data_fields = [
('text', '')
]
text = forms.CharField(
label=_('Text'),
required=True,
widget=SummernoteInplaceWidget(),
)
def clean_text(self):
if not BLEACH_INSTALLED:
return self.cleaned_data['text']
ALLOWED_TAGS = [
'a', 'abbr', 'acronym', 'b', 'blockquote',
'code', 'em', 'i', 'li', 'ol', 'strong', 'ul',
]
ALLOWED_ATTRIBUTES = {
'a': ['href', 'title'],
'abbr': ['title'],
'acronym': ['title'],
}
allowed_tags = getattr(
settings,
'FOBI_PLUGIN_CONTENT_RICHTEXT_ALLOWED_TAGS',
ALLOWED_TAGS
)
allowed_attrs = getattr(
settings,
'FOBI_PLUGIN_CONTENT_RICHTEXT_ALLOWED_ATTRIBUTES',
ALLOWED_ATTRIBUTES
)
return bleach.clean(
text=self.cleaned_data['text'],
tags=allowed_tags,
attributes=allowed_attrs,
strip=True,
strip_comments=True,
)