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

Add support for extra navigation with next/prev links #553

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
17 changes: 17 additions & 0 deletions docs/guide/yaml-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ Notice how this page's sidebar colorscheme has [changed to green]{.greenery}? Vi
- `page.image`: The image to use for the page. This is used for the [[ogp]] meta tag `og:image` meta tag. If not specified, the first image in the page is used. Relative URLs are automatically rewritten to absolute URLs if `page.siteUrl` is non-empty.


- `next`, `prev`: Lists of wikilinks to be used for custom navigation. When set, the following template is available:

```
<ema:has:prev>
<div class="flex-1 p-4 mt-8 bg-gray-100 rounded">
<span class="mb-2 text-xl font-semibold text-gray-500">Next:
<ema:note:prev>
<a class="text-${theme}-600 mavenLinkBold hover:bg-${theme}-50 mr-2"
href="${nav:url}">
<nav:title />
</a>
</ema:note:prev>
</span>
</div>
</ema:has:prev>
```

## Examples

- https://github.com/srid/srid/blob/master/index.yaml
Expand Down
40 changes: 39 additions & 1 deletion emanote/src/Emanote/View/Template.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Emanote.View.Template (emanoteSiteOutput, render) where

import Commonmark.Extensions.WikiLink qualified as WikiLink
import Control.Monad.Logger (MonadLoggerIO)
import Data.Aeson.Optics (key, _String)
import Data.Aeson.Types qualified as Aeson
import Data.List (partition)
import Data.Map.Syntax ((##))
Expand Down Expand Up @@ -33,8 +35,9 @@ import Heist.Extra.Splices.Pandoc.Ctx (emptyRenderCtx)
import Heist.Extra.Splices.Tree qualified as Splices
import Heist.Interpreted qualified as HI
import Heist.Splices qualified as Heist
import Network.URI.Slug qualified as Slug
import Optics.Core (Prism', review)
import Optics.Operators ((.~), (^.))
import Optics.Operators ((.~), (^.), (^?))
import Relude
import Text.Blaze.Renderer.XmlHtml qualified as RX
import Text.Pandoc.Builder qualified as B
Expand Down Expand Up @@ -185,6 +188,17 @@ renderLmlHtml model note = do
$ if MN.noteHasFeed note
then feedDiscoveryLink model note
else mempty

let mNext = getMetaList note "next"
forM_ mNext $ \nexts ->
"ema:note:next" ## navSplice model note nexts
"ema:has:next" ## Heist.ifElseISplice (isJust mNext)
let mPrev = getMetaList note "prev"
traceShowM (MN._noteMeta note)
forM_ mPrev $ \prevs ->
"ema:note:prev" ## navSplice model note prevs
"ema:has:prev" ## Heist.ifElseISplice (isJust mPrev)

"ema:note:backlinks" ##
backlinksSplice model (G.modelLookupBacklinks r model)
let (backlinksDaily, backlinksNoDaily) = partition (Calendar.isDailyNote . fst) $ G.modelLookupBacklinks r model
Expand All @@ -209,6 +223,30 @@ renderLmlHtml model note = do
$ \ctx' ->
renderToc ctx' toc

-- | Return a meta top attribute as a single elem or a list of elem
getMetaList :: MN.Note -> Aeson.Key -> Maybe [Text]
getMetaList note k =
MN._noteMeta note
^? key k >>= \v ->
let singleValue = (: []) <$> (v ^? _String)
listValue = Aeson.parseMaybe Aeson.parseJSON v -- Q: how to do that with aeson-optics?
in singleValue <|> listValue

navSplice :: Model -> MN.Note -> [Text] -> HI.Splice Identity
navSplice model note links = (HI.runChildrenWith . (navSplices model)) `foldMapM` routes
where
mkWikiLink = WikiLink.mkWikiLinkFromSlugs . pure . Slug.decodeSlug
routes = mapMaybe (G.lookupNoteByWikiLink model (note ^. MN.noteRoute) . mkWikiLink) links

navSplices :: Model -> R.LMLRoute -> H.Splices (HI.Splice Identity)
navSplices model source = do
"nav:title" ## C.titleSplice ctx (M.modelLookupTitle source model)
"nav:url" ## HI.textSplice (SR.siteRouteUrl model $ SR.lmlSiteRoute (R.LMLView_Html, source))
where
note = fromMaybe (error "backlink note missing - impossible") $ M.modelLookupNoteByRoute' source model
meta = Meta.getEffectiveRouteMetaWith (note ^. MN.noteMeta) source model
ctx = C.mkTemplateRenderCtx model source meta

backlinksSplice :: Model -> [(R.LMLRoute, NonEmpty [B.Block])] -> HI.Splice Identity
backlinksSplice model (bs :: [(R.LMLRoute, NonEmpty [B.Block])]) =
Splices.listSplice bs "backlink"
Expand Down
Loading