This commit contains the latest updates from the generic Website template, which move the toolchain to Swift 6.4, gate analytics and structured data behind traits, and rework page routing: - Updated the Swift toolchain for all the package dependencies and the Website service to version 6.4. (345b305) - Adapted all the existing middlewares in the Infrastructure package to Swift 6.4. (26008df) - Moved test resource teardown in the Persistence and the Website library into defer blocks. (27984a9) - Gated analytics behind a trait and reworked structured data in the Infrastructure package. (c7d4769) - Enabled the Analytics trait in the Website service. (f6a6bbd) - Reworked page routing in the Website service. (d1cb2c1) - Gated the structured data features in the Infrastructure package behind a trait. (f0a8791) - Enabled the StructuredData trait of the Infrastructure package in the Website service. (bbfdeb3) - Fixed the asset pin and a build warning in the Dockerfile of the Website service. (6ed0f9b) The root README change in 345b305 was left out, as this project no longer carries that file. From d1cb2c1, the RootController rework was left out, as the prototype serves a session-aware landing page and routes its other pages through their own controllers; the view-event reporter was appended to the prototype's shared script instead. The prototype code was adapted to the stricter Swift 6.4 settings: `String(format:)` was swapped for safe formatting, the NoIndex middleware takes a `@concurrent` next handler, and the tests flagged by warnings-as-errors were tightened. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
132 lines
3.4 KiB
Swift
132 lines
3.4 KiB
Swift
import Elementary
|
|
import Foundation
|
|
import Infrastructure
|
|
|
|
/// A ``Page`` with fixed content, metadata, and stub assets.
|
|
struct StubPage: Page {
|
|
|
|
// MARK: Properties
|
|
|
|
#if Analytics
|
|
/// The analytics tracker rendered as a deferred script in the document head, or `nil` to omit it.
|
|
var analytics: Analytics? = nil
|
|
#endif
|
|
|
|
/// The version token appended to the page's asset URLs, or `nil` to leave them unversioned.
|
|
let assetVersion: String?
|
|
|
|
/// The canonical URL rendered in the document head, or `nil` to omit it.
|
|
let canonicalURL: String?
|
|
|
|
/// The locale the page content is localized to.
|
|
let locale: Locale
|
|
|
|
/// The card rendered as link-preview tags in the document head, or `nil` to omit them.
|
|
let socialCard: SocialCard?
|
|
|
|
#if StructuredData
|
|
/// The structured data rendered as a JSON-LD script in the document head, or `nil` to omit it.
|
|
var structuredData: StructuredData? = nil
|
|
#endif
|
|
|
|
/// The summary rendered in the document head, or `nil` to omit it.
|
|
let summary: String?
|
|
|
|
// MARK: Initializers
|
|
|
|
/// Creates a stub page.
|
|
/// - Parameters:
|
|
/// - locale: the locale the page content is localized to. Defaults to `en`.
|
|
/// - assetVersion: the version token appended to the page's asset URLs, or `nil` (the
|
|
/// default) to leave them unversioned.
|
|
/// - canonicalURL: the canonical URL rendered in the document head, or `nil` (the default)
|
|
/// to omit it.
|
|
/// - socialCard: the card rendered as link-preview tags in the document head, or `nil`
|
|
/// (the default) to omit them.
|
|
/// - summary: the summary rendered in the document head, or `nil` (the default)
|
|
/// to omit it.
|
|
init(
|
|
locale: Locale = .init(identifier: "en"),
|
|
assetVersion: String? = nil,
|
|
canonicalURL: String? = nil,
|
|
socialCard: SocialCard? = nil,
|
|
summary: String? = nil
|
|
) {
|
|
self.assetVersion = assetVersion
|
|
self.canonicalURL = canonicalURL
|
|
self.locale = locale
|
|
self.socialCard = socialCard
|
|
self.summary = summary
|
|
}
|
|
|
|
// MARK: Computed
|
|
|
|
var content: some HTML {
|
|
p { "Stub content" }
|
|
}
|
|
|
|
var lang: String {
|
|
locale.language.languageCode?.identifier ?? "en"
|
|
}
|
|
|
|
var metadata: some HTML {
|
|
meta(
|
|
.name("stub"),
|
|
.content("marker")
|
|
)
|
|
}
|
|
|
|
var scripts: [any Asset] {
|
|
[StubAsset(
|
|
fileExtensions: [.css, .js],
|
|
fileName: "stub"
|
|
)]
|
|
}
|
|
|
|
var stylesheets: [any Asset] {
|
|
[StubAsset(
|
|
fileExtensions: [.css, .js],
|
|
fileName: "stub"
|
|
)]
|
|
}
|
|
|
|
var title: String {
|
|
"Stub Page"
|
|
}
|
|
|
|
}
|
|
|
|
#if Analytics
|
|
// MARK: - Analytics
|
|
|
|
extension StubPage {
|
|
|
|
// MARK: Initializers
|
|
|
|
/// Creates a stub page embedding the given analytics tracker.
|
|
/// - Parameter analytics: the analytics tracker rendered as a deferred script in the document head.
|
|
init(analytics: Analytics) {
|
|
self.init()
|
|
self.analytics = analytics
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
#if StructuredData
|
|
// MARK: - Structured data
|
|
|
|
extension StubPage {
|
|
|
|
// MARK: Initializers
|
|
|
|
/// Creates a stub page with the given structured data.
|
|
/// - Parameter structuredData: the structured data to render.
|
|
init(structuredData: StructuredData) {
|
|
self.init()
|
|
self.structuredData = structuredData
|
|
}
|
|
|
|
}
|
|
#endif
|