Python Web开发学习

Django添加Markdown输入框和渲染

2018-05-20  本文已影响12人  吾星喵

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">  &lt;!&ndash;默认代码css&ndash;&gt;-->
<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 %}

参考 https://blog.csdn.net/drcbin/article/details/80151763

上一篇下一篇

猜你喜欢

热点阅读