Хочу поделится что у меня получилось и с какими вопросами столкнулся
Пошел по пути использования интерфейсов, первое что понравилось, некоторые вещи стали намного проще и концептуально понятней, потихоньку стала исчезать магия, второе, что не понравилось - кода стало намного, намного больше.
Все хорошо, но возникло два вопроса.
1. Обычно я стараюсь много чего выносить в конфиги. Приведу пример, так роутинг я обычно описываю в отдельном файле (yaml) как-то так:
index:
view: views.index.index
url:
- /
- /page/<int:page>
renderer: actions/index/index.html
acl: VIEW
Описания меню вынесены также в конфиги:
index:
order: 100
title: blog_menu_all
counter: views.new.count_topics_new
submenu:
index:
order: 100
title: blog_menu_all_good
new:
order: 200
title: blog_menu_all_new
counter: views.new.count_topics_new
hide_if_zero: true
Плагину чтобы дописать что-то в меню достаточно указать в своем конфиге:
index:
submenu:
plugin:
order: 150
title: blog_menu_plugin
title автоматом попадает в gettext, а index, new, plugin являются endpoint-ами и соответственно автоматически подсвечиваются.
Напомню что речь идет про Flask.
В стиле же Trac получается примерно такой код:
class IRouteProvider(Interface):
def connect():
"""Mount endpoint & routes of view.
Format: (enpoint, route1, route2, ...)
"""
def handle(context, request):
"""Process the request."""
class INavigationContributor(Interface):
"""Extension point interface for components that contribute items to the
navigation.
"""
def get_active_navigation_item(request):
"""This method is only called for the `IRouteProvider` processing the
request.
It should return the name of the navigation item that should be
highlighted as active/current.
"""
def get_navigation_items(request):
"""Should return an iterable object over the list of navigation items to
add, each being a tuple in the form (category, endpoint, title, counter [optional],
hide_if_zero [optional], quotted [optional]).
"""
class IndexModule(Component):
'''Main page
'''
required = True
implements(INavigationContributor, IPermissionRequestor, IRouteProvider)
# INavigationContributor methods
def get_active_navigation_item(self, request):
return 'index'
def get_navigation_items(self, request):
return [( .... )]
# IPermissionRequestor methods
def get_permission_actions(self):
return ['VIEW']
# IRouteProvider methods
def connect(self):
return ('index', '/', '/page/<int:page>',)
def handle(self, context, request, page=1):
return 'actions/index/index.html', dict( ... )
Можно конечно пойти гибридным способом и что-то оставить в конфигурационных файлах, а что-то в самом коде компонента.
На мой взгляд в некоторых случаях конфиг лучше, в плане что не надо менять код, чтобы изменить например вид урлов, порядок сортировки навигации и т.д.
Хотелось бы услышать мнение по этому вопросу.
2. И второе. Так как на мой взгляд архитектура Фласка несколько отличается от компонентной, то приходится переписывать некоторые части его функционала которыми я раньше пользовался а теперь не могу.
Приведу пример, например мне нужно выполнить рендеринг шаблона. можно конечно воспользоваться render_template, но на случай если плагинам потребуется иметь свои шаблоны, может даже не jinja2, получается опять же как то так:
class ITemplateProvider(Interface):
def get_template_loader():
'''Возвращает загрузчик шаблонов'''
def get_translations():
'''Возвращает класс GNUTranslations либо путь к каталогу'''
class BroserView(Component):
"""Web site chrome assembly manager."""
required = True
implements(IRouteProvider, ITemplateProvider)
navigation_contributors = ExtensionPoint(INavigationContributor)
template_providers = ExtensionPoint(ITemplateProvider)
+ много буков по имплементации всего этого добра
Лично у меня получается что чтобы интегрировать функционал фреймворка в код требуется больше усилий, чем написать свою реализацию.
Т.е. получается, может я ошибаюсь, что либо скоро от Flask кроме роутинга ничего не останется, либо придется не трогать тот функционал который есть, либо взять другой фреймворк. Либо я не могу правильно их интегрировать.
Хотелось бы также понять, отчего возникает дискомфорт, либо просто от неумения пользоваться интерфейсами, либо по причинам, которые я попытался изложить выше.