Автор (ы) | Майкл Снойман |
---|---|
Разработчик (и) | Майкл Снойман и др. |
Первоначальный выпуск | 2010 |
Стабильный выпуск | 1.6.18 / 2020-05-31 |
Репозиторий | |
Написано на | Haskell |
Операционная система | Кросс-платформенная |
Доступно в | Haskell |
Тип | Веб-фреймворк |
Лицензия | Лицензия MIT |
Веб-сайт | www.yesodweb.com |
Yesod (IPA: ; Иврит : יְסוֺד, «Фонд») - это бесплатный веб-фреймворк с открытым исходным кодом на основе Haskell для продуктивной разработки шрифтов. -safe, REST на основе модели (где URL идентифицируют ресурсы, а методы HTTP идентифицируют переходы), высокопроизводительные веб-приложения, разработанные et al.
Yesod основан на шаблонах для создания экземпляров для перечисленных сущностей и функций обработки динамического содержимого с помощью конструкций Template Haskell для размещения шаблонов содержимого eDSL, называемых QuasiQuotes, где содержимое преобразуется в кодовые выражения с помощью инструкций метапрограммирования.
Существуют также шаблоны веб-языка сниппета, которые допускают интерполяцию кодовых выражений, что делает их полностью проверенными на тип во время компиляции.
Yesod разделяет свои функции на отдельные библиотеки, поэтому вы можете выбрать свою {базу данных, рендеринг html, формы и т. д.} функциональную библиотеку по вашему выбору.
Yesod использует интерфейс веб-приложения API, сокращенно WAI, для изоляции сервлетов, или веб-приложения., С серверов, с обработчиками для серверных протоколов CGI, FastCGI, SCGI, Warp, Launch (открыть как локальный URL-адрес в браузере по умолчанию, закрыть сервер при закрытии окна),
См. исх. Yesod требует типа данных, который создает экземпляры классов контроллера . Это называется фундаментным типом. В приведенном ниже примере оно называется «MyApp».
Модель REST идентифицирует веб-ресурс с помощью веб-пути. Здесь ресурсы REST получают имена с суффиксом R (например, «HomeR») и перечислены в шаблоне описания карты сайта parseRoutes. Из этого списка берутся имена маршрутов и имена обработчиков диспетчеризации.
Yesod использует метапрограммирование Template Haskell для генерации кода из шаблонов во время компиляции, обеспечивая совпадение имен в шаблонах и все проверки типов (например, имена веб-ресурсов и имена обработчиков).
При вставке вызова mkYesod это вызовет примитивы Template Haskell для генерации кода, соответствующего элементам типа маршрута, и экземплярам классов диспетчерского контроллера для отправки вызовов GET для маршрута HomeR к подпрограмме с именем, составляющей их обе как «getHomeR», ожидая существующего обработчика, который соответствует имени.
Пример «Hello world» на основе интерфейса сервера CGI (фактические типы обработчиков изменились, но философия осталась):
{- file wai-cgi-hello.hs -} {- # LANGUAGE PackageImports, TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings # -} import "wai" Network.Wai import "wai-extra" Network.Wai.Handler.CGI (запустить) - взаимозаменяемый обработчик WAI import "yesod" Yesod import "yesod-core" Yesod.Handler (getRequest) import "text" Data.Text (Text) import "shakespeare" Text.Cassius (Color (..), colorBlack) - - данные типа Foundation MyApp = MyApp - шаблон карты сайта, путь к списку, имя ресурса и принятые методы - mkYesod принимает имя типа основания в качестве параметра. для составления имен диспетчерских функций mkYesod "MyApp" [parseRoutes | / HomeR GET |] экземпляр Yesod MyApp - шаблон CSS со структурой отступов myStyle :: [Text] → CssUrl url myStyle paramStyle = [cassius |.box border: 1px solid # {boxColor} |], где boxColor = case paramStyle of ["высококонтрастный"] → colorBlack _ → Color 0 0 255 - HTML-шаблон со структурированным отступом myHtml :: [(Text, Text)] → URL-адрес HtmlUrl myHtml params = [деревня |
Привет, мир! Есть # {параметры длины} параметры : $ if null params
Ничего не перечислить $ else
getHomeR :: Handler RepHtml getHomeR = do req <- getRequest let params = reqGetParams req paramStyle <- lookupGetParams "style" defaultLayout $ do -- adding widgets to the Widget monad (a ''Writer'' monad) setTitle "Yesod example" toWidgetHead $ myStyle paramStyle toWidgetBody $ myHtml params -- there are ''run'' function variants for different WAI handlers main = toWaiApp MyApp>>= run
# cgi test export REMOTE_ADDR = 127.0.0.1 export REQUEST_METHOD = GET export PATH_INFO = / export QUERY_STRING = 'p1 = abc; p2 = def; style = high-Contrast './wai-cgi-hello
См. исх. Yesod следует модели REpresentational State Transfer доступа к веб-документам, идентифицируя документы. и каталоги как ресурсы с конструктором маршрута, названным с суффиксом R в верхнем регистре (например, HomeR).
Захват сегмента URL-адреса в качестве параметра возможен с указанием префикса '#' для одиночного сегментный захват или "*" для многосегментного захвата, за которым следует тип параметра.
- с учетом типа основания MyApp mkYesod "MyApp" [parseRoutes | / HomeR - HTTP-методы не указаны: все методы принимаются / blog BlogR GET POST - префикс '#' указывает сегмент пути как параметр обработчика маршрута / article / # ArticleId ArticleR GET PUT - префикс '*' указывает параметр как последовательность частей пути / ветка / * Тексты BranchR GET - для упрощения грамматики составные типы должны использовать псевдоним, например. type Тексты для '' [Text] '' |]
data Route MyApp = HomeR - в шаблонах указывается как: @ {HomeR} | BlogR - в шаблонах: @ {BlogR} | ArticleR ArticleId - в шаблонах: @ {ArticleR myArticleId} | Тексты BranchR - в шаблонах: @ {BranchR myBranchSegments}
- для «/ HomeR» - HTTP-методы не указаны ⇒ только один обработчик с префиксом 'handler' 'handlerHomeR :: HasReps t ⇒ Handler t - для "/ blog BlogR GET POST" getBlogR :: HasReps t ⇒ Handler t postBlogR :: HasReps t ⇒ Handler t - for "/ article / #ArticleId ArticleR GET PUT "getArticleR :: HasReps t ⇒ ArticleId → Handler t putArticleR :: HasReps t ⇒ ArticleId → Handler t
См. Исх.
См. Исх. Плагины аутентификации: OpenId, BrowserId, Email, GoogleEmail, HashDB, RpxNow.
См. Исх. Бэкэнды сеанса: ClientSession (он сохраняет сеанс в файле cookie), ServerSession (он хранит большую часть данных сеанса на сервере)
Успешное, неудачное или ориентировочное сообщение может быть сохранено (setMessage) в сеансе и будет показано, если оно существует, с помощью процедуры default_layout через шаблон default_layout.hamlet
, очищаемый при консультации.
Подсайты с общим префиксом URL для рабочих процессов, обслуживания файлов или разделения сайта. См. Ссылку
Встроенные дочерние сайты: Static, Auth
См. Ссылку
Тип формы здесь является объектом который используется в контроллере для синтаксического анализа и обработки полей формы, вводимых пользователем, и создания пары (FormResult, Widget), где виджет содержит макет следующей визуализации формы с сообщениями об ошибках и метками. Его также можно использовать для создания новой формы с пробелами или значениями по умолчанию.
Тип формы принимает форму функции фрагмента HTML, который должен быть встроен в представление, которое будет содержать скрытые поля для целей безопасности.
Объект формы создается из Applicative / Monadic композиции полей для комбинированного / последовательного анализа входных данных полей.
Существует три типа форм:
Генераторы полей, имена которых состоят из начального типа формы (a | m | i)
, за которым следует (req | opt) {- обязательно или необязательно -}
, иметь компонент fieldParse и компонент fieldView.
Фактические параметры и типы функции имеют менял через версии Yesod. Проверьте подписи в книге Yesod и библиотеки.
Магия заключается в экземпляре Applicative типа данных FormResult, где (<*>) собирает сообщения об ошибках для случая FormFailure [textErrMsg]
значения результатов
Monadic формы допускают произвольную компоновку форм и улучшенную обработку членов hiddenField.
Образец аппликативной формы:
- запись для данных полей нашей формы Person = Person {personName :: Text, personAge :: Int, personLikings :: Maybe Text} - тип Form имеет дополнительный параметр для встраиваемого фрагмента html, содержащий скрытое поле токена CSRF для типа безопасности Sub master x = Html → MForm sub master (FormResult x, Widget) { - - для сообщений в функциях проверки: @param master: экземпляр yesod для использования в renderMessage (возврат из getYesod обработчика) @param languages: языки страниц для использования в renderMessage - необязательная запись по умолчанию: @param mbPersonDefaults: Just defaults_record, или ничего для пустой формы -} personForm :: MyFoundationType → [Text] → Maybe Person → Sub master P erson {- '' aopt '' (необязательный компонент поля AForm) для полей "Может быть", '' areq '' (обязательный fld AForm comp.) вставит атрибут "required" -} Основные языки personForm mbPersonDefaults = renderTable $ Person <$>areq TextField fldSettingsName mbNameDefault <*>areq customPersonAgeField fldSettingsAge mbAgeDefault <*>Aopt textareaField fldSettingsLikings mbLikingsDefault где mbNameDefault = БПМЖ PERSONNAME mbPersonDefaults mbAgeDefault = БПМЖ персонажа mbPersonDefaults mbLikingsDefault = БПМЖ personLikings mbPersonDefaults - "fieldSettingsLabel" возвращает первоначальную fieldSettings запись - недавно Запись «FieldSettings» может быть определена из метки String, поскольку она реализует IsString fldSettingsName = (fieldSettingsLabel MsgName) {fsAttrs = [(«maxlength», «20»)]} fldSettingsAge = fieldSettingsLabel MsgAge fldSettingsLikings = (fieldSettingsLikings) ("столбцы", "40"), ("строки", "10")]} customPersonAgeField = проверить validateAge intField validateAge y | y < 18 = Left $ renderMessage master languages MsgUnderAge | otherwise = Right y
Показанные типы соответствуют более старой версии, но философия остается.
Монада Handler возвращает контент в одном или нескольких форматах как компоненты типов, реализующих класс HasReps {RepHtml, RepJson, RepXml, RepPlain, двойной RepHtmlJson, пару или список пар [(ContentType, Содержание)],..}. Примеры Json:
Реализация chooseRep по умолчанию в HasReps выбирает возвращаемое представление документа в соответствии с предпочтительным списком типов содержимого принимаемого заголовка клиента.
Монада виджетов, основанная на монаде Writer и аргументе defaultLayout, облегчает объединение виджетов вместе.
[qq |... |]
представляет структурированный HTML-шаблон на основе отступов. (См. Документ.)'$' ставит префикс строк логических операторов.
Автоматические закрывающие теги генерируются только для тега в начальной позиции строки.
toWidget [деревня | $ doctype 5# {pageTitle} - Мой сайт ^ {headerTemplate} _ {MsgArticleListTitle} $ if null article
_ {MsgSorryNoArticles} $ else
$ forall art <- articles
- # {articleNumber art}.- # {articleTitle art}
См. Исх. Это шаблоны представления содержимого, которые следуют общему шаблону подстановки кодовых выражений в фигурных скобках с разными префиксом символов для ссылки на
^ {...}
^ {template params}
,@ {...}
@ {HomeR}
,_ {...}
_ {MsgMessageLabel params}
# {...}
# {haskell_expression}
какой тип должен быть конвертируемым
.msg") с интерполяцией параметров, тип выражения должен быть экземпляром Text.Shakespeare.I18N.ToMessage. Использование неанглийского текста в выражениях требует использования Unicode типа Text, поскольку GHC для типа String отображает символы, отличные от ASCII, как экранированные числовые коды.
См. ссылку
Сообщения приложения Yesod можно локализовать (i18n ). Они должны храниться в папке сообщений, в файлах с именами на основе ISO, как
Записи сообщений следуют шаблону EBNF :
- EBNF: идентификатор, {'', параметр, '@', тип}, ":", текст с интерполяциями. ArticleUnexistent param @ Int64: конструкторы сообщений, которые не существует в статье # {param}
- в коде myMsg :: MyAppMessage - тип данных, добавляющий "Message" к основному типу myMsg = MsgArticleUnexistent myArticleId - конструктор, добавляющий "Msg" к сообщению. label - в шаблонах виджетов _ {MsgArticleUnexistent myArticleId}
Фактическая поддержка i18n отсутствует в шаблоне приложения стека. Вы должны добавить mkMessage «MyApp» messagesFolder isoLangDefault
в файл «Foundation.hs», чтобы создать экземпляры сообщений.
Например количество посетителей. См. Ссылку
Для <249 существует поддержка первого класса.>PostgreSQL, SQLite, MongoDB, CouchDB и MySQL с экспериментальной поддержкой Redis.
Структура базы данных описана в шаблоне, в котором перечислены сущности, поля и ограничения.
share [mkPersist sqlSettings, mkMigrate «migrateAll» - генерирует процедуру миграции с указанным именем] [persist | Пользователь - имя таблицы и тип записи объекта - неявный автоинкремент столбца «id» в качестве первичного ключа, типизированный UserId идентификатор Text - относится к db. столбец таблицы «идент»; - генерирует поле записи с префиксом к имени таблицы как "userIdent" пароль. Текст Может быть - Может быть указывает на поле, допускающее значение NULL. Уникальный идентификатор пользователя - уникальное ограничение с пробелом sep. последовательность полей Электронная почта - имя таблицы и тип записи объекта - неявный автоинкремент столбца «id» в качестве первичного ключа, введенный EmailId email Text пользователь UserId - внешний ключ путем указания других таблиц Типы EntityField verkey Текст Может быть newAddedColumn Text "default = 'sometext' :: изменение символа "- уровень sql Ограничение по умолчанию UniqueEmail email - уникальное ограничение |]
Пример для постоянных запросов rawSQL и Esqueleto.
Следующие пакеты являются частью платформы yesod:
Новые приложения Yesod генерируются из шаблонов инструмента HaskellStack, заменяя предыдущие команда "yesod init"
Приложение на основе стека. к именам шаблонов добавляется префикс yesod как "yesod- {minimal | postgres | sqlite | mysql | mongo |...}"
yesod devel
запускается с сайта проекта, перекомпилирует и перезапускает проект на каждое изменение дерева файлов.add-handler yesod
добавляет в проект новый обработчик и модуль, добавляя предложение импорта для обработчика в модуле «Application».См. ссылки.
Keter - это процесс как служба, который обрабатывает развертывание и перезапуск серверов веб-приложений Yesod и, согласно веб-приложение, создание базы данных для PostgreSQL.
Консольная команда yesod keter
упаковывает веб-приложение. в качестве пакета кетер для загрузки в папку кетер с именем «входящие».
Кетер следит за «входящей» папкой и распаковывает приложение. к временному, затем назначает веб-приложению порт для прослушивания и запускает его.
Первоначально он работал с Nginx как обратным прокси (версия кетера 0.1 *), добавляя записи виртуального сервера в его конфигурацию и создавая Nginx перезагрузите его, но теперь сам Keter предоставляет свои собственные функции обратного прокси, удаляя зависимость Nginx и выступая в качестве основного веб-сервера.
Старая документация (на основе Nginx).
См. Ссылку