From 187d45478615e64dbe91540bbe16df0d21f50198 Mon Sep 17 00:00:00 2001 From: Dvonderstueck Date: Wed, 3 Jul 2024 13:01:47 +0200 Subject: [PATCH 1/5] the content of the page switches if there is a hx request header (still using two different .ft. I want to change this) --- .../grandcentrix/backend/plugins/Routing.kt | 13 +++++++------ .../grandcentrix/backend/plugins/StatusPage.kt | 13 +++++++------ .../grandcentrix/backend/plugins/Templating.kt | 18 ++++++++++++++++++ src/main/resources/templates/errorttt.ftl | 6 ++++++ 4 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/templates/errorttt.ftl diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt index 8f02e3e..a2f6fbb 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt @@ -18,6 +18,7 @@ import net.grandcentrix.backend.repository.HousesRepository.Companion.HousesRepo import net.grandcentrix.backend.repository.MoviesRepository.Companion.MoviesRepositoryInstance import net.grandcentrix.backend.repository.PotionsRepository.Companion.PotionsRepositoryInstance import net.grandcentrix.backend.repository.SpellsRepository.Companion.SpellsRepositoryInstance +import respondTemplates fun Application.configureRouting() { @@ -114,7 +115,7 @@ fun Application.configureRouting() { get("/books") { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplate( + call.respondTemplates( "books.ftl", mapOf( "books" to BooksRepositoryInstance.getAll(), @@ -129,7 +130,7 @@ fun Application.configureRouting() { get("/houses") { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplate( + call.respondTemplates( "houses.ftl", mapOf( "houses" to HousesRepositoryInstance.getAll(), @@ -144,7 +145,7 @@ fun Application.configureRouting() { get("/characters") { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplate( + call.respondTemplates( "characters.ftl", mapOf( "characters" to CharactersRepositoryInstance.getAll(), @@ -160,7 +161,7 @@ fun Application.configureRouting() { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplate( + call.respondTemplates( "movies.ftl", mapOf( "movies" to MoviesRepositoryInstance.getAll(), @@ -176,7 +177,7 @@ fun Application.configureRouting() { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplate( + call.respondTemplates( "potions.ftl", mapOf( "potions" to PotionsRepositoryInstance.getAll(), @@ -192,7 +193,7 @@ fun Application.configureRouting() { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplate( + call.respondTemplates( "spells.ftl", mapOf( "spells" to SpellsRepositoryInstance.getAll(), diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt index 948a8da..bae3291 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt @@ -10,6 +10,7 @@ import io.ktor.server.routing.* import io.ktor.server.sessions.* import net.grandcentrix.backend.controllers.UserSession import net.grandcentrix.backend.controllers.getProfilePicture +import respondTemplates fun Application.configureStatusPage() { routing { @@ -21,7 +22,7 @@ fun Application.configureStatusPage() { when (cause) { is RequestException -> { val userSession: UserSession? = call.sessions.get() - call.respondTemplate( + call.respondTemplates( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -36,7 +37,7 @@ fun Application.configureStatusPage() { is DAOException -> { val userSession = call.sessions.get() - call.respondTemplate( + call.respondTemplates( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -62,7 +63,7 @@ fun Application.configureStatusPage() { is UserAlreadyExistsException -> { val userSession: UserSession? = call.sessions.get() - call.respondTemplate( + call.respondTemplates( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -79,7 +80,7 @@ fun Application.configureStatusPage() { else -> { val userSession = call.sessions.get() - call.respondTemplate( + call.respondTemplates( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -94,7 +95,7 @@ fun Application.configureStatusPage() { status(HttpStatusCode.NotFound) { call, _ -> val userSession: UserSession? = call.sessions.get() - call.respondTemplate( + call.respondTemplates( "error.ftl", mapOf( "errorMessage" to "Oops! It wasn't possible to find the page, or it doesn't exist.", @@ -107,7 +108,7 @@ fun Application.configureStatusPage() { status(HttpStatusCode.InternalServerError) { call, _ -> val userSession: UserSession? = call.sessions.get() - call.respondTemplate( + call.respondTemplates( "error.ftl", mapOf( "errorMessage" to "Status 500 - Internal Server Error", diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt index 7f6b670..91c4fa1 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt @@ -1,11 +1,29 @@ import freemarker.cache.ClassTemplateLoader import freemarker.core.HTMLOutputFormat +import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.freemarker.* +import io.ktor.server.request.* +import io.ktor.server.response.* fun Application.configureTemplating() { install(FreeMarker) { templateLoader = ClassTemplateLoader(this::class.java.classLoader, "templates") outputFormat = HTMLOutputFormat.INSTANCE } +} + +suspend fun ApplicationCall.respondTemplates( + template: String, + model: Any? = null, + etag: String? = null, + contentType: ContentType = ContentType.Text.Html.withCharset(Charsets.UTF_8) +): Unit { + val hxRequest = request.header("HX-Request")?.toBoolean() ?: false + if (hxRequest) { + // HX-Request is true, respond accordingly + respond(FreeMarkerContent("errorttt.ftl", model, etag, contentType)) + } else { + respond(FreeMarkerContent(template, model, etag, contentType)) + } } \ No newline at end of file diff --git a/src/main/resources/templates/errorttt.ftl b/src/main/resources/templates/errorttt.ftl new file mode 100644 index 0000000..eb82630 --- /dev/null +++ b/src/main/resources/templates/errorttt.ftl @@ -0,0 +1,6 @@ + +

${errorMessage}

+ +
+ Back +
From 4d4ce791ed2fe52476c711d97e7db11f595d07da Mon Sep 17 00:00:00 2001 From: Dvonderstueck Date: Wed, 3 Jul 2024 15:19:32 +0200 Subject: [PATCH 2/5] now it works without another template (i believe it works) --- .../backend/plugins/Templating.kt | 13 ++- src/main/resources/templates/_layout.ftl | 105 ++++++++++-------- src/main/resources/templates/error.ftl | 7 +- 3 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt index 91c4fa1..eb635d5 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt @@ -20,10 +20,13 @@ suspend fun ApplicationCall.respondTemplates( contentType: ContentType = ContentType.Text.Html.withCharset(Charsets.UTF_8) ): Unit { val hxRequest = request.header("HX-Request")?.toBoolean() ?: false - if (hxRequest) { - // HX-Request is true, respond accordingly - respond(FreeMarkerContent("errorttt.ftl", model, etag, contentType)) + val modelWithHxRequest = if (model is Map<*, *>) { + model + ("hxRequest" to hxRequest) } else { - respond(FreeMarkerContent(template, model, etag, contentType)) + mapOf("hxRequest" to hxRequest, "model" to model) } -} \ No newline at end of file + + respond(FreeMarkerContent(template, modelWithHxRequest, etag, contentType)) +} + + diff --git a/src/main/resources/templates/_layout.ftl b/src/main/resources/templates/_layout.ftl index 76f0653..4be91b9 100644 --- a/src/main/resources/templates/_layout.ftl +++ b/src/main/resources/templates/_layout.ftl @@ -1,53 +1,53 @@ <#global userSession = "null"> <#global profilePicture = "/static/img/no_profile_picture.png"> -<#macro base> - - - - Wizard - - - - - +<#macro base hxRequest=false> + + + + Wizard + + + + + +<#if !hxRequest>
-

Wizard @@ -63,8 +63,15 @@

+ + +<#if hxRequest> +
+ + + <#nested /> -
- <#nested> -
- \ No newline at end of file + <#if hxRequest> +
+ + diff --git a/src/main/resources/templates/error.ftl b/src/main/resources/templates/error.ftl index c2ecbf1..ab9723f 100644 --- a/src/main/resources/templates/error.ftl +++ b/src/main/resources/templates/error.ftl @@ -1,12 +1,9 @@ <#import "_layout.ftl" as layout /> -<#assign userSession = session in layout> -<#assign profilePicture = profilePictureData in layout> - -<@layout.base> +<@layout.base hxRequest=hxRequest>

${errorMessage}

Back
- \ No newline at end of file + From 5013ac5a30286b7427e93ddefdeb187a6a7e321c Mon Sep 17 00:00:00 2001 From: Dvonderstueck Date: Mon, 8 Jul 2024 07:27:36 +0200 Subject: [PATCH 3/5] added code comments --- .../grandcentrix/backend/plugins/Templating.kt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt index eb635d5..86dfb1c 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt @@ -14,18 +14,23 @@ fun Application.configureTemplating() { } suspend fun ApplicationCall.respondTemplates( - template: String, - model: Any? = null, - etag: String? = null, - contentType: ContentType = ContentType.Text.Html.withCharset(Charsets.UTF_8) + template: String, // The name of the template to be rendered + model: Any? = null, // The data model to be passed to the template, default is null + etag: String? = null, // The ETag for caching purposes, default is null + contentType: ContentType = ContentType.Text.Html.withCharset(Charsets.UTF_8) // The content type of the response, default is HTML with UTF-8 charset ): Unit { + // Retrieve the "HX-Request" header from the request and convert it to a Boolean. Default to false if the header is not present. val hxRequest = request.header("HX-Request")?.toBoolean() ?: false + + // Prepare the model to include the hxRequest variable. If the original model is a Map, add hxRequest to it. + // Otherwise, create a new map with hxRequest and the original model. val modelWithHxRequest = if (model is Map<*, *>) { - model + ("hxRequest" to hxRequest) + model + ("hxRequest" to hxRequest) // Add hxRequest to the existing model map } else { - mapOf("hxRequest" to hxRequest, "model" to model) + mapOf("hxRequest" to hxRequest, "model" to model) // Create a new map containing hxRequest and the original model } + // Respond with the rendered FreeMarker template, passing the template name, modified model, etag, and content type. respond(FreeMarkerContent(template, modelWithHxRequest, etag, contentType)) } From dbe13e0ddeb7dd447d0b63f6692eebcf5998de47 Mon Sep 17 00:00:00 2001 From: Dvonderstueck Date: Mon, 8 Jul 2024 08:15:36 +0200 Subject: [PATCH 4/5] removed a test file --- src/main/resources/templates/errorttt.ftl | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/main/resources/templates/errorttt.ftl diff --git a/src/main/resources/templates/errorttt.ftl b/src/main/resources/templates/errorttt.ftl deleted file mode 100644 index eb82630..0000000 --- a/src/main/resources/templates/errorttt.ftl +++ /dev/null @@ -1,6 +0,0 @@ - -

${errorMessage}

- -
- Back -
From 40a7b4858788fb7ef6ad98f985c58bbd9f4ee930 Mon Sep 17 00:00:00 2001 From: Dvonderstueck Date: Thu, 11 Jul 2024 08:53:39 +0200 Subject: [PATCH 5/5] changed naming + deleted unused parameters + changes how the modle and mapping works to make it better --- .../grandcentrix/backend/plugins/Routing.kt | 14 +++++------ .../backend/plugins/StatusPage.kt | 14 +++++------ .../backend/plugins/Templating.kt | 24 +++++++------------ 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt index a2f6fbb..22f9465 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/Routing.kt @@ -18,7 +18,7 @@ import net.grandcentrix.backend.repository.HousesRepository.Companion.HousesRepo import net.grandcentrix.backend.repository.MoviesRepository.Companion.MoviesRepositoryInstance import net.grandcentrix.backend.repository.PotionsRepository.Companion.PotionsRepositoryInstance import net.grandcentrix.backend.repository.SpellsRepository.Companion.SpellsRepositoryInstance -import respondTemplates +import respondTemplating fun Application.configureRouting() { @@ -115,7 +115,7 @@ fun Application.configureRouting() { get("/books") { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplates( + call.respondTemplating( "books.ftl", mapOf( "books" to BooksRepositoryInstance.getAll(), @@ -130,7 +130,7 @@ fun Application.configureRouting() { get("/houses") { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplates( + call.respondTemplating( "houses.ftl", mapOf( "houses" to HousesRepositoryInstance.getAll(), @@ -145,7 +145,7 @@ fun Application.configureRouting() { get("/characters") { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplates( + call.respondTemplating( "characters.ftl", mapOf( "characters" to CharactersRepositoryInstance.getAll(), @@ -161,7 +161,7 @@ fun Application.configureRouting() { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplates( + call.respondTemplating( "movies.ftl", mapOf( "movies" to MoviesRepositoryInstance.getAll(), @@ -177,7 +177,7 @@ fun Application.configureRouting() { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplates( + call.respondTemplating( "potions.ftl", mapOf( "potions" to PotionsRepositoryInstance.getAll(), @@ -193,7 +193,7 @@ fun Application.configureRouting() { val userSession: UserSession? = call.sessions.get() val username = call.sessions.get()?.username - call.respondTemplates( + call.respondTemplating( "spells.ftl", mapOf( "spells" to SpellsRepositoryInstance.getAll(), diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt index bae3291..30a6952 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/StatusPage.kt @@ -10,7 +10,7 @@ import io.ktor.server.routing.* import io.ktor.server.sessions.* import net.grandcentrix.backend.controllers.UserSession import net.grandcentrix.backend.controllers.getProfilePicture -import respondTemplates +import respondTemplating fun Application.configureStatusPage() { routing { @@ -22,7 +22,7 @@ fun Application.configureStatusPage() { when (cause) { is RequestException -> { val userSession: UserSession? = call.sessions.get() - call.respondTemplates( + call.respondTemplating( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -37,7 +37,7 @@ fun Application.configureStatusPage() { is DAOException -> { val userSession = call.sessions.get() - call.respondTemplates( + call.respondTemplating( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -63,7 +63,7 @@ fun Application.configureStatusPage() { is UserAlreadyExistsException -> { val userSession: UserSession? = call.sessions.get() - call.respondTemplates( + call.respondTemplating( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -80,7 +80,7 @@ fun Application.configureStatusPage() { else -> { val userSession = call.sessions.get() - call.respondTemplates( + call.respondTemplating( "error.ftl", mapOf( "errorMessage" to cause.message, @@ -95,7 +95,7 @@ fun Application.configureStatusPage() { status(HttpStatusCode.NotFound) { call, _ -> val userSession: UserSession? = call.sessions.get() - call.respondTemplates( + call.respondTemplating( "error.ftl", mapOf( "errorMessage" to "Oops! It wasn't possible to find the page, or it doesn't exist.", @@ -108,7 +108,7 @@ fun Application.configureStatusPage() { status(HttpStatusCode.InternalServerError) { call, _ -> val userSession: UserSession? = call.sessions.get() - call.respondTemplates( + call.respondTemplating( "error.ftl", mapOf( "errorMessage" to "Status 500 - Internal Server Error", diff --git a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt index 86dfb1c..bc772c6 100644 --- a/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt +++ b/src/main/kotlin/net/grandcentrix/backend/plugins/Templating.kt @@ -1,6 +1,5 @@ import freemarker.cache.ClassTemplateLoader import freemarker.core.HTMLOutputFormat -import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.freemarker.* import io.ktor.server.request.* @@ -13,25 +12,18 @@ fun Application.configureTemplating() { } } -suspend fun ApplicationCall.respondTemplates( - template: String, // The name of the template to be rendered - model: Any? = null, // The data model to be passed to the template, default is null - etag: String? = null, // The ETag for caching purposes, default is null - contentType: ContentType = ContentType.Text.Html.withCharset(Charsets.UTF_8) // The content type of the response, default is HTML with UTF-8 charset +suspend fun ApplicationCall.respondTemplating( + template: String, + model: Map<*, *>? = null ): Unit { - // Retrieve the "HX-Request" header from the request and convert it to a Boolean. Default to false if the header is not present. val hxRequest = request.header("HX-Request")?.toBoolean() ?: false - // Prepare the model to include the hxRequest variable. If the original model is a Map, add hxRequest to it. - // Otherwise, create a new map with hxRequest and the original model. - val modelWithHxRequest = if (model is Map<*, *>) { - model + ("hxRequest" to hxRequest) // Add hxRequest to the existing model map - } else { - mapOf("hxRequest" to hxRequest, "model" to model) // Create a new map containing hxRequest and the original model + val modelWithHxRequest: Map<*, *> = when (model) { + is Map<*, *> -> model + ("hxRequest" to hxRequest) + null -> mapOf("hxRequest" to hxRequest) + else -> throw IllegalArgumentException("Model must be a Map") } - // Respond with the rendered FreeMarker template, passing the template name, modified model, etag, and content type. - respond(FreeMarkerContent(template, modelWithHxRequest, etag, contentType)) + respond(FreeMarkerContent(template, modelWithHxRequest)) } -