使用标记标记突出显示语法,以及Django的一小部分Automagick
django(72岁), 蟒蛇(59)在Django中实现语法突出显示和标记支持方面有很多好的资源,当我开始在博客上工作时,我将代码从我在这里找到的示例. 这是一篇做得很好的文章,最后得到了一个可用的系统(我在这里重用了它的核心)。但本文将着眼于稍微扩展它的功能,并简化代码。
如果您要实现上述文章的代码,您将最终编写如下所示的标记:
###我的文章
- 我的列表条目1
- 我的列表条目2
<代码班级=“python”>def x(a,b):返回a*b
这是一个合理的解决方案,但是我发现代码元素有点笨拙,所以这里是我的Django语法高亮和标记的替代实现。在其实现之后,降价将这样写:
###我的文章
- 我的列表条目1
- 我的列表条目2
@@python def x(a,b):返回a*b
@@你的千年可能会有所不同,但我认为这对可读性和可写性都有很大的提高。此外,这里显示的MarkDown++解决方案允许访问所有Pygments语法Lexer,以便您可以使用html+django、ruby、scheme或apache等语言。
实施
第一步是下载[MarkDown+][markdownp]。您可以将它添加到Python路径,或者我亲自将其添加为调用它的Django应用程序中的文件,因此我将其导入如下:
进口myproject.myapp.markdownp作为降价
接下来,我们需要制作包含我们内容的模型:
班进入(模型.模型):标题=模型.查菲尔德(最大长度=200)身体=模型.文本字段()正文\u html=模型.文本字段(空白的=是的,无效的=是的)使用降价=模型.布尔场(违约=是的)
给它一个保存方法
定义节约(自己):如果自己.使用降价:自己.正文\u html=降价.降价(自己.html格式)其他的:自己.正文\u html=自己.身体超级的(进入,自己).节约()
就这样,现在可以使用MarkDown++语法来突出显示代码语法。您需要保存此css文件把它放在你的媒体文件夹中,模板可以加载它的地方(它是语法着色所需的css,不应该干扰你现有的css)。
再往前走一点
现在您已经实现了一个有效的降价和代码语法highlighter,但是我们可以把它修饰得更漂亮一些。
通常,您会在内容中引用一些文件(图像或其他文件)。不幸的是,手工编写参考链接是一个容易出错的过程:
[我的文件]://www.klytx.com/media/lifeflow/myfile.jpg
如果你写了很多,就会有点乏味。如果参赛者为自己写参考文献不是很好吗?好吧,我们可以,我们要去(整个国家都欢欣鼓舞)。
首先让我们添加一个资源模型:
班资源(模型.模型):标题=模型.查菲尔德(最大长度=50)降价标识=模型.查菲尔德(最大长度=50)内容=模型.文件字段(上传到=“我的应用程序/资源”)
现在我们需要对前面的条目进行一些修改:
班进入(模型.模型):标题=模型.查菲尔德(最大长度=200)身体=模型.文本字段()正文\u html=模型.文本字段(空白的=是的,无效的=是的)使用降价=模型.布尔场(违约=是的)
定义节约(自己):如果自己.使用降价:件=[自己.html格式,]对于物件在里面资源.物体.全部的():裁判=u'\否\n[%s码]:%s码"%s码"\否\n'%(物件.降价标识,物件.获取\u内容\u url(),物件.标题,)件.追加(物件)内容=u“\不".参加(件)自己.正文\u html=降价.降价(内容)其他的:自己.正文\u html=自己.身体超级的(进入,自己).节约()
现在,当你写一篇文章的时候,你可以使用你创建的任何资源中的任何一个markdown\u id。
在查看代码之后,您会想:“为什么不让它只导入条目实际使用的资源?只是简单地投入一段对多的关系,然后…臭名昭著,这就是我所做的,但很快它就变成了一个非常不愉快的解决方案。。。让我解释一下。
如果有许多字段将您的条目链接到资源实例,那么您将执行以下操作以获取相关资源:
参考文献=进入.资源.全部的()
这是伟大的,非常容易和所有的爵士乐。只是没用。问题是,保存条目时,也保存了资源和条目之间的新关系。这意味着在保存条目的时间点,与该条目相关的资源的完全更新列表还不可用。所以你认为你可以这样做:
定义节约:超级的(进入,自己).节约()物件=自己.资源.全部的()#等超级的(进入,自己).节约()
但不幸的是,你不能。无论出于什么原因,更改并没有足够快地进入数据库,以便在那个时候更新它(免责声明:我的开发主要使用SQLite3,它有糟糕的数据库锁定,也许这种方法在PostgreSQL上效果更好,但我对此表示怀疑)。
好吧,现在你在想“让我们使用dispatcher来监听post save钩子,然后再次保存条目。”你是对的,这是可行的,但没有你想象的那么干净。问题的关键在于,如果使用post\u save钩子立即再次调用resave,那么仍然无法更新内容,实际上您必须等待2-3秒才能获得更改。
我并不特别推荐使用它,但为了完整起见,这里是我目前针对这个更新问题的解决方案:
进口时间,线从django数据库进口模型从django.dispatch公司进口调度员从django.db.型号进口信号##########################你的模特来这里##########################
定义重保存\u对象(发件人,实例,信号,*参数,**关键字参数):定义是否保存():时间.睡觉(三)尝试:实例.节约()除了:通过身份证件=unicode码(实例)+unicode码(实例.身份证件)尝试:应该保存吗=重新保存历史[身份证件]除了键错误:重新保存历史[身份证件]=是的应该保存吗=是的如果应该保存吗是是的:重新保存历史[身份证件]=假线.启动\u新线程(是否保存,())其他的:重新保存历史[身份证件]=是的
重新保存历史={}调度员.连接(重保存\u对象,信号=信号.保存后,发件人=进入)
这是非常黑客,但它是我提出的唯一可行的解决方案(除了简单地将所有资源添加到每个条目)。它的关键是使用一个单独的线程等待3秒钟,然后重新保存它。有一些额外的代码可以防止无限的save循环。
向前和向上
预先创建引用链接,这样您就不必有一个有腿的想法:您可以创建到上一篇和下一篇文章的自动链接,以及博客上的博客链接,无论您使用什么。给它一个快速的想法,也许你可以把一些你的写作工作流程转移到软件上。
我想看看是否有人有任何更好的解决方案,只加载相关的参考。如果有任何问题,请告诉我。