Web applications Heist:如何在模板中插入子模板的动态列表?

Web applications Heist:如何在模板中插入子模板的动态列表?,web-applications,haskell,haskell-snap-framework,heist,Web Applications,Haskell,Haskell Snap Framework,Heist,我正在写一个在线调查网站。我有一个问题列表,所有问题都放在一个html页面上,列表的长度未知。每个问题的表单存储在模板qu.tpl中,页面为qu.tpl。现在我想: 为每个问题替换qu1.tpl中的一些名称 将qu.tpl中的某些内容替换一次 并将qu.tpl的所有实例化粘贴到qu.tpl 根据我在教程中学到的知识,我尝试使用localHeist和bindString在qu.tpl中使用localHeist和bindString递归地将标记替换为,但这不起作用,因为qu.tpl已经呈现,因此新插

我正在写一个在线调查网站。我有一个问题列表,所有问题都放在一个html页面上,列表的长度未知。每个问题的表单存储在模板
qu.tpl
中,页面为
qu.tpl
。现在我想:

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

  • qu.tpl中的某些内容替换一次

  • 并将
    qu.tpl
    的所有实例化粘贴到
    qu.tpl

  • 根据我在教程中学到的知识,我尝试使用
    localHeist
    bindString
    qu.tpl
    中使用
    localHeist
    bindString
    递归地将标记
    替换为
    ,但这不起作用,因为
    qu.tpl
    已经呈现,因此新插入的apply标记无法解析

    我该怎么做呢


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

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

    questionSplice :: Monad m => Int -> Splice m
    questionSplice n = do
      splices <- setupSplicesForThisQuestion
      mTemplate <- callTemplate (B.pack ("qu"++(show n))) splices
      return $ fromMaybe [] mTemplate
    
    questionSplice::Monad m=>Int->Splice m
    问题n=do
    
    拼接感谢mightybyte在irc上帮助我解决这个问题。8个小时后,我被禁止回答自己的问题,以下是我对同一答案的变体:

  • 构建一个拼接,读取模板qu1.tpl,实例化它(即,在列表中填写问题的名称和编号),然后返回它。heist函数callTemplate可以帮助您实现这一点。(此拼接在下面的伪代码中称为拼接X。)

  • 编写另一个拼接,折叠拼接X,以便获得(实例化的)问题列表,而不是单个问题。(伪代码中的功能拼接。)

  • 使用bindSplice而不是bindString

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

    …->让
    拼接::单子m=>拼接m
    拼接=折叠(\ts(s,i)->
    liftM((++)ts)$STIPLEX(quName,quNumber))
    []
    (zip问题名称[0..])
    拼接X::Monad m=>(字符串,Int)->拼接m
    接头X(quName,quNumber)=
    做
    mt错误“拼接渲染失败”
    Just(t::Template)->返回t
    在里面
    --填写(固定的)问题清单
    heistLocal(绑定拼接“qulist”拼接)$
    --在此之前,实例化整个页面
    实例化页$
    渲染“曲”
    
    顺便说一句,我的sourceforge头像太弱,无法创建新标签。有人想把这个贴上“抢劫”的标签吗

    链接:

    #freenode IRC网络上的snapframework通道


    当我试图找出模板循环时,我多次遇到这个问题。遗憾的是,这里的一切可能都过时了,版本0.5(或更低),而版本0.6(我猜)引入了runChildrenWith

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

    列出测试条目.tpl:

    <listTestEntries>
      <dt><testEntry/></dt>
      <dd>This is part of the repeated template</dd>
    </listTestEntries>
    
    
    这是重复模板的一部分
    
    Site.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)
    
    listTestEntriesHandler::Handler应用程序()
    listTestEntriesHandler=do
    结果一.剪接处理程序
    listTestEntriesSplice=I.mapSplices(I.runChildrenWith.listTestEntrySplice)
    listTestEntrySplice::Monad m=>字符串->拼接(HeistT n m模板)
    listTestEntrySplice dataEntry=do
    “testEntry”##I.textplice(T.pack$”数据:“++数据项)
    

    有关正在运行的演示,请参阅。

    这里的一般问题可能是“子模板”,而当我们使用递归模板时(当我们要编写拼接以呈现递归类型时),MyByte给出的答案可能是最好的方法?递归模板已经让我绊倒了好几次,所以如果callTemplate可能是缺少的链接,我很高兴。
    <listTestEntries>
      <dt><testEntry/></dt>
      <dd>This is part of the repeated template</dd>
    </listTestEntries>
    
    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)