Библиотека сайта rus-linux.net
Фреймворк Yesod
Глава 22 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: Yesod
Автор: Michael Snoyman
Перевод: Н.Ромоданов
Обработчики
После того, как вы определите ваши маршруты, вы должны сообщить Yesod, как вы хотите отвечать на запросы. Это то место, где в игру вступают функции - обработчики. Настройка очень проста: для каждого ресурса (например, HomepageR) и метода запроса, создается функция с именем methodResourceR. Для нашего предыдущего примера, нам потребовалось бы четыре функции: getHomepageR
, getAddEntryR
, postAddEntryR
и getEntryR
.
Все параметры, полученные из маршрута, передаются в качестве аргументов в функцию - обработчик. В функции getEntryR
первый аргумент будет иметь тип EntryId
, тогда как во всех остальных функциях никаких аргументов не будет вообще.
Функции - обработчики размещаются внутри монады Handler
, в которой поддерживается большое количество возможностей, например, перенаправление запроса, доступ к сессии и выполнение запросов к базе данных. Что касается последней возможности, то типичный способ начать работу с функцией getEntryR
будет выглядеть следующим образом:
getEntryR entryId = do entry <- runDB $ get404 entryId
Это позволит запустить действие, с помощью которого из базы данных будет получена запись, ассоциированная с данным ID. Если такой записи нет, то будет возвращен ответ 404.
Каждая функция - обработчик вернет некоторое значение, которое должно быть экземпляром типа HasReps
. Это еще одна особенность, где свою роль играет RESTful: вместо того, чтобы просто вернуть некоторый фрагмент HTML или некоторый объект JSON, вы можете возвращать значение, которое может представлять собой и то, и другое в зависимости от заголовка запроса HTTP Accept. Другими словами, ресурс в Yesod является специфическим элементом данных, и его можно возвращать в одном из множества представлений.
Виджеты
Предположим, вы хотите добавить навигационную панель на нескольких различных страницах вашего сайта. Эта навигационная панель будет загружать пять самых последних постов блога (хранящихся в вашей базе данных), генерировать HTML, а затем использовать несколько фрагментов CSS и Javascript для соблюдения общего стиля сайта.
Если для того, чтобы собрать эти компоненты вместе, нет высокоуровнего интерфейса, то реализация может быть причиной головной боли. Вы можете добавить CSS к файлу CSS, который используется на всем сайте, но такое добавление вспомогательных деклараций не всегда является тем, что вам необходимо. Все тоже самое относится к Javascript, хотя с ним немного хуже: наличие дополнительного фрагмента Javascript может вызвать проблемы на странице, для работы с которой он не был предназначен. Вы также нарушаете модульность, поскольку вам потребуется генерировать результаты, получаемые из базы данных, с исользованием нескольких обработчиков.
В Yesod, у нас есть очень простое решение: виджеты. Виджет является фрагментом кода, в котором воедино связаны HTML, CSS и Javascript, что позволяет вам добавлять содержимое сразу в заголовок и в тело веб страницы, и вы сможете запустить любой произвольный код, для которого есть обработчик. Например, для то того, чтобы реализовать нашу навигационную панель:
-- Get last five blog posts. The "lift" says to run this code like we're in the handler. entries <- lift $ runDB $ selectList [] [LimitTo 5, Desc EntryPosted] toWidget [hamlet| <ul .navbar> $forall entry <- entries <li>l#{entryTitle entry} |] toWidget [lucius| .navbar { color: red } |] toWidget [julius|alert("Some special Javascript to play with my navbar");|]
Но здесь заложено даже больше, чем делается. Когда вы в Yesod создаете страницу, то стандартный подход состоит в объединении нескольких виджетов в один виджет, в котором содержится весь контент вашей страницы, а затем к нему применяется функция defaultLayout
. Эта функция определена для каждого сайта, и представляет собой использование стандартного макета сайта.
сегда есть два подхода, определяющих, куда следует поместить код CSS и Javascript:
- Объединить их и поместить их внутри вашего HTML в теги
style
иscript
, соответственно. - Поместить их во внешние файлы и обращаться к ним с помощью тегов
link
иscript
, соответственно.
Кроме того, размер вашего Javascript может быть автоматически уменьшен до минимума. Второй вариант является более предпочтительным, поскольку он позволяет выполнить несколько дополнительных оптимизаций:
- Файлы создаются с именами, создаваемыми с помощью хэш-функции по содержимому файла. Это означает, что вы можете пользоваться ими и в будущем, причем не беспокоясь о том, что пользователи получать устаревший контент.
- Ваш JavaScript можно загружать асинхронно.
Второй пункт требует некоторой доработки. Виджеты содержат не только JavaScript в его исходном виде, но в них также есть список Javascript-зависимостей. Например, во многих сайтах есть ссылки на библиотеку JQuery, а затем в них добавляются несколько фрагментов Javascript, в которых эта библиотека используется. Yesod может с помощью yepnope.js
автоматически преобразовать все это в асинхронную загрузку.
Другими словами, виджеты позволяют создавать модульный динамически компонуемый код, что в результате ведет к исключительно эффективному представлению ваших статических ресурсов.
Подсайты subsite
Во многих веб-сайты есть общие области функциональных возможностей. Пожалуй, двумя наиболее распространенными примерами этого служат статические файлы и аутентификация. В Yesod, вы можете легко поместить такой код в виде подсайта subsite. Все, что вам нужно сделать, это добавить к вашим маршрутам дополнительную строку. Например, чтобы добавить статический подсайт, вы должны написать:
/static StaticR Static getStatic
Первый аргумент сообщает, откуда начинается подсайт. Для статического подсайта обычно используется /static
, но вы можете использовать все, что вы захотите. StaticR
является именем маршрута; оно также полностью зависит от вас, но, по соглашению, используется StaticR
. Static
это имя статического подсайта, это единственное, что вы не можете поменять. getStatic
является функцией, которая возвращает настройки статического сайта, например, где расположены статические файлы.
Как и все обработчики, у обработчиков подсайтов также есть доступ к функции defaultLayout
. Это означает, что для хорошо продуманного подсайта будет автоматически использоваться внешний дизайн вашего сайта без каких-либо дополнительных вмешательств с вашей стороны.
Далее: Усвоенные уроки