Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. Each question has the form stored in template qu1.tpl and the page is qu.tpl. Now I want to:

  1. replace some names in qu1.tpl for each question

  2. replace some things in qu.tpl once

  3. and stick all instantiations of qu1.tpl into qu.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.

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

like image 980
maf Avatar asked Jul 22 '11 09:07

maf


1 Answers

In Heist, when you're doing something that involves calculations on dynamic data you usually will use a splice. 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. 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.

The important part here is the callTemplate function. It is Heist's function for rendering templates from inside a TemplateMonad computation. 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.

like image 153
mightybyte Avatar answered Nov 07 '22 15:11

mightybyte