From 6f9da3004080c0c568e28a836f95b71ea40ef59b Mon Sep 17 00:00:00 2001 From: erjemin Date: Mon, 24 Aug 2026 21:14:21 +0300 Subject: [PATCH] =?UTF-8?q?add:=20=D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=B0=20(13)=20CodeMirror=20=D0=B2=20=D0=B0=D0=B4=D0=BC=D0=B8?= =?UTF-8?q?=D0=BD=D0=BA=D0=B5=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5?= =?UTF-8?q?=D1=82...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hypn0/hypn0_site/admin.py | 94 ++++++++++++++++++- ...odemirror-patch.js => codemirror-patch.js} | 0 2 files changed, 92 insertions(+), 2 deletions(-) rename public/static/codemirror/{odemirror-patch.js => codemirror-patch.js} (100%) diff --git a/hypn0/hypn0_site/admin.py b/hypn0/hypn0_site/admin.py index df21cdf..2c5f2bf 100644 --- a/hypn0/hypn0_site/admin.py +++ b/hypn0/hypn0_site/admin.py @@ -223,7 +223,8 @@ class TbHypn0ItemAdmin(admin.ModelAdmin): ) return "Нет файла" - +# ---- +# АДМИНКА ЛАЙКОВ/ДИСЛАЙКОВ @admin.register(TbVote) class TbVoteAdmin(admin.ModelAdmin): """ @@ -246,11 +247,100 @@ class TbVoteAdmin(admin.ModelAdmin): return f"{obj.s_fingerprint[:12]}..." +# ---- +# АДМИНКА БЛОГА +# Кастомная форма +class BlogPostAdminForm(CodeMirrorFormMixin): + """ + Кастомная форма для админки потов в блог (TbBlogPost). + Добавляет виджеты CodeMirror для текстовых полей. + """ + # Виртуальные поля для настройки типографа + etp_enable = forms.BooleanField( + label="Включить типограф", + initial=False, + required=False, + help_text="Включить автоматическую типографику для HTML полей (заголовок, тизер, контент)   " + ) + etp_language = forms.ChoiceField( + label="Язык типографики", + choices=[('ru', 'Русский'), ('en', 'English'), ('ru,en', 'Ru + En')], + initial='ru', + required=False + ) + etp_quotes = forms.BooleanField( + label="Кавычки", + initial=True, + required=False, + help_text="Заменять кавычки
(«ёлочки» для русского, “лапки” для английского)   " + ) + etp_hyphenation = forms.BooleanField( + label="Расставлять переносы", + initial=True, + required=False, + help_text="Расставлять мягкие переносы (­)   
" + "в словах длиннее 14 символов   " + ) + etp_sanitize = forms.BooleanField( + label="Очистка HTML", + initial=False, + required=False, + help_text="Удалять весь HTML из исходного текста   " + ) + etp_hanging_punctuation = forms.BooleanField( + label="Висячая пунктуация", + initial=False, + required=False, + help_text="Выносить пунктуацию в начало строк
   " + "(только для заголовков... для тизера и контента отключается автоматически)   " + ) + etp_mode = forms.ChoiceField( + label="Режим вывода", + choices=[('mixed', 'Смешанный (Mixed)'), ('unicode', 'Юникод (Unicode)'), ('mnemonic', 'Мнемоники')], + initial='mixed', + required=False, + help_text="Формат спецсимволов (например, кавычек, тире, многоточий) в HTML: смешанный, юникод" + " или мнемоники   " + ) + + class Meta: + model = TbBlogPost + fields = ( + # Виртуальные поля для настройки типографа + 'etp_enable', 'etp_language', 'etp_quotes', 'etp_hyphenation', 'etp_sanitize', + 'etp_hanging_punctuation', 'etp_mode', + # Остальные поля модели TbArticle + 's_title', 'slug', 's_teaser', 's_content', 'f_cover_img', + 'is_published', 'd_published_at', + ) + + def __init__(self, *args, **kwargs): + """ + При инициализации формы подгружаем CodeMirror редактор. + Получаем request из kwargs, переданных из get_form_kwargs в AdminClass. + """ + # Извлекаем request из kwargs если он есть + self.request = kwargs.pop('request', None) + + super().__init__(*args, **kwargs) + + # Конфигурируем поля для CodeMirror + self.setup_codemirror_field('s_title', language='text', + css_class='codemirror-width-l codemirror-no-lines') + self.setup_codemirror_field('slug', language='text', + css_class='codemirror-width-l codemirror-no-lines') + self.setup_codemirror_field('s_teaser', language='html', + css_class='codemirror-width-l codemirror-min-height-5') + self.setup_codemirror_field('s_content', language='html', + css_class='codemirror-width-xl codemirror-min-height-10') + @admin.register(TbBlogPost) -class TbBlogPostAdmin(admin.ModelAdmin): +class TbBlogPostAdmin(RequestInFormMixin, admin.ModelAdmin): """ Управление статьями блога, документацией и инфо-страницами (HTML + etpgrf). """ + form = BlogPostAdminForm + list_display = ("id", "s_title_display", "slug", "is_published", "d_published_at", "d_created_at") list_display_links = ("id", "s_title_display") list_filter = ("is_published", "d_published_at", "d_created_at") diff --git a/public/static/codemirror/odemirror-patch.js b/public/static/codemirror/codemirror-patch.js similarity index 100% rename from public/static/codemirror/odemirror-patch.js rename to public/static/codemirror/codemirror-patch.js