Django添加Markdown输入框和渲染
Django添加Markdown支持
Markdown渲染,自带markdown库
安装markdown
pip install markdown
模型中添加文本转换
from markdown import markdown
from django.utils.html import mark_safe
# 事件处理
class EventProcess(models.Model):
reply = models.TextField(max_length=100, verbose_name='事件回复')
event = models.ForeignKey(EventContent, on_delete=models.CASCADE, related_name='event_process', verbose_name='事件内容')
created = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated = models.DateTimeField(auto_now=True, verbose_name='更新时间')
user = models.ForeignKey(User, related_name='event_process', verbose_name='创建人')
class Meta:
ordering = ['created']
verbose_name = '事件处理'
verbose_name_plural = verbose_name
def __str__(self):
return self.reply[:20]
def get_reply_as_markdown(self):
"""
当使用Mardown功能时,我们需要先让它转义一下特殊字符,然后再解析出Markdown标签。
这样做之后,输出字符串可以安全的在模板中使用。
:return:
"""
return mark_safe(markdown(self.reply, safe_mode='escape'))
模板中使用
{{ process.get_reply_as_markdown }}
如果模型中直接返回转换过的markdown文本
# return mark_safe(markdown(self.reply, safe_mode='escape'))
return markdown(self.reply)
则模型中使用
{{ process.get_reply_as_markdown|safe }}
Markdown表单
https://github.com/pandao/editor.md
下载解压到 \static\editor.md 目录下,里面包含很多css和js文件
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.min.css' %}" />
<form action="{% url 'start_processing' event.pk %}" method="post" role="form">
<div class="form-group">
<label>{{ request.user.username }}</label>
<!--<textarea class="form-control" rows="5" name="reply" placeholder="请输入处理回复 ..."></textarea>-->
<div id="editormd">
<textarea style="display:none;" name="reply" placeholder="请输入处理回复 ..."></textarea>
</div>
</div>
<button type="submit" class="btn btn-primary">回复</button>
{% csrf_token %}
</form>
<script src="{% static 'js/jquery/jquery.min.js' %}"></script>
<script src="{% static 'editor.md/editormd.min.js' %}"></script>
<script type="text/javascript">
$(function() {
var editor = editormd("editormd", {
path : "{% static 'editor.md/lib/' %}", // Autoload modules mode, codemirror, marked... dependents libs path
// width : "1000px", //设置宽度
placeholder : "请输入处理回复 ...", // 输入框提示文字
height : 320,
syncScrolling : "single"
});
/*
// or
var editor = editormd({
id : "editormd",
path : "../lib/"
});
*/
});
</script>
使用showdown来渲染,js方式
引入showdown
选择的showdown: https://github.com/showdownjs/showdown ,可以下载到本地进行引入。
先引入showdown,通过在线的方式: https://cdnjs.com/libraries/showdown
<!--css-->
<!--渲染位置-->
{% if processes %}
{% for process in processes %}
<p id="id_reply_{{ process.id }}">{{ process.reply }}</p>
{% endfor %}
{% endif %}
<script src="{% static 'js/jquery/jquery.min.js' %}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.8.6/showdown.min.js"></script>
{% if processes %}
{% for process in processes %}
<script type="text/javascript">
$(document).ready(() => {
var src = $('#id_reply_{{ process.id }}').text()
var converter = new showdown.Converter();
var html = converter.makeHtml(src);
$('#id_reply_{{ process.id }}').html(html);
})
</script>
{% endfor %}
{% endif %}
由于需要for循环显示{{ process.reply }}
内容,id将使用实例的id,即id_reply_{{ process.id }}
js也是对不同的id渲染出不同的结果。
使用代码高亮
上面解决markdown解析的问题,但是代码并没有高亮,需要其他库来解决
访问 https://highlightjs.org/download/ 来自定义并下载生成的js,然后引入,或者是引入在线js,以及css
<!--css-->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> <!--默认代码css-->
<!--渲染位置-->
{% if processes %}
{% for process in processes %}
<p id="id_reply_{{ process.id }}">{{ process.reply }}</p>
{% endfor %}
{% endif %}
<script src="{% static 'js/jquery/jquery.min.js' %}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.8.6/showdown.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
{% if processes %}
{% for process in processes %}
<script type="text/javascript">
$(document).ready(() => {
var src = $('#id_reply_{{ process.id }}').text()
var converter = new showdown.Converter();
var html = converter.makeHtml(src);
$('#id_reply_{{ process.id }}').html(html);
})
</script>
{% endfor %}
{% endif %}
然后初始化<script>hljs.initHighlightingOnLoad();</script>
初始化高亮
{% if processes %}
{% for process in processes %}
<script type="text/javascript">
$(document).ready(() => {
var src = $('#id_reply_{{ process.id }}').text()
var converter = new showdown.Converter();
var html = converter.makeHtml(src);
$('#id_reply_{{ process.id }}').html(html);
hljs.initHighlightingOnLoad();
})
</script>
{% endfor %}
{% endif %}
更多样式的选择
上述的代码高亮如果太喜欢,可以访问 https://highlightjs.org/static/demo/ 预览更多的样式, 并且访问 https://github.com/isagalaev/highlight.js/tree/master/src/styles 去找样式对应的文件名,替换掉(不要忘记在“.css”之前添加“.min”)
即<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/<style_name>.min.css">
完整代码Markdown输入框和渲染
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.min.css' %}" />
<!--<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> <!–默认代码css–>-->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/vs.min.css">
<!--渲染位置-->
{% if processes %}
{% for process in processes %}
<p id="id_reply_{{ process.id }}">{{ process.reply }}</p>
<!--{{ process.get_reply_as_markdown }}-->
{% endfor %}
{% endif %}
<form action="{% url 'start_processing' event.pk %}" method="post" role="form">
<!--<textarea class="form-control" rows="5" name="reply" placeholder="请输入处理回复 ..."></textarea>-->
<div id="editormd">
<textarea style="display:none;" name="reply" placeholder="请输入处理回复 ..."></textarea>
</div>
{% csrf_token %}
<button type="submit" class="btn btn-primary">回复</button>
</form>
<script src="{% static 'js/jquery/jquery.min.js' %}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.8.6/showdown.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script src="{% static 'editor.md/editormd.min.js' %}"></script>
<script type="text/javascript">
$(function() {
var editor = editormd("editormd", {
path : "{% static 'editor.md/lib/' %}", // Autoload modules mode, codemirror, marked... dependents libs path
// width : "1000px", //设置宽度
placeholder : "请输入处理回复 ...", // 输入框提示文字
height : 320,
syncScrolling : "single"
});
/*
// or
var editor = editormd({
id : "editormd",
path : "../lib/"
});
*/
});
</script>
{% if processes %}
{% for process in processes %}
<script type="text/javascript">
$(document).ready(() => {
var src = $('#id_reply_{{ process.id }}').text()
var converter = new showdown.Converter();
var html = converter.makeHtml(src);
$('#id_reply_{{ process.id }}').html(html);
hljs.initHighlightingOnLoad();
})
</script>
{% endfor %}
{% endif %}