v2.0.8 (#16)
- Embed htmx library to `Giraffe.Htmx.Common`, add links to load package-provided script - Update CDN links for v2.0.8 - Add .NET 10 support Reviewed-on: #16
This commit was merged in pull request #16.
This commit is contained in:
@@ -14,6 +14,8 @@ htmx uses attributes and HTTP headers to attain its interactivity; the libraries
|
||||
|---|---|
|
||||
|[](https://www.nuget.org/packages/Giraffe.Htmx/)|[](https://www.nuget.org/packages/Giraffe.ViewEngine.Htmx/)|
|
||||
|
||||
Both of these packages will also install `Giraffe.Htmx.Common`, which has some common definitions and provides a local-to-your-project version of the htmx JavaScript _(as of v2.0.8)_.
|
||||
|
||||
## Server Side (`Giraffe.Htmx`)
|
||||
|
||||
In addition to the regular HTTP request payloads, htmx sets [one or more headers](https://htmx.org/docs/#request_headers) along with the request. Once `Giraffe.Htmx` is opened, these are available as properties on `HttpContext.Request.Headers`. These consist of the header name, translated to a .NET name (ex. `HX-Current-URL` becomes `HxCurrentUrl`), and a strongly-typed property based on the expected value of that header. Additionally, they are all exposed as `Option`s, as they may or may not be present for any given request.
|
||||
@@ -42,6 +44,8 @@ let theHandler : HttpHandler =
|
||||
|
||||
Of note is that the `HX-Trigger` headers can take either one or more events. For a single event with no parameters, use `withHxTrigger`; for a single event with parameters, or multiple events, use `withHxTriggerMany`. Both these have `AfterSettle` and `AfterSwap` versions as well.
|
||||
|
||||
`HtmxScript.local` provides an `HtmlString` with a script tag to load the package-provided htmx library. This can be used in code, Razor templates, etc. (If you're using Giraffe.ViewEngine, see below.)
|
||||
|
||||
## View Engine (`Giraffe.ViewEngine.Htmx`)
|
||||
|
||||
As htmx uses [attributes](https://htmx.org/docs/#attributes) to extend HTML, the primary part of this library defines attributes that can be used within Giraffe views. Simply open `Giraffe.ViewEngine.Htmx`, and these attributes, along with support modules, will be visible.
|
||||
@@ -66,7 +70,7 @@ let shiftClick =
|
||||
]
|
||||
```
|
||||
|
||||
If you want to load htmx from unpkg, `Htmx.Script.minified` or `Htmx.Script.unminified` can be used to load the script in your HTML trees.
|
||||
If you want to use the package-provided htmx library, `Htmx.Script.local` will create the `script` tag for you. To load htmx from jsDelivr, `Htmx.Script.cdnMinified` or `Htmx.Script.cdnUnminified` can be used to load the script in your HTML trees. In this case, if you are using a Content Security Policy (CSP) header, `cdn.jsdelivr.net` will need to be added to the `script-src` list.
|
||||
|
||||
## Feedback / Help
|
||||
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
[<AutoOpen>]
|
||||
module Giraffe.Htmx.Common
|
||||
|
||||
/// <summary>The version of htmx embedded in the package</summary>
|
||||
let HtmxVersion = "2.0.8"
|
||||
|
||||
/// <summary>The path for the provided htmx script</summary>
|
||||
let internal htmxLocalScript = $"/_content/Giraffe.Htmx.Common/htmx.min.js?ver={HtmxVersion}"
|
||||
|
||||
/// <summary>Serialize a list of key/value pairs to JSON (very rudimentary)</summary>
|
||||
/// <param name="pairs">The key/value pairs to be serialized to JSON</param>
|
||||
/// <returns>A string with the key/value pairs serialized to JSON</returns>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Giraffe.Htmx.Common
|
||||
|
||||
This package contains common code shared between [`Giraffe.Htmx`](https://www.nuget.org/packages/Giraffe.Htmx) and [`Giraffe.ViewEngine.Htmx`](https://www.nuget.org/packages/Giraffe.ViewEngine.Htmx), and will be automatically installed when you install either one.
|
||||
This package contains common code shared between [`Giraffe.Htmx`](https://www.nuget.org/packages/Giraffe.Htmx) and [`Giraffe.ViewEngine.Htmx`](https://www.nuget.org/packages/Giraffe.ViewEngine.Htmx), and will be automatically installed when you install either one. It also contains htmx as a static web asset, allowing it to be loaded from your local (or published) project.
|
||||
|
||||
**htmx version: 2.0.6**
|
||||
**htmx version: 2.0.8**
|
||||
|
||||
1
src/Common/wwwroot/htmx.min.js
vendored
Normal file
1
src/Common/wwwroot/htmx.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,15 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<VersionPrefix>2.0.6</VersionPrefix>
|
||||
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
|
||||
<VersionPrefix>2.0.8</VersionPrefix>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageReleaseNotes>- All packages now have full XML documentation
|
||||
- Adds HxSync module and attribute helper to view engine
|
||||
- Updates script tags to pull htmx 2.0.6 (no header or attribute changes)
|
||||
- Drops .NET 6 support
|
||||
<PackageReleaseNotes>- Adds package-provided script (available via Giraffe.Htmx.Common); use app.MapStaticAssets() for publish support, use builder.UseStaticWebAssets() for non-development/non-published execution
|
||||
- [View Engine] Deprecates Script.minified and Script.unminified (use Script.cdnMinified and Script.cdnUnminified instead)
|
||||
- Updates script tags to pull htmx 2.0.8 (no header or attribute changes)
|
||||
- Adds .NET 10 support
|
||||
|
||||
NOTE: The CDN for htmx changed from unpkg.com to cdn.jsdelivr.net; sites with Content-Security-Policy headers will want to update their allowed domains accordingly
|
||||
See full release notes, including more info about the package-provided script, at https://git.bitbadger.solutions/bit-badger/Giraffe.Htmx/releases/tag/v2.0.8
|
||||
|
||||
NOTE: As of 2.0.6, the CDN for htmx changed from unpkg.com to cdn.jsdelivr.net; sites with Content-Security-Policy headers will want to update their allowed script-src domains accordingly
|
||||
</PackageReleaseNotes>
|
||||
<Authors>danieljsummers</Authors>
|
||||
<Company>Bit Badger Solutions</Company>
|
||||
|
||||
@@ -170,3 +170,15 @@ module Handlers =
|
||||
/// <seealso href="https://htmx.org/headers/hx-trigger/">Documentation</seealso>
|
||||
let withHxTriggerManyAfterSwap evts : HttpHandler =
|
||||
toJson evts |> setHttpHeader "HX-Trigger-After-Swap"
|
||||
|
||||
|
||||
/// <summary>Load the package-provided version of the htmx script</summary>
|
||||
[<RequireQualifiedAccess>]
|
||||
module HtmxScript =
|
||||
|
||||
open Giraffe.Htmx.Common
|
||||
open Microsoft.AspNetCore.Html
|
||||
|
||||
/// <summary><c>script</c> tag to load the package-provided version of the htmx script</summary>
|
||||
let local = HtmlString $"""<script src="{htmxLocalScript}"></script>"""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This package enables server-side support for [htmx](https://htmx.org) within [Giraffe](https://giraffe.wiki) and ASP.NET's `HttpContext`.
|
||||
|
||||
**htmx version: 2.0.6**
|
||||
**htmx version: 2.0.8**
|
||||
|
||||
_Upgrading from v1.x: the [migration guide](https://htmx.org/migration-guide-htmx-1/) does not currently specify any request or response header changes. This means that there are no required code changes in moving from v1.* to v2.*._
|
||||
|
||||
@@ -34,6 +34,8 @@ let myHandler : HttpHander =
|
||||
|
||||
The `HxSwap` module has constants to use for the `HX-Reswap` header. These may be extended with settle, show, and other qualifiers; see the htmx documentation for the `hx-swap` attribute for more information.
|
||||
|
||||
To load the package-provided htmx library without using Giraffe.ViewEngine, use `HtmxScript.local`.
|
||||
|
||||
### Learn
|
||||
|
||||
The naming conventions of this library were selected to mirror those provided by htmx. The header properties become `Hx*` on the `ctx.Request.Headers` object, and the response handlers are `withHx*` based on the header being set. The only part that does not line up is `withHxTrigger*` and `withHxTriggerMany`; the former set work with a single string (to trigger a single event with no arguments), while the latter set supports both arguments and multiple events.
|
||||
@@ -3,6 +3,12 @@ module Common
|
||||
open Expecto
|
||||
open Giraffe.Htmx
|
||||
|
||||
/// Test to ensure the version was updated
|
||||
let version =
|
||||
test "HtmxVersion is correct" {
|
||||
Expect.equal HtmxVersion "2.0.8" "htmx version incorrect"
|
||||
}
|
||||
|
||||
/// Tests for the HxSwap module
|
||||
let swap =
|
||||
testList "HxSwap" [
|
||||
@@ -30,4 +36,4 @@ let swap =
|
||||
]
|
||||
|
||||
/// All tests for this module
|
||||
let allTests = testList "Htmx.Common" [ swap ]
|
||||
let allTests = testList "Htmx.Common" [ version; swap ]
|
||||
|
||||
@@ -3,6 +3,7 @@ module Htmx
|
||||
open System
|
||||
open Expecto
|
||||
open Giraffe.Htmx
|
||||
open Microsoft.AspNetCore.Html
|
||||
open Microsoft.AspNetCore.Http
|
||||
open NSubstitute
|
||||
|
||||
@@ -354,5 +355,16 @@ let handlers =
|
||||
}
|
||||
]
|
||||
|
||||
/// Tests for the HtmxScript module
|
||||
let script =
|
||||
testList "HtmxScript" [
|
||||
test "local generates correct link" {
|
||||
Expect.equal
|
||||
(string HtmxScript.local)
|
||||
$"""<script src="/_content/Giraffe.Htmx.Common/htmx.min.js?ver={HtmxVersion}"></script>"""
|
||||
"htmx script link is incorrect"
|
||||
}
|
||||
]
|
||||
|
||||
/// All tests for this module
|
||||
let allTests = testList "Htmx" [ dictExtensions; reqExtensions; handlers ]
|
||||
let allTests = testList "Htmx" [ dictExtensions; reqExtensions; handlers; script ]
|
||||
|
||||
@@ -842,22 +842,31 @@ let attributes =
|
||||
}
|
||||
]
|
||||
|
||||
open Giraffe.Htmx.Common
|
||||
|
||||
/// Tests for the Script module
|
||||
let script =
|
||||
testList "Script" [
|
||||
test "minified succeeds" {
|
||||
let html = RenderView.AsString.htmlNode Script.minified
|
||||
test "local succeeds" {
|
||||
let html = RenderView.AsString.htmlNode Script.local
|
||||
Expect.equal
|
||||
html
|
||||
"""<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js" integrity="sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm" crossorigin="anonymous"></script>"""
|
||||
"Minified script tag is incorrect"
|
||||
$"""<script src="/_content/Giraffe.Htmx.Common/htmx.min.js?ver={HtmxVersion}"></script>"""
|
||||
"Local script tag is incorrect"
|
||||
}
|
||||
test "unminified succeeds" {
|
||||
let html = RenderView.AsString.htmlNode Script.unminified
|
||||
test "cdnMinified succeeds" {
|
||||
let html = RenderView.AsString.htmlNode Script.cdnMinified
|
||||
Expect.equal
|
||||
html
|
||||
"""<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.js" integrity="sha384-ksKjJrwjL5VxqAkAZAVOPXvMkwAykMaNYegdixAESVr+KqLkKE8XBDoZuwyWVUDv" crossorigin="anonymous"></script>"""
|
||||
"Unminified script tag is incorrect"
|
||||
$"""<script src="https://cdn.jsdelivr.net/npm/htmx.org@{HtmxVersion}/dist/htmx.min.js" integrity="sha256-Iig+9oy3VFkU8KiKG97cclanA9HVgMHSVSF9ClDTExM=" crossorigin="anonymous"></script>"""
|
||||
"CDN minified script tag is incorrect"
|
||||
}
|
||||
test "cdnUnminified succeeds" {
|
||||
let html = RenderView.AsString.htmlNode Script.cdnUnminified
|
||||
Expect.equal
|
||||
html
|
||||
$"""<script src="https://cdn.jsdelivr.net/npm/htmx.org@{HtmxVersion}/dist/htmx.js" integrity="sha256-upUwYnay6R+DA68rROTAP+EdfO3NvOqtE513PgDyAYM=" crossorigin="anonymous"></script>"""
|
||||
"CDN unminified script tag is incorrect"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -788,18 +788,33 @@ module HtmxAttrs =
|
||||
/// <summary>Script tags to pull htmx into a web page</summary>
|
||||
module Script =
|
||||
|
||||
/// <summary>Script tag to load the minified version from unpkg.com</summary>
|
||||
let minified =
|
||||
script [ _src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js"
|
||||
_integrity "sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm"
|
||||
open System
|
||||
|
||||
/// <summary>Script tag to load the package-provided version of htmx</summary>
|
||||
let local = script [ _src htmxLocalScript ] []
|
||||
|
||||
/// <summary>Script tag to load the minified version from jsdelivr.net</summary>
|
||||
/// <remarks>Ensure <c>cdn.jsdelivr.net</c> is in your CSP <c>script-src</c> list (if applicable)</remarks>
|
||||
let cdnMinified =
|
||||
script [ _src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"
|
||||
_integrity "sha256-Iig+9oy3VFkU8KiKG97cclanA9HVgMHSVSF9ClDTExM="
|
||||
_crossorigin "anonymous" ] []
|
||||
|
||||
/// <summary>Script tag to load the unminified version from unpkg.com</summary>
|
||||
let unminified =
|
||||
script [ _src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.js"
|
||||
_integrity "sha384-ksKjJrwjL5VxqAkAZAVOPXvMkwAykMaNYegdixAESVr+KqLkKE8XBDoZuwyWVUDv"
|
||||
/// <summary>Script tag to load the unminified version from jsdelivr.net</summary>
|
||||
/// <remarks>Ensure <c>cdn.jsdelivr.net</c> is in your CSP <c>script-src</c> list (if applicable)</remarks>
|
||||
let cdnUnminified =
|
||||
script [ _src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.js"
|
||||
_integrity "sha256-upUwYnay6R+DA68rROTAP+EdfO3NvOqtE513PgDyAYM="
|
||||
_crossorigin "anonymous" ] []
|
||||
|
||||
/// <summary>Script tag to load the minified version from jsdelivr.net</summary>
|
||||
[<Obsolete "Use cdnMinified instead; this will be removed in v4">]
|
||||
let minified = cdnMinified
|
||||
|
||||
/// <summary>Script tag to load the unminified version from jsdelivr.net</summary>
|
||||
[<Obsolete "Use cdnUnminified instead; this will be removed in v4">]
|
||||
let unminified = cdnUnminified
|
||||
|
||||
|
||||
/// <summary>Functions to extract and render an HTML fragment from a document</summary>
|
||||
[<RequireQualifiedAccess>]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This package enables [htmx](https://htmx.org) support within the [Giraffe](https://giraffe.wiki) view engine.
|
||||
|
||||
**htmx version: 2.0.6**
|
||||
**htmx version: 2.0.8**
|
||||
|
||||
_Upgrading from v1.x: see [the migration guide](https://htmx.org/migration-guide-htmx-1/) for changes_
|
||||
|
||||
@@ -29,7 +29,7 @@ Support modules include:
|
||||
- `HxTrigger`
|
||||
- `HxVals`
|
||||
|
||||
There are two `XmlNode`s that will load the htmx script from jsdelivr; `Htmx.Script.minified` loads the minified version, and `Htmx.Script.unminified` loads the unminified version (useful for debugging).
|
||||
`Htmx.Script.local` creates an `XmlNode` to load the package-provided htmx library. There are also two `XmlNode`s that will load the htmx script from jsdelivr; `Htmx.Script.cdnMinified` loads the minified version, and `Htmx.Script.cdnUnminified` loads the unminified version (useful for debugging). When using the CDN nodes and a Content Security Policy (CSP) header, `cdn.jsdelivr.net` needs to be listed as an allowable `script-src`.
|
||||
|
||||
This also supports [fragment rendering](https://bitbadger.solutions/blog/2022/fragment-rendering-in-giraffe-view-engine.html), providing the flexibility to render an entire template, or only a portion of it (based on the element's `id` attribute).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user