Разработка web-приложений с repoze.bfg
Upcoming SlideShare
Loading in...5
×
 

Разработка web-приложений с repoze.bfg

on

  • 1,972 views

 

Statistics

Views

Total Views
1,972
Views on SlideShare
1,946
Embed Views
26

Actions

Likes
0
Downloads
11
Comments
0

1 Embed 26

http://www.slideshare.net 26

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Разработка web-приложений с repoze.bfg Разработка web-приложений с repoze.bfg Presentation Transcript

  • Разработка web-приложений с repoze.bfg Андрей Попп 8mayday@gmail.com http://braintrace.ru @andreypopp
  • Что такое repoze.bfg Это минималистичный web-фрэймворк, вобравший в себя идеи Zope, Django, Pylons. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Что такое repoze.bfg Ключевые моменты: WSGI. MVC (скорее даже MTV). Компонентная архитектура. 100% покрытие тестами (по отчётам утилиты Coverage). Отличная документация. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Что такое repoze.bfg Фрэймворк предоставляет инструменты, помогающие решению следующих проблем: Конфигурация приложения. Маршрутизация запросов. Шаблонизация. Аутентификация и авторизация. Интернационализация и локализация. Тестирование приложения. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Что такое repoze.bfg Остальное вопросы остаются за разработчиком: Где и как хранятся данные приложения. Как генерировать и обрабатывать формы. Где хранить данные сессии. Кэширование. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Что такое repoze.bfg Repoze.bfg использует хорошо знакомые и проверенные технологии: WebOb/Paste – уровень WSGI. ZCA/ZCML – компонентная архитектура и конфигурация. Babel – интернационализация и локализация. Zope Page Templates – система шаблонизации. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Неужели repoze.bfg использует библиотеки Zope?! Андрей Попп: Разработка web-приложений с repoze.bfg
  • Использование Zope библиотек Да, repoze.bfg использует Zope библиотеки, но: Их использование – это просто деталь реализации фрэймворка. Пользователь фрэймворка не обязан знать и использовать библиотеки Zope. Библиотеки Zope не так уж плохи. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Начинаем работать с repoze.bfg Чтобы создать проект repoze.bfg, можно воспользоваться одним из шаблонов Paste: paster create -t < template_name > < project_name > Шаблонов всего три: bfg_starter, bfg_zodb, bfg_alchemy, bfg_routesalchemy, но об этом позже. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Начинаем работать с repoze.bfg В результате получаем готовую структуру пакета под управлением setuptools (или distribute). Приложение уже настроено для запуска с помощью Paste: paster serve paste . ini -- reload Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Конфигурация приложения это: URL приложения и как они отображаются на представления. Статические ресурсы и используемые шаблоны. Политики аутентификации и авторизации. Файлы с локализацией. Компоненты, специфичные для приложения. Почти как settings.py и urls.py в Django. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Конфигурацию приложения не стоит путать с настройками приложения. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Конфигурация выполняется с помощью объекта Configurator: Императивно – c помощью вызовов Configurator.add_route, Configurator.add_view и т.д. Декларативно – с помощью ZCML. С помощью декораторов. После выполнения конфигурации необходимо вызвать метод Configurator.make_wsgi_app(), чтобы создать сконфигурированное WSGI приложение. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Пример: императивная конфигурация myproject/run.py: ... config = Configurator () config . begin () config . add_view ( views . show_entries ) config . add_view ( views . show_comments ) config . end () wsgi_app = config . make_wsgi_app () ... Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Пример: конфигурация с помощью декораторов myproject/run.py: ... config = Configurator () config . begin () config . scan () config . end () wsgi_app = config . make_wsgi_app () ... myproject/views.py: ... @bfg_view () def show_entries ( request ): return Response () ... Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Пример: декларативная конфигурация с помощью ZCML myproject/run.py: ... config = Configurator () config . begin () config . load_zcml ( ’ configure . zcml ’) config . end () wsgi_app = config . make_wsgi_app () ... myproject/configure.zcml: ... < view view =" myproject . views . show_entries " > < view view =" myproject . views . show_comments " > ... Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Все три приведённых примера абсолютно идентичны в плане конечного результата. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Но использование ZCML позволяет разрабатывать расширяемые приложения. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Что такое ZCML ZCML (Zope Configuration Markup Language) – декларативный, основанный на XML, язык для описания конфигураций. Для repoze.bfg cуществует набор директив ZCML (таких как view), которые потом преобразуются в вызовы функций (в случае с view – в вызов метода Configuration.add_view). Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Директива ZCML – include С помощью директивы include можно подгружать конфигурацию из других ZCML файлов других пакетов: ... < include package =" anotherproject " / > < include package =" yetanotherproject " / > ... Порядок таких включений имеет значение, потому что директивы, встречающиеся в файлах конфигурации могут переопределять друг друга. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Преобразование директив конфигурации в вызовы функций производится только после считывания всех необходимых файлов конфигурации. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Именно потому, что с ZCML возможно переопределять конфигурацию приложения, его необходимо использовать для разработки расширяемых приложений. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Пример организации ZCML конфигурации в приложении Обычно экземпляр установленного приложения содержит следующую ZCML конфигурацию: ... < include package =" myproject . core " / > < include package =" myproject . additional_module " / > ... Андрей Попп: Разработка web-приложений с repoze.bfg
  • Конфигурация приложения Пример организации ZCML конфигурации в приложении Если нам нужно добавить ещё функционала в приложение: ... < include package =" myproject . core " / > < include package =" myproject . additional_module " / > <include package="myproject.plugins.openid"/> ... Мы просто подключаем конфигурацию пакета, который предоставляет нужный функционал. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Поговорим о представлениях в repoze.bfg. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Представления в repoze.bfg Представлением может служить, как функция вида def my_view ( request ): return Response ( ’ Hello , world ! ’) так и класс с методом __call__ class MyView ( object ): def __init__ ( self , request ): pass def __call__ ( self ): return Response ( ’ Hello , world ! ’) Андрей Попп: Разработка web-приложений с repoze.bfg
  • Представления в repoze.bfg Аргумент request – это объект WebOb.Request. Представление должно возвращать объект с атрибутами: status – строка HTTP статуса. headerlist – список HTTP заголовков. app_iter – итератор по телу ответа. Таким объектом, например, является WebOb.Response. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Представления в repoze.bfg Кроме того, представление может зависеть от контекста def my_view (context, request ): return Response ( ’ Hello , world ! ’) или class MyView ( object ): def __init__ ( self , context, request ): pass def __call__ ( self ): return Response ( ’ Hello , world ! ’) Андрей Попп: Разработка web-приложений с repoze.bfg
  • Представления в repoze.bfg Контекст представления – это объект из предметной области приложения. Для каждого запроса он определяется с помощью механизма нахождения контекста, но об этом позже. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Представления в repoze.bfg Почему хорошо иметь в приложении контекстно-зависимые представления: Для разных типов контекста можно определять разные представления. Можно устанавливать ограничения на представления в зависимости от контекста. Но использование контекстно-зависимых представлений в приложении полностью опционально, если хочется – можно делать как в Django, Pylons. . . Андрей Попп: Разработка web-приложений с repoze.bfg
  • Как происходит маршрутизация запросов в repoze.bfg или как URL запроса отображается на представление? Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Весь процесс маршрутизации запроса происходит в две фазы: Нахождение контекста для запроса. Выбор представления для запроса и найденного контекста. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Существует три способа организовать маршрутизацию запросов в приложении: Нахождение контекста с помощью обхода графа объектов и последующий выбор представления. Сопоставление URL запроса с шаблонами, контекст указывается явно для шаблона URL. Гибридный способ – сначала идёт сопоставление с нужным URL-шаблоном, а потом обход графа объектов. Аналогично первому способу работает Zope, второй способ характерен для Django, Pylons и т.п. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обход графа Удобно использовать, когда: Множество объектов предметной области имеет структуру графа. URL приложения можно интерпретировать как пути в этом графе. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обход графа Обход графа начинается с корневого объекта. Фабрика для создания корневого объекта указывается на этапе конфигурации: config = Configurator ( root_factory = some_factory , ...) Где some_factory – это функция, которая принимает request единственным аргументом и возвращает корневой объект. def some_factory ( request ): return RootObject () Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обход графа Обычно, в качестве корневого объекта используется интерфейс к БД или любому другому механизму хранения данных. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обход графа Допустим, что мы проектируем приложение для управления статическими страницами. Кроме корневого объекта RootObject, у нас есть следующие объекты предметной области: Объект PageManager – это менеджер статических страниц, через него мы можем получить нужную страницу по её идентификатору. Объект Page – представляет отдельную страницу. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обход графа Как происходит обход графа на примере URL /pages/page1: 1 URL разбивается на части: [’pages’, ’page1’]. 2 Вызывается метод RootObject.__getitem__ с аргументом ’pages’. Этот метод возвращает объект PageManager. 3 Вызывается метод PageManager.__getitem__ с аргументом ’page1’. В результате получаем объект Page. Так как частей URL у нас больше не осталось, найденный объект Page является контекстом данного запроса. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Выбор представления После того, как мы нашли контекст, нам нужно выбрать подходящее представление. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Выбор представления Представления для объектов предметной области определяются на этапе конфигурации. Императивно: config . add_view ( show_page , for_ = Page ) config . add_view ( show_comment , for_ = Comment ) или с помощью ZCML: < view view =" views . show_page " for =" models . Page " / > < view view =" views . show_comment " for =" models . Comment " / > Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Выбор представления Выбор представления учитывает Method Resolution Order. Если не найдено представления для конкретного типа, будет использовано представление для его супертипа. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Выбор представления Кроме этого, можно определять разные представления для разных HTTP методов, разных значений HTTP заголовков и на основе других предикатов. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Шаблоны URL Если маршрутизация запросов с помощью обхода графа не подходит, можно использовать сопоставление URL с шаблонами. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Шаблоны URL Механизм сопоставления URL с шаблонами работает также, как и в Django, Routes и т.д. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Шаблоны URL Шаблоны URL приложения определяются на этапе конфигурации. Императивно: config . add_route ( view = show_page , path ="/ pages /: page_id " ) или с помощью ZCML: < route view =" views . show_page " path ="/ p /: page_id " /> Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Шаблоны URL Контекст указывается явно: config . add_route ( view = show_page , path ="/ pages /: page_id " , factory=" some_factory " ) или с помощью ZCML: < route view =" views . show_page " path ="/ p /: page_id " factory=" some_factory " /> Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Шаблоны URL Для каждого шаблона можно определить несколько представлений для разных типов контекста: < route name =" pages " path ="/ p /: page_id " factory =" some_factory " /> < view route_name =" pages " for =" Page " /> < view route_name =" pages " for =" MainPage " /> Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Гибридный метод Можно комбинировать обход графа и шаблоны URL: < route name =" pages " path ="/ pages /: category_id /* traverse " factory =" some_factory " /> В этом случае первая URL сначала будет сопоставляться с /pages/:category_id, а оставшаяся часть будет использоована для обхода графа объектов начиная с объекта, произведённого с some_factory. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обработка исключений Что происходит, если во время выполнения представления происходит исключение? Андрей Попп: Разработка web-приложений с repoze.bfg
  • Маршрутизация запросов Обработка исключений В этом случае контекст запроса изменяется на текущее исключение и происходит выбор подходящего представления. Представления для исключений регистрируются обычным образом: < view for =" webob . exc . HTTPNotFound " view =" notfound_view " /> Если во время исполнения любого представления произойдёт исключение webob.exc.HTTPNotFound, то исполнение перейдёт к notfound_view. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Шаблонизация По-умолчанию, repoze.bfg предлагает использовать шаблонизатор Chameleon – это реализация Zope Page Templates и Genshi. Кроме того, на pypi присутствует пакет repoze.bfg.jinja2 – для работы с шаблонизатором Jinja2. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Шаблонизация Как уже упоминалось, представление должно возращать объект с интерфейсом Response. Это не всегда удобно, особенно когда дело касается тестирования, а представление рендерит тяжёлый шаблон: response = myview ( request ) assert ’ Some text ’ in ’ ’. join ( response . app_iter ) Андрей Попп: Разработка web-приложений с repoze.bfg
  • Шаблонизация Repoze.bfg предлагает следующее решение: Представления возвращает dict() объект. За преобразование этого объекта в конечный Response ответственнен отдельный объект – рендерер. Рендерер определяется для каждого представления на этапе конфигурации. Шаблоны являются рендерерами. < view view =" views . some_pages " renderer =" list_pages . jinja2 " /> Андрей Попп: Разработка web-приложений с repoze.bfg
  • Шаблонизация В repoze.bfg по-умолчанию присутствуют рендереры для вывода JSON и ZPT шаблонов. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Шаблонизация Пакет repoze.bfg.jinja2 предоставляет рендерер для шаблонов Jinja2. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Заключение На этом всё. Читайте документацию – http://docs.repoze.org/bfg/. Андрей Попп: Разработка web-приложений с repoze.bfg
  • Спасибо! Вопросы? Андрей Попп: Разработка web-приложений с repoze.bfg