Sergei_Erjemin
@Sergei_Erjemin
Улыбайся, будь самураем...

Как в админке Django настроить codemirror на подсветку нескольких языков?

Для одного своего пет-проекта понадобилось использовать подсветку синтаксиса для одного из 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. При его обновлении всё порушится и эту самодельную «моду» надо будет собирать заново. Это, мне кажется, неправильно. Хочется включить несколько «мод» (режимов подсветки) одновременно штатным способом. Как?
  • Вопрос задан
  • 53 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы