Hayst: How to insert a dynamic list of subpatterns in a template?

I am writing a site for online surveys. I have a list of questions that all go on the same html page, and a list of unknown length. Each question has a form stored in the qu1.tpl template, and the qu.tpl page. Now I want:

  • replace some names in qu1.tpl for each question

  • replace some things in qu.tpl once

  • and stick with all instances of qu1.tpl in qu.tpl

Using what I learned in the tutorial, I tried to recursively replace the <qulist/> with <apply template="qu1.tpl"><qulist/> in qu.tpl using localHeist and bindString , but this will not work because qu.tpl already displayed so that the newly inserted application tag does not allow.

What should I do instead?

(I think this is a more general question. If you can think of other applications to which the answer applies, add text and tags for search engines.)

+6
source share
3 answers

In Heist, when you do something related to dynamic data calculations, you will usually use splicing. Your first two points can be processed by connecting splices. For the third point, I would start by creating a splicing function that displays a specific question template. It will 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 

You can then bind this splicing to a specific tag and use it anywhere in qu.tpl or any other template.

The important part here is the callTemplate function. This is a Heist function for rendering templates inside a TemplateMonad calculation. I don’t think that much has been said about this in the textbooks, because this was not a precedent to which people usually relate, and it is easy to miss in the API docs.

+4
source

thanks mightybyte for helping me with this on irc. after 8 hours, when I was forbidden to answer myself, here is my version of the same answer:

  • build a splice that reads the qu1.tpl template, creates an instance of it (that is, fills the name and number of the question in the list) and returns it. heist functionTemplate helps you with this. (This splice is called splicex in the pseudo-code below.)

  • write another splice that splicex adds up so that you get a list of (instances) of questions instead of one. (functional splicing in pseudo-code.)

  • use bindSplice instead of bindString.

pseudocode (tested, then modified and 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 original avatar is too weak to create new tags. can anyone mark this "heist"?

links:

http://snapframework.com/

#snapframework channel on IRC network freenode.

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

+1
source

When I tried to figure out the template loops, I came across this question several times. Unfortunately, everything here is probably deprecated, version 0.5 (or lower), and version 0.6 (I think) introduced runChildrenWith.

A simple example of using runChildrenWith would be:

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 nm Template) listTestEntrySplice dataEntry = do "testEntry" ## I.textSplice (T.pack $ "data: " ++ dataEntry) 

See https://github.com/michaxm/heist-template-loop-demo for a demo version.

0
source

Source: https://habr.com/ru/post/893345/


All Articles