Add helper for optimized markdown data source.

This commit is contained in:
Dillon Kearns 2021-06-20 08:18:56 -07:00
parent 66c6bf7063
commit 44d6811f71
3 changed files with 55 additions and 47 deletions

View File

@ -1,9 +1,47 @@
module MarkdownCodec exposing (codec)
module MarkdownCodec exposing (codec, withFrontmatter)
import DataSource
import DataSource.File as StaticFile
import Markdown.Block as Block exposing (Block)
import Markdown.Parser
import Markdown.Renderer
import OptimizedDecoder exposing (Decoder)
import Serialize as S
withFrontmatter :
(frontmatter -> List view -> value)
-> String
-> Decoder frontmatter
-> Markdown.Renderer.Renderer view
-> DataSource.DataSource value
withFrontmatter constructor filePath frontmatterDecoder renderer =
DataSource.map2 constructor
(StaticFile.onlyFrontmatter
frontmatterDecoder
filePath
)
((StaticFile.bodyWithoutFrontmatter
filePath
|> DataSource.andThen
(\rawBody ->
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Couldn't parse markdown.")
|> DataSource.fromResult
)
)
|> DataSource.distillSerializeCodec ("markdown-blocks-" ++ filePath)
(S.list codec)
|> DataSource.andThen
(\blocks ->
blocks
|> Markdown.Renderer.render renderer
|> DataSource.fromResult
)
)
codec : S.Codec Never Block
codec =
S.customType

View File

@ -226,37 +226,17 @@ head static =
type alias Data =
{ body : List (Html Msg)
, metadata : ArticleMetadata
{ metadata : ArticleMetadata
, body : List (Html Msg)
}
data : RouteParams -> DataSource Data
data route =
DataSource.map2 Data
((StaticFile.bodyWithoutFrontmatter
("content/blog/" ++ route.slug ++ ".md")
|> DataSource.andThen
(\rawBody ->
rawBody
|> Markdown.Parser.parse
|> Result.mapError (\_ -> "Couldn't parse markdown.")
|> DataSource.fromResult
)
)
|> DataSource.distillSerializeCodec ("markdown-blocks-" ++ route.slug)
(S.list MarkdownCodec.codec)
|> DataSource.andThen
(\blocks ->
blocks
|> Markdown.Renderer.render TailwindMarkdownRenderer.renderer
|> DataSource.fromResult
)
)
(StaticFile.onlyFrontmatter
frontmatterDecoder
("content/blog/" ++ route.slug ++ ".md")
)
MarkdownCodec.withFrontmatter Data
("content/blog/" ++ route.slug ++ ".md")
frontmatterDecoder
TailwindMarkdownRenderer.renderer
type alias ArticleMetadata =

View File

@ -9,18 +9,17 @@ import DocsSection exposing (Section)
import Head
import Head.Seo as Seo
import Heroicon
import Html.Styled as Html
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attr exposing (css)
import List.Extra
import Markdown.Block as Block exposing (Block)
import Markdown.Parser
import Markdown.Renderer
import MarkdownCodec
import NextPrevious
import OptimizedDecoder as Decode exposing (Decoder)
import Page exposing (Page, PageWithState, StaticPayload)
import Pages.PageUrl exposing (PageUrl)
import Pages.Url
import Serialize
import Shared
import TableOfContents
import Tailwind.Breakpoints as Bp
@ -186,7 +185,7 @@ head static =
type alias Data =
{ body : { description : String, body : List Block }
{ body : { description : String, body : List (Html Msg) }
, titles : { title : String, previousAndNext : ( Maybe NextPrevious.Item, Maybe NextPrevious.Item ) }
, editUrl : String
}
@ -242,10 +241,7 @@ view maybeUrl sharedModel static =
, Bp.xl [ Tw.pr_36 ]
]
]
((static.data.body.body
|> Markdown.Renderer.render TailwindMarkdownRenderer.renderer
|> Result.withDefault [ Html.text "" ]
)
(static.data.body.body
++ [ NextPrevious.view static.data.titles.previousAndNext
, Html.hr [] []
, Html.footer
@ -277,7 +273,7 @@ view maybeUrl sharedModel static =
}
pageBody : RouteParams -> DataSource { description : String, body : List Block }
pageBody : RouteParams -> DataSource { description : String, body : List (Html msg) }
pageBody routeParams =
let
slug : String
@ -287,17 +283,11 @@ pageBody routeParams =
in
Glob.expectUniqueMatch (findBySlug slug)
|> DataSource.andThen
(DataSource.File.bodyWithFrontmatter
(\body ->
Decode.map2
(\description parsedMarkdown ->
{ description = description
, body = parsedMarkdown
}
)
(Decode.field "description" Decode.string)
(markdownBodyDecoder body)
)
(\filePath ->
MarkdownCodec.withFrontmatter (\description body -> { description = description, body = body })
filePath
(Decode.field "description" Decode.string)
TailwindMarkdownRenderer.renderer
)