Плагины для веб приложения на django
Уже сейчас в byteflow ощущается необходимость плагинов, то ли ещё будет ) Я решил оформить свои мысли документально, чтобы потом было проще обсуждать.
Итак, как мне видятся плагины в byteflow: каждый плагин это поддиректория-модуль каталога plugins. В __init__.py содержится информация об авторе, версии и т.д. Каждый плагин имеет уникальную метку, состоящую из букв латинского алфавита, цифр и знака подчёркивания. Не должно быть двух плагинов с одинаковой меткой. Метку можно использовать, когда нужно привязать какую-то информацию в БД к плагину, например, статус активности. Также, используя метку можно запрашивать обновления с официального сайта byteflow, где будут храниться плагины.
Плагины могут объявлять свои template tags. Имя template tag плагина обязано начинаться с mod_[метка плагина]_ Может быть, имеет смысл автоматически делать глобальными все template tags активных плагинов.
Плагины могут содержать urls, views, models, middlewares, которые должны подлючаться автоматически в settings.py и глобальном urls.py. Однако непонятно, как это делать, если, скажем, информацию об активности плагина мы будем хранить в БД, ведь БД в settings.py недоступна.
Где лучше хранить статические файлы типа стилей и картинок я не знаю. Если в каталогах плагинов, то надо морочаться с симлинками для подключения их в MEDIA_PATH, если же копировать в MEDIA_PATH, то усложняется установка плагина: не просто воткнуть в plugins, но ещё и скопировать куда нужно статические файлы.
Также мне весьма нравится идея хуков. Т.е. базовое приложение объявляет точки подключения, в которые плагины могут подключаться и влиять на процесс. Возьмём для примера такую точку подключения, как сохранение публикации в блоге. Используя систему хуков плагин может подключиться к этой точке и изменить сохраняемые данные заменив, например, известные ему аббревиатуры на HTML-код, показывающий расшифровку акронима, при наведении на него.
В джанго встроен pydispatcher, позволяющий посылать и обрабатывать сигналы, но, как мне кажется, система принудительных хуков, позволит плагинам более гибко и просто изменять алгоритм работы базовой системы. Сигналы - это асинхронная модель - мы посылаем сигнал и продолжаем что-то делать, а сигнал кто-то ловит и тоже что-то делает… Хук же - это передача эстафетной палочки - в один момент времени объект обрабатывается в одном месте.
Некоторым плагинам может понадобиться место на диске, чтобы хранить данные, для этого можно завести отдельную директорию, в которой создавать директорию с правами на запись для каждого активируемого плагина.
Итак, как мне видятся плагины в byteflow: каждый плагин это поддиректория-модуль каталога plugins. В __init__.py содержится информация об авторе, версии и т.д. Каждый плагин имеет уникальную метку, состоящую из букв латинского алфавита, цифр и знака подчёркивания. Не должно быть двух плагинов с одинаковой меткой. Метку можно использовать, когда нужно привязать какую-то информацию в БД к плагину, например, статус активности. Также, используя метку можно запрашивать обновления с официального сайта byteflow, где будут храниться плагины.
Плагины могут объявлять свои template tags. Имя template tag плагина обязано начинаться с mod_[метка плагина]_ Может быть, имеет смысл автоматически делать глобальными все template tags активных плагинов.
Плагины могут содержать urls, views, models, middlewares, которые должны подлючаться автоматически в settings.py и глобальном urls.py. Однако непонятно, как это делать, если, скажем, информацию об активности плагина мы будем хранить в БД, ведь БД в settings.py недоступна.
Где лучше хранить статические файлы типа стилей и картинок я не знаю. Если в каталогах плагинов, то надо морочаться с симлинками для подключения их в MEDIA_PATH, если же копировать в MEDIA_PATH, то усложняется установка плагина: не просто воткнуть в plugins, но ещё и скопировать куда нужно статические файлы.
Также мне весьма нравится идея хуков. Т.е. базовое приложение объявляет точки подключения, в которые плагины могут подключаться и влиять на процесс. Возьмём для примера такую точку подключения, как сохранение публикации в блоге. Используя систему хуков плагин может подключиться к этой точке и изменить сохраняемые данные заменив, например, известные ему аббревиатуры на HTML-код, показывающий расшифровку акронима, при наведении на него.
В джанго встроен pydispatcher, позволяющий посылать и обрабатывать сигналы, но, как мне кажется, система принудительных хуков, позволит плагинам более гибко и просто изменять алгоритм работы базовой системы. Сигналы - это асинхронная модель - мы посылаем сигнал и продолжаем что-то делать, а сигнал кто-то ловит и тоже что-то делает… Хук же - это передача эстафетной палочки - в один момент времени объект обрабатывается в одном месте.
Некоторым плагинам может понадобиться место на диске, чтобы хранить данные, для этого можно завести отдельную директорию, в которой создавать директорию с правами на запись для каждого активируемого плагина.



















Comments
Сигналы в pydispatcher’e используют синхронную модель, а не асинхронную.
Гм, действительно
И тут нашли неточность )) злые юзеры
я не злой юзер, я добрый unix way программист :)
Почти всё уже украдено до нас http://gulopine.gamemusic.org/2008/jan/10/simple-plugin-framework/ :)
Таки как раз сейчас читаю - мне пираныч её уже два раза кидал )
Интересно, касательно “хуков” сильно перекликается с моими идеями :)
А на счет статических файлов отдельно — не вижу ничего плохого, ведь они реально не входят в django application.
И распространять плагины как питоновские яйца =).
В общем-то зачем придумывать велосипед - уже давно есть, например, Trac. Там система плагинов довольно разумная.
Я вот только не пойму реальный смысл. Для django самого это нафик не нужно. Если кто то в дальнейшем создаст CMS на базе django - вот туда только.
Ай, не заметил сначала, это вы о своём byteflow.. ж)
Я сделал проще, выдрал из Trac (core.py). Помоему более элегантное решение, чем simple-plugin-framework.
В core/interface.py (core - это мой основной application в проекте) определил класс CorePluginManager и функцию get_plugin_manager - полу-фабрибрика/полу-синглетон.
И какой плагин без расширения urls?
Соотвественно в urls/init.py проекта, определяем url_extend, который используется в местах, где мы хотим предоставить возможность расширения функциональности.
Пример (в модуле urls проекта):
В плагине (расширяем new_product):
Ага, спасибо, изучу как будет время ) Мы уже присматривались к trac core при обсуждении системы плагинов в byteflow.