snapframework / snap

Top-level package for the official Snap Framework libraries, includes the snaplets API as well as infrastructure for sessions, auth, and templates.
http://snapframework.com/
BSD 3-Clause "New" or "Revised" License
456 stars 68 forks source link

Unclear documentation on how to define and "install" new splices #163

Open wjt opened 8 years ago

wjt commented 8 years ago

I generated an app with snap init, which uses Heist for templating. Now I want to add a page which interpolates some part of the URL, or a query parameter, or some procedurally-generated content into a template. I believe what I want to do is define a splice?

The quickstart guide points me to two other pages:

My first stop was the Snaplets tutorial, I think because snaplets are mentioned on the home page. The example routes here explain clearly how to manipulate state, but not how to render anything other than plain text. This tutorial makes reference to Part2.hs (where “a little dummy code for the Foo and Bar snaplets” lives) but doesn't link to it. It then refers me to the snap package's documentation.

Here, the Snap.Snaplet.Heist module sounds promising, particularly this documented line of boilerplate:

    addConfig h heistConfigWithMyAppSplices

Or maybe the docs for heistLocal:

You might want to use this if you had a set of splices which were customised for a specific action. To do that you would do:

heistLocal (bindSplices mySplices) handlerThatNeedsSplices

But again I can't find any working examples. So I backtrack and read the Heist Template Tutorial, and I learn:

To initialize Heist, you need to put all your splices and templates into a HeistConfig and pass it to initHeist. Heist provides two sets of default splices: defaultInterpretedSplices and defaultLoadTimeSplices. These contain Heist’s built-in splices for running in interpreted and compiled modes respectively.

I'm still none the wiser about how to "put all my splices into a HeistConfig", though.

Reading code from GitHub code search, it looks like I need to do something like:

app :: SnapletInit App App
app = makeSnaplet "app" "An snaplet example application." Nothing $ do
    -- ...
    let sc = mempty & scInterpretedSplices .~ ("placeholder" ## placeholder)
    addConfig h sc
    -- ...

-- based on reading http://snapframework.com/docs/tutorials/heist#heist-programming
placeholder :: I.Splice Snap
placeholder = do
    return [X.Element "img" attrs []]
  where
    attrs = [ ("src", "https://placehold.it/350x150") ]

But this just yields:

src/Site.hs:103:17:
    Couldn't match type `Snap' with `Handler App App'
    Expected type: SpliceConfig (Handler App App)
      Actual type: SpliceConfig Snap
    In the second argument of `addConfig', namely `sc'
    In a stmt of a 'do' block: addConfig h sc

At this point I'm afraid I gave up. I was hoping to be able to propose some patches for the docs but I genuinely can't work out how the pieces fit together.

mightybyte commented 8 years ago

It looks like you actually have it right. I believe you just have the wrong type signature for placeholder. Instead of this:

placeholder :: I.Splice Snap

Try this:

placeholder :: I.Splice (Handler App App)

On Dec 4, 2015, at 4:20 AM, Will Thompson notifications@github.com wrote:

I generated an app with snap init, which uses Heist for templating. Now I want to add a page which interpolates some part of the URL, or a query parameter, or some procedurally-generated content into a template. I believe what I want to do is define a splice?

The quickstart guide points me to two other pages:

Snap API tutorial – this explains how routing works very well, and mentions Heist in passing (but not how to use it) Snap reference documentation – quite intimidating, but let's give this a try. My first stop was the Snaplets tutorial, I think because snaplets are mentioned on the home page. The example routes here explain clearly how to manipulate state, but not how to render anything other than plain text. This tutorial makes reference to Part2.hs (where “a little dummy code for the Foo and Bar snaplets” lives) but doesn't link to it. It then refers me to the snap package's documentation.

Here, the Snap.Snaplet.Heist module sounds promising, particularly this documented line of boilerplate:

addConfig h heistConfigWithMyAppSplices

Or maybe the docs for heistLocal:

You might want to use this if you had a set of splices which were customised for a specific action. To do that you would do:

heistLocal (bindSplices mySplices) handlerThatNeedsSplices

But again I can't find any working examples. So I backtrack and read the Heist Template Tutorial, and I learn:

To initialize Heist, you need to put all your splices and templates into a HeistConfig and pass it to initHeist. Heist provides two sets of default splices: defaultInterpretedSplices and defaultLoadTimeSplices. These contain Heist’s built-in splices for running in interpreted and compiled modes respectively.

I'm still none the wiser about how to "put all my splices into a HeistConfig", though.

Reading code from GitHub code search, it looks like I need to do something like:

app :: SnapletInit App App app = makeSnaplet "app" "An snaplet example application." Nothing $ do -- ... let sc = mempty & scInterpretedSplices .~ ("placeholder" ## placeholder) addConfig h sc -- ...

-- based on reading http://snapframework.com/docs/tutorials/heist#heist-programming placeholder :: I.Splice Snap placeholder = do return [X.Element "img" attrs []] where attrs = [ ("src", "https://placehold.it/350x150") ] But this just yields:

src/Site.hs:103:17: Couldn't match type Snap' withHandler App App' Expected type: SpliceConfig (Handler App App) Actual type: SpliceConfig Snap In the second argument of addConfig', namelysc' In a stmt of a 'do' block: addConfig h sc At this point I'm afraid I gave up. I was hoping to be able to propose some patches for the docs but I genuinely can't work out how the pieces fit together.

— Reply to this email directly or view it on GitHub.

wjt commented 8 years ago

Right enough, it compiles if I make that change! Thanks.

If I have time this weekend I'll have a crack at some doc tweaks.

mightybyte commented 8 years ago

That would be great. This kind of feedback is very valuable.

On Fri, Dec 4, 2015 at 12:28 PM, Will Thompson notifications@github.com wrote:

Right enough, it compiles if I make that change! Thanks.

If I have time this weekend I'll have a crack at some doc tweaks.

— Reply to this email directly or view it on GitHub https://github.com/snapframework/snap/issues/163#issuecomment-162028717.