我正在为在线调查撰写网站。我有一个问题列表,所有问题都在一个html页面上进行,列表的长度未知。每个问题的表单都存储在模板qu1.tpl
中,页面为qu.tpl
。现在我想:
为每个问题替换qu1.tpl
中的一些名称
替换qu.tpl
一次
并将qu1.tpl
的所有实例都粘贴到qu.tpl
使用我在本教程中学到的内容,我尝试使用<qulist/>
和<apply template="qu1.tpl"><qulist/>
在qu.tpl
中使用localHeist
递归替换标记bindString
,但这不能工作,因为qu.tpl
已经呈现,因此新插入的应用标记无法解析。
我该怎么做呢?
(我想这是一个更普遍的问题。如果你能想到答案适用的其他应用程序,请为搜索引擎添加文字和标签。)
答案 0 :(得分: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文档中遗漏。
答案 1 :(得分:1)
感谢mightybyte帮助我解决这个问题。在我被禁止回答自己的8小时之后,这是我对同一答案的变体:
构建一个读取模板qu1.tpl的拼接,实例化它(即填写列表中问题的名称和编号),然后返回它。 heist函数callTemplate可以帮助你。 (这个拼接在下面的伪代码中称为splicex。)
编写另一个折叠splicex的拼接,以便获得(实例化的)问题列表而不是单个问题。 (伪代码中的函数拼接。)
使用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头像太弱而无法创建新标签。有人想用“抢劫”标记这个吗?
链接:
freenode IRC网络上的#snapframework频道。
答案 2 :(得分: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>
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)
有关正在运行的演示,请参阅https://github.com/michaxm/heist-template-loop-demo。