From f1249440b177168e4bd2cea22f726f115915c7c7 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 25 Apr 2022 13:36:16 -0400 Subject: [PATCH] Add metadata support - Begin WIP on Bit Badger theme --- src/MyWebLog.Data/Data.fs | 2 + src/MyWebLog.Domain/DataTypes.fs | 9 + src/MyWebLog.Domain/SupportTypes.fs | 7 + src/MyWebLog.Domain/ViewModels.fs | 42 +++- src/MyWebLog/Handlers.fs | 9 +- src/MyWebLog/Program.fs | 4 +- src/MyWebLog/themes/admin/page-edit.liquid | 44 ++++ .../themes/bit-badger/home-page.liquid | 98 ++++++++ src/MyWebLog/themes/bit-badger/layout.liquid | 45 ++++ .../themes/bit-badger/single-page.liquid | 5 + src/MyWebLog/wwwroot/themes/admin/admin.js | 89 +++++++ .../themes/bit-badger/bit-badger-auth.png | Bin 0 -> 23158 bytes .../wwwroot/themes/bit-badger/bitbadger.png | Bin 0 -> 17821 bytes .../wwwroot/themes/bit-badger/facebook.png | Bin 0 -> 6518 bytes .../wwwroot/themes/bit-badger/favicon.ico | Bin 0 -> 9528 bytes .../bit-badger/screenshots/bay-vista.png | Bin 0 -> 55577 bytes .../bit-badger/screenshots/cassy-fiano.png | Bin 0 -> 58589 bytes .../screenshots/dr-melissa-clouthier.png | Bin 0 -> 70797 bytes .../emerald-mountain-christian-school.png | Bin 0 -> 71356 bytes .../screenshots/futility-closet.png | Bin 0 -> 92669 bytes .../screenshots/hard-corps-wife.png | Bin 0 -> 71627 bytes .../screenshots/liberty-pundits.png | Bin 0 -> 69306 bytes .../screenshots/mindy-mackenzie.png | Bin 0 -> 38444 bytes .../screenshots/my-prayer-journal.png | Bin 0 -> 23468 bytes .../themes/bit-badger/screenshots/nsx.png | Bin 0 -> 47811 bytes .../bit-badger/screenshots/olivet-baptist.png | Bin 0 -> 15508 bytes .../screenshots/photography-by-michelle.png | Bin 0 -> 91626 bytes .../bit-badger/screenshots/prayer-tracker.png | Bin 0 -> 42936 bytes .../screenshots/riehl-world-news.png | Bin 0 -> 73056 bytes .../themes/bit-badger/screenshots/tcms.png | Bin 0 -> 34726 bytes .../bit-badger/screenshots/tech-blog.png | Bin 0 -> 61486 bytes .../bit-badger/screenshots/the-shark-tank.png | Bin 0 -> 97351 bytes .../screenshots/virtual-prayer-room.png | Bin 0 -> 44572 bytes .../wwwroot/themes/bit-badger/style.css | 217 ++++++++++++++++++ .../wwwroot/themes/bit-badger/twitter.png | Bin 0 -> 10348 bytes 35 files changed, 558 insertions(+), 13 deletions(-) create mode 100644 src/MyWebLog/themes/bit-badger/home-page.liquid create mode 100644 src/MyWebLog/themes/bit-badger/layout.liquid create mode 100644 src/MyWebLog/themes/bit-badger/single-page.liquid create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/bit-badger-auth.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/bitbadger.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/facebook.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/favicon.ico create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/bay-vista.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/cassy-fiano.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/dr-melissa-clouthier.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/emerald-mountain-christian-school.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/futility-closet.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/hard-corps-wife.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/liberty-pundits.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/mindy-mackenzie.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/my-prayer-journal.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/nsx.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/olivet-baptist.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/photography-by-michelle.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/prayer-tracker.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/riehl-world-news.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/tcms.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/tech-blog.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/the-shark-tank.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/screenshots/virtual-prayer-room.png create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/style.css create mode 100644 src/MyWebLog/wwwroot/themes/bit-badger/twitter.png diff --git a/src/MyWebLog.Data/Data.fs b/src/MyWebLog.Data/Data.fs index efdb6e6..e335d33 100644 --- a/src/MyWebLog.Data/Data.fs +++ b/src/MyWebLog.Data/Data.fs @@ -342,8 +342,10 @@ module Page = "permalink", page.permalink "updatedOn", page.updatedOn "showInPageList", page.showInPageList + "template", page.template "text", page.text "priorPermalinks", page.priorPermalinks + "metadata", page.metadata "revisions", page.revisions ] write; withRetryDefault; ignoreResult diff --git a/src/MyWebLog.Domain/DataTypes.fs b/src/MyWebLog.Domain/DataTypes.fs index 27cb1a2..89147f2 100644 --- a/src/MyWebLog.Domain/DataTypes.fs +++ b/src/MyWebLog.Domain/DataTypes.fs @@ -1,6 +1,7 @@ namespace MyWebLog open System +open MyWebLog /// A category under which a post may be identified [] @@ -119,6 +120,9 @@ type Page = /// The current text of the page text : string + /// Metadata for this page + metadata : MetaItem list + /// Permalinks at which this page may have been previously served (useful for migrated content) priorPermalinks : Permalink list @@ -141,6 +145,7 @@ module Page = showInPageList = false template = None text = "" + metadata = [] priorPermalinks = [] revisions = [] } @@ -182,6 +187,9 @@ type Post = /// The tags for the post tags : string list + /// Metadata for the post + metadata : MetaItem list + /// Permalinks at which this post may have been previously served (useful for migrated content) priorPermalinks : Permalink list @@ -205,6 +213,7 @@ module Post = text = "" categoryIds = [] tags = [] + metadata = [] priorPermalinks = [] revisions = [] } diff --git a/src/MyWebLog.Domain/SupportTypes.fs b/src/MyWebLog.Domain/SupportTypes.fs index f36f65a..f5127c8 100644 --- a/src/MyWebLog.Domain/SupportTypes.fs +++ b/src/MyWebLog.Domain/SupportTypes.fs @@ -98,7 +98,14 @@ type MetaItem = value : string } +/// Functions to support metadata items +module MetaItem = + /// An empty metadata item + let empty = + { name = ""; value = "" } + + /// A revision of a page or post [] type Revision = diff --git a/src/MyWebLog.Domain/ViewModels.fs b/src/MyWebLog.Domain/ViewModels.fs index cee7e04..b9b73e3 100644 --- a/src/MyWebLog.Domain/ViewModels.fs +++ b/src/MyWebLog.Domain/ViewModels.fs @@ -1,7 +1,6 @@ namespace MyWebLog.ViewModels open System -open System.Collections.Generic open MyWebLog /// Details about a category, used to display category lists @@ -136,13 +135,21 @@ type EditPageModel = /// The text of the page text : string + + /// Names of metadata items + metaNames : string[] + + /// Values of metadata items + metaValues : string[] } + /// Create an edit model from an existing page static member fromPage (page : Page) = let latest = match page.revisions |> List.sortByDescending (fun r -> r.asOf) |> List.tryHead with | Some rev -> rev | None -> Revision.empty + let page = if page.metadata |> List.isEmpty then { page with metadata = [ MetaItem.empty ] } else page { pageId = PageId.toString page.id title = page.title permalink = Permalink.toString page.permalink @@ -150,6 +157,8 @@ type EditPageModel = isShownInPageList = page.showInPageList source = MarkupText.sourceType latest.text text = MarkupText.text latest.text + metaNames = page.metadata |> List.map (fun m -> m.name) |> Array.ofList + metaValues = page.metadata |> List.map (fun m -> m.value) |> Array.ofList } @@ -182,6 +191,12 @@ type EditPostModel = /// Whether this post should be published doPublish : bool + + /// Names of metadata items + metaNames : string[] + + /// Values of metadata items + metaValues : string[] } /// Create an edit model from an existing past static member fromPost (post : Post) = @@ -189,15 +204,18 @@ type EditPostModel = match post.revisions |> List.sortByDescending (fun r -> r.asOf) |> List.tryHead with | Some rev -> rev | None -> Revision.empty - { postId = PostId.toString post.id - title = post.title - permalink = Permalink.toString post.permalink - source = MarkupText.sourceType latest.text - text = MarkupText.text latest.text - tags = String.Join (", ", post.tags) - categoryIds = post.categoryIds |> List.map CategoryId.toString |> Array.ofList - status = PostStatus.toString post.status - doPublish = false + let post = if post.metadata |> List.isEmpty then { post with metadata = [ MetaItem.empty ] } else post + { postId = PostId.toString post.id + title = post.title + permalink = Permalink.toString post.permalink + source = MarkupText.sourceType latest.text + text = MarkupText.text latest.text + tags = String.Join (", ", post.tags) + categoryIds = post.categoryIds |> List.map CategoryId.toString |> Array.ofList + status = PostStatus.toString post.status + doPublish = false + metaNames = post.metadata |> List.map (fun m -> m.name) |> Array.ofList + metaValues = post.metadata |> List.map (fun m -> m.value) |> Array.ofList } @@ -251,6 +269,9 @@ type PostListItem = /// Tags for the post tags : string list + + /// Metadata for the post + meta : MetaItem list } /// Create a post list item from a post @@ -265,6 +286,7 @@ type PostListItem = text = post.text categoryIds = post.categoryIds |> List.map CategoryId.toString tags = post.tags + meta = post.metadata } diff --git a/src/MyWebLog/Handlers.fs b/src/MyWebLog/Handlers.fs index c8d5276..86bc180 100644 --- a/src/MyWebLog/Handlers.fs +++ b/src/MyWebLog/Handlers.fs @@ -361,10 +361,13 @@ module Page = } match result with | Some (title, page) -> + let model = EditPageModel.fromPage page return! Hash.FromAnonymousObject {| csrf = csrfToken ctx - model = EditPageModel.fromPage page + model = model + metadata = Array.zip model.metaNames model.metaValues + |> Array.mapi (fun idx (name, value) -> [| string idx; name; value |]) page_title = title templates = templatesForTheme ctx "page" |} @@ -408,6 +411,10 @@ module Page = showInPageList = model.isShownInPageList template = match model.template with "" -> None | tmpl -> Some tmpl text = MarkupText.toHtml revision.text + metadata = Seq.zip model.metaNames model.metaValues + |> Seq.filter (fun it -> fst it > "") + |> Seq.map (fun it -> { name = fst it; value = snd it }) + |> List.ofSeq revisions = revision :: page.revisions } do! (match model.pageId with "new" -> Data.Page.add | _ -> Data.Page.update) page conn diff --git a/src/MyWebLog/Program.fs b/src/MyWebLog/Program.fs index 9ad58a3..f931fa2 100644 --- a/src/MyWebLog/Program.fs +++ b/src/MyWebLog/Program.fs @@ -25,8 +25,8 @@ type WebLogMiddleware (next : RequestDelegate) = /// DotLiquid filters module DotLiquidBespoke = - open DotLiquid open System.IO + open DotLiquid /// A filter to generate nav links, highlighting the active link (exact match) type NavLinkFilter () = @@ -166,7 +166,7 @@ let main args = builder.Services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(fun opts -> - opts.ExpireTimeSpan <- TimeSpan.FromMinutes 20. + opts.ExpireTimeSpan <- TimeSpan.FromMinutes 60. opts.SlidingExpiration <- true opts.AccessDeniedPath <- "/forbidden") let _ = builder.Services.AddLogging () diff --git a/src/MyWebLog/themes/admin/page-edit.liquid b/src/MyWebLog/themes/admin/page-edit.liquid index c5eb1a1..c94e7e3 100644 --- a/src/MyWebLog/themes/admin/page-edit.liquid +++ b/src/MyWebLog/themes/admin/page-edit.liquid @@ -56,6 +56,50 @@ +
+
+
+ + Metadata + + +
+
+ {%- for meta in metadata %} +
+
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+ {% endfor -%} +
+ + +
+
+
+
diff --git a/src/MyWebLog/themes/bit-badger/home-page.liquid b/src/MyWebLog/themes/bit-badger/home-page.liquid new file mode 100644 index 0000000..9b83987 --- /dev/null +++ b/src/MyWebLog/themes/bit-badger/home-page.liquid @@ -0,0 +1,98 @@ +
+
+ {{ page.text }} +
+ +
diff --git a/src/MyWebLog/themes/bit-badger/layout.liquid b/src/MyWebLog/themes/bit-badger/layout.liquid new file mode 100644 index 0000000..b71ab5a --- /dev/null +++ b/src/MyWebLog/themes/bit-badger/layout.liquid @@ -0,0 +1,45 @@ + + + + + {{ page_title }} » Bit Badger Solutions + + + + + + {{ content }} + + + \ No newline at end of file diff --git a/src/MyWebLog/themes/bit-badger/single-page.liquid b/src/MyWebLog/themes/bit-badger/single-page.liquid new file mode 100644 index 0000000..23adf69 --- /dev/null +++ b/src/MyWebLog/themes/bit-badger/single-page.liquid @@ -0,0 +1,5 @@ +
+

{{ page.title }}

+ {{ page.text }} +


« Home

+
diff --git a/src/MyWebLog/wwwroot/themes/admin/admin.js b/src/MyWebLog/wwwroot/themes/admin/admin.js index b030360..b99d5a1 100644 --- a/src/MyWebLog/wwwroot/themes/admin/admin.js +++ b/src/MyWebLog/wwwroot/themes/admin/admin.js @@ -1,4 +1,93 @@ const Admin = { + /** The next index for a metadata item */ + nextMetaIndex : 0, + + /** + * Set the next meta item index + * @param idx The index to set + */ + // Calling a function with a Liquid variable does not look like an error in the IDE... + setNextMetaIndex(idx) { + this.nextMetaIndex = idx + }, + + /** + * Add a new row for metadata entry + */ + addMetaItem() { + // Remove button + const removeBtn = document.createElement("button") + removeBtn.type = "button" + removeBtn.className = "btn btn-sm btn-danger" + removeBtn.innerHTML = "−" + removeBtn.setAttribute("onclick", `Admin.removeMetaItem(${this.nextMetaIndex})`) + + const removeCol = document.createElement("div") + removeCol.className = "col-1 text-center align-self-center" + removeCol.appendChild(removeBtn) + + // Name + const nameField = document.createElement("input") + nameField.type = "text" + nameField.name = "metaNames" + nameField.id = `metaNames_${this.nextMetaIndex}` + nameField.className = "form-control" + nameField.placeholder = "Name" + + const nameLabel = document.createElement("label") + nameLabel.htmlFor = nameField.id + nameLabel.innerText = nameField.placeholder + + const nameFloat = document.createElement("div") + nameFloat.className = "form-floating" + nameFloat.appendChild(nameField) + nameFloat.appendChild(nameLabel) + + const nameCol = document.createElement("div") + nameCol.className = "col-3" + nameCol.appendChild(nameFloat) + + // Value + const valueField = document.createElement("input") + valueField.type = "text" + valueField.name = "metaValues" + valueField.id = `metaValues_${this.nextMetaIndex}` + valueField.className = "form-control" + valueField.placeholder = "Value" + + const valueLabel = document.createElement("label") + valueLabel.htmlFor = valueField.id + valueLabel.innerText = valueField.placeholder + + const valueFloat = document.createElement("div") + valueFloat.className = "form-floating" + valueFloat.appendChild(valueField) + valueFloat.appendChild(valueLabel) + + const valueCol = document.createElement("div") + valueCol.className = "col-8" + valueCol.appendChild(valueFloat) + + // Put it all together + const newRow = document.createElement("div") + newRow.className = "row mb-3" + newRow.id = `meta_${this.nextMetaIndex}` + newRow.appendChild(removeCol) + newRow.appendChild(nameCol) + newRow.appendChild(valueCol) + + document.getElementById("metaItems").appendChild(newRow) + this.nextMetaIndex++ + }, + + /** + * Remove a metadata item + * @param idx The index of the metadata item to remove + */ + removeMetaItem(idx) { + document.getElementById(`meta_${idx}`).remove() + }, + /** * Confirm and delete a category * @param id The ID of the category to be deleted diff --git a/src/MyWebLog/wwwroot/themes/bit-badger/bit-badger-auth.png b/src/MyWebLog/wwwroot/themes/bit-badger/bit-badger-auth.png new file mode 100644 index 0000000000000000000000000000000000000000..42c407cbbd1072aa37412613c41d38521916c77a GIT binary patch literal 23158 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