Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blaze-html -> lucid2 #50

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
watch_file *.cabal
use flake
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Ema Template

A very simple example [Ema](https://ema.srid.ca/) site that is based on Blaze HTML & TailwindCSS 3. Use it to bootstrap your next static site using Ema.
A very simple example [Ema](https://ema.srid.ca/) site that is based on Lucid2 & TailwindCSS 3. Use it to bootstrap your next static site using Ema.

The generated HTML site can be previewed here: https://srid.github.io/ema-template/

Expand All @@ -20,7 +20,7 @@ All but the final step need to be done only once. Check [the Ema tutorial](https

## Note

- This project uses [relude](https://github.com/kowainik/relude) as its prelude, as well as Tailwind+Blaze as CSS utility and HTML DSL. Even though the author highly recommends them, you are of course free to swap them out for the library of your choice.
- This project uses [relude](https://github.com/kowainik/relude) as its prelude, as well as Tailwind+Lucid as CSS utility and HTML DSL. Even though the author highly recommends them, you are of course free to swap them out for the library of your choice.
- Tailwind CSS is compiled, alongside Ghcid, via foreman (see `flake.nix`)
- As a first step to using this template, rename your project using https://srid.ca/haskell-template/start#rename-the-project (use `ema-template` in place of `haskell-template`)
- Configuration:
Expand Down
1 change: 1 addition & 0 deletions ema-template.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ executable ema-template
, ema-generics >=0.10
, filepath
, generic-optics
, lucid2
, monad-logger
, optics-core
, optparse-applicative
Expand Down
61 changes: 28 additions & 33 deletions src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ import Ema
import Ema.CLI qualified
import Ema.Route.Generic.TH
import Ema.Route.Lib.Extra.StaticRoute qualified as SR
import Lucid
import Optics.Core (Prism', (%))
import Options.Applicative
import Text.Blaze.Html.Renderer.Utf8 qualified as RU
import Text.Blaze.Html5 ((!))
import Text.Blaze.Html5 qualified as H
import Text.Blaze.Html5.Attributes qualified as A

data Model = Model
{ modelBaseUrl :: Text
Expand Down Expand Up @@ -61,58 +58,56 @@ instance EmaSite Route where

renderHtmlRoute :: Prism' FilePath Route -> Model -> HtmlRoute -> LByteString
renderHtmlRoute rp m r = do
RU.renderHtml $ do
H.docType
H.html ! A.lang "en" $ do
H.head $ do
renderHead rp m r
H.body ! A.class_ "bg-gray-50" $ do
renderBody rp m r

renderHead :: Prism' FilePath Route -> Model -> HtmlRoute -> H.Html
renderBS $ doctypehtml_ $ do
head_ $ renderHead rp m r
body_ [class_ "bg-gray-50"] $ renderBody rp m r

renderHead :: Prism' FilePath Route -> Model -> HtmlRoute -> Html ()
renderHead rp model r = do
H.meta ! A.charset "UTF-8"
H.meta ! A.name "viewport" ! A.content "width=device-width, initial-scale=1"
H.title $ H.toHtml $ routeTitle r <> " - Ema Template"
H.base ! A.href (H.toValue $ modelBaseUrl model)
H.link ! A.rel "stylesheet" ! A.href (staticRouteUrl rp model "tailwind.css")
meta_ [charset_ "UTF-8"]
meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1"]
title_ $ toHtml $ routeTitle r <> " - Ema Template"
base_ [href_ $ modelBaseUrl model]
link_ [rel_ "stylesheet", href_ $ staticRouteUrl rp model "tailwind.css"]

renderBody :: Prism' FilePath Route -> Model -> HtmlRoute -> H.Html
renderBody :: Prism' FilePath Route -> Model -> HtmlRoute -> Html ()
renderBody rp model r = do
H.div ! A.class_ "container mx-auto mt-8 p-4 max-w-prose border-2 bg-white rounded-lg shadow" $ do
div_ [class_ "container mx-auto mt-8 p-4 max-w-prose border-2 bg-white rounded-lg shadow"] $ do
renderNavbar rp r
H.h1 ! A.class_ "text-3xl font-bold" $ H.toHtml $ routeTitle r
h1_ [class_ "text-3xl font-bold"] $ toHtml $ routeTitle r
case r of
HtmlRoute_Index -> do
"You are on the index page. Want to see "
routeLink rp HtmlRoute_About "About"
"?"
HtmlRoute_About -> do
"You are on the about page."
H.a ! A.href (staticRouteUrl rp model "logo.svg") ! A.target "_blank" $ do
H.img ! A.src (staticRouteUrl rp model "logo.svg") ! A.class_ "py-4 w-32" ! A.alt "Ema Logo"
a_ [href_ $ staticRouteUrl rp model "logo.svg", target_ "_blank"] $ do
img_ [src_ $ staticRouteUrl rp model "logo.svg", class_ "py-4 w-32", alt_ "Ema Logo"]

renderNavbar :: Prism' FilePath Route -> HtmlRoute -> H.Html
renderNavbar :: Prism' FilePath Route -> HtmlRoute -> Html ()
renderNavbar rp currentRoute =
H.nav ! A.class_ "w-full text-xl font-bold flex space-x-4 mb-4" $ do
nav_ [class_ "w-full text-xl font-bold flex space-x-4 mb-4"] $ do
forM_ (universe @HtmlRoute) $ \r ->
let extraClass = if r == currentRoute then "bg-rose-400 text-white" else "text-gray-700"
in H.a
! A.href (H.toValue $ routeUrl rp $ Route_Html r)
! A.class_ ("rounded p-2 " <> extraClass)
$ H.toHtml
in a_
[ href_ $ routeUrl rp $ Route_Html r
, class_ $ "rounded p-2 " <> extraClass
]
$ toHtml
$ routeTitle r

routeTitle :: HtmlRoute -> Text
routeTitle r = case r of
HtmlRoute_Index -> "Home"
HtmlRoute_About -> "About"

routeLink :: Prism' FilePath Route -> HtmlRoute -> H.Html -> H.Html
routeLink :: Prism' FilePath Route -> HtmlRoute -> Html () -> Html ()
routeLink rp r =
H.a
! A.href (H.toValue $ routeUrl rp $ Route_Html r)
! A.class_ "text-rose-400"
a_
[ href_ $ routeUrl rp $ Route_Html r
, class_ "text-rose-400"
]

-- | Link to a file under ./static
staticRouteUrl :: (IsString r) => Prism' FilePath Route -> Model -> FilePath -> r
Expand Down
Loading