6

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

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

  2. qu.tpl一次性更换一些东西

  3. 并将所有实例qu1.tpl化为qu.tpl

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

我应该怎么做?

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

4

3 回答 3

4

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

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 函数。这是 Heist 的函数,用于从 TemplateMonad 计算中渲染模板。我认为教程中没有太多讨论它,因为它不是人们通常关心的用例,而且很容易在 API 文档中遗漏。

于 2011-07-22T13:16:00.920 回答
1

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

  1. 构建一个读取模板 qu1.tpl 的拼接,将其实例化(即,在列表中填写问题的名称和编号),然后返回它。抢劫功能 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

于 2011-07-22T19:50:30.677 回答
0

当我试图找出模板循环时,我多次偶然发现这个问题。可悲的是,这里的一切都可能已经过时了,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

于 2014-07-20T15:17:33.503 回答