Как расширить панель инструментов¶
Панель инструментов django CMS предоставляет API, который позволяет вам добавлять, удалять и манипулировать элементами панели инструментов в вашем собственном коде. Это поможет вам интегрировать режим редактирования django CMS в ваше приложение и предоставить вашим пользователям оптимизированный опыт редактирования.
См.также
Extending the Toolbar в учебнике
Создайте файл cms_toolbars.py
¶
Для того чтобы взаимодействовать с API панели инструментов, необходимо создать подкласс CMSToolbar
в собственном коде и зарегистрировать его.
Этот класс должен быть создан в файле cms_toolbars.py
вашего приложения, где он будет обнаружен автоматически при запуске Django runserver.
Вы также можете использовать CMS_TOOLBARS
для управления тем, какие классы панели инструментов загружаются.
Определите и зарегистрируйте подкласс CMSToolbar
¶
from cms.toolbar_base import CMSToolbar
from cms.toolbar_pool import toolbar_pool
class MyToolbarClass(CMSToolbar):
[...]
toolbar_pool.register(MyToolbarClass)
Метод cms.toolbar_pool.ToolbarPool.register
также может быть использован в качестве декоратора:
@toolbar_pool.register
class MyToolbarClass(CMSToolbar):
[...]
Наполнение панели инструментов¶
Для управления тем, что будет отображаться на панели инструментов django CMS, доступны два метода:
populate()
, который вызывается до того, как будет отрисована остальная часть страницыpost_template_populate()
, который вызывается после отрисовки шаблона страницы
Последний метод позволяет управлять панелью инструментов на основе содержимого страницы, например, состояния плагинов или заполнителей, но если вам это не нужно, лучше выбрать более простой метод populate()
.
class MyToolbar(CMSToolbar):
def populate(self):
# add items to the toolbar
Теперь вам нужно решить, какие именно элементы будут отображаться на панели инструментов. К ним можно отнести:
Добавление ссылок и кнопок на панель инструментов¶
Вы можете добавить ссылки и кнопки в качестве элементов в экземпляр меню, используя различные методы add_
.
Действие |
Вариант текстовой ссылки |
Вариант кнопки |
---|---|---|
Открытая ссылка |
||
Открыть ссылку в боковом фрейме |
||
Открыть ссылку в модальном окне |
||
POST-действие |
Основной формой для использования любого из них является:
def populate(self):
self.toolbar.add_link_item( # or add_button(), add_modal_item(), etc
name='A link',
url=url
)
Обратите внимание, что хотя эти элементы панели инструментов могут принимать различные позиционные аргументы в своих методах, мы настоятельно рекомендуем использовать именованные аргументы, как указано выше. Это поможет гарантировать, что ваши собственные классы и методы панелей инструментов переживут обновления. Подробную информацию о сигнатуре каждого метода см. в справочной документации, ссылки на которую приведены в таблице выше.
Открытие URL-адреса в iframe¶
Обычным случаем является предоставление URL, который открывается в боковом фрейме или модальном диалоге на той же странице. Administration… в меню сайта, который открывает админку Django в боковом фрейме, является хорошим примером этого. И боковой фрейм, и модальный диалог - это HTML iframe.
Типичное использование бокового фрейма - отображение списка администраторов (аналогично тому, что используется в tutorial example):
from cms.utils.urlutils import admin_reverse
[...]
class PollToolbar(CMSToolbar):
def populate(self):
self.toolbar.add_sideframe_item(
name='Poll list',
url=admin_reverse('polls_poll_changelist')
)
Типичное использование модального элемента - отображение администратора для экземпляра модели:
self.toolbar.add_modal_item(name='Add new poll', url=admin_reverse('polls_poll_add'))
Однако вы не ограничены этими примерами и можете открыть любой подходящий ресурс внутри модального или бокового фрейма. Обратите внимание, что протоколы должны совпадать, а запрашиваемый ресурс должен разрешать это.
Добавление кнопок на панель инструментов¶
Кнопка является подклассом cms.toolbar.items.Button
.
Кнопки также могут быть добавлены в список - ButtonList
- это группа визуально связанных кнопок.
def populate(self):
button_list = self.toolbar.add_button_list()
button_list.add_button(name='Button 1', url=url_1)
button_list.add_button(name='Button 2', url=url_2)
Поиск существующих элементов панели инструментов¶
find_items()
и find_first()
.¶
Поиск предметов по их типу:
def populate(self):
self.toolbar.find_items(item_type=LinkItem)
найдет все LinkItem
на панели инструментов (но не, например, в меню на панели инструментов - он не ищет другие элементы на панели инструментов для собственных элементов).
find_items()
возвращает список объектов ItemSearchResult
; find_first()
возвращает первый объект в этом списке. Они имеют схожее поведение, поэтому в примерах здесь будет использоваться только find_items()
.
Аргумент item_type
всегда обязателен, но вы можете уточнить поиск, используя другие их атрибуты, например:
self.toolbar.find_items(Menu, disabled=True))
Обратите внимание, что эти два метода можно использовать и для поиска элементов в классах Menu
и SubMenu
.
Управление положением элементов на панели инструментов¶
Методы добавления пунктов меню на панель инструментов принимают необязательный аргумент position
, который можно использовать для управления тем, куда будет вставлен пункт.
По умолчанию (position=None
) элемент будет вставлен после существующих элементов на том же уровне иерархии (новое подменю станет последним подменю меню, новое меню станет последним меню на панели инструментов и так далее).
Позиция 0
вставляет элемент перед всеми остальными.
Если у вас уже есть объект, его тоже можно использовать в качестве ссылки. Например:
def populate(self):
link = self.toolbar.add_link_item('Link', url=link_url)
self.toolbar.add_button('Button', url=button_url, position=link)
добавит новую кнопку перед элементом ссылки.
Наконец, вы можете использовать ItemSearchResult
в качестве позиции:
def populate(self):
self.toolbar.add_link_item('Link', url=link_url)
link = self.toolbar.find_first(LinkItem)
self.toolbar.add_button('Button', url=button_url, position=link)
и поскольку ItemSearchResult
может быть приведено к целому числу, вы даже можете сделать:
self.toolbar.add_button(„Button“, url=button_url, position=link+1)
Управление тем, как и когда появляется панель инструментов¶
По умолчанию ваш подкласс CMSToolbar
будет активен (т.е. его методы populate
будут вызываться) в панели инструментов на каждой странице, когда пользователь is_staff
. Однако иногда подкласс CMSToolbar
должен появляться на панели инструментов только при посещении страниц, связанных с определенным приложением.
Подкласс CMSToolbar
имеет полезный атрибут, который может помочь определить, должна ли панель инструментов быть активирована. is_current_app
является True
, когда приложение, содержащее класс панели инструментов, совпадает с приложением, обрабатывающим запрос.
Это позволяет, например, активировать его выборочно:
def populate(self):
if not self.is_current_app:
return
[...]
Если класс панели инструментов находится в другом приложении, а не в том, для которого вы хотите, чтобы он был активен, вы можете перечислить все приложения, которые он должен поддерживать при создании класса:
supported_apps = ['some_app']
supported_apps
- это кортеж прикладных точечных путей (например: supported_apps = ('whatever.path.app', 'another.path.app')
.
Атрибут app_path
будет содержать имя приложения, обрабатывающего текущий запрос - если app_path
находится в supported_apps
, то is_current_app
будет True
.
Изменение существующей панели инструментов¶
Если вам нужно изменить существующую панель инструментов (например, изменить атрибут или поведение метода), вы можете сделать это, создав ее подкласс, который реализует необходимые изменения, и зарегистрировав его вместо исходного.
Оригинальный класс можно снять с регистрации, используя toolbar_pool.unregister()
, как в примере ниже. Также, если вы изначально вызывали класс панели инструментов с помощью CMS_TOOLBARS
, вам нужно будет изменить его, чтобы он ссылался на новый класс.
Пример, в котором мы снимаем с регистрации оригинал и регистрируем свой собственный:
from cms.toolbar_pool import toolbar_pool
from third_party_app.cms_toolbar import ThirdPartyToolbar
@toolbar_pool.register
class MyBarToolbar(ThirdPartyToolbar):
[...]
toolbar_pool.unregister(ThirdPartyToolbar)
Обнаружение изменений URL-адреса объекта¶
Если вы хотите следить за созданием объектов или редактированием моделей и перенаправлять после их добавления или изменения, добавьте на панель инструментов атрибут watch_models
.
Пример:
class PollToolbar(CMSToolbar):
watch_models = [Poll]
def populate(self):
...
После добавления этой функции каждое изменение экземпляра Poll
через боковой фрейм или модальное окно будет вызывать перенаправление на URL экземпляра опроса, который был отредактирован, в соответствии со статусом панели инструментов:
в режиме черновик возвращается
get_draft_url()
(илиget_absolute_url()
, если первого не существует)в режиме live, и метод существует, возвращается
get_public_url()
.
Frontend¶
Если вам необходимо взаимодействовать с панелью инструментов или иным образом учитывать ее в коде фронтенда вашего сайта, она предоставляет крючки CSS и JavaScript для использования.
Он добавит различные классы к элементу <html>
страницы:
cms-ready
, когда панель инструментов готоваcms-toolbar-expanded
, когда панель инструментов полностью развернутаcms-toolbar-expanding
иcms-toolbar-collapsing
во время анимации панели инструментов.
Панель инструментов также запускает событие JavaScript под названием cms-ready
в документе. Вы можете прослушать это событие с помощью jQuery:
CMS.$(document).on('cms-ready', function () { ... });