简体   繁体   English

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

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

I am writing a site for online surveys.我正在写一个在线调查网站。 I have a list of questions that all go on one html page and the list is of unknown length.我有一个问题列表,其中一个 html 页面上的所有 go 并且该列表的长度未知。 Each question has the form stored in template qu1.tpl and the page is qu.tpl .每个问题的表格都存储在模板qu1.tpl中,页面是qu.tpl Now I want to:现在我想:

  1. replace some names in qu1.tpl for each question为每个问题替换qu1.tpl中的一些名称

  2. replace some things in qu.tpl oncequ.tpl中的一些东西替换一次

  3. and stick all instantiations of qu1.tpl into qu.tpl并将 qu1.tpl 的所有实例化qu1.tplqu.tpl

Using what I learned in the tutorial, I tried to recursively replace a tag <qulist/> with <apply template="qu1.tpl"><qulist/> in qu.tpl using localHeist and bindString but this cannot work because qu.tpl is already rendered so the newly inserted apply tag doesn't resolve.使用我在教程中学到的知识,我尝试使用localHeistbindStringqu.tpl中用<apply template="qu1.tpl"><qulist/>递归替换标签<qulist/>但这不起作用,因为qu.tpl已呈现,因此新插入的应用标签无法解析。

what should I do instead?我应该怎么做?

(I guess this is a more general question. If you can think of other applications the answer applies to, please add text and tags for the search engines.) (我想这是一个更普遍的问题。如果您能想到答案适用的其他应用程序,请为搜索引擎添加文本和标签。)

In Heist, when you're doing something that involves calculations on dynamic data you usually will use a splice.在 Heist 中,当你做一些涉及动态数据计算的事情时,你通常会使用拼接。 Your first two points can be handled by binding splices.您的前两点可以通过绑定拼接处理。 For the third point, I would start by creating a splice function that renders a particular question template.对于第三点,我将首先创建一个呈现特定问题模板的拼接 function。 It would look something like this:它看起来像这样:

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

Now you can create a splice for the list of survey questions:现在您可以为调查问题列表创建一个拼接:

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

Then you can bind this splice to a particular tag and use it anywhere in qu.tpl or any other template.然后,您可以将此拼接绑定到特定标签并在 qu.tpl 或任何其他模板中的任何位置使用它。

The important part here is the callTemplate function.这里重要的部分是 callTemplate function。 It is Heist's function for rendering templates from inside a TemplateMonad computation.它是 Heist 的 function,用于从 TemplateMonad 计算内部渲染模板。 I don't think it is talked about much in the tutorials because it hasn't been a use case that people are usually concerned with, and it's easy to miss in the API docs.我认为教程中没有太多讨论它,因为它不是人们通常关心的用例,而且在 API 文档中很容易错过。

thanks to mightybyte for helping me out with this on irc.感谢mightybyte在irc上帮助我解决这个问题。 after the 8 hours that i was banned from answering to myself, here is my variant of the same answer:在我被禁止回答自己的 8 小时之后,这是我的相同答案的变体:

  1. build a splice that reads template qu1.tpl, instantiates it (ie, fills in name and number of the question in the list), and returns it.构建一个读取模板 qu1.tpl 的拼接,将其实例化(即,在列表中填写问题的名称和编号),然后返回它。 the heist function callTemplate helps you with that.抢劫 function callTemplate 可以帮助您。 (this splice is called splicex in the pseudocode below.) (这个拼接在下面的伪代码中称为 splicex。)

  2. write another splice that folds splicex so that you get a list of (instantiated) questions instead of a single one.编写另一个折叠 splicex 的拼接,以便获得(实例化的)问题列表而不是单个问题。 (function splice in the pseudocode.) (伪代码中的函数拼接。)

  3. use bindSplice instead of bindString.使用 bindSplice 而不是 bindString。

pseudocode (tested then modifed and ripped out of context) -伪代码(测试然后修改并脱离上下文) -

 ... -> 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"

btw, my sourceforge avatar is too weak to create new tags.顺便说一句,我的 sourceforge 头像太弱,无法创建新标签。 anybody care to tag this with 'heist'?有人愿意用“抢劫”来标记这个吗?

links:链接:

http://snapframework.com/ http://snapframework.com/

#snapframework channel on the freenode IRC network. freenode IRC 网络上的#snapframework 频道。

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

When I tried to figure out template loops, I stumbled multiple times across this question.当我试图找出模板循环时,我多次偶然发现这个问题。 Sadly, everything here is probably outdated, version 0.5 (or below) while version 0.6 (I guess) introduced runChildrenWith.可悲的是,这里的一切都可能已经过时了,0.5 版(或更低版本)而 0.6 版(我猜)引入了 runChildrenWith。

A simple example for using runChildrenWith would be:使用 runChildrenWith 的一个简单示例是:

list_test_entries.tpl: list_test_entries.tpl:

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

Site.hs:网站.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)

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

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

相关问题 如何通过动态导航制作动态内容? - How do I make dynamic content with dynamic navigation? 如何上传CSV文件,然后自动将数据插入数据库? - How do I upload a CSV file and then automatically insert the data into the DB? 如何使用 django 模板在一个 for 循环中同时遍历两个列表,以在聊天机器人应用程序中实现 - How can I traverse through two list concurrently in one for loop using in django templates to be implemented in a chatbot app Kohana 3.3:如何为管理子目录创建路由? - Kohana 3.3: How do I create routes for an admin sub-directory? 在Django中,如何访问views.py中的模板值? - In Django, how do I access template values in the views.py? 如何使用 Django 将 PDF 嵌入到我的模板中? - How do I embed a PDF into my template with Django? 如何在Hoplon中创建有序列表? - How do I create an ordered list in Hoplon? 如何从Thymeleaf模板访问库JAR文件中的样式表? - How do I access style sheets in a library JAR file from a Thymeleaf template? 如何使用gettext在HTML :: Template [:: Compiled]中进行I18N? - How can I do I18N in HTML::Template[::Compiled] with gettext? 具有主模板和子视图的Java HTML View Engine - Java HTML View Engine with Master Templates and Sub Views
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM