Switch from django-markdown-deux to a pipeline thru markdown for rendering + bleach for sanitising
This commit is contained in:
parent
93be2f5a32
commit
8f8e53bb27
7 changed files with 58 additions and 64 deletions
9
Pipfile
9
Pipfile
|
@ -7,11 +7,11 @@ name = "pypi"
|
||||||
|
|
||||||
[packages]
|
[packages]
|
||||||
|
|
||||||
django = "*"
|
Django = "*"
|
||||||
django-compressor = "*"
|
django_compressor = "*"
|
||||||
gunicorn = "*"
|
gunicorn = "*"
|
||||||
"psycopg2" = "*"
|
"psycopg2" = "*"
|
||||||
pillow = "*"
|
Pillow = "*"
|
||||||
python-memcached = "*"
|
python-memcached = "*"
|
||||||
django-favicon-plus = "*"
|
django-favicon-plus = "*"
|
||||||
django-meta = "*"
|
django-meta = "*"
|
||||||
|
@ -21,8 +21,9 @@ django-otp = "*"
|
||||||
qrcode = "*"
|
qrcode = "*"
|
||||||
django-otp-agents = "*"
|
django-otp-agents = "*"
|
||||||
python-slugify = "*"
|
python-slugify = "*"
|
||||||
django-markdown-deux = "*"
|
|
||||||
"mf2py" = "*"
|
"mf2py" = "*"
|
||||||
|
Markdown = "*"
|
||||||
|
bleach = "*"
|
||||||
|
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
|
|
21
Pipfile.lock
generated
21
Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "ead57b340efa8b663100364efa6b9037299456bb3e37d533b6d7c4404608749c"
|
"sha256": "500facb148117065fc6e7d207f81bdc88a0f9b3c18e48e0f1b08542143775649"
|
||||||
},
|
},
|
||||||
"host-environment-markers": {
|
"host-environment-markers": {
|
||||||
"implementation_name": "cpython",
|
"implementation_name": "cpython",
|
||||||
|
@ -35,6 +35,13 @@
|
||||||
],
|
],
|
||||||
"version": "==4.6.0"
|
"version": "==4.6.0"
|
||||||
},
|
},
|
||||||
|
"bleach": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:7a316eac1eef1e98b9813636ebe05878aab1a658d2708047fb00fe2bcbc49f84",
|
||||||
|
"sha256:760a9368002180fb8a0f4ea48dc6275378e6f311c39d0236d7b904fca1f5ea0d"
|
||||||
|
],
|
||||||
|
"version": "==2.1.1"
|
||||||
|
},
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:54a07c09c586b0e4c619f02a5e94e36619da8e2b053e20f594348c0611803704",
|
"sha256:54a07c09c586b0e4c619f02a5e94e36619da8e2b053e20f594348c0611803704",
|
||||||
|
@ -102,12 +109,6 @@
|
||||||
],
|
],
|
||||||
"version": "==0.0.7"
|
"version": "==0.0.7"
|
||||||
},
|
},
|
||||||
"django-markdown-deux": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:5b4a3cd9454af5b4cec0e19151b41d98d09400ddae0688afb81dbf62a4edafff"
|
|
||||||
],
|
|
||||||
"version": "==1.0.5"
|
|
||||||
},
|
|
||||||
"django-meta": {
|
"django-meta": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2a5b8d95099f69fb9736630c4fbf4fcc2972a1fcd9c708a5bb72dde22e84d8dd",
|
"sha256:2a5b8d95099f69fb9736630c4fbf4fcc2972a1fcd9c708a5bb72dde22e84d8dd",
|
||||||
|
@ -189,11 +190,11 @@
|
||||||
],
|
],
|
||||||
"version": "==4.1.0"
|
"version": "==4.1.0"
|
||||||
},
|
},
|
||||||
"markdown2": {
|
"markdown": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:264731e7625402227ff6fb01f2d814882da7705432659a18a419c508e8bfccb1"
|
"sha256:73af797238b95768b3a9b6fe6270e250e5c09d988b8e5b223fd5efa4e06faf81"
|
||||||
],
|
],
|
||||||
"version": "==2.3.4"
|
"version": "==2.6.9"
|
||||||
},
|
},
|
||||||
"mf2py": {
|
"mf2py": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% load humanize markdown_deux_tags %}<article class="card h-entry">
|
{% load humanize markdown %}<article class="card h-entry">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if entry.name %}<h4 class="card-title p-name">{{ entry.name }}</h4>{% endif %}
|
{% if entry.name %}<h4 class="card-title p-name">{{ entry.name }}</h4>{% endif %}
|
||||||
<div class="e-content{% if not entry.name %} p-name{% endif %}">{{ entry.content | markdown }}</div>
|
<div class="e-content{% if not entry.name %} p-name{% endif %}">{{ entry.content | markdown }}</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends 'lemoncurry/layout.html' %}
|
{% extends 'lemoncurry/layout.html' %}
|
||||||
{% load markdown_deux_tags static %}
|
{% load markdown static %}
|
||||||
{% block html_class %}h-feed{% endblock %}
|
{% block html_class %}h-feed{% endblock %}
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
<link rel="stylesheet" type="text/stylus" href="{% static 'home/css/index.styl' %}" />
|
<link rel="stylesheet" type="text/stylus" href="{% static 'home/css/index.styl' %}" />
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
</a>
|
</a>
|
||||||
</h6>
|
</h6>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if user.note %}<div class="p-note">{{ user.note | markdown:'trusted' }}</div>{% endif %}
|
{% if user.note %}<div class="p-note">{{ user.note | markdown }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
|
|
|
@ -73,7 +73,6 @@ INSTALLED_APPS = [
|
||||||
'django_otp',
|
'django_otp',
|
||||||
'django_otp.plugins.otp_totp',
|
'django_otp.plugins.otp_totp',
|
||||||
'favicon',
|
'favicon',
|
||||||
'markdown_deux',
|
|
||||||
'meta',
|
'meta',
|
||||||
|
|
||||||
'lemoncurry',
|
'lemoncurry',
|
||||||
|
@ -208,52 +207,6 @@ AGENT_COOKIE_SECURE = True
|
||||||
# https://django-otp-official.readthedocs.io/en/latest/overview.html
|
# https://django-otp-official.readthedocs.io/en/latest/overview.html
|
||||||
OTP_TOTP_ISSUER = LEMONCURRY_SITE_NAME
|
OTP_TOTP_ISSUER = LEMONCURRY_SITE_NAME
|
||||||
|
|
||||||
|
|
||||||
# django-markdown-deux
|
|
||||||
# https://github.com/trentm/django-markdown-deux
|
|
||||||
def copy_update(source_dict, **kwargs):
|
|
||||||
copy = source_dict.copy()
|
|
||||||
copy.update(**kwargs)
|
|
||||||
return copy
|
|
||||||
|
|
||||||
|
|
||||||
link_patterns = [(re.compile(pat), rep) for (pat, rep) in (
|
|
||||||
# autolink actual URLs in text
|
|
||||||
(
|
|
||||||
r'((([A-Za-z]{3,9}:(?:\/\/)?)' + # scheme
|
|
||||||
r'(?:[\-;:&=\+\$,\w]+@)?' + # basic auth
|
|
||||||
r'[A-Za-z0-9\.\-]+(:[0-9]+)?' + # ip address
|
|
||||||
r'|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)' + # or hostname
|
|
||||||
r'((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)' + # path
|
|
||||||
r'#?(?:[\.\!\/\\\w]*))?)', # hash
|
|
||||||
r'\1'
|
|
||||||
),
|
|
||||||
)]
|
|
||||||
|
|
||||||
|
|
||||||
MARKDOWN_DEUX_DEFAULT_STYLE = {
|
|
||||||
'extras': (
|
|
||||||
'code-friendly',
|
|
||||||
'cuddled-lists',
|
|
||||||
'fenced-code-blocks',
|
|
||||||
'footnotes',
|
|
||||||
'header-ids',
|
|
||||||
'spoiler',
|
|
||||||
'tag-friendly',
|
|
||||||
),
|
|
||||||
'link_patterns': link_patterns,
|
|
||||||
'safe_mode': 'escape',
|
|
||||||
}
|
|
||||||
|
|
||||||
MARKDOWN_DEUX_STYLES = {
|
|
||||||
'default': MARKDOWN_DEUX_DEFAULT_STYLE,
|
|
||||||
'trusted': copy_update(
|
|
||||||
MARKDOWN_DEUX_DEFAULT_STYLE,
|
|
||||||
link_patterns=[],
|
|
||||||
safe_mode=False,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
# django-meta
|
# django-meta
|
||||||
# https://django-meta.readthedocs.io/en/latest/settings.html
|
# https://django-meta.readthedocs.io/en/latest/settings.html
|
||||||
META_SITE_PROTOCOL = 'https'
|
META_SITE_PROTOCOL = 'https'
|
||||||
|
|
21
lemoncurry/templatetags/bleach.py
Normal file
21
lemoncurry/templatetags/bleach.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from django import template
|
||||||
|
from django.template.defaultfilters import stringfilter
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
|
from bleach.sanitizer import Cleaner, ALLOWED_TAGS
|
||||||
|
from bleach.linkifier import LinkifyFilter
|
||||||
|
|
||||||
|
tags = ['code', 'p']
|
||||||
|
tags.extend(ALLOWED_TAGS)
|
||||||
|
attributes = {
|
||||||
|
'a': ('href', 'title', 'class')
|
||||||
|
}
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
cleaner = Cleaner(tags=tags, attributes=attributes, filters=(LinkifyFilter,))
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
@stringfilter
|
||||||
|
def bleach(html):
|
||||||
|
return mark_safe(cleaner.clean(html))
|
18
lemoncurry/templatetags/markdown.py
Normal file
18
lemoncurry/templatetags/markdown.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
from markdown import Markdown
|
||||||
|
from .bleach import bleach
|
||||||
|
|
||||||
|
md = Markdown(extensions=(
|
||||||
|
'markdown.extensions.extra',
|
||||||
|
'markdown.extensions.headerid',
|
||||||
|
'markdown.extensions.sane_lists',
|
||||||
|
'markdown.extensions.smarty',
|
||||||
|
))
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def markdown(source):
|
||||||
|
return bleach(md.reset().convert(source))
|
Loading…
Reference in a new issue