Для одного своего пет-проекта понадобилось использовать подсветку синтаксиса для одного из
TextField полей. Для этого отлично подходит
codemirror. Попробовав несколько «батареек» с виджетами, решил отказаться от внешних зависимостей и прикрутить codemirror самостоятельно (если честно, батарейки у меня просто не заработали, зато
нашелся вполне рабочий рецепт).
В моделях есть
TbTemplate
с полями для описания шаблонов. Оттуда бэкенд берёт шаблоны для рендера, а само TextField-поле с шаблоном —
szJinjaCode
.
Делаю вот так.
В
admin.py
:
class TemplateAdminForm(forms.ModelForm):
class Meta:
model = TbTemplate
fields = "__all__"
widgets = {
'szJinjaCode': forms.Textarea(attrs={'class': 'jinja2-editor'})
}
# -- Управление шаблонами
@admin.register(TbTemplate)
class AdminTemplate(admin.ModelAdmin):
class Media:
# настройка подключения codemirror
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'
)
# подключение формы TemplateAdminForm
form = TemplateAdminForm
# далее остальные описания для админки модели TbTemplate
# ...
# ...
Как видно из кода, нужно ещё в статику положить инициализационный файл
/static/js/codemirror/init_jinja2.js
. Собственно он взять из рецепта и немного модифицирован:
// Этот файл нужен для инициализации jinja-редактора шаблонов codemirror в админке
// рецепт: https://webdevblog.ru/redaktirovanie-json-polej-cherez-django-adminku/
(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);
});
});
})();
Запускаем, и всё работает. Точнее работает подсветка тегов и переменных
Jinja2. Если в
init_jinja2.js поменять
mode: 'text/jinja2'
на
mode: 'text/html'
— будет подсвечиваться html-код, но не будут подсвечена разметка Jinja2… Хочется чтобы подсвечивалось оба кода. Еще лучше если ещё подсвечивать
CSS,
JavaScript и
JSON. Как заставить
codemirror подсвечивать одновременно это всё?
P.S. Напрашивается вариант — взять в
codemirror нужные файлы «модов» из каталога
/static/codemirror-5.65.13/mode/
и собрать из них свою «моду», но это калечащее решение для самого
codemirror. При его обновлении всё порушится и эту самодельную «моду» надо будет собирать заново. Это, мне кажется, неправильно. Хочется включить несколько «мод» (режимов подсветки) одновременно штатным способом. Как?