Commit Graph
6 Commits
Author SHA1 Message Date
javier 6c66ea74cc Localization support for the Website service (#10)
This PR contains the work done to introduce server-side localization support to the **Website** service so the landing and error pages are served in the visitor's negotiated language, backed by a new reusable Localization package.

To provide further details about the work:

* Created the _Localization_ package — a bundle-bound `Localize` method and a `LanguageList` type.
* Language negotiation — `NegotiateLanguage` method picks the best supported language from the request's _Accept-Language_ header (falling back to the default); the `LocalizationMiddleware` middleware resolves it per request and stores it on a new `LocalizedRequestContext` / `WebsiteRequestContext` context.
* Localized responses — `LocalizedHTMLCollectionResponse` pre-renders each page once per language and caches the bytes (with `Content-Language` + `Vary: Accept-Language`), reused by the  `RootController` controller and `NotFoundMiddleware` middleware.
* The `CachedHTMLResponse` response gained custom-header support.
* Localized pages — the `IndexPage` and `ErrorPage` pages now resolve their strings via `Localize` method;
* Added `Localizable.xcstrings` catalogs.
* Wired the `LocalizationMiddleware` middlewaer into the router.

Reviewed-on: rock-n-code/loud-amsterdam#10
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-06-29 23:08:36 +00:00
javier 7c18cd9ec0 Response compression for the Website service (#7)
This PR contains the work done to add response compression to the Website service by registering the `ResponseCompressionMiddleware` middleware so responses are compressed when the client advertises support and the body exceeds a minimum size.

To provide further details about the work done:

* Added the **HummingbirdCompression** package dependency.
* Integrated the `ResponseCompressionMiddleware` middleware into the router, ahead of the not-found and static file middleware.
* Made the `minimum-response-size-to-compress` threshold configurable, with a default.

Reviewed-on: rock-n-code/loud-amsterdam#7
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-06-28 06:15:05 +00:00
javier a621ada0bf HTML rendering support for the Website service (#5)
This PR contains the work done to replace the use of static _HTML_ files with type-safe HTML rendered server-side via **Elementary** through **Hummingbird**.

To provide further details about the work done:

* Added the **Elementary** dependencies.
* Added the `IndexPage` and `ErrorPage` pages, ported from the old HTML boilerplate; removed the static files.
* Added the `RootController` controller serving GET / using the `IndexPage` page, wired into the router.
* Reworked the `NotFoundMiddleware` middleare to render `ErrorPage` page directly; non-notFound errors still propagate.
* the `FileMiddleware` middleware no longer searches for any static `index.html` file.
* Simplified the `StaticFile` enumeration, dropped unused constants and now-unnecessary throws.

Reviewed-on: rock-n-code/loud-amsterdam#5
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-06-28 05:07:19 +00:00
javier f5f14eb97c File not found middleware for the Website service (#4)
This PR contains the work done to add a `NotFoundMiddleware` middleware to the Website service so requests matching neither a route nor a static file return a custom 404.html page with a 404 Not Found status. Also enables index.html fallback so the landing page is served at the site root.

To provider further details about the work done:
* NotFoundMiddleware — intercepts the `.notFound` error from the  `FileMiddleware` middleware and serves the preloaded error page with the correct content type; all other errors propagate. Falls back to a minimal body if the file is missing.
* Router — wires the `NotFoundMiddleware` middleware ahead of the `FileMiddleware` and enables searchForIndexHtml.
* Package — adds the **Hummingbird** product to the Library target.
* Tooling — sets a custom working directory in the Xcode scheme; removes the unused `pkg-deps` target from the `Makefile` file.

Reviewed-on: rock-n-code/loud-amsterdam#4
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-06-27 12:16:50 +00:00
javier 7542bc595f Static file serving support for the Website service (#3)
This PR contains the work done to support the static files serving for the **Website** service, and also included the essential boilerplate assets from the **HTML5 boilerplate** project.

To provide further details about the work done:

* Serving: Added the `FileMiddleware` middlewqare to the router; `path`, `server name`, and `log level` now read from config with defaults.
* Library: Added the `StaticFile` enumeration with a `contentType` property, plus typed config-key/value constants and the `Configuration` dependency on WebsiteCore.
* Assets: Added the **HTML5 boilerplate** (HTML, CSS, JS, icons, manifest, robots) to the *Resources/Static* folder.
* Docker: Stage the Resources directory as read-only.
* Tests: Added a test plan, and a shared Xcode scheme.

Reviewed-on: rock-n-code/loud-amsterdam#3
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-06-27 10:59:32 +00:00
javier 08b210e7c6 Website service target setup (#2)
This PR contains the work done to add and setup the *Website* service target, a **Hummingbird** server app, into the Xcode project as a SwiftPM package with full support for containerization and driven by a `Makefile` file.

To provide further details about the work done:

* Swift package — SwiftPM manifest with a Website executable, related library, and test targets; depends on **hummingbird** and **swift-configuration**.
* Containerization — Multi-stage `Dockerfile` producing a static-linked release build with jemalloc, running as a non-root user on port 8080. Production and local-dev `docker-compose` files included.
* Configuration — `.env.local` template (with `.env` git-ignored) and `.dockerignore`/`.gitignore` entries.
* Makefile — Self-documenting operational commands:
  * pkg — SwiftPM: _build, release, test, clean, reset, deps, outdated, update_
  * img — Docker lifecycle: _build, mount, unmount, release_

Notes

* New service only — no changes to existing code; nothing else in the repo is affected.
* App logic is currently scaffolding; this PR establishes the service structure, build, and deployment tooling.

Reviewed-on: rock-n-code/loud-amsterdam#2
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-06-27 02:26:33 +00:00