import Foundation import Hummingbird import Infrastructure /// Serves the website's root routes. /// /// The controller exposes its routes through its `RouterController` conformance, so the application that composes it registers them declaratively: /// /// ```swift /// router.addController { /// RootController() /// } /// ``` /// /// - Note: `Context` is the request context the routes are resolved against, and must match the context of the router the routes are added to. public struct RootController { // MARK: Properties /// The landing page, rendered once per supported language and reused for every request. private let responses: LocalizedHTMLCollectionResponse // MARK: Initializers /// Creates a root controller. /// - Parameter assetVersion: the version token appended to the page's asset URLs, or `nil` (the default) to leave them unversioned. public init( assetVersion: String? = nil ) { self.responses = .init(bundle: .module) { IndexPage( locale: $0, assetVersion: assetVersion ) } } } // MARK: - RouteController extension RootController: RouterController { // MARK: Properties public var routes: RouteCollection { let routes = RouteCollection(context: Context.self) routes.get( .Root.index, use: index ) return routes } } // MARK: - Helpers private extension RootController { // MARK: Methods /// Handles a request for the landing page. /// /// Renders the ``IndexPage`` in the language stored on the context by ``LocalizationMiddleware``, falling back to the default language. /// - Parameters: /// - request: the incoming request. /// - context: the context the request is resolved against. /// - Returns: the cached ``IndexPage`` response for the context's language. @Sendable func index( request: Request, context: Context ) -> Response { responses.response( for: context.language, request: request ) } } // MARK: - Constants private extension RouterPath { /// A namespace for the ``RootController`` route paths. enum Root { /// The path of the landing page. static let index: RouterPath = "/" } }