WIP on DotLiquid support

This commit is contained in:
2022-04-16 23:06:38 -04:00
parent 62f7896621
commit 98eb2b1785
78 changed files with 451 additions and 45 deletions

View File

@@ -0,0 +1,62 @@
namespace MyWebLog.Features.Admin
open Microsoft.AspNetCore.Authorization
open Microsoft.AspNetCore.Mvc
open Microsoft.AspNetCore.Mvc.Rendering
open MyWebLog
open MyWebLog.Features.Shared
open RethinkDb.Driver.Net
open System.Threading.Tasks
/// Controller for admin-specific displays and routes
[<Route "/admin">]
[<Authorize>]
type AdminController () =
inherit MyWebLogController ()
[<HttpGet "">]
member this.Index () = task {
let getCount (f : WebLogId -> IConnection -> Task<int>) = f this.WebLog.id this.Db
let! posts = Data.Post.countByStatus Published |> getCount
let! drafts = Data.Post.countByStatus Draft |> getCount
let! pages = Data.Page.countAll |> getCount
let! listed = Data.Page.countListed |> getCount
let! cats = Data.Category.countAll |> getCount
let! topCats = Data.Category.countTopLevel |> getCount
return this.View (DashboardModel (
this.WebLog,
Posts = posts,
Drafts = drafts,
Pages = pages,
ListedPages = listed,
Categories = cats,
TopLevelCategories = topCats
))
}
[<HttpGet "settings">]
member this.Settings() = task {
let! allPages = Data.Page.findAll this.WebLog.id this.Db
return this.View (SettingsModel (
this.WebLog,
DefaultPages =
(Seq.singleton (SelectListItem ("- {Resources.FirstPageOfPosts} -", "posts"))
|> Seq.append (allPages |> Seq.map (fun p -> SelectListItem (p.title, PageId.toString p.id))))
))
}
[<HttpPost "settings">]
member this.SaveSettings (model : SettingsModel) = task {
match! Data.WebLog.findByHost this.WebLog.urlBase this.Db with
| Some webLog ->
let updated = model.UpdateSettings webLog
do! Data.WebLog.updateSettings updated this.Db
// Update cache
WebLogCache.set (WebLogCache.hostToDb this.HttpContext) updated
// TODO: confirmation message
return this.RedirectToAction (nameof this.Index);
| None -> return this.NotFound ()
}

View File

@@ -0,0 +1,76 @@
namespace MyWebLog.Features.Admin
open MyWebLog
open MyWebLog.Features.Shared
/// The model used to display the dashboard
type DashboardModel (webLog) =
inherit MyWebLogModel (webLog)
/// The number of published posts
member val Posts = 0 with get, set
/// The number of post drafts
member val Drafts = 0 with get, set
/// The number of pages
member val Pages = 0 with get, set
/// The number of pages in the page list
member val ListedPages = 0 with get, set
/// The number of categories
member val Categories = 0 with get, set
/// The top-level categories
member val TopLevelCategories = 0 with get, set
open Microsoft.AspNetCore.Mvc.Rendering
open System.ComponentModel.DataAnnotations
/// View model for editing web log settings
type SettingsModel (webLog) =
inherit MyWebLogModel (webLog)
/// Default constructor
[<System.Obsolete "Only used for model binding; use the WebLogDetails constructor">]
new() = SettingsModel WebLog.empty
/// The name of the web log
[<Required (AllowEmptyStrings = false)>]
[<Display ( ResourceType = typeof<Resources>, Name = "Name")>]
member val Name = webLog.name with get, set
/// The subtitle of the web log
[<Display(ResourceType = typeof<Resources>, Name = "Subtitle")>]
member val Subtitle = (defaultArg webLog.subtitle "") with get, set
/// The default page
[<Required>]
[<Display(ResourceType = typeof<Resources>, Name = "DefaultPage")>]
member val DefaultPage = webLog.defaultPage with get, set
/// How many posts should appear on index pages
[<Required>]
[<Display(ResourceType = typeof<Resources>, Name = "PostsPerPage")>]
[<Range(0, 50)>]
member val PostsPerPage = webLog.postsPerPage with get, set
/// The time zone in which dates/times should be displayed
[<Required>]
[<Display(ResourceType = typeof<Resources>, Name = "TimeZone")>]
member val TimeZone = webLog.timeZone with get, set
/// Possible values for the default page
member val DefaultPages = Seq.empty<SelectListItem> with get, set
/// Update the settings object from the data in this form
member this.UpdateSettings (settings : WebLog) =
{ settings with
name = this.Name
subtitle = (match this.Subtitle with "" -> None | sub -> Some sub)
defaultPage = this.DefaultPage
postsPerPage = this.PostsPerPage
timeZone = this.TimeZone
}

View File

@@ -0,0 +1,61 @@
@model DashboardModel
@{
Layout = "_AdminLayout";
ViewBag.Title = Resources.Dashboard;
}
<article class="container pt-3">
<div class="row">
<section class="col-lg-5 offset-lg-1 col-xl-4 offset-xl-2 pb-3">
<div class="card">
<header class="card-header text-white bg-primary">@Resources.Posts</header>
<div class="card-body">
<h6 class="card-subtitle text-muted pb-3">
@Resources.Published <span class="badge rounded-pill bg-secondary">@Model.Posts</span>
&nbsp; @Resources.Drafts <span class="badge rounded-pill bg-secondary">@Model.Drafts</span>
</h6>
<a asp-action="All" asp-controller="Post" class="btn btn-secondary me-2">@Resources.ViewAll</a>
<a asp-action="Edit" asp-controller="Post" asp-route-id="new" class="btn btn-primary">
@Resources.WriteANewPost
</a>
</div>
</div>
</section>
<section class="col-lg-5 col-xl-4 pb-3">
<div class="card">
<header class="card-header text-white bg-primary">@Resources.Pages</header>
<div class="card-body">
<h6 class="card-subtitle text-muted pb-3">
@Resources.All <span class="badge rounded-pill bg-secondary">@Model.Pages</span>
&nbsp; @Resources.ShownInPageList <span class="badge rounded-pill bg-secondary">@Model.ListedPages</span>
</h6>
<a asp-action="All" asp-controller="Page" class="btn btn-secondary me-2">@Resources.ViewAll</a>
<a asp-action="Edit" asp-controller="Page" asp-route-id="new" class="btn btn-primary">
@Resources.CreateANewPage
</a>
</div>
</div>
</section>
</div>
<div class="row">
<section class="col-lg-5 offset-lg-1 col-xl-4 offset-xl-2 pb-3">
<div class="card">
<header class="card-header text-white bg-secondary">@Resources.Categories</header>
<div class="card-body">
<h6 class="card-subtitle text-muted pb-3">
@Resources.All <span class="badge rounded-pill bg-secondary">@Model.Categories</span>
&nbsp; @Resources.TopLevel <span class="badge rounded-pill bg-secondary">@Model.TopLevelCategories</span>
</h6>
<a asp-action="All" asp-controller="Category" class="btn btn-secondary me-2">@Resources.ViewAll</a>
<a asp-action="Edit" asp-controller="Category" asp-route-id="new" class="btn btn-secondary">
@Resources.AddANewCategory
</a>
</div>
</div>
</section>
</div>
<div class="row pb-3">
<div class="col text-end">
<a asp-action="Settings" class="btn btn-secondary">@Resources.ModifySettings</a>
</div>
</div>
</article>