2014-11-04 5 views
2

Я хочу использовать веб-сайт в качестве рабочего примера, чтобы помочь узнать Haskell. Я пытаюсь следить за Heist tutorial с сайта Snap и отображать результат факториальной функции на веб-странице.Свяжите сплайсинг, чтобы пометить его в Heist

Я могу получить пример функции «серверная сторона» без жалобы компилятора, но я не могу понять, как привязать функцию к тегу, который я могу затем поместить в HTML. В частности, эта часть работает отлично (скажем, Site.hs):

factSplice :: Splice Snap 
factSplice = do 
    input <- getParamNode 
    let text = T.unpack $ X.nodeText input 
     n = read text :: Int 
    return [X.TextNode $ T.pack $ show $ product [1..n]] 

Но действительно важная часть - как оценить эту функцию как часть веб-страницы (например, как привязать его к тегу например < факт />) - является загадочным. Инструкции говорят о снижении:

bindSplice "fact" factSplice templateState 

где-то в коде. Но этого недостаточно. Этот оператор не является выражением (stuff = bindSplice ...), поэтому неясно как или , где, чтобы поместить его в код. Более того, совершенно неясно, откуда должна прийти «templateState». Похоже, что «templateState» должен быть заполнителем значений по умолчанию, таких как emptyTemplateState или defaultHeistState, но оба они, как представляется, устарели много лет назад, а последняя версия Heist (0.14) не распознает их.

MightyByte прокомментировал этот вопрос несколько раз в 2011 году, но ответы на весь блеск выше точно запутанная часть, то есть как получить данные на веб-странице. Может ли кто-нибудь помочь?

- ОБНОВЛЕНИЕ -

Большое спасибо, mightybyte! Ваше объяснение и некоторые беглые выскакивающие в исходном коде были сбиты с толку, и я смог получить факториальный пример из учебника веб-сайта Snap. Вот мое решение - я полный n00b, поэтому извиняюсь, если объяснение кажется педантичным или очевидным.

Я более или менее использовал подход addConfig, который мог бы предложить, просто скопировав реализацию addAuthSplices с SpliceHelpers.hs. Я начал с проектом по умолчанию с помощью «оснастки инициализации», и определил функцию addMySplices в Site.hs

addMySplices :: HasHeist b => Snaplet (Heist b) -> Initializer b v() 
addMySplices h = addConfig h sc 
    where 
     sc = mempty & scInterpretedSplices .~ is 
     is = do 
      "fact" ## factSplice 

Это использует линзы, чтобы получить доступ к полям нейтрального элемента SpliceConfig mempty, так что мне пришлось добавить Control.Lens к в Site.hs, а также Data.Monoid для размещения mempty в области. Я также изменил сигнатуру типа факториального сращивания на factSplice :: Monad n => I.Splice n, но в противном случае функция не изменится по форме в учебнике Heist. Тогда я поставил вызов addMySplices в инициализаторе приложения, прямо рядом с addAuthSplices в Site.hs

app :: SnapletInit App App 
... 
addAuthSplices h auth 
addMySplices h 
... 

, что приводит к factSplice связываясь с тегом <fact>. Удаление <fact>8</fact> в один из шаблонов по умолчанию отображает 40320 на странице, как описано.

This question примерно год назад содержит поверхностно подобное решение, но не работает с последней версией Heist; разница в том, что некоторые поля были доступны через линзы, а не непосредственно, что объясняется в блоге проекта Snap в объявлении Heist 0.14. В частности, hcCompliedSplices был полностью переопределен - есть даже дружественное предупреждение об этом в Types.hs.

+0

Отлично. Благодарим за публикацию обновления. Я уверен, что это будет хороший ресурс для тех, кто сталкивается с этой трудностью в будущем. – mightybyte

ответ

0

Если вы посмотрите на модуль Heist верхнего уровня, вы увидите the initHeist function. Как указывает документация, это основная функция инициализации. И вы должны передать все ваши шаблоны и сращивания. Взгляд на подпись типа говорит нам, что все они объединены в тип данных HeistConfig.

initHeist :: Monad n => HeistConfig n -> EitherT [String] IO (HeistState n) 

Это дает вам обратно HeistState, который является то, что вы передаете renderTemplate, когда вы хотите сделать шаблон. Кроме того, HeistConfig содержит поле SpliceConfig для всех ваших сращиваний.

Но это все интерфейс низкого уровня. Хейст был разработан, чтобы не иметь зависимости от Snap. Это библиотека шаблонов и может работать с любой веб-картой. (Или даже автономный без каких-либо веб-фреймворков вообще для таких вещей, как генерация HTML-почты.) Если вы используете Heist с Snap, вы, вероятно, захотите использовать удобные вещи, которые мы поставляем, которые обрабатывают детали вызова initHeist, renderTemplate, и т. д.

Для рабочего примера лучше всего посмотреть на шаблон проекта, который вы получаете, когда выполняете «snap init». Вы можете увидеть этот код on github here. Если вы посмотрите в Application.hs, вы увидите, что в структуре данных приложения есть строка, включающая в себя привязку Хейста. Затем, если вы посмотрите на the bottom of Site.hs, вы увидите, что есть вызов heistInit. Эта функция определяется с помощью рукоятки для удаления хеста here. Snaplet заботится об инициализации, управлении штатами, перезагрузке шаблонов «на лету» и т. Д. Для вас.

Итак, чтобы все это произошло ... из описанного выше API Heist, мы видим, что нам нужно определить наши сращивания внутри HeistConfig. Но наше приложение будет взаимодействовать со всем этим, главным образом, с помощью API Snaplet. Так что, если мы посмотрим на heist snaplet API что-то с участием HeistConfig/SpliceConfig, мы находим две соответствующие функции:

heistInit' :: FilePath -> HeistConfig (Handler b b) -> SnapletInit b (Heist b) 
addConfig :: Snaplet (Heist b) -> SpliceConfig (Handler b b) -> Initializer b v() 

Эти сигнатуры типа предлагают два способа определения ваших сращивания. Вы можете использовать heistInit' вместо heistInit и передать свой HeistConfig перед ним. Или вы можете добавить свои сращивания впоследствии, позвонив addConfig с результатом Snaplet (Heist b).

+0

Привет. Я потратил день, пытаясь запустить пример сращивания. Я не нашел никакого рабочего примера. Предполагается ли он работать с новейшими версиями span и heist? Во всяком случае, я не знаю, как все складывать. Боюсь, я всегда буду потерян без полного примера (я имею в виду полный код приложения). –

+0

@ StéphaneLaurent https://github.com/snapframework/heist/issues/101#event-950899490 http://stackoverflow.com/a/42115188/1663462 Вышеуказанное может быть полезно –

 Смежные вопросы

  • Нет связанных вопросов^_^