diff --git a/scripts/prepare_docs.sh b/scripts/prepare_docs.sh
index dfac6904..5b65689b 100755
--- a/scripts/prepare_docs.sh
+++ b/scripts/prepare_docs.sh
@@ -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 \
\
diff --git a/src/fobi/contrib/plugins/form_elements/content/content_richtext/README.rst b/src/fobi/contrib/plugins/form_elements/content/content_richtext/README.rst
new file mode 100644
index 00000000..f55dd010
--- /dev/null
+++ b/src/fobi/contrib/plugins/form_elements/content/content_richtext/README.rst
@@ -0,0 +1,93 @@
+fobi.contrib.plugins.form_elements.content.content_richtext
+-----------------------------------------------------------
+
+A ``Fobi`` Rich text form element plugin based on
+`Summernote `_.
+
+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``.
diff --git a/src/fobi/contrib/plugins/form_elements/content/content_richtext/__init__.py b/src/fobi/contrib/plugins/form_elements/content/content_richtext/__init__.py
new file mode 100644
index 00000000..c2cf0bb6
--- /dev/null
+++ b/src/fobi/contrib/plugins/form_elements/content/content_richtext/__init__.py
@@ -0,0 +1,10 @@
+__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext'
+__author__ = 'Frantisek Holop '
+__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'
diff --git a/src/fobi/contrib/plugins/form_elements/content/content_richtext/apps.py b/src/fobi/contrib/plugins/form_elements/content/content_richtext/apps.py
new file mode 100644
index 00000000..01939507
--- /dev/null
+++ b/src/fobi/contrib/plugins/form_elements/content/content_richtext/apps.py
@@ -0,0 +1,18 @@
+__title__ = 'fobi.contrib.plugins.form_elements.content.content_richtext.apps'
+__author__ = 'Frantisek Holop '
+__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
diff --git a/src/fobi/contrib/plugins/form_elements/content/content_richtext/base.py b/src/fobi/contrib/plugins/form_elements/content/content_richtext/base.py
new file mode 100644
index 00000000..e860f2b0
--- /dev/null
+++ b/src/fobi/contrib/plugins/form_elements/content/content_richtext/base.py
@@ -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 '
+__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)]
diff --git a/src/fobi/contrib/plugins/form_elements/content/content_richtext/fobi_form_elements.py b/src/fobi/contrib/plugins/form_elements/content/content_richtext/fobi_form_elements.py
new file mode 100644
index 00000000..ab1ce5cc
--- /dev/null
+++ b/src/fobi/contrib/plugins/form_elements/content/content_richtext/fobi_form_elements.py
@@ -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 '
+__copyright__ = 'RIPE NCC'
+__license__ = 'GPL 2.0/LGPL 2.1'
+__all__ = ('ContentRichTextPlugin',)
+
+
+form_element_plugin_registry.register(ContentRichTextPlugin)
diff --git a/src/fobi/contrib/plugins/form_elements/content/content_richtext/forms.py b/src/fobi/contrib/plugins/form_elements/content/content_richtext/forms.py
new file mode 100644
index 00000000..2f5643b7
--- /dev/null
+++ b/src/fobi/contrib/plugins/form_elements/content/content_richtext/forms.py
@@ -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 '
+__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,
+ )