{ "info": { "author": "Jaap Roes", "author_email": "jaap.roes@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "======================\nDjango Rich Text Field\n======================\n\n.. image:: https://badge.fury.io/py/django-richtextfield.svg\n :target: https://pypi.python.org/pypi/django-richtextfield/\n :alt: Latest Version\n\n.. image:: https://travis-ci.org/jaap3/django-richtextfield.svg?branch=master\n :target: https://travis-ci.org/jaap3/django-richtextfield\n\n.. image:: https://coveralls.io/repos/jaap3/django-richtextfield/badge.svg?branch=master\n :target: https://coveralls.io/r/jaap3/django-richtextfield?branch=master\n\nA Django model field and widget that renders a customizable rich\ntext/WYSIWYG widget.\n\nSupports global `editor settings`_, reusable `editor profiles`_\nand per `field & widget settings`_. There's built-in support for\npluggable server side `content sanitizers`_.\n\nTested with TinyMCE_ and CKEditor_. Designed to be easily extended to\nuse other editors.\n\n\nQuickstart\n----------\n\nInstall ``django-richtextfield`` and add it to your Django\nproject's ``INSTALLED_APPS``, ``django.contrib.admin`` must also be in ``INSTALLED_APPS``::\n\n INSTALLED_APPS = [\n 'django.contrib.admin',\n ...\n 'djrichtextfield'\n ]\n\nAdd the urls to the project's urlpatterns::\n\n path('djrichtextfield/', include('djrichtextfield.urls'))\n\nConfigure ``django-richtextfield`` in ``settings.py``::\n\n DJRICHTEXTFIELD_CONFIG = {\n 'js': ['//tinymce.cachefly.net/4.1/tinymce.min.js'],\n 'init_template': 'djrichtextfield/init/tinymce.js',\n 'settings': {\n 'menubar': False,\n 'plugins': 'link image',\n 'toolbar': 'bold italic | link image | removeformat',\n 'width': 700\n }\n }\n\nNow you're ready to use the field in your models::\n\n from djrichtextfield.models import RichTextField\n\n class Post(models.Model):\n content = RichTextField()\n\nor forms::\n\n from djrichtextfield.widgets import RichTextWidget\n\n class CommentForm(forms.ModelForm):\n content = forms.CharField(widget=RichTextWidget())\n\n\nConfiguration\n-------------\n\nDefine the ``DJRICHTEXTFIELD_CONFIG`` dictionary in your project settings.\nThis dictionary can have the following keys:\n\n.. _conf_js:\n\nJavascript souce(s)\n^^^^^^^^^^^^^^^^^^^\n\n``'js'``\n A list of required javascript files. These can be URLs to a CDN or paths\n relative to your ``STATIC_URL`` e.g.::\n\n 'js': ['//cdn.ckeditor.com/4.4.4/standard/ckeditor.js']\n\n or::\n\n 'js': ['path/to/editor.js', 'path/to/plugin.js']\n\n.. _conf_css:\n\nCSS souce(s)\n^^^^^^^^^^^^\n\n``'css'``\n A dictionary of CSS files required for various forms of output media.\n These can be URLs to a CDN or paths relative to your ``STATIC_URL`` e.g.::\n\n 'css': {\n 'all': [\n 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css'\n ]\n }\n\n or::\n\n 'css': {'all': ['path/to/editor.css', 'path/to/plugin.css']}\n\n\n.. _conf_init_template:\n\nEditor init template\n^^^^^^^^^^^^^^^^^^^^\n\n``'init_template'``\n Path to the `init template`_ for your editor. Currently\n ``django-richtextfield`` ships with two templates, either::\n\n 'init_template': 'djrichtextfield/init/tinymce.js'\n\n or::\n\n 'init_template': 'djrichtextfield/init/ckeditor.js'\n\n.. _conf_settings:\n\nEditor settings\n^^^^^^^^^^^^^^^\n\n``'settings'``\n A Python dictionary with the **default** configuration data for your\n editor e.g.::\n\n 'settings': { # TinyMCE\n 'menubar': False,\n 'plugins': 'link image',\n 'toolbar': 'bold italic | link image | removeformat',\n 'width': 700\n }\n\n or::\n\n 'settings': { # CKEditor\n 'toolbar': [\n {'items': ['Format', '-', 'Bold', 'Italic', '-',\n 'RemoveFormat']},\n {'items': ['Link', 'Unlink', 'Image', 'Table']},\n {'items': ['Source']}\n ],\n 'format_tags': 'p;h1;h2;h3',\n 'width': 700\n }\n\n.. _conf_profiles:\n\nEditor profiles\n^^^^^^^^^^^^^^^\n\n``'profiles'``\n This is an **optional** configuration key. Profiles are \"named\" custom\n settings used to configure specific type of fields. You can configure\n profiles like this::\n\n 'profiles': {\n 'basic': {\n 'toolbar': 'bold italic | removeformat'\n },\n 'advanced': {\n 'plugins': 'link image table code',\n 'toolbar': 'formatselect | bold italic | removeformat |'\n ' link unlink image table | code'\n }\n }\n\n .. note:: A profile is treated the same way as directly defined\n `field & widget settings`_. This means that\n profile settings are merged with the defaults!\n\n.. _conf_sanitizer:\n\nContent sanitizers\n^^^^^^^^^^^^^^^^^^\n\n``'sanitizer'``\n This is an **optional** configuration key. A sanitizer can be used to\n process submitted values before it is returned by the widget. By default no\n processing is performed on submitted values. You can configure a sanitizer\n either by providing a function or an importable path to a function, like\n so::\n\n 'sanitizer': lambda value: '

Title

' + value\n\n or::\n\n 'sanitizer': 'bleach.clean'\n\n.. _conf_sanitizer_profiles:\n\n``'sanitizer_profiles'``\n This is an **optional** configuration key. It is possible to override\n the default or configured sanitizer for each of the configured `profiles`_.\n For example to set a custom sanitizer for the ``advanced`` profile::\n\n 'sanitizer_profiles': {\n 'advanced': lambda value: value + 'This text has been sanitized.'\n }\n\n\nField & Widget settings\n-----------------------\n\nYou can override the default settings per field::\n\n class CommentForm(forms.ModelForm):\n content = forms.CharField(widget=RichTextWidget())\n content.widget.field_settings = {'your': 'custom', 'settings': True}\n\nor::\n\n class Post(models.Model):\n content = RichTextField(\n field_settings={'your': 'custom', 'settings': True},\n sanitizer='bleach.linkify'\n )\n\nIt's recommended to use `profiles`_, they make it easier to switch configs\nor even editors on a later date. You use a profile like this::\n\n class CommentForm(forms.ModelForm):\n content = forms.CharField(widget=RichTextWidget(field_settings='basic'))\n\nor::\n\n class Post(models.Model):\n content = RichTextField(field_settings='advanced')\n\n.. note:: Fields always inherit the default settings, customs settings and\n profiles are merged with the defaults!\n\n\nCustom init / Using another editor\n----------------------------------\n\nIt should be fairly easy to use this project with another editor.\nAll that's required is to configure ``DJRICHTEXTFIELD_CONFIG`` to load the\nright Javascript/CSS files and to create a custom `init template`_.\n\nFor example, to use jQuery based Summernote_ (lite) editor::\n\n DJRICHTEXTFIELD_CONFIG = {\n 'js': [\n '//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js',\n '//cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote-lite.js',\n ],\n 'css': {\n 'all': [\n '//cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote-lite.css',\n ]\n },\n 'init_template': 'path/to/init/summernote.js',\n 'settings': {\n 'followingToolbar': False,\n 'minHeight': 250,\n 'width': 700,\n 'toolbar': [\n ['style', ['bold', 'italic', 'clear']],\n ],\n }\n }\n\nInit template\n^^^^^^^^^^^^^\n\nThe init template is a Django template (so it should be in the template and\nnot in the static directory). It contains a tiny bit of Javascript that's\ncalled to initialize each editor. For example, the init template for Summernote\nwould like this::\n\n $('#' + id).summernote(settings)\n\nThe init template has the following Javascript variables available from the\nouter scope:\n\n``$e``\n jQuery wrapped textarea to be replaced (using the jQuery version bundled\n with Django's admin)\n``id``\n The ``id`` attribute of the textarea\n``default_settings``\n ``DJRICHTEXTFIELD_CONFIG['settings']`` as a JS object\n``custom_settings``\n The ``field_settings`` as a JS object\n``settings``\n Merge of ``default_settings`` and ``custom_settings``\n\n\nHandling uploads & other advanced features\n------------------------------------------\n\n``django-richtextfield`` built to be editor agnostic. This means that it's\nup to you to handle file uploads, show content previews and support\nother \"advanced\" features.\n\n\n.. _Profiles: conf_profiles_\n.. _TinyMCE: https://www.tinymce.com/\n.. _CKEditor: https://ckeditor.com/\n.. _Summernote: https://summernote.org/\n\n\nHistory\n-------\n\n1.4.0 (2019-01-31)\n^^^^^^^^^^^^^^^^^^\n\n* Add support for pluggable server side content sanitizers\n\n\n1.3.0 (2018-11-05)\n^^^^^^^^^^^^^^^^^^\n\n* Allow CSS files to be included by a ``RichTextWidget``\n\n\n1.2.4 (2018-09-25)\n^^^^^^^^^^^^^^^^^^\n\n* Fix display issue in Django 2.1's admin interface\n\n\n1.2.3 (2018-09-11)\n^^^^^^^^^^^^^^^^^^\n\n* Add support for Django 2.1\n\n\n1.2.2 (2018-06-12)\n^^^^^^^^^^^^^^^^^^\n\n* Conditionally load the (un)minified version of jquery depending on ``DEBUG``\n* Load jQuery before all other scripts\n\n\n1.2.1 (2018-01-18)\n^^^^^^^^^^^^^^^^^^\n\n* Add ``['admin/js/vendor/jquery/jquery.min.js', 'admin/js/jquery.init.js']``\n to ``RichTextWidget.media.js``. This makes the widget usable outside of the\n admin (but still requires ``django.contrib.admin`` to be in ``INSTALLED_APPS``)\n and prevents javascript errors inside the admin in certain edge cases.\n\n\n1.2 (2017-12-04)\n^^^^^^^^^^^^^^^^\n\n* Remove support for Django < 1.11\n* Add support for Django 2.0\n\n\n1.1 (2016-01-14)\n^^^^^^^^^^^^^^^^\n\n* Remove support for Django < 1.8\n* Tested with Django 1.8 & Django 1.9\n\n1.0.1 (2014-11-13)\n^^^^^^^^^^^^^^^^^^\n\n* Fix unicode error\n\n1.0 (2014-09-30)\n^^^^^^^^^^^^^^^^\n\n* First release", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/jaap3/django-richtextfield", "keywords": "django-richtextfield,djrichtextfield django wywiwyg field", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "django-richtextfield", "package_url": "https://pypi.org/project/django-richtextfield/", "platform": "", "project_url": "https://pypi.org/project/django-richtextfield/", "project_urls": { "Homepage": "https://github.com/jaap3/django-richtextfield" }, "release_url": "https://pypi.org/project/django-richtextfield/1.4.0/", "requires_dist": null, "requires_python": "", "summary": "A Django model field and widget that renders a customizable WYSIWYG/rich text editor", "version": "1.4.0" }, "last_serial": 4763554, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "8887cb89751c2d5af1f4a9f02b0b3e6d", "sha256": "271ad82cd0c64819c19c92971998a9d87d1e6246546698f0535cbe2bd84887f4" }, "downloads": -1, "filename": "django_richtextfield-1.0-py2-none-any.whl", "has_sig": false, "md5_digest": "8887cb89751c2d5af1f4a9f02b0b3e6d", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11025, "upload_time": "2014-09-30T13:22:18", "url": "https://files.pythonhosted.org/packages/e3/b1/1edf0806fdc332da89002c6e131e0baf407d42371af2df5ce431bd39ba36/django_richtextfield-1.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3a2d481f8ea27dd61d0aac56a22f48e2", "sha256": "6d7314d56a7a4db7d70fb457aff888b5e0a7262e01b4a6d2857be37ba7f8a344" }, "downloads": -1, "filename": "django-richtextfield-1.0.tar.gz", "has_sig": false, "md5_digest": "3a2d481f8ea27dd61d0aac56a22f48e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13780, "upload_time": "2014-09-30T13:22:14", "url": "https://files.pythonhosted.org/packages/61/ad/b3d1dca54bf6f0273b0e3f7ff1705ae211ddd82ccab50b0b3b44abb760ed/django-richtextfield-1.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "6eab625330964c9eac68bcf6bf12a0cb", "sha256": "62a53b1e500a721b613dc6cc841f87065da0f99cecf82c113441f304593c7f81" }, "downloads": -1, "filename": "django_richtextfield-1.0.1-py2-none-any.whl", "has_sig": false, "md5_digest": "6eab625330964c9eac68bcf6bf12a0cb", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11306, "upload_time": "2014-11-13T15:02:06", "url": "https://files.pythonhosted.org/packages/33/0a/a77950b8dd6a12637a5a1471b7533e34281d00a4887ecb25878d548eee28/django_richtextfield-1.0.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "76cc841a6abac9ec0925294ce152de59", "sha256": "aea6bdaa928e5fcfaf79c6206d6b266d177fbc29aae788a07e6923d70ea14953" }, "downloads": -1, "filename": "django-richtextfield-1.0.1.tar.gz", "has_sig": false, "md5_digest": "76cc841a6abac9ec0925294ce152de59", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13963, "upload_time": "2014-11-13T15:02:04", "url": "https://files.pythonhosted.org/packages/7d/4d/da522265e3018880bbe67c7871834ba41ed52e9aa0fa3793beace51b03e1/django-richtextfield-1.0.1.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "4d9eb19dc4bb5def23c03fe12e24287a", "sha256": "5536864526b8a6e44ac9c8b9a2a65b05d0410110661376ea3caa71385349454f" }, "downloads": -1, "filename": "django_richtextfield-1.1-py2-none-any.whl", "has_sig": false, "md5_digest": "4d9eb19dc4bb5def23c03fe12e24287a", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11165, "upload_time": "2016-01-14T09:36:50", "url": "https://files.pythonhosted.org/packages/cd/d3/17e76d8d9a260e404268d956a66ecbfcbd4b28d0e6e85a6d89bc6890b6e9/django_richtextfield-1.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2d98b9f330aefd61630a991785db2a1b", "sha256": "fe0f9ab86d29c0ea84f6592184b30dd588151310509216d4afee91d78810da48" }, "downloads": -1, "filename": "django_richtextfield-1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "2d98b9f330aefd61630a991785db2a1b", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 11170, "upload_time": "2016-01-14T09:34:53", "url": "https://files.pythonhosted.org/packages/01/41/ef91965e501b07abb377f9228dfb5e4f5218815c347ee3ecb6044c4f152b/django_richtextfield-1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a07f7e7f6b877b6a58585fa7a75ed6f3", "sha256": "75edc5de43ea315e54039c96a8c63892167c1c500f20274985007eb3493cecb6" }, "downloads": -1, "filename": "django-richtextfield-1.1.tar.gz", "has_sig": false, "md5_digest": "a07f7e7f6b877b6a58585fa7a75ed6f3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13374, "upload_time": "2016-01-14T09:31:05", "url": "https://files.pythonhosted.org/packages/ca/f4/f0c67108731bee8aed66051355a8113a93561fca4a15024efa1cad893ff3/django-richtextfield-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "a63f46c6b9b03412f845dfbe2b8879e4", "sha256": "674deb2d35732bac4798d9b81c1d177d86c980851ce75d1a3fd6fba7b351d82b" }, "downloads": -1, "filename": "django-richtextfield-1.2.tar.gz", "has_sig": false, "md5_digest": "a63f46c6b9b03412f845dfbe2b8879e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13407, "upload_time": "2017-12-04T11:25:43", "url": "https://files.pythonhosted.org/packages/13/b5/752e1638481279d5e7b1b62353e020bf6359ae340dfbacecb5b45cc0f303/django-richtextfield-1.2.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "163cd42c936a72ed83d534e5509103f2", "sha256": "11d42b9dfd029feb2174ac4bc385cfd1f8ac556f2118c1026534167030447bd9" }, "downloads": -1, "filename": "django-richtextfield-1.2.1.tar.gz", "has_sig": false, "md5_digest": "163cd42c936a72ed83d534e5509103f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13764, "upload_time": "2018-01-18T08:58:19", "url": "https://files.pythonhosted.org/packages/f3/2e/35aacf187dbae1c7241d7c367b4a2d366bc8da5874e223960306efd4b04e/django-richtextfield-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "edfd1528f0245bcb9d65ec3f8cd2eef3", "sha256": "19b04d42c3cbff714ab7258bda9c0ba1600ec37c54df72de649bf2470b53b178" }, "downloads": -1, "filename": "django-richtextfield-1.2.2.tar.gz", "has_sig": false, "md5_digest": "edfd1528f0245bcb9d65ec3f8cd2eef3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13921, "upload_time": "2018-06-12T11:41:52", "url": "https://files.pythonhosted.org/packages/e9/39/64639650b498410f3ee7218c5c3a665133598ef4445d11ca87320319092a/django-richtextfield-1.2.2.tar.gz" } ], "1.2.3": [ { "comment_text": "", "digests": { "md5": "87db04c5a197a806d378e612045dab7c", "sha256": "5e2701a0f5561ec031dc5d9a13e4ba1bcd168e37fe69bd98c90e8913c3b11b63" }, "downloads": -1, "filename": "django-richtextfield-1.2.3.tar.gz", "has_sig": false, "md5_digest": "87db04c5a197a806d378e612045dab7c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14195, "upload_time": "2018-09-11T10:03:12", "url": "https://files.pythonhosted.org/packages/3e/da/e694e234e5a30eef018ac4203f01c9061edad2a4485af9873f2f3e91e67a/django-richtextfield-1.2.3.tar.gz" } ], "1.2.4": [ { "comment_text": "", "digests": { "md5": "3ebec05fed6bfed186c531b7f293f3b4", "sha256": "fcbaeccedd74e006dcb037271a2fd0f23848bfed0ecc6f83b4ca880fd7c94195" }, "downloads": -1, "filename": "django-richtextfield-1.2.4.tar.gz", "has_sig": false, "md5_digest": "3ebec05fed6bfed186c531b7f293f3b4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14315, "upload_time": "2018-09-25T07:22:11", "url": "https://files.pythonhosted.org/packages/65/c0/f140326745a523407c50d5e5f7ae5b628d2e5607fd731b1b8bb6da2492e7/django-richtextfield-1.2.4.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "85eafac69af5e6c421a2db45d08a1f9b", "sha256": "0c46f3a21a04debfb12e2cd7fe128e2d251452ae4bbc97547617f39635a53384" }, "downloads": -1, "filename": "django-richtextfield-1.3.0.tar.gz", "has_sig": false, "md5_digest": "85eafac69af5e6c421a2db45d08a1f9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15255, "upload_time": "2018-11-05T10:01:12", "url": "https://files.pythonhosted.org/packages/9d/4a/cc03868e11f76d21342927f0412b98b4f567097f2774d7068ddeb43634d1/django-richtextfield-1.3.0.tar.gz" } ], "1.4.0": [ { "comment_text": "", "digests": { "md5": "cfd2192428bb2ef732da8b21ada447e3", "sha256": "26d98cac9b113df749ec00827f242e9c3844a1b4fb37554763d58371cc7d5217" }, "downloads": -1, "filename": "django-richtextfield-1.4.0.tar.gz", "has_sig": false, "md5_digest": "cfd2192428bb2ef732da8b21ada447e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17805, "upload_time": "2019-01-31T12:43:04", "url": "https://files.pythonhosted.org/packages/fb/c5/aae0a4042e65c7b4c88a2feb7a16643575bae6724444fe9a9264516949d7/django-richtextfield-1.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "cfd2192428bb2ef732da8b21ada447e3", "sha256": "26d98cac9b113df749ec00827f242e9c3844a1b4fb37554763d58371cc7d5217" }, "downloads": -1, "filename": "django-richtextfield-1.4.0.tar.gz", "has_sig": false, "md5_digest": "cfd2192428bb2ef732da8b21ada447e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17805, "upload_time": "2019-01-31T12:43:04", "url": "https://files.pythonhosted.org/packages/fb/c5/aae0a4042e65c7b4c88a2feb7a16643575bae6724444fe9a9264516949d7/django-richtextfield-1.4.0.tar.gz" } ] }