I think I did asked a similar question some time ago but it was not answered due to unstable API. So I was waiting for the 0.13 to pass by. I am not sure if it is correct to bring up a similar question...?
What is the alternative to interpreted runChildrenWith(Text)
and mapSplices
in the compiled splices world? (this combination seems to be the most common)
I would really appreciate some code examples if possible.
If I understand correctly, we get together all the application splices and then add them to the heistInit
. Can anyone show how to do it please?
Does the splice binding tag has to be unique across the whole application?
Is there a completed snap project utilising
new APIs and compiled splices so that I could read and see learn?
Thank you.
-- UPDATE --
Great answer below. But some parts (the ones with lenses) got me even more confused, unfortunately. If I understand correctly this is the simple way to splice a string:
mySplice = "testSplice" ## testSplice
where testSplice = return $ C.yieldRuntimeText $ do
return "text to be spliced"
If i need to run the spliced string several times, say in 5 table raws i would do it like this:
mySplices = C.manyWithSplices C.runChildren mySplice
Is this correct?
I get bunch of errors trying to add the splices in heist config.
addConfig h $ mempty
{
hcCompiledSplices = "mySplice" ## mySplice -- or mySplices
}
Where am I going wrong? Sorry for being slow.
All I need really ( just for now so I can understand) is to splice and display a simple string that I receive from database.
-- UPDATE 2 --
Thanks to the extremle helpfull Daniel`s answer I can finally get something working.
So far I get both variants of code working.
The first one, thanks to Daniel
stringSplice :: Monad n => C.Splice n
stringSplice = C.manyWithSplices C.runChildren splicefuncs (return ["aa","bb","cc"])
where
splicefuncs = "string" ## (C.pureSplice . C.textSplice $ id)
And the secod
testSplice :: C.Splice (Handler App App)
testSplice = return $ C.yieldRuntimeText $ return "text to be spliced"
Where
(C.pureSplice . C.textSplice $ id)
produces similar results to
return $ C.yieldRuntimeText $ return "text to be spliced"
Is there difference between the above? Any cases that one would prefer one to another? They seem to produce the same results.
There is a "deferMany" function in the compiled splices lib that, according to the docs, produces similar results to the mapSplices in interpreted lib. Can we use it instead of "C.manyWithSplices C.runChildren" combination??
Let's say you want to display information about a list of persons using compiled splices (assume that we start from the scaffolding generated by
snap init
.)A very simple
_persons.tpl
template with dummy values would be something likeWhere
person
,name
,age
, andlocation
are the tags to be spliced.We define a trivial Snaplet that holds the info
and we add it to the
App
record:we add the following to the app initializer
This function constructs a Handler that returns the list of persons (using
view
fromControl.Lens
):This function constructs the appropiate compiled splice from a
RuntimeSplice
that produces a list of Persons.RuntimeSplice
s represent information that can only be known at run time, as opposed to load time:And this function can be used to register the splice in the global Heist configuration. Notice that we lift the
Handler
into aRuntimeSplice
:Be sure to add this line to the app initializer:
And to add the following pair to the app's routes:
If you now run the server, navigating to
http://127.0.0.1:8000/persons
should show the list.UPDATE
For the simpler case (no complex records, no lenses) in which you only want to show a list of strings.
The template could be something like:
The top-level splice would be:
This means "when we encounter the tag associated to this splice, perform an action that produces a list of strings, and for each string, render the contents of the tag, substituting the current string for the
string
tag".Notice that the signature of manyWithSplices forces the stuff to the right of the
(##)
to have typeRuntimeSplice n Text -> Splice n
. Hereid
has typeText -> Text
.C.TextSplice
transforms it into something of typeText -> Builder
, andC.pureSplice
performs the final transformation into aRuntimeSplice n Text -> Splice n
.In place of
(return ["aa","bb","cc"])
you could provide a more complex action that connected a database and extracted the strings form there.A function to register this splice would be: