V2 #1

Merged
danieljsummers merged 102 commits from v2 into main 2022-06-23 00:35:12 +00:00
6 changed files with 31 additions and 16 deletions
Showing only changes of commit c198d33ec0 - Show all commits

View File

@ -14,7 +14,7 @@
<PackageReference Include="Microsoft.FSharpLu.Json" Version="0.11.7" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="RethinkDb.Driver" Version="2.3.150" />
<PackageReference Include="RethinkDb.Driver.FSharp" Version="0.8.0-alpha-0003" />
<PackageReference Include="RethinkDb.Driver.FSharp" Version="0.8.0-alpha-0004" />
</ItemGroup>
<ItemGroup>

View File

@ -98,6 +98,8 @@ module private Helpers =
hash.Add ("current_page", ctx.Request.Path.Value.Substring 1)
hash.Add ("messages", messages)
do! ctx.Session.CommitAsync ()
// NOTE: DotLiquid does not support {% render %} or {% include %} in its templates, so we will do a two-pass
// render; the net effect is a "layout" capability similar to Razor or Pug
@ -107,6 +109,7 @@ module private Helpers =
// ...then render that content with its layout
let! layoutTemplate = TemplateCache.get theme "layout"
return! htmlString (layoutTemplate.Render hash) next ctx
}
@ -115,6 +118,12 @@ module private Helpers =
return! viewForTheme (deriveWebLogFromHash hash ctx).themePath template next ctx hash
}
/// Redirect after doing some action; commits session and issues a temporary redirect
let redirectToGet url : HttpHandler = fun next ctx -> task {
do! ctx.Session.CommitAsync ()
return! redirectTo false url next ctx
}
/// Get the web log ID for the current request
let webLogId ctx = (WebLogCache.get ctx).id
@ -233,7 +242,7 @@ module Admin =
WebLogCache.set ctx updated
do! addMessage ctx { UserMessage.success with message = "Web log settings saved successfully" }
return! redirectTo false "/admin" next ctx
return! redirectToGet "/admin" next ctx
| None -> return! Error.notFound next ctx
}
@ -318,7 +327,7 @@ module Page =
do! (match model.pageId with "new" -> Data.Page.add | _ -> Data.Page.update) page conn
if updateList then do! PageListCache.update ctx
do! addMessage ctx { UserMessage.success with message = "Page saved successfully" }
return! redirectTo false $"/page/{PageId.toString page.id}/edit" next ctx
return! redirectToGet $"/page/{PageId.toString page.id}/edit" next ctx
| None -> return! Error.notFound next ctx
}
@ -428,7 +437,7 @@ module User =
message = "Logged on successfully"
detail = Some $"Welcome to {webLog.name}!"
}
return! redirectTo false "/admin" next ctx
return! redirectToGet "/admin" next ctx
| _ ->
do! addMessage ctx { UserMessage.error with message = "Log on attempt unsuccessful" }
return! logOn next ctx
@ -438,7 +447,7 @@ module User =
let logOff : HttpHandler = fun next ctx -> task {
do! ctx.SignOutAsync CookieAuthenticationDefaults.AuthenticationScheme
do! addMessage ctx { UserMessage.info with message = "Log off successful" }
return! redirectTo false "/" next ctx
return! redirectToGet "/" next ctx
}

View File

@ -16,7 +16,7 @@
<ItemGroup>
<PackageReference Include="DotLiquid" Version="2.2.610" />
<PackageReference Include="Giraffe" Version="6.0.0" />
<PackageReference Include="RethinkDB.DistributedCache" Version="0.9.0-alpha02" />
<PackageReference Include="RethinkDB.DistributedCache" Version="0.9.0-alpha03" />
</ItemGroup>
<ItemGroup>

View File

@ -164,7 +164,6 @@ let main args =
let _ = builder.Services.AddLogging ()
let _ = builder.Services.AddAuthorization ()
let _ = builder.Services.AddAntiforgery ()
let _ = builder.Services.AddGiraffe ()
// Configure RethinkDB's connection
JsonConverters.all () |> Seq.iter Converter.Serializer.Converters.Add
@ -180,14 +179,17 @@ let main args =
} |> Async.AwaitTask |> Async.RunSynchronously
let _ = builder.Services.AddSingleton<IConnection> conn
let _ = builder.Services.AddDistributedRethinkDBCache (fun opts ->
opts.Database <- rethinkCfg.Database
opts.Connection <- conn)
// let _ = builder.Services.AddDistributedRethinkDBCache (fun opts ->
// opts.Connection <- conn)
let _ = builder.Services.AddDistributedMemoryCache ()
let _ = builder.Services.AddSession(fun opts ->
opts.IdleTimeout <- TimeSpan.FromMinutes 30
opts.Cookie.HttpOnly <- true
opts.Cookie.IsEssential <- true)
// this needs to be after the session... maybe?
let _ = builder.Services.AddGiraffe ()
// Set up DotLiquid
Template.RegisterFilter typeof<DotLiquidBespoke.NavLinkFilter>
Template.RegisterTag<DotLiquidBespoke.UserLinksTag> "user_links"

View File

@ -1,24 +1,28 @@
<h2 class="my-3">{{ page_title }}</h2>
<article class="container">
<a href="/page/new/edit" class="btn btn-primary btn-sm my-3">Create a New Page</a>
<table class="table table-sm table-striped table-hover">
<a href="/page/new/edit" class="btn btn-primary btn-sm mb-3">Create a New Page</a>
<table class="table table-sm table-hover">
<thead>
<tr>
<th scope="col">Actions</th>
<th scope="col">Title</th>
<th scope="col">In List?</th>
<th scope="col">Last Updated</th>
</tr>
</thead>
<tbody>
{% for pg in pages -%}
<tr>
<td><a href="/page/{{ pg.id }}/edit">Edit</a></td>
<td>
{{ pg.title }}
{%- if pg.is_default %} &nbsp; <span class="badge bg-success">HOME PAGE</span>{% endif -%}
{%- if pg.show_in_page_list %} &nbsp; <span class="badge bg-primary">IN PAGE LIST</span> {% endif -%}<br>
<small>
<a href="/{% unless pg.is_default %}{{ pg.permalink }}{% endunless %}" target="_blank">View Page</a>
<span class="text-muted"> &bull; </span>
<a href="/page/{{ pg.id }}/edit">Edit Page</a>
<span class="text-muted"> &bull; </span>
<a href="#" class="text-danger">Delete Page</a>
</small>
</td>
<td>{% if pg.show_in_page_list %} Yes {% else %} No {% endif %}</td>
<td>{{ pg.updated_on | date: "MMMM d, yyyy" }}</td>
</tr>
{%- endfor %}