繁体   English   中英

Heist:如何将子模板的动态列表插入到模板中?

[英]Heist: How do I insert a dynamic list of sub-templates into a template?

我正在写一个在线调查网站。 我有一个问题列表,其中一个 html 页面上的所有 go 并且该列表的长度未知。 每个问题的表格都存储在模板qu1.tpl中,页面是qu.tpl 现在我想:

  1. 为每个问题替换qu1.tpl中的一些名称

  2. qu.tpl中的一些东西替换一次

  3. 并将 qu1.tpl 的所有实例化qu1.tplqu.tpl

使用我在教程中学到的知识,我尝试使用localHeistbindStringqu.tpl中用<apply template="qu1.tpl"><qulist/>递归替换标签<qulist/>但这不起作用,因为qu.tpl已呈现,因此新插入的应用标签无法解析。

我应该怎么做?

(我想这是一个更普遍的问题。如果您能想到答案适用的其他应用程序,请为搜索引擎添加文本和标签。)

在 Heist 中,当你做一些涉及动态数据计算的事情时,你通常会使用拼接。 您的前两点可以通过绑定拼接处理。 对于第三点,我将首先创建一个呈现特定问题模板的拼接 function。 它看起来像这样:

questionSplice :: Monad m => Int -> Splice m
questionSplice n = do
  splices <- setupSplicesForThisQuestion
  mTemplate <- callTemplate (B.pack ("qu"++(show n))) splices
  return $ fromMaybe [] mTemplate

现在您可以为调查问题列表创建一个拼接:

surveyQuestions :: Monad m => Splice m
surveyQuestions = do
  questions <- getSurveyQuestions
  mapSplices questionSplice questions

然后,您可以将此拼接绑定到特定标签并在 qu.tpl 或任何其他模板中的任何位置使用它。

这里重要的部分是 callTemplate function。 它是 Heist 的 function,用于从 TemplateMonad 计算内部渲染模板。 我认为教程中没有太多讨论它,因为它不是人们通常关心的用例,而且在 API 文档中很容易错过。

感谢mightybyte在irc上帮助我解决这个问题。 在我被禁止回答自己的 8 小时之后,这是我的相同答案的变体:

  1. 构建一个读取模板 qu1.tpl 的拼接,将其实例化(即,在列表中填写问题的名称和编号),然后返回它。 抢劫 function callTemplate 可以帮助您。 (这个拼接在下面的伪代码中称为 splicex。)

  2. 编写另一个折叠 splicex 的拼接,以便获得(实例化的)问题列表而不是单个问题。 (伪代码中的函数拼接。)

  3. 使用 bindSplice 而不是 bindString。

伪代码(测试然后修改并脱离上下文) -

 ... -> let
          splice :: Monad m => Splice m
          splice = foldM (\ ts (s, i) ->
                             liftM ((++) ts) $ splicex (quName, quNumber))
                         []
                         (zip questionName [0..])

          splicex :: Monad m => (String, Int) -> Splice m
          splicex (quName, quNumber) =
              do
                mt <- callTemplate "qu1"
                        [ ("question-name", Data.Text.pack quName)
                        , ("question-number", Data.Text.pack $ show quNumber)
                        ]

                case mt of
                  Nothing -> error "splice rendering failed."
                  Just (t :: Template) -> return t
         in
           -- fill in the list of (instatiated) questions
           heistLocal (bindSplice "qulist" splice) $
           -- before that, instantiate the overall page
           instantiatePage $
           render "qu"

顺便说一句,我的 sourceforge 头像太弱,无法创建新标签。 有人愿意用“抢劫”来标记这个吗?

链接:

http://snapframework.com/

freenode IRC 网络上的#snapframework 频道。

http://snapframework.com/docs/tutorials/heist

当我试图找出模板循环时,我多次偶然发现这个问题。 可悲的是,这里的一切都可能已经过时了,0.5 版(或更低版本)而 0.6 版(我猜)引入了 runChildrenWith。

使用 runChildrenWith 的一个简单示例是:

list_test_entries.tpl:

<listTestEntries>
  <dt><testEntry/></dt>
  <dd>This is part of the repeated template</dd>
</listTestEntries>

网站.hs:

listTestEntriesHandler :: Handler App App  ()
listTestEntriesHandler = do
    results <- getData 
    renderWithSplices "list_test_entries"
        ("listTestEntries" ## listTestEntriesSplice results)

getData :: Handler App App [String]
getData = return ["1", "2", "3"]

listTestEntriesSplice  :: [String] -> I.Splice AppHandler
listTestEntriesSplice = I.mapSplices (I.runChildrenWith . listTestEntrySplice)

listTestEntrySplice :: Monad m => String -> Splices (HeistT n m Template)
listTestEntrySplice dataEntry = do
  "testEntry" ## I.textSplice (T.pack $ "data: " ++ dataEntry)

有关运行演示,请参阅https://github.com/michaxm/heist-template-loop-demo

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM