For one of my pet projects, I needed to use syntax highlighting for one of the TextField fields. Codemirror is great for this. After trying several “django-batteries” with widgets, I decided to abandon external dependencies and install codemirror myself.
Models have TbTemplate
with fields for describing templates. From there, the backend takes templates for rendering, and the TextField
itself with the template is szJinjaCode
.
I do it like this.
admin.py:
class TemplateAdminForm(forms.ModelForm):
class Meta:
model = TbTemplate
fields = "__all__"
widgets = {
'szJinjaCode': forms.Textarea(attrs={'class': 'jinja2-editor'})
}
# Template admin
@admin.register(TbTemplate)
class AdminTemplate(admin.ModelAdmin):
class Media:
# set for codemirror ON
css = {
'all': (
# '/static/codemirror-5.65.13/doc/docs.css',
'/static/codemirror-5.65.13/lib/codemirror.css',
'/static/codemirror-5.65.13/addon/hint/show-hint.css',
'/static/codemirror-5.65.13/addon/lint/lint.css',
'/static/codemirror-5.65.13/theme/rubyblue.css',
)
}
js = (
'/static/codemirror-5.65.13/lib/codemirror.js',
'/static/codemirror-5.65.13/addon/hint/show-hint.js',
'/static/codemirror-5.65.13/addon/hint/xml-hint.js',
'/static/codemirror-5.65.13/addon/hint/html-hint.js',
'/static/codemirror-5.65.13/mode/xml/xml.js',
'/static/codemirror-5.65.13/mode/javascript/javascript.js',
'/static/codemirror-5.65.13/mode/css/css.js',
'/static/codemirror-5.65.13/mode/htmlmixed/htmlmixed.js',
'/static/codemirror-5.65.13/mode/jinja2/jinja2.js',
# '/static/codemirror-5.65.13/addon/runmode/colorize.js',
# '/static/codemirror-5.65.13/addon/hint/html-hint.js',
# '/static/codemirror-5.65.13/addon/lint/lint.js',
# '/static/codemirror-5.65.13/addon/lint/html-lint.js',
'/static/js/codemirror/init_jinja2.js'
)
# set form TemplateAdminForm
form = TemplateAdminForm
# other description for admin TbTemplate
# ...
# ...
As you can see from the code, you also need to run the initialization file /static/js/codemirror/init_jinja2.js
into statics-files. Actually, he took from the recipe and changed it a little:
/static/js/codemirror/init_jinja2.js
(function(){
var $ = django.jQuery;
$(document).ready(function(){
$('.jinja2-editor').each(function(idx, el){
function getSelectedRange() {
return { from: editor.getCursor(true), to: editor.getCursor(false) };
}
var editor = CodeMirror.fromTextArea(el, {
lineNumbers: true,
tabSize: 2,
// mode: 'text/html',
mode: 'text/jinja2',
gutters: ['CodeMirror-lint-markers'],
theme: 'rubyblue',
lint: true,
});
CodeMirror.commands["selectAll"](editor);
var range = getSelectedRange();
editor.autoFormatRange(range.from, range.to);
range = getSelectedRange();
editor.commentRange(false, range.from, range.to);
});
});
})();
We start, and everything works. The highlighting of Jinja2-tags and variables works more precisely. If you change mode: 'text/jinja2'
to mode: 'text/html'
in init_jinja2.js
, the html-code will be highlighted, but the Jinja2-markup will not be highlighted… I want both codes to be highlighted. Even better if you also highlight CSS, JavaScript and JSON. How to make codemirror highlight it all at the same time?
P.S. The option suggests itself — to take the necessary “mod” files from the /static/codemirror-5.65.13/mode/
directory into codemirror and assemble your own “mode” from them, but this is a crippling solution for codemirror itself. When it is codemirror-updated, everything will collapse and this home-made “mod” will have to be reassembled. This, it seems to me, is wrong. I would like to turn on several “mod” (backlight modes) at the same time in a regular way. How?