Search code examples
haskellheist

How to stick a compiled splice into a tag using compiled Heist


I created an example repository here.

The idea is to have a minimal example of using the Haskell templating system Heist without Snap and using its newer compiled Heist feature.

The example repository does not include a server, but the code is intended to be used in a server environment eventually. Therefore, I want to do the following:

  1. Pre-compile my splices when the server starts
  2. Make a single database call to load all the data for a given view for a REST route (think GET /users)
  3. Apply the pre-compiled splices to the data and stick them into a template

For the example repository, step 1 happens at the start of main; step 2 is replaced with a simple reader monad; and step 3 is what happens at the bottom of main.

It is the last point (3) that I'm struggling with. In the end, I will be calling C.renderTemplate with my Heist state and the name of the template. That template will have a tag inside of it, currently called apply-content (a bit confusing, since that's from interpeted Heist, but it shouldn't matter I guess). This apply-content tag will be replaced with different content by every route. For the purpose of the example repository, I want to take the body.tpl, which has a body-greeting tag, and replace apply-content in index.tpl with it.

The only idea I have right now is to modify the list of compiled splices in right before calling renderTemplate. But I didn't find any examples of that in the tutorials, nor on GitHub. So I'm inclined to believe that that's not how it's supposed to work.


Solution

  • The answer to this question is surprisingly simple.

    In compiled mode, you can, and should, still be making use of the basic template abstractions provided by Heist.

    If we replace body.tpl with:

    <apply template="index">
      <p><body-greeting /></p>
    </apply>
    

    and change main.hs so it calls C.renderTemplate heistState "body" instead of "index", we get the desired output: the greeting generated at runtime, inserted into the body template, which is inserted into the index template.

    You can see the changes in this commit