Implementation for static site generator
This commit is contained in:
parent
d74c8be135
commit
bafc75086a
@ -21,7 +21,7 @@ context(SiteData, FlowContent) private fun spcSpotlightContent(
|
|||||||
) {
|
) {
|
||||||
// Banner
|
// Banner
|
||||||
// Note: The "styleN" class below should match that of the header element.
|
// Note: The "styleN" class below should match that of the header element.
|
||||||
section("style2") {
|
section("style1") {
|
||||||
id = "banner"
|
id = "banner"
|
||||||
div("inner") {
|
div("inner") {
|
||||||
span("image") {
|
span("image") {
|
||||||
|
@ -65,7 +65,7 @@ internal val FortyDataRenderer: SiteBuilder.(Data<*>) -> Unit = { data ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
context(SiteData, HTML) private fun HTML.spcHome() {
|
context(SiteData, HTML) private fun spcHome() {
|
||||||
spcHead()
|
spcHead()
|
||||||
body("is-preload") {
|
body("is-preload") {
|
||||||
wrapper {
|
wrapper {
|
||||||
|
46
src/main/kotlin/space/kscience/snark/KtorSiteBuilder.kt
Normal file
46
src/main/kotlin/space/kscience/snark/KtorSiteBuilder.kt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package space.kscience.snark
|
||||||
|
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.html.respondHtml
|
||||||
|
import io.ktor.server.http.content.*
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.createRouteFromPath
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import kotlinx.html.HTML
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
class KtorSiteBuilder(override val data: SiteData, private val ktorRoute: Route) : SiteBuilder {
|
||||||
|
|
||||||
|
override fun assetFile(remotePath: String, file: Path) {
|
||||||
|
ktorRoute.file(remotePath, file.toFile())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assetDirectory(remotePath: String, directory: Path) {
|
||||||
|
ktorRoute.static(remotePath) {
|
||||||
|
files(directory.toFile())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun page(route: Name, content: context(SiteData, HTML)() -> Unit) {
|
||||||
|
ktorRoute.get(route.toWebPath()) {
|
||||||
|
call.respondHtml {
|
||||||
|
val dataWithUrl = data.copyWithRequestHost(call.request)
|
||||||
|
content(dataWithUrl, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun route(subRoute: Name): SiteBuilder =
|
||||||
|
KtorSiteBuilder(data, ktorRoute.createRouteFromPath(subRoute.toWebPath()))
|
||||||
|
|
||||||
|
override fun assetResourceFile(remotePath: String, resourcesPath: String) {
|
||||||
|
ktorRoute.resource(resourcesPath, resourcesPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assetResourceDirectory(resourcesPath: String) {
|
||||||
|
ktorRoute.resources(resourcesPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun withData(newData: SiteData): SiteBuilder = KtorSiteBuilder(newData, ktorRoute)
|
||||||
|
}
|
@ -1,12 +1,7 @@
|
|||||||
package space.kscience.snark
|
package space.kscience.snark
|
||||||
|
|
||||||
import io.ktor.server.application.Application
|
import io.ktor.server.application.Application
|
||||||
import io.ktor.server.application.call
|
|
||||||
import io.ktor.server.html.respondHtml
|
|
||||||
import io.ktor.server.http.content.*
|
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.createRouteFromPath
|
|
||||||
import io.ktor.server.routing.get
|
|
||||||
import io.ktor.server.routing.routing
|
import io.ktor.server.routing.routing
|
||||||
import kotlinx.html.HTML
|
import kotlinx.html.HTML
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
@ -72,46 +67,11 @@ public fun SiteBuilder.mountSite(route: Name, dataRoot: DataTree<*>, block: Site
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class KtorSiteRoute(override val data: SiteData, private val ktorRoute: Route) : SiteBuilder {
|
|
||||||
|
|
||||||
override fun assetFile(remotePath: String, file: Path) {
|
|
||||||
ktorRoute.file(remotePath, file.toFile())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun assetDirectory(remotePath: String, directory: Path) {
|
|
||||||
ktorRoute.static(remotePath) {
|
|
||||||
files(directory.toFile())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun page(route: Name, content: context(SiteData, HTML)() -> Unit) {
|
|
||||||
ktorRoute.get(route.toWebPath()) {
|
|
||||||
call.respondHtml {
|
|
||||||
val dataWithUrl = data.copyWithRequestHost(call.request)
|
|
||||||
content(dataWithUrl, this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun route(subRoute: Name): SiteBuilder =
|
|
||||||
KtorSiteRoute(data, ktorRoute.createRouteFromPath(subRoute.toWebPath()))
|
|
||||||
|
|
||||||
override fun assetResourceFile(remotePath: String, resourcesPath: String) {
|
|
||||||
ktorRoute.resource(resourcesPath, resourcesPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun assetResourceDirectory(resourcesPath: String) {
|
|
||||||
ktorRoute.resources(resourcesPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun withData(newData: SiteData): SiteBuilder = KtorSiteRoute(newData, ktorRoute)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun Route.mountSnark(
|
inline fun Route.mountSnark(
|
||||||
data: SiteData,
|
data: SiteData,
|
||||||
block: context(SiteData, SiteBuilder)() -> Unit,
|
block: context(SiteData, SiteBuilder)() -> Unit,
|
||||||
) {
|
) {
|
||||||
block(data, KtorSiteRoute(data, this@mountSnark))
|
block(data, KtorSiteBuilder(data, this@mountSnark))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Application.mountSnark(
|
fun Application.mountSnark(
|
||||||
|
@ -79,7 +79,6 @@ fun DataTree<*>.resolveAllHtml(predicate: (name: Name, meta: Meta) -> Boolean):
|
|||||||
|
|
||||||
val SiteData.homeRef get() = resolveRef("").removeSuffix("/")
|
val SiteData.homeRef get() = resolveRef("").removeSuffix("/")
|
||||||
|
|
||||||
|
|
||||||
fun SiteData.findByType(contentType: String, baseName: Name = Name.EMPTY) = resolveAllHtml { name, meta ->
|
fun SiteData.findByType(contentType: String, baseName: Name = Name.EMPTY) = resolveAllHtml { name, meta ->
|
||||||
name.startsWith(baseName) && meta["content_type"].string == contentType
|
name.startsWith(baseName) && meta["content_type"].string == contentType
|
||||||
}
|
}
|
||||||
|
46
src/main/kotlin/space/kscience/snark/StaticSiteBuilder.kt
Normal file
46
src/main/kotlin/space/kscience/snark/StaticSiteBuilder.kt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package space.kscience.snark
|
||||||
|
|
||||||
|
import kotlinx.html.HTML
|
||||||
|
import kotlinx.html.html
|
||||||
|
import kotlinx.html.stream.createHTML
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.copyTo
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
|
class StaticSiteBuilder(override val data: SiteData, private val path: Path) : SiteBuilder {
|
||||||
|
override fun assetFile(remotePath: String, file: Path) {
|
||||||
|
file.copyTo(path.resolve(remotePath))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assetDirectory(remotePath: String, directory: Path) {
|
||||||
|
directory.copyTo(path.resolve(remotePath))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assetResourceFile(remotePath: String, resourcesPath: String) {
|
||||||
|
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(path.resolve(remotePath))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assetResourceDirectory(resourcesPath: String) {
|
||||||
|
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun page(route: Name, content: context(SiteData, HTML) () -> Unit) {
|
||||||
|
val htmlBuilder = createHTML()
|
||||||
|
|
||||||
|
htmlBuilder.html {
|
||||||
|
content(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
val newPath = path.resolve(route.toWebPath() + ".html")
|
||||||
|
|
||||||
|
newPath.parent.createDirectories()
|
||||||
|
newPath.writeText(htmlBuilder.finalize())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun route(subRoute: Name): SiteBuilder = StaticSiteBuilder(data, path.resolve(subRoute.toWebPath()))
|
||||||
|
|
||||||
|
override fun withData(newData: SiteData): SiteBuilder = StaticSiteBuilder(newData, path)
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user