haskell-servant / haskell-servant/servant
HTML templating with external files
- Dominant language
- Haskell
- Stars
- 2k
- Forks
- 427
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 5
Description
I spent the last day or so looking into ways to render HTML templates with Haskell and combine those with servant, and came away unsatisfied. All the solutions I found required a potentially objectionable workaround.
- **blaze-html** requires embedding HTML generation code in your source file. No separation of logic and presentation. It also usually requires qualified imports for all the blaze combinators, which reduces readability IMO.
- **lucid** has basically the same problem as blaze.
- **heist** needs IO to load templates and to render them. `mimeRender` doesn't allow IO. `servant-ede` works around this by using `unsafePerformIO`, which is definitely potentially objectionable.
- **hamlet** is the closest thing to "convenient," and even lets the programmer use separate template files, but it replaces the necessity of IO with Template Haskell (i.e. runs the IO actions during compile time). This slows down compilation considerably. Also, if you don't like hamlet syntax, you're out of luck.
- Using **Raw** as your API response type technically allows all of the above without needing any unsafe functions or TH, but it tosses out the guarantees that such and such endpoint will return so and so data as whatever content type, which is the whole reason I'm using servant in the first place.
My gut feeling is that `MimeRender` is just not powerful enough to let users use a templating engine, but since I'm not an expert on the internals or architecture of servant I'd welcome some input on my assessment. Ideally I would like `mimeRender` maybe to be `Proxy ct -> a -> EitherT ServantErr IO ByteString`, or for another function `mimeRenderM` to be added to the typeclass and by default implemented in terms of `mimeRender`.
Thoughts?
Contributor guide
Assessment
This issue has not been assessed yet.