mirror of
https://github.com/django/django.git
synced 2024-11-30 23:20:50 +01:00
Removed django.contrib.markup.
This commit is contained in:
parent
f27a4ee327
commit
ebd2598596
@ -1,90 +0,0 @@
|
||||
"""
|
||||
Set of "markup" template filters for Django. These filters transform plain text
|
||||
markup syntaxes to HTML; currently there is support for:
|
||||
|
||||
* Textile, which requires the PyTextile library available at
|
||||
http://loopcore.com/python-textile/
|
||||
|
||||
* Markdown, which requires the Python-markdown library from
|
||||
http://www.freewisdom.org/projects/python-markdown
|
||||
|
||||
* reStructuredText, which requires docutils from http://docutils.sf.net/
|
||||
"""
|
||||
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from django.utils.encoding import force_bytes, force_text
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter(is_safe=True)
|
||||
def textile(value):
|
||||
try:
|
||||
import textile
|
||||
except ImportError:
|
||||
if settings.DEBUG:
|
||||
raise template.TemplateSyntaxError("Error in 'textile' filter: The Python textile library isn't installed.")
|
||||
return force_text(value)
|
||||
else:
|
||||
return mark_safe(force_text(textile.textile(force_bytes(value), encoding='utf-8', output='utf-8')))
|
||||
|
||||
@register.filter(is_safe=True)
|
||||
def markdown(value, arg=''):
|
||||
"""
|
||||
Runs Markdown over a given value, optionally using various
|
||||
extensions python-markdown supports.
|
||||
|
||||
Syntax::
|
||||
|
||||
{{ value|markdown:"extension1_name,extension2_name..." }}
|
||||
|
||||
To enable safe mode, which strips raw HTML and only returns HTML
|
||||
generated by actual Markdown syntax, pass "safe" as the first
|
||||
extension in the list.
|
||||
|
||||
If the version of Markdown in use does not support extensions,
|
||||
they will be silently ignored.
|
||||
|
||||
"""
|
||||
import warnings
|
||||
warnings.warn('The markdown filter has been deprecated',
|
||||
category=DeprecationWarning)
|
||||
try:
|
||||
import markdown
|
||||
except ImportError:
|
||||
if settings.DEBUG:
|
||||
raise template.TemplateSyntaxError("Error in 'markdown' filter: The Python markdown library isn't installed.")
|
||||
return force_text(value)
|
||||
else:
|
||||
markdown_vers = getattr(markdown, "version_info", 0)
|
||||
if markdown_vers < (2, 1):
|
||||
if settings.DEBUG:
|
||||
raise template.TemplateSyntaxError(
|
||||
"Error in 'markdown' filter: Django does not support versions of the Python markdown library < 2.1.")
|
||||
return force_text(value)
|
||||
else:
|
||||
extensions = [e for e in arg.split(",") if e]
|
||||
if extensions and extensions[0] == "safe":
|
||||
extensions = extensions[1:]
|
||||
return mark_safe(markdown.markdown(
|
||||
force_text(value), extensions, safe_mode=True, enable_attributes=False))
|
||||
else:
|
||||
return mark_safe(markdown.markdown(
|
||||
force_text(value), extensions, safe_mode=False))
|
||||
|
||||
@register.filter(is_safe=True)
|
||||
def restructuredtext(value):
|
||||
import warnings
|
||||
warnings.warn('The restructuredtext filter has been deprecated',
|
||||
category=DeprecationWarning)
|
||||
try:
|
||||
from docutils.core import publish_parts
|
||||
except ImportError:
|
||||
if settings.DEBUG:
|
||||
raise template.TemplateSyntaxError("Error in 'restructuredtext' filter: The Python docutils library isn't installed.")
|
||||
return force_text(value)
|
||||
else:
|
||||
docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
|
||||
parts = publish_parts(source=force_bytes(value), writer_name="html4css1", settings_overrides=docutils_settings)
|
||||
return mark_safe(force_text(parts["fragment"]))
|
@ -1,108 +0,0 @@
|
||||
# Quick tests for the markup templatetags (django.contrib.markup)
|
||||
import re
|
||||
import warnings
|
||||
|
||||
from django.template import Template, Context
|
||||
from django import test
|
||||
from django.utils import unittest
|
||||
from django.utils.html import escape
|
||||
|
||||
try:
|
||||
import textile
|
||||
except ImportError:
|
||||
textile = None
|
||||
|
||||
try:
|
||||
import markdown
|
||||
markdown_version = getattr(markdown, "version_info", 0)
|
||||
except ImportError:
|
||||
markdown = None
|
||||
|
||||
try:
|
||||
import docutils
|
||||
except ImportError:
|
||||
docutils = None
|
||||
|
||||
class Templates(test.TestCase):
|
||||
|
||||
textile_content = """Paragraph 1
|
||||
|
||||
Paragraph 2 with "quotes" and @code@"""
|
||||
|
||||
markdown_content = """Paragraph 1
|
||||
|
||||
## An h2"""
|
||||
|
||||
rest_content = """Paragraph 1
|
||||
|
||||
Paragraph 2 with a link_
|
||||
|
||||
.. _link: http://www.example.com/"""
|
||||
|
||||
def setUp(self):
|
||||
self.save_warnings_state()
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning, module='django.contrib.markup')
|
||||
|
||||
def tearDown(self):
|
||||
self.restore_warnings_state()
|
||||
|
||||
@unittest.skipUnless(textile, 'textile not installed')
|
||||
def test_textile(self):
|
||||
t = Template("{% load markup %}{{ textile_content|textile }}")
|
||||
rendered = t.render(Context({'textile_content':self.textile_content})).strip()
|
||||
self.assertEqual(rendered.replace('\t', ''), """<p>Paragraph 1</p>
|
||||
|
||||
<p>Paragraph 2 with “quotes” and <code>code</code></p>""")
|
||||
|
||||
@unittest.skipIf(textile, 'textile is installed')
|
||||
def test_no_textile(self):
|
||||
t = Template("{% load markup %}{{ textile_content|textile }}")
|
||||
rendered = t.render(Context({'textile_content':self.textile_content})).strip()
|
||||
self.assertEqual(rendered, escape(self.textile_content))
|
||||
|
||||
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
|
||||
def test_markdown(self):
|
||||
t = Template("{% load markup %}{{ markdown_content|markdown }}")
|
||||
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()
|
||||
pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")
|
||||
self.assertTrue(pattern.match(rendered))
|
||||
|
||||
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
|
||||
def test_markdown_attribute_disable(self):
|
||||
t = Template("{% load markup %}{{ markdown_content|markdown:'safe' }}")
|
||||
markdown_content = "{@onclick=alert('hi')}some paragraph"
|
||||
rendered = t.render(Context({'markdown_content':markdown_content})).strip()
|
||||
self.assertTrue('@' in rendered)
|
||||
|
||||
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
|
||||
def test_markdown_attribute_enable(self):
|
||||
t = Template("{% load markup %}{{ markdown_content|markdown }}")
|
||||
markdown_content = "{@onclick=alert('hi')}some paragraph"
|
||||
rendered = t.render(Context({'markdown_content':markdown_content})).strip()
|
||||
self.assertFalse('@' in rendered)
|
||||
|
||||
@unittest.skipIf(markdown, 'markdown is installed')
|
||||
def test_no_markdown(self):
|
||||
t = Template("{% load markup %}{{ markdown_content|markdown }}")
|
||||
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()
|
||||
self.assertEqual(rendered, self.markdown_content)
|
||||
|
||||
@unittest.skipUnless(docutils, 'docutils not installed')
|
||||
def test_docutils(self):
|
||||
t = Template("{% load markup %}{{ rest_content|restructuredtext }}")
|
||||
rendered = t.render(Context({'rest_content':self.rest_content})).strip()
|
||||
# Different versions of docutils return slightly different HTML
|
||||
try:
|
||||
# Docutils v0.4 and earlier
|
||||
self.assertEqual(rendered, """<p>Paragraph 1</p>
|
||||
<p>Paragraph 2 with a <a class="reference" href="http://www.example.com/">link</a></p>""")
|
||||
except AssertionError:
|
||||
# Docutils from SVN (which will become 0.5)
|
||||
self.assertEqual(rendered, """<p>Paragraph 1</p>
|
||||
<p>Paragraph 2 with a <a class="reference external" href="http://www.example.com/">link</a></p>""")
|
||||
|
||||
@unittest.skipIf(docutils, 'docutils is installed')
|
||||
def test_no_docutils(self):
|
||||
t = Template("{% load markup %}{{ rest_content|restructuredtext }}")
|
||||
rendered = t.render(Context({'rest_content':self.rest_content})).strip()
|
||||
self.assertEqual(rendered, self.rest_content)
|
@ -145,9 +145,6 @@ If you want to run the full suite of tests, you'll need to install a number of
|
||||
dependencies:
|
||||
|
||||
* PyYAML_
|
||||
* Markdown_
|
||||
* Textile_
|
||||
* Docutils_
|
||||
* setuptools_
|
||||
* memcached_, plus a :ref:`supported Python binding <memcached>`
|
||||
* gettext_ (:ref:`gettext_on_windows`)
|
||||
@ -160,9 +157,6 @@ Each of these dependencies is optional. If you're missing any of them, the
|
||||
associated tests will be skipped.
|
||||
|
||||
.. _PyYAML: http://pyyaml.org/wiki/PyYAML
|
||||
.. _Markdown: http://pypi.python.org/pypi/Markdown/1.7
|
||||
.. _Textile: http://pypi.python.org/pypi/textile
|
||||
.. _docutils: http://pypi.python.org/pypi/docutils/0.4
|
||||
.. _setuptools: http://pypi.python.org/pypi/setuptools/
|
||||
.. _memcached: http://memcached.org/
|
||||
.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html
|
||||
@ -200,7 +194,7 @@ multiple modules by using a ``tests`` directory in the normal Python way.
|
||||
For the tests to be found, a ``models.py`` file must exist, even if it's empty.
|
||||
If you have URLs that need to be mapped, put them in ``tests/urls.py``.
|
||||
|
||||
To run tests for just one contrib app (e.g. ``markup``), use the same
|
||||
To run tests for just one contrib app (e.g. ``auth``), use the same
|
||||
method as above::
|
||||
|
||||
./runtests.py --settings=settings markup
|
||||
./runtests.py --settings=settings auth
|
||||
|
@ -31,7 +31,6 @@ those packages have.
|
||||
formtools/index
|
||||
gis/index
|
||||
humanize
|
||||
markup
|
||||
messages
|
||||
redirects
|
||||
sitemaps
|
||||
@ -121,13 +120,6 @@ A set of Django template filters useful for adding a "human touch" to data.
|
||||
|
||||
See the :doc:`humanize documentation </ref/contrib/humanize>`.
|
||||
|
||||
markup
|
||||
======
|
||||
|
||||
A collection of template filters that implement common markup languages
|
||||
|
||||
See the :doc:`markup documentation </ref/contrib/markup>`.
|
||||
|
||||
messages
|
||||
========
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
=====================
|
||||
django.contrib.markup
|
||||
=====================
|
||||
|
||||
.. module:: django.contrib.markup
|
||||
:synopsis: A collection of template filters that implement common markup languages.
|
||||
|
||||
.. deprecated:: 1.5
|
||||
This module has been deprecated.
|
||||
|
||||
Django provides template filters that implement the following markup
|
||||
languages:
|
||||
|
||||
* ``textile`` -- implements `Textile`_ -- requires `PyTextile`_
|
||||
* ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_ (>=2.1)
|
||||
* ``restructuredtext`` -- implements `reST (reStructured Text)`_
|
||||
-- requires `doc-utils`_
|
||||
|
||||
In each case, the filter expects formatted markup as a string and
|
||||
returns a string representing the marked-up text. For example, the
|
||||
``textile`` filter converts text that is marked-up in Textile format
|
||||
to HTML.
|
||||
|
||||
To activate these filters, add ``'django.contrib.markup'`` to your
|
||||
:setting:`INSTALLED_APPS` setting. Once you've done that, use
|
||||
``{% load markup %}`` in a template, and you'll have access to these filters.
|
||||
For more documentation, read the source code in
|
||||
:file:`django/contrib/markup/templatetags/markup.py`.
|
||||
|
||||
.. warning::
|
||||
|
||||
The output of markup filters is marked "safe" and will not be escaped when
|
||||
rendered in a template. Always be careful to sanitize your inputs and make
|
||||
sure you are not leaving yourself vulnerable to cross-site scripting or
|
||||
other types of attacks.
|
||||
|
||||
.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29
|
||||
.. _Markdown: http://en.wikipedia.org/wiki/Markdown
|
||||
.. _reST (reStructured Text): http://en.wikipedia.org/wiki/ReStructuredText
|
||||
.. _PyTextile: http://loopcore.com/python-textile/
|
||||
.. _Python-markdown: http://pypi.python.org/pypi/Markdown
|
||||
.. _doc-utils: http://docutils.sf.net/
|
||||
|
||||
reStructured Text
|
||||
-----------------
|
||||
|
||||
When using the ``restructuredtext`` markup filter you can define a
|
||||
:setting:`RESTRUCTUREDTEXT_FILTER_SETTINGS` in your django settings to
|
||||
override the default writer settings. See the `restructuredtext writer
|
||||
settings`_ for details on what these settings are.
|
||||
|
||||
.. warning::
|
||||
|
||||
reStructured Text has features that allow raw HTML to be included, and that
|
||||
allow arbitrary files to be included. These can lead to XSS vulnerabilities
|
||||
and leaking of private information. It is your responsibility to check the
|
||||
features of this library and configure appropriately to avoid this. See the
|
||||
`Deploying Docutils Securely
|
||||
<http://docutils.sourceforge.net/docs/howto/security.html>`_ documentation.
|
||||
|
||||
.. _restructuredtext writer settings: http://docutils.sourceforge.net/docs/user/config.html#html4css1-writer
|
||||
|
||||
Markdown
|
||||
--------
|
||||
|
||||
The Python Markdown library supports options named "safe_mode" and
|
||||
"enable_attributes". Both relate to the security of the output. To enable both
|
||||
options in tandem, the markdown filter supports the "safe" argument::
|
||||
|
||||
{{ markdown_content_var|markdown:"safe" }}
|
||||
|
||||
.. warning::
|
||||
|
||||
Versions of the Python-Markdown library prior to 2.1 do not support the
|
||||
optional disabling of attributes. This is a security flaw. Therefore,
|
||||
``django.contrib.markup`` has dropped support for versions of
|
||||
Python-Markdown < 2.1 in Django 1.5.
|
@ -1502,20 +1502,6 @@ Default: ``()`` (Empty tuple)
|
||||
A tuple of profanities, as strings, that will be forbidden in comments when
|
||||
``COMMENTS_ALLOW_PROFANITIES`` is ``False``.
|
||||
|
||||
.. setting:: RESTRUCTUREDTEXT_FILTER_SETTINGS
|
||||
|
||||
RESTRUCTUREDTEXT_FILTER_SETTINGS
|
||||
--------------------------------
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
A dictionary containing settings for the ``restructuredtext`` markup filter from
|
||||
the :doc:`django.contrib.markup application </ref/contrib/markup>`. They override
|
||||
the default writer settings. See the Docutils restructuredtext `writer settings
|
||||
docs`_ for details.
|
||||
|
||||
.. _writer settings docs: http://docutils.sourceforge.net/docs/user/config.html#html4css1-writer
|
||||
|
||||
.. setting:: ROOT_URLCONF
|
||||
|
||||
ROOT_URLCONF
|
||||
|
@ -2356,16 +2356,6 @@ django.contrib.humanize
|
||||
A set of Django template filters useful for adding a "human touch" to data. See
|
||||
:doc:`/ref/contrib/humanize`.
|
||||
|
||||
django.contrib.markup
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A collection of template filters that implement these common markup languages:
|
||||
|
||||
* Textile
|
||||
* Markdown
|
||||
* reST (reStructuredText)
|
||||
|
||||
See the :doc:`markup documentation </ref/contrib/markup>`.
|
||||
|
||||
django.contrib.webdesign
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -48,13 +48,6 @@ escaping.
|
||||
You should also be very careful when storing HTML in the database, especially
|
||||
when that HTML is retrieved and displayed.
|
||||
|
||||
Markup library
|
||||
--------------
|
||||
|
||||
If you use :mod:`django.contrib.markup`, you need to ensure that the filters are
|
||||
only used on trusted input, or that you have correctly configured them to ensure
|
||||
they do not allow raw HTML output. See the documentation of that module for more
|
||||
information.
|
||||
|
||||
Cross site request forgery (CSRF) protection
|
||||
============================================
|
||||
|
Loading…
Reference in New Issue
Block a user