dot语言在django ckeditor的使用
可以使用 CKEditor 编辑器,并在 Django 项目中集成一些工具来支持在文章中间插入和渲染 DOT 语言生成的图形。下面是一个详细的方案,包括步骤、代码示例和一些建议(ECharts也可以):
核心思路:
- CKEditor 插件: 创建一个自定义的 CKEditor 插件,用于插入 DOT 代码。
- 后端处理: 后端接收文章内容,找到 DOT 代码块,使用 Graphviz 将其渲染为 SVG 或其他格式的图形。
- 前端渲染: 将渲染好的图形替换原来的 DOT 代码块,并显示在页面上。
步骤详解:
1. 安装必要的库:
pip install graphviz
安装本地
centos安装
yum install graphviz
注:windows也要装exe软件,去官网下载
详情查看:https://graphviz.org/download/
2. CKEditor 配置和插件创建:
-
配置 CKEditor: 在你的
settings.py
文件中,确保你已经正确配置了 CKEditor。# settings.py CKEDITOR_CONFIGS = { 'default': { 'toolbar': 'full', # 或者使用你自定义的工具栏 'extraPlugins': ['dotblock'], # 添加自定义插件 }, }
-
创建自定义插件
dotblock
:-
在你的 Django App 的
static
目录下(例如your_app/static/your_app/ckeditor/plugins
)创建以下文件结构:your_app/ static/ your_app/ ckeditor/ plugins/ dotblock/ plugin.js dialogs/ dotblock.js
-
plugin.js
内容:CKEDITOR.plugins.add('dotblock', { requires: 'dialog', icons: 'dotblock', init: function (editor) { var pluginName = 'dotblock'; CKEDITOR.dialog.add(pluginName, this.path + 'dialogs/dotblock.js'); editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName)); editor.ui.addButton('dotblock', { label: '插入 Dot 图', command: pluginName, toolbar: 'insert', // 你可以自定义工具栏 icon: this.path + 'icons/dotblock.png' }); } });
-
在
your_app/static/your_app/ckeditor/plugins/dotblock
目录下 创建icons文件夹,并且放入一个名为dotblock.png
的图标。你也可以使用其他的图标。 -
dialogs/dotblock.js
内容:CKEDITOR.dialog.add('dotblock', function (editor) { return { title: '插入 Dot 代码', minWidth: 400, minHeight: 200, contents: [ { id: 'tab-dot', label: 'Dot 代码', elements: [ { type: 'textarea', id: 'dotCode', label: 'DOT 代码', rows: 10, 'style': 'width: 100%;' } ] } ], onOk: function () { var dialog = this; var dotCode = dialog.getValueOf('tab-dot', 'dotCode'); var element = editor.document.createElement('pre'); element.addClass('dot-code'); // 添加一个类,方便后端识别 element.setText(dotCode); editor.insertElement(element); } }; });
-
3. 后端处理 (Django View):
-
在你的 Django 应用的
views.py
文件中,添加如下函数来处理文章内容:from django.shortcuts import render from django.http import JsonResponse from django.utils.html import format_html import graphviz import re import html from django.utils.safestring import mark_safe def render_dot_in_content(content): """ 查找 DOT 代码块,并渲染为 SVG """ def replace_dot(match): dot_code = match.group(1).strip() try: dot_code = html.unescape(dot_code) graph = graphviz.Source(dot_code) svg_code = graph.pipe(format='svg').decode('utf-8') # 移除 xml 头部信息 svg_code = re.sub(r'<\?xml.*\?>', '', svg_code) # 将 xlink:href 属性替换为正常的 href 属性, 并且添加 target="_blank" svg_code = svg_code.replace('xlink:href="', 'href="').replace('<a ','<a target="_blank" ') # 使用 mark_safe 标记, 但是不使用 format_html return mark_safe(f'<div style="text-align:center;overflow:auto;">{svg_code}</div>') except Exception as e: return f'<pre>Error rendering dot: {e}</pre>' pattern = r'<pre class="dot-code">(.*?)</pre>' rendered_content = re.sub(pattern,replace_dot,content,flags=re.DOTALL) return rendered_content def article_detail(request, article_id): # ... 从数据库中获取文章数据 ... article = ... # 根据你的数据库操作获取 Article 对象 content = article.content rendered_content = render_dot_in_content(content) context = { 'article': article, 'content': rendered_content, } return render(request, 'your_app/article_detail.html', context)
-
在你的 model.py 中,你需要保证 content 是 TextField 或者 RichTextField,可以存储大量的文本数据。
from django.db import models
from ckeditor.fields import RichTextField
class Article(models.Model):
title = models.CharField(max_length=200)
content = RichTextField()
# ... 其他字段 ...
def __str__(self):
return self.title
4. 前端渲染 (HTML 模板):
- 在你的 HTML 模板中 (例如
your_app/article_detail.html
),确保你的文章内容被正确渲染:
```html
<!DOCTYPE html>
<html>
<head>
<title>{{ article.title }}</title>
<style>
.dot-graph{
margin:10px 0;
}
</style>
</head>
<body>
<h1>{{ article.title }}</h1>
<div class="article-content">
{{ content|safe }}
</div>
</body>
</html>
**5\. URL 配置:**
在 urls.py
中添加对应的 url
from django.urls import path
from . import views
urlpatterns = [
path('article/<int:article_id>/', views.article_detail, name='article_detail'),
]
**解释:**
- **CKEditor 插件:**
- `plugin.js`: 定义了插件的基本结构,包括图标、命令,以及注册 dialog。
- `dialogs/dotblock.js`: 创建了一个弹出窗口,让用户可以输入 DOT 代码,并将其包装在带有 `dot-code` 类的 `<pre>` 标签中。
- **后端 (Django):**
- `render_dot_in_content`: 使用正则表达式找出文章内容中带有 `.dot-code` 类的 `<pre>` 标签,提取 DOT 代码,并使用 `graphviz` 生成 SVG 代码。然后,将 `<pre>` 标签替换为包含 SVG 的 `<div>` 标签。
- `article_detail`: 从数据库获取文章,调用 `render_dot_in_content` 处理文章内容,然后将渲染后的内容传递给模板。
- **前端 (HTML):**
- 模板显示文章标题和内容,由于我们在 `views.py` 中已经将 dot 代码转换为了 `SVG` 代码,这里只需要显示即可。
**注意事项:**
- **样式:** 你可能需要添加 CSS 来美化 SVG 图的显示效果。
- **安全性:** 如果你的用户可能输入恶意 DOT 代码,请确保采取适当的安全措施,例如使用沙箱环境来运行 Graphviz。
- **错误处理:** `render_dot_in_content` 中的 `try...except` 块可以帮助你处理无效的 DOT 代码,并显示错误信息,方便调试。
- **扩展:** 你可以根据需要添加其他功能,比如支持自定义图形属性、实时预览等。
- **其他格式:** 你也可以使用其他格式,比如 PNG, JPEG 等。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=368
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
发表评论
评论列表 (0 条评论)
暂无评论,快来抢沙发吧!