Merge pull request #38 from dillonkearns/generate-files

Add hook for generating static files
This commit is contained in:
Dillon Kearns 2020-01-25 16:35:31 -08:00 committed by GitHub
commit dc6aac330e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 543 additions and 194 deletions

View File

@ -9,8 +9,12 @@
"dependencies": {
"direct": {
"avh4/elm-color": "1.0.0",
"billstclair/elm-xml-eeue56": "1.0.1",
"dillonkearns/elm-markdown": "1.1.3",
"dillonkearns/elm-oembed": "1.0.0",
"dillonkearns/elm-rss": "1.0.0",
"dillonkearns/elm-sitemap": "1.0.0",
"dmy/elm-imf-date-time": "1.0.1",
"elm/browser": "1.0.2",
"elm/core": "1.0.2",
"elm/html": "1.0.0",
@ -42,7 +46,10 @@
"elm/regex": "1.0.0",
"elm/virtual-dom": "1.0.2",
"fredcy/elm-parseint": "2.0.1",
"mgold/elm-nonempty-list": "4.0.2"
"justinmimbs/time-extra": "1.1.0",
"lazamar/dict-parser": "1.0.2",
"mgold/elm-nonempty-list": "4.0.2",
"ryannhg/date-format": "2.3.0"
}
},
"test-dependencies": {

View File

@ -0,0 +1,72 @@
module Feed exposing (fileToGenerate)
import Metadata exposing (Metadata(..))
import Pages
import Pages.PagePath as PagePath exposing (PagePath)
import Rss
fileToGenerate :
{ siteTagline : String
, siteUrl : String
}
->
List
{ path : PagePath Pages.PathKey
, frontmatter : Metadata
, body : String
}
->
{ path : List String
, content : String
}
fileToGenerate config siteMetadata =
{ path = [ "blog", "feed.xml" ]
, content = generate config siteMetadata
}
generate :
{ siteTagline : String
, siteUrl : String
}
->
List
{ path : PagePath Pages.PathKey
, frontmatter : Metadata
, body : String
}
-> String
generate { siteTagline, siteUrl } siteMetadata =
Rss.generate
{ title = "elm-pages Blog"
, description = siteTagline
, url = "https://elm-pages.com/blog"
, lastBuildTime = Pages.builtAt
, generator = Just "elm-pages"
, items = siteMetadata |> List.filterMap metadataToRssItem
, siteUrl = siteUrl
}
metadataToRssItem :
{ path : PagePath Pages.PathKey
, frontmatter : Metadata
, body : String
}
-> Maybe Rss.Item
metadataToRssItem page =
case page.frontmatter of
Article article ->
Just
{ title = article.title
, description = article.description
, url = PagePath.toString page.path
, categories = []
, author = article.author.name
, pubDate = Rss.Date article.published
, content = Nothing
}
_ ->
Nothing

View File

@ -11,6 +11,7 @@ import Element.Border
import Element.Events
import Element.Font as Font
import Element.Region
import Feed
import FontAwesome
import Head
import Head.Seo as Seo
@ -21,6 +22,7 @@ import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Exploration as D
import MarkdownRenderer
import Metadata exposing (Metadata)
import MySitemap
import Pages exposing (images, pages)
import Pages.Directory as Directory exposing (Directory)
import Pages.Document
@ -65,11 +67,31 @@ main =
, documents = [ markdownDocument ]
, manifest = manifest
, canonicalSiteUrl = canonicalSiteUrl
, generateFiles = generateFiles
, onPageChange = OnPageChange
, internals = Pages.internals
}
generateFiles :
List
{ path : PagePath Pages.PathKey
, frontmatter : Metadata
, body : String
}
->
List
(Result String
{ path : List String
, content : String
}
)
generateFiles siteMetadata =
[ Feed.fileToGenerate { siteTagline = siteTagline, siteUrl = canonicalSiteUrl } siteMetadata |> Ok
, MySitemap.build { siteUrl = canonicalSiteUrl } siteMetadata |> Ok
]
markdownDocument : ( String, Pages.Document.DocumentHandler Metadata ( MarkdownRenderer.TableOfContents, List (Element Msg) ) )
markdownDocument =
Pages.Document.parser
@ -462,6 +484,13 @@ highlightableLink currentPath linkDirectory displayName =
}
commonHeadTags : List (Head.Tag Pages.PathKey)
commonHeadTags =
[ Head.rssLink "/blog/feed.xml"
, Head.sitemapLink "/sitemap.xml"
]
{-| <https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards>
<https://htmlhead.dev>
<https://html.spec.whatwg.org/multipage/semantics.html#standard-metadata-names>
@ -469,127 +498,129 @@ highlightableLink currentPath linkDirectory displayName =
-}
head : Metadata -> List (Head.Tag Pages.PathKey)
head metadata =
case metadata of
Metadata.Page meta ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = siteTagline
, locale = Nothing
, title = meta.title
}
|> Seo.website
commonHeadTags
++ (case metadata of
Metadata.Page meta ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = siteTagline
, locale = Nothing
, title = meta.title
}
|> Seo.website
Metadata.Doc meta ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, locale = Nothing
, description = siteTagline
, title = meta.title
}
|> Seo.website
Metadata.Doc meta ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, locale = Nothing
, description = siteTagline
, title = meta.title
}
|> Seo.website
Metadata.Article meta ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = meta.image
, alt = meta.description
, dimensions = Nothing
, mimeType = Nothing
}
, description = meta.description
, locale = Nothing
, title = meta.title
}
|> Seo.article
{ tags = []
, section = Nothing
, publishedTime = Just (Date.toIsoString meta.published)
, modifiedTime = Nothing
, expirationTime = Nothing
}
Metadata.Article meta ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = meta.image
, alt = meta.description
, dimensions = Nothing
, mimeType = Nothing
}
, description = meta.description
, locale = Nothing
, title = meta.title
}
|> Seo.article
{ tags = []
, section = Nothing
, publishedTime = Just (Date.toIsoString meta.published)
, modifiedTime = Nothing
, expirationTime = Nothing
}
Metadata.Author meta ->
let
( firstName, lastName ) =
case meta.name |> String.split " " of
[ first, last ] ->
( first, last )
Metadata.Author meta ->
let
( firstName, lastName ) =
case meta.name |> String.split " " of
[ first, last ] ->
( first, last )
[ first, middle, last ] ->
( first ++ " " ++ middle, last )
[ first, middle, last ] ->
( first ++ " " ++ middle, last )
[] ->
( "", "" )
[] ->
( "", "" )
_ ->
( meta.name, "" )
in
Seo.summary
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = meta.avatar
, alt = meta.name ++ "'s elm-pages articles."
, dimensions = Nothing
, mimeType = Nothing
}
, description = meta.bio
, locale = Nothing
, title = meta.name ++ "'s elm-pages articles."
}
|> Seo.profile
{ firstName = firstName
, lastName = lastName
, username = Nothing
}
_ ->
( meta.name, "" )
in
Seo.summary
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = meta.avatar
, alt = meta.name ++ "'s elm-pages articles."
, dimensions = Nothing
, mimeType = Nothing
}
, description = meta.bio
, locale = Nothing
, title = meta.name ++ "'s elm-pages articles."
}
|> Seo.profile
{ firstName = firstName
, lastName = lastName
, username = Nothing
}
Metadata.BlogIndex ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = siteTagline
, locale = Nothing
, title = "elm-pages blog"
}
|> Seo.website
Metadata.BlogIndex ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = siteTagline
, locale = Nothing
, title = "elm-pages blog"
}
|> Seo.website
Metadata.Showcase ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = siteTagline
, locale = Nothing
, title = "elm-pages sites showcase"
}
|> Seo.website
Metadata.Showcase ->
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = images.iconPng
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = siteTagline
, locale = Nothing
, title = "elm-pages sites showcase"
}
|> Seo.website
)
canonicalSiteUrl : String

View File

@ -0,0 +1,32 @@
module MySitemap exposing (..)
import Metadata exposing (Metadata(..))
import Pages
import Pages.PagePath as PagePath exposing (PagePath)
import Sitemap
build :
{ siteUrl : String
}
->
List
{ path : PagePath Pages.PathKey
, frontmatter : Metadata
, body : String
}
->
{ path : List String
, content : String
}
build config siteMetadata =
{ path = [ "sitemap.xml" ]
, content =
Sitemap.build config
(siteMetadata
|> List.map
(\page ->
{ path = PagePath.toString page.path, lastMod = Nothing }
)
)
}

View File

@ -20,8 +20,11 @@ function unpackFile(filePath) {
}
module.exports = class AddFilesPlugin {
constructor(data) {
constructor(data, filesToGenerate) {
this.pagesWithRequests = data;
this.filesToGenerate = filesToGenerate;
console.log('this.filesToGenerate', this.filesToGenerate);
}
apply(compiler) {
compiler.hooks.emit.tap("AddFilesPlugin", compilation => {
@ -52,6 +55,18 @@ module.exports = class AddFilesPlugin {
size: () => rawContents.length
};
});
this.filesToGenerate.forEach(file => {
// Couldn't find this documented in the webpack docs,
// but I found the example code for it here:
// https://github.com/jantimon/html-webpack-plugin/blob/35a154186501fba3ecddb819b6f632556d37a58f/index.js#L470-L478
compilation.assets[file.path] = {
source: () => file.content,
size: () => file.content.length
};
});
});
}
};

View File

@ -16,11 +16,12 @@ const ClosurePlugin = require("closure-webpack-plugin");
const readline = require("readline");
module.exports = { start, run };
function start({ routes, debug, customPort, manifestConfig, routesWithRequests }) {
function start({ routes, debug, customPort, manifestConfig, routesWithRequests, filesToGenerate }) {
const config = webpackOptions(false, routes, {
debug,
manifestConfig,
routesWithRequests
routesWithRequests,
filesToGenerate
});
const compiler = webpack(config);
@ -66,12 +67,13 @@ function start({ routes, debug, customPort, manifestConfig, routesWithRequests }
// app.use(express.static(__dirname + "/path-to-static-folder"));
}
function run({ routes, manifestConfig, routesWithRequests }, callback) {
function run({ routes, manifestConfig, routesWithRequests, filesToGenerate }, callback) {
webpack(
webpackOptions(true, routes, {
debug: false,
manifestConfig,
routesWithRequests
routesWithRequests,
filesToGenerate
})
).run((err, stats) => {
if (err) {
@ -119,12 +121,12 @@ function printProgress(progress, message) {
function webpackOptions(
production,
routes,
{ debug, manifestConfig, routesWithRequests }
{ debug, manifestConfig, routesWithRequests, filesToGenerate }
) {
const common = {
mode: production ? "production" : "development",
plugins: [
new AddFilesPlugin(routesWithRequests),
new AddFilesPlugin(routesWithRequests, filesToGenerate),
new CopyPlugin([
{
from: "static/**/*",

View File

@ -86,6 +86,7 @@ function run() {
markdownContent,
content,
function(payload) {
console.log('@@@@@@@@@ filesToGenerate', payload.filesToGenerate);
if (contents.watch) {
startWatchIfNeeded();
if (!devServerRunning) {
@ -95,6 +96,7 @@ function run() {
debug: contents.debug,
manifestConfig: payload.manifest,
routesWithRequests: payload.pages,
filesToGenerate: payload.filesToGenerate,
customPort: contents.customPort
});
}
@ -107,7 +109,8 @@ function run() {
{
routes,
manifestConfig: payload.manifest,
routesWithRequests: payload.pages
routesWithRequests: payload.pages,
filesToGenerate: payload.filesToGenerate
},
() => {}
);

View File

@ -4,7 +4,7 @@ workbox.precaching.precacheAndRoute(self.__precacheManifest);
workbox.routing.registerNavigationRoute(
workbox.precaching.getCacheKeyForURL("/index.html"),
{
blacklist: [/admin/]
blacklist: [/admin/, /\./]
}
);
workbox.routing.registerRoute(

View File

@ -1,5 +1,6 @@
module Head exposing
( Tag, metaName, metaProperty
, rssLink, sitemapLink
, AttributeValue
, currentPageFullUrl, fullImageUrl, fullPageUrl, raw
, toJson, canonicalLink
@ -15,6 +16,7 @@ But this module might be useful if you have a special use case, or if you are
writing a plugin package to extend `elm-pages`.
@docs Tag, metaName, metaProperty
@docs rssLink, sitemapLink
## `AttributeValue`s
@ -106,9 +108,49 @@ canonicalLink maybePath =
]
{-| Add a link to the site's RSS feed.
Example:
rssLink "/feed.xml"
```html
<link rel="alternate" type="application/rss+xml" href="/rss.xml">
```
-}
rssLink : String -> Tag pathKey
rssLink url =
node "link"
[ ( "rel", raw "alternate" )
, ( "type", raw "application/rss+xml" )
, ( "href", raw url )
]
{-| Add a link to the site's RSS feed.
Example:
sitemapLink "/feed.xml"
```html
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
```
-}
sitemapLink : String -> Tag pathKey
sitemapLink url =
node "link"
[ ( "rel", raw "sitemap" )
, ( "type", raw "application/xml" )
, ( "href", raw url )
]
{-| Example:
Head.metaProperty "fb:app_id" ( Head.raw "123456789" )
Head.metaProperty "fb:app_id" (Head.raw "123456789")
Results in `<meta property="fb:app_id" content="123456789" />`

View File

@ -533,6 +533,19 @@ application :
, content : Content
, toJsPort : Json.Encode.Value -> Cmd Never
, manifest : Manifest.Config pathKey
, generateFiles :
List
{ path : PagePath pathKey
, frontmatter : metadata
, body : String
}
->
List
(Result String
{ path : List String
, content : String
}
)
, canonicalSiteUrl : String
, pathKey : pathKey
, onPageChange : PagePath pathKey -> userMsg
@ -613,6 +626,19 @@ cliApplication :
, content : Content
, toJsPort : Json.Encode.Value -> Cmd Never
, manifest : Manifest.Config pathKey
, generateFiles :
List
{ path : PagePath pathKey
, frontmatter : metadata
, body : String
}
->
List
(Result String
{ path : List String
, content : String
}
)
, canonicalSiteUrl : String
, pathKey : pathKey
, onPageChange : PagePath pathKey -> userMsg

View File

@ -44,6 +44,13 @@ type ToJsPayload pathKey
type alias ToJsSuccessPayload pathKey =
{ pages : Dict String (Dict String String)
, manifest : Manifest.Config pathKey
, filesToGenerate : List FileToGenerate
}
type alias FileToGenerate =
{ path : List String
, content : String
}
@ -55,8 +62,8 @@ toJsCodec =
Errors errorList ->
errors errorList
Success { pages, manifest } ->
success (ToJsSuccessPayload pages manifest)
Success { pages, manifest, filesToGenerate } ->
success (ToJsSuccessPayload pages manifest filesToGenerate)
)
|> Codec.variant1 "Errors" Errors Codec.string
|> Codec.variant1 "Success"
@ -90,6 +97,21 @@ successCodec =
|> Codec.field "manifest"
.manifest
(Codec.build Manifest.toJson (Decode.succeed stubManifest))
|> Codec.field "filesToGenerate"
.filesToGenerate
(Codec.build
(\list ->
list
|> Json.Encode.list
(\item ->
Json.Encode.object
[ ( "path", item.path |> String.join "/" |> Json.Encode.string )
, ( "content", item.content |> Json.Encode.string )
]
)
)
(Decode.succeed [])
)
|> Codec.buildObject
@ -128,34 +150,50 @@ type Msg
= GotStaticHttpResponse { request : { masked : RequestDetails, unmasked : RequestDetails }, response : Result Http.Error String }
type alias Config pathKey userMsg userModel metadata view =
{ init : Maybe (PagePath pathKey) -> ( userModel, Cmd userMsg )
, update : userMsg -> userModel -> ( userModel, Cmd userMsg )
, subscriptions : userModel -> Sub userMsg
, view :
List ( PagePath pathKey, metadata )
->
{ path : PagePath pathKey
, frontmatter : metadata
}
->
StaticHttp.Request
{ view : userModel -> view -> { title : String, body : Html userMsg }
, head : List (Head.Tag pathKey)
}
, document : Pages.Document.Document metadata view
, content : Content
, toJsPort : Json.Encode.Value -> Cmd Never
, manifest : Manifest.Config pathKey
, generateFiles :
List
{ path : PagePath pathKey
, frontmatter : metadata
, body : String
}
->
List
(Result String
{ path : List String
, content : String
}
)
, canonicalSiteUrl : String
, pathKey : pathKey
, onPageChange : PagePath pathKey -> userMsg
}
cliApplication :
(Msg -> msg)
-> (msg -> Maybe Msg)
-> (Model -> model)
-> (model -> Maybe Model)
->
{ init : Maybe (PagePath pathKey) -> ( userModel, Cmd userMsg )
, update : userMsg -> userModel -> ( userModel, Cmd userMsg )
, subscriptions : userModel -> Sub userMsg
, view :
List ( PagePath pathKey, metadata )
->
{ path : PagePath pathKey
, frontmatter : metadata
}
->
StaticHttp.Request
{ view : userModel -> view -> { title : String, body : Html userMsg }
, head : List (Head.Tag pathKey)
}
, document : Pages.Document.Document metadata view
, content : Content
, toJsPort : Json.Encode.Value -> Cmd Never
, manifest : Manifest.Config pathKey
, canonicalSiteUrl : String
, pathKey : pathKey
, onPageChange : PagePath pathKey -> userMsg
}
-> Config pathKey userMsg userModel metadata view
-> Platform.Program Flags model msg
cliApplication cliMsgConstructor narrowMsg toModel fromModel config =
let
@ -177,7 +215,7 @@ cliApplication cliMsgConstructor narrowMsg toModel fromModel config =
\msg model ->
case ( narrowMsg msg, fromModel model ) of
( Just cliMsg, Just cliModel ) ->
update config cliMsg cliModel
update siteMetadata config cliMsg cliModel
|> Tuple.mapSecond (perform cliMsgConstructor config.toJsPort)
|> Tuple.mapFirst toModel
@ -248,21 +286,7 @@ init :
(Model -> model)
-> ContentCache.ContentCache metadata view
-> Result (List BuildError) (List ( PagePath pathKey, metadata ))
->
{ config
| view :
List ( PagePath pathKey, metadata )
->
{ path : PagePath pathKey
, frontmatter : metadata
}
->
StaticHttp.Request
{ view : userModel -> view -> { title : String, body : Html userMsg }
, head : List (Head.Tag pathKey)
}
, manifest : Manifest.Config pathKey
}
-> Config pathKey userMsg userModel metadata view
-> Decode.Value
-> ( model, Effect pathKey )
init toModel contentCache siteMetadata config flags =
@ -298,7 +322,7 @@ init toModel contentCache siteMetadata config flags =
staticResponsesInit []
( updatedRawResponses, effect ) =
sendStaticResponsesIfDone mode secrets Dict.empty [] staticResponses config.manifest
sendStaticResponsesIfDone config siteMetadata mode secrets Dict.empty [] staticResponses
in
( Model staticResponses secrets [] updatedRawResponses mode |> toModel
, effect
@ -324,6 +348,8 @@ init toModel contentCache siteMetadata config flags =
staticResponsesInit []
in
updateAndSendPortIfDone
config
siteMetadata
(Model
staticResponses
secrets
@ -332,10 +358,11 @@ init toModel contentCache siteMetadata config flags =
mode
)
toModel
config.manifest
Err metadataParserErrors ->
updateAndSendPortIfDone
config
siteMetadata
(Model Dict.empty
secrets
(metadataParserErrors |> List.map Tuple.second)
@ -343,10 +370,11 @@ init toModel contentCache siteMetadata config flags =
mode
)
toModel
config.manifest
Err error ->
updateAndSendPortIfDone
config
siteMetadata
(Model Dict.empty
SecretsDict.masked
[ { title = "Internal Error"
@ -357,20 +385,25 @@ init toModel contentCache siteMetadata config flags =
Dev
)
toModel
config.manifest
updateAndSendPortIfDone : Model -> (Model -> model) -> Manifest.Config pathKey -> ( model, Effect pathKey )
updateAndSendPortIfDone model toModel manifest =
updateAndSendPortIfDone :
Config pathKey userMsg userModel metadata view
-> Result (List BuildError) (List ( PagePath pathKey, metadata ))
-> Model
-> (Model -> model)
-> ( model, Effect pathKey )
updateAndSendPortIfDone config siteMetadata model toModel =
let
( updatedAllRawResponses, effect ) =
sendStaticResponsesIfDone
config
siteMetadata
model.mode
model.secrets
model.allRawResponses
model.errors
model.staticResponses
manifest
in
( { model | allRawResponses = updatedAllRawResponses } |> toModel
, effect
@ -382,24 +415,12 @@ type alias PageErrors =
update :
{ config
| view :
List ( PagePath pathKey, metadata )
->
{ path : PagePath pathKey
, frontmatter : metadata
}
->
StaticHttp.Request
{ view : userModel -> view -> { title : String, body : Html userMsg }
, head : List (Head.Tag pathKey)
}
, manifest : Manifest.Config pathKey
}
Result (List BuildError) (List ( PagePath pathKey, metadata ))
-> Config pathKey userMsg userModel metadata view
-> Msg
-> Model
-> ( Model, Effect pathKey )
update config msg model =
update siteMetadata config msg model =
case msg of
GotStaticHttpResponse { request, response } ->
let
@ -456,7 +477,7 @@ update config msg model =
}
( updatedAllRawResponses, effect ) =
sendStaticResponsesIfDone updatedModel.mode updatedModel.secrets updatedModel.allRawResponses updatedModel.errors updatedModel.staticResponses config.manifest
sendStaticResponsesIfDone config siteMetadata updatedModel.mode updatedModel.secrets updatedModel.allRawResponses updatedModel.errors updatedModel.staticResponses
in
( { updatedModel | allRawResponses = updatedAllRawResponses }
, effect
@ -585,8 +606,16 @@ isJust maybeValue =
False
sendStaticResponsesIfDone : Mode -> SecretsDict -> Dict String (Maybe String) -> List BuildError -> StaticResponses -> Manifest.Config pathKey -> ( Dict String (Maybe String), Effect pathKey )
sendStaticResponsesIfDone mode secrets allRawResponses errors staticResponses manifest =
sendStaticResponsesIfDone :
Config pathKey userMsg userModel metadata view
-> Result (List BuildError) (List ( PagePath pathKey, metadata ))
-> Mode
-> SecretsDict
-> Dict String (Maybe String)
-> List BuildError
-> StaticResponses
-> ( Dict String (Maybe String), Effect pathKey )
sendStaticResponsesIfDone config siteMetadata mode secrets allRawResponses errors staticResponses =
let
pendingRequests =
staticResponses
@ -737,18 +766,86 @@ sendStaticResponsesIfDone mode secrets allRawResponses errors staticResponses ma
let
updatedAllRawResponses =
Dict.empty
generatedFiles =
siteMetadata
|> Result.withDefault []
|> List.map
(\( pagePath, metadata ) ->
let
contentForPage =
config.content
|> List.filterMap
(\( path, { body } ) ->
let
pagePathToGenerate =
PagePath.toString pagePath
currentContentPath =
"/" ++ (path |> String.join "/")
in
if pagePathToGenerate == currentContentPath then
Just body
else
Nothing
)
|> List.head
|> Maybe.andThen identity
in
{ path = pagePath
, frontmatter = metadata
, body = contentForPage |> Maybe.withDefault ""
}
)
|> config.generateFiles
generatedOkayFiles =
generatedFiles
|> List.filterMap
(\result ->
case result of
Ok ok ->
Just ok
_ ->
Nothing
)
generatedFileErrors =
generatedFiles
|> List.filterMap
(\result ->
case result of
Ok ok ->
Nothing
Err error ->
Just
{ title = "Generate Files Error"
, message =
[ Terminal.text "I encountered an Err from your generateFiles function. Message:\n"
, Terminal.text <| "Error: " ++ error
]
}
)
allErrors : List BuildError
allErrors =
errors ++ failedRequests ++ generatedFileErrors
in
( updatedAllRawResponses
, SendJsData
(if List.isEmpty errors && List.isEmpty failedRequests then
(if List.isEmpty allErrors then
Success
(ToJsSuccessPayload
(encodeStaticResponses mode staticResponses)
manifest
config.manifest
generatedOkayFiles
)
else
Errors <| BuildError.errorsToString (failedRequests ++ errors)
Errors <| BuildError.errorsToString allErrors
)
)

View File

@ -77,6 +77,19 @@ application :
}
, documents : List ( String, Document.DocumentHandler metadata view )
, manifest : Pages.Manifest.Config pathKey
, generateFiles :
List
{ path : PagePath pathKey
, frontmatter : metadata
, body : String
}
->
List
(Result String
{ path : List String
, content : String
}
)
, onPageChange : PagePath pathKey -> userMsg
, canonicalSiteUrl : String
, internals : Pages.Internal.Internal pathKey
@ -97,6 +110,7 @@ application config =
, subscriptions = config.subscriptions
, document = Document.fromList config.documents
, content = config.internals.content
, generateFiles = config.generateFiles
, toJsPort = config.internals.toJsPort
, manifest = config.manifest
, canonicalSiteUrl = config.canonicalSiteUrl

View File

@ -564,9 +564,17 @@ start pages =
Debug.todo "Couldn't find page"
}
in
{-
(Model -> model)
-> ContentCache.ContentCache metadata view
-> Result (List BuildError) (List ( PagePath pathKey, metadata ))
-> Config pathKey userMsg userModel metadata view
-> Decode.Value
-> ( model, Effect pathKey )
-}
ProgramTest.createDocument
{ init = Main.init identity contentCache siteMetadata config
, update = Main.update config
, update = Main.update siteMetadata config
, view = \_ -> { title = "", body = [] }
}
|> ProgramTest.withSimulatedEffects simulateEffects