From 218e76a2a838b451da23bd84b80b24e404f509df Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 24 Jun 2022 17:23:08 +0300 Subject: [PATCH] Complete refactor to new routing API --- src/main/kotlin/ru/mipt/spc/master.kt | 79 ++++++++++--------- src/main/kotlin/ru/mipt/spc/spcHome.kt | 2 +- .../space/kscience/snark/KtorSiteBuilder.kt | 8 +- .../space/kscience/snark/PageBuilder.kt | 2 +- .../space/kscience/snark/StaticSiteBuilder.kt | 31 +++++--- 5 files changed, 71 insertions(+), 51 deletions(-) diff --git a/src/main/kotlin/ru/mipt/spc/master.kt b/src/main/kotlin/ru/mipt/spc/master.kt index 77b32e2..8ab69d8 100644 --- a/src/main/kotlin/ru/mipt/spc/master.kt +++ b/src/main/kotlin/ru/mipt/spc/master.kt @@ -2,6 +2,7 @@ package ru.mipt.spc import kotlinx.coroutines.runBlocking import kotlinx.html.* +import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.data.await import space.kscience.dataforge.data.getByType import space.kscience.dataforge.meta.Meta @@ -280,9 +281,9 @@ private val HtmlData.mentorPageId get() = "mentor-${id}" internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asName()) { - val magProgSiteContext = snark.readDirectory(dataPath.resolve("content")) + val magProgData: DataTree = snark.readDirectory(dataPath.resolve("content")) - route(prefix, magProgSiteContext, setAsRoot = true) { + route(prefix, magProgData, setAsRoot = true) { assetDirectory("assets", dataPath.resolve("assets")) assetDirectory("images", dataPath.resolve("images")) @@ -356,57 +357,57 @@ internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asNa magProgFooter() } } - } - val mentors = data.findByContentType("magprog_mentor").values.sortedBy { - it.order - } + val mentors = data.findByContentType("magprog_mentor").values.sortedBy { + it.order + } - mentors.forEach { mentor -> - page(mentor.mentorPageId.asName()) { + mentors.forEach { mentor -> + page(mentor.mentorPageId.asName()) { - magProgHead("Научное программирование: ${mentor.name}") - body("is-preload") { - header { - id = "header" - a(classes = "title") { - href = "$homeRef#mentors" - +"Научные руководители" - } - nav { - ul { - mentors.forEach { - li { - a { - href = resolvePageRef(it.mentorPageId) - +it.name.substringAfterLast(" ") + magProgHead("Научное программирование: ${mentor.name}") + body("is-preload") { + header { + id = "header" + a(classes = "title") { + href = "$homeRef#mentors" + +"Научные руководители" + } + nav { + ul { + mentors.forEach { + li { + a { + href = resolvePageRef(it.mentorPageId) + +it.name.substringAfterLast(" ") + } } } } } } - } - div { - id = "wrapper" - section("wrapper") { - id = "main" - div("inner") { - h1("major") { +mentor.name } - val imageClass = mentor.meta["image.position"].string ?: "left" - span("image $imageClass") { - mentor.imagePath?.let { photoPath -> - img( - src = resolveRef(photoPath), - alt = mentor.name - ) + div { + id = "wrapper" + section("wrapper") { + id = "main" + div("inner") { + h1("major") { +mentor.name } + val imageClass = mentor.meta["image.position"].string ?: "left" + span("image $imageClass") { + mentor.imagePath?.let { photoPath -> + img( + src = resolveRef(photoPath), + alt = mentor.name + ) + } } + htmlData(mentor) } - htmlData(mentor) } } + magProgFooter() } - magProgFooter() } } } diff --git a/src/main/kotlin/ru/mipt/spc/spcHome.kt b/src/main/kotlin/ru/mipt/spc/spcHome.kt index b3c89f4..96e4f5c 100644 --- a/src/main/kotlin/ru/mipt/spc/spcHome.kt +++ b/src/main/kotlin/ru/mipt/spc/spcHome.kt @@ -150,7 +150,7 @@ context(PageBuilder) private fun HTML.spcHome() { header("major") { h3 { a(classes = "link") { - href = resolvePageRef("magprog") + href = resolvePageRef("magprog.index") +"""Master's program""" } } diff --git a/src/main/kotlin/space/kscience/snark/KtorSiteBuilder.kt b/src/main/kotlin/space/kscience/snark/KtorSiteBuilder.kt index f435855..efd8afb 100644 --- a/src/main/kotlin/space/kscience/snark/KtorSiteBuilder.kt +++ b/src/main/kotlin/space/kscience/snark/KtorSiteBuilder.kt @@ -19,6 +19,8 @@ import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.withDefault import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.cutLast +import space.kscience.dataforge.names.endsWith import java.nio.file.Path import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -57,7 +59,11 @@ internal class KtorSiteBuilder( override fun resolveRef(ref: String): String = resolveRef(pageBaseUrl, ref) - override fun resolvePageRef(pageName: Name): String = resolveRef(pageName.tokens.joinToString(separator = "/")) + override fun resolvePageRef(pageName: Name): String = if(pageName.endsWith(SiteBuilder.INDEX_PAGE_TOKEN)){ + resolveRef(pageName.cutLast().tokens.joinToString(separator = "/")) + } else { + resolveRef(pageName.tokens.joinToString(separator = "/")) + } } override fun page(route: Name, content: context(PageBuilder, HTML)() -> Unit) { diff --git a/src/main/kotlin/space/kscience/snark/PageBuilder.kt b/src/main/kotlin/space/kscience/snark/PageBuilder.kt index 71333a4..c189d63 100644 --- a/src/main/kotlin/space/kscience/snark/PageBuilder.kt +++ b/src/main/kotlin/space/kscience/snark/PageBuilder.kt @@ -25,7 +25,7 @@ interface PageBuilder : ContextAware { fun PageBuilder.resolvePageRef(pageName: String) = resolvePageRef(pageName.parseAsName()) -val PageBuilder.homeRef get() = resolvePageRef(Name.EMPTY) +val PageBuilder.homeRef get() = resolvePageRef(Name.EMPTY).removeSuffix("/") /** * Resolve a Html builder by its full name diff --git a/src/main/kotlin/space/kscience/snark/StaticSiteBuilder.kt b/src/main/kotlin/space/kscience/snark/StaticSiteBuilder.kt index 15e252d..b2451c9 100644 --- a/src/main/kotlin/space/kscience/snark/StaticSiteBuilder.kt +++ b/src/main/kotlin/space/kscience/snark/StaticSiteBuilder.kt @@ -56,19 +56,23 @@ internal class StaticSiteBuilder( javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyRecursively(path) } + private fun resolveRef(baseUrl: String, ref: String) = if (baseUrl.isEmpty()) { + ref + } else { + "${baseUrl.removeSuffix("/")}/$ref" + } + inner class StaticPageBuilder : PageBuilder { override val data: DataTree<*> get() = this@StaticSiteBuilder.data override val meta: Meta get() = this@StaticSiteBuilder.meta override val context: Context get() = this@StaticSiteBuilder.context - override fun resolveRef(ref: String): String { - TODO("Not yet implemented") - } + override fun resolveRef(ref: String): String = resolveRef(baseUrl, ref) - override fun resolvePageRef(pageName: Name): String { - TODO("Not yet implemented") - } + override fun resolvePageRef(pageName: Name): String = resolveRef( + pageName.tokens.joinToString(separator = "/", postfix = ".html") + ) } @@ -98,14 +102,23 @@ internal class StaticSiteBuilder( snark = snark, data = dataOverride ?: data, meta = metaOverride?.withDefault(meta) ?: meta, - baseUrl = baseUrl, + baseUrl = if (setAsRoot) { + resolveRef(baseUrl, routeName.toWebPath()) + } else { + baseUrl + }, path = path.resolve(routeName.toWebPath()) ) } -fun SnarkPlugin.static(outputPath: Path, data: DataTree<*> = DataTree.empty(), block: SiteBuilder.() -> Unit) { +fun SnarkPlugin.static( + outputPath: Path, + data: DataTree<*> = DataTree.empty(), + siteUrl: String = outputPath.absolutePathString(), + block: SiteBuilder.() -> Unit, +) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - StaticSiteBuilder(this, data, meta, "", outputPath).block() + StaticSiteBuilder(this, data, meta, siteUrl, outputPath).block() } \ No newline at end of file