forked from SPC/spc-site
Resolving paths for static sites.
This commit is contained in:
parent
bafc75086a
commit
d657282a33
@ -8,7 +8,7 @@ import kotlinx.html.style
|
|||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.fetch
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.snark.SnarkPlugin
|
import space.kscience.snark.SnarkPlugin
|
||||||
import space.kscience.snark.mountSnark
|
import space.kscience.snark.site
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.FileSystems
|
import java.nio.file.FileSystems
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
@ -50,7 +50,7 @@ fun Application.spcModule() {
|
|||||||
val context = Context("spc-site") {
|
val context = Context("spc-site") {
|
||||||
plugin(SnarkPlugin)
|
plugin(SnarkPlugin)
|
||||||
}
|
}
|
||||||
val snarkPlugin = context.fetch(SnarkPlugin)
|
val snark = context.fetch(SnarkPlugin)
|
||||||
|
|
||||||
val dataPath = Path.of("data")
|
val dataPath = Path.of("data")
|
||||||
|
|
||||||
@ -86,16 +86,16 @@ fun Application.spcModule() {
|
|||||||
dataPath.resolve(DEPLOY_DATE_FILE).writeText(date)
|
dataPath.resolve(DEPLOY_DATE_FILE).writeText(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
mountSnark(snarkPlugin) {
|
snark.site {
|
||||||
val homeDataPath = resolveData(
|
val homeDataPath = resolveData(
|
||||||
javaClass.getResource("/home")!!.toURI(),
|
this@spcModule.javaClass.getResource("/home")!!.toURI(),
|
||||||
dataPath / "home"
|
dataPath / "home"
|
||||||
)
|
)
|
||||||
|
|
||||||
spcHome(rootPath = homeDataPath)
|
spcHome(rootPath = homeDataPath)
|
||||||
|
|
||||||
val mastersDataPath = resolveData(
|
val mastersDataPath = resolveData(
|
||||||
javaClass.getResource("/magprog")!!.toURI(),
|
this@spcModule.javaClass.getResource("/magprog")!!.toURI(),
|
||||||
dataPath / "magprog"
|
dataPath / "magprog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ context(SiteData) internal fun HTML.magProgHead(title: String) {
|
|||||||
}
|
}
|
||||||
link {
|
link {
|
||||||
rel = "stylesheet"
|
rel = "stylesheet"
|
||||||
href = resolveRef("css/main.css")
|
href = resolveRef("assets/css/main.css")
|
||||||
}
|
}
|
||||||
link {
|
link {
|
||||||
rel = "shortcut icon"
|
rel = "shortcut icon"
|
||||||
@ -230,7 +230,7 @@ context(SiteData) internal fun HTML.magProgHead(title: String) {
|
|||||||
noScript {
|
noScript {
|
||||||
link {
|
link {
|
||||||
rel = "stylesheet"
|
rel = "stylesheet"
|
||||||
href = resolveRef("css/noscript.css")
|
href = resolveRef("assets/css/noscript.css")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,25 +253,25 @@ context(SiteData) internal fun BODY.magProgFooter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/jquery.min.js")
|
src = resolveRef("assets/js/jquery.min.js")
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/jquery.scrollex.min.js")
|
src = resolveRef("assets/js/jquery.scrollex.min.js")
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/jquery.scrolly.min.js")
|
src = resolveRef("assets/js/jquery.scrolly.min.js")
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/browser.min.js")
|
src = resolveRef("assets/js/browser.min.js")
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/breakpoints.min.js")
|
src = resolveRef("assets/js/breakpoints.min.js")
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/util.js")
|
src = resolveRef("assets/js/util.js")
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
src = resolveRef("js/main.js")
|
src = resolveRef("assets/js/main.js")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asNa
|
|||||||
val magProgSiteContext = snark.readDirectory(dataPath.resolve("content"))
|
val magProgSiteContext = snark.readDirectory(dataPath.resolve("content"))
|
||||||
|
|
||||||
mountSite(prefix, magProgSiteContext) {
|
mountSite(prefix, magProgSiteContext) {
|
||||||
assetDirectory("", dataPath.resolve("assets"))
|
assetDirectory("assets", dataPath.resolve("assets"))
|
||||||
assetDirectory("images", dataPath.resolve("images"))
|
assetDirectory("images", dataPath.resolve("images"))
|
||||||
|
|
||||||
page {
|
page {
|
||||||
|
15
src/main/kotlin/ru/mipt/spc/staticRender.kt
Normal file
15
src/main/kotlin/ru/mipt/spc/staticRender.kt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package ru.mipt.spc
|
||||||
|
|
||||||
|
import space.kscience.dataforge.context.Global
|
||||||
|
import space.kscience.dataforge.context.fetch
|
||||||
|
import space.kscience.snark.SnarkPlugin
|
||||||
|
import space.kscience.snark.static
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.toPath
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
Global.fetch(SnarkPlugin).static(Path.of("build/out")) {
|
||||||
|
spcHome(rootPath = javaClass.getResource("/home")!!.toURI().toPath())
|
||||||
|
spcMaster(dataPath = javaClass.getResource("/magprog")!!.toURI().toPath())
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,19 @@
|
|||||||
package space.kscience.snark
|
package space.kscience.snark
|
||||||
|
|
||||||
|
import io.ktor.http.URLBuilder
|
||||||
|
import io.ktor.http.URLProtocol
|
||||||
|
import io.ktor.server.application.Application
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.html.respondHtml
|
import io.ktor.server.html.respondHtml
|
||||||
import io.ktor.server.http.content.*
|
import io.ktor.server.http.content.*
|
||||||
|
import io.ktor.server.plugins.origin
|
||||||
|
import io.ktor.server.request.ApplicationRequest
|
||||||
|
import io.ktor.server.request.host
|
||||||
|
import io.ktor.server.request.port
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.createRouteFromPath
|
import io.ktor.server.routing.createRouteFromPath
|
||||||
import io.ktor.server.routing.get
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.routing
|
||||||
import kotlinx.html.HTML
|
import kotlinx.html.HTML
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -44,3 +52,36 @@ class KtorSiteBuilder(override val data: SiteData, private val ktorRoute: Route)
|
|||||||
|
|
||||||
override fun withData(newData: SiteData): SiteBuilder = KtorSiteBuilder(newData, ktorRoute)
|
override fun withData(newData: SiteData): SiteBuilder = KtorSiteBuilder(newData, ktorRoute)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PublishedApi
|
||||||
|
internal fun SiteData.copyWithRequestHost(request: ApplicationRequest): SiteData {
|
||||||
|
val uri = URLBuilder(
|
||||||
|
protocol = URLProtocol.createOrDefault(request.origin.scheme),
|
||||||
|
host = request.host(),
|
||||||
|
port = request.port(),
|
||||||
|
pathSegments = baseUrlPath.split("/"),
|
||||||
|
)
|
||||||
|
return copy(baseUrlPath = uri.buildString())
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun Route.snarkSite(
|
||||||
|
data: SiteData,
|
||||||
|
block: SiteBuilder.() -> Unit,
|
||||||
|
) {
|
||||||
|
block(KtorSiteBuilder(data, this@snarkSite))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Application.snarkSite(
|
||||||
|
data: SiteData,
|
||||||
|
block: SiteBuilder.() -> Unit,
|
||||||
|
) {
|
||||||
|
routing {
|
||||||
|
snarkSite(data, block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context (Application) fun SnarkPlugin.site(
|
||||||
|
block: SiteBuilder.() -> Unit,
|
||||||
|
) {
|
||||||
|
snarkSite(SiteData.empty(this), block)
|
||||||
|
}
|
@ -1,8 +1,5 @@
|
|||||||
package space.kscience.snark
|
package space.kscience.snark
|
||||||
|
|
||||||
import io.ktor.server.application.Application
|
|
||||||
import io.ktor.server.routing.Route
|
|
||||||
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
|
||||||
import space.kscience.dataforge.context.ContextAware
|
import space.kscience.dataforge.context.ContextAware
|
||||||
@ -66,27 +63,3 @@ public fun SiteBuilder.mountSite(route: Name, dataRoot: DataTree<*>, block: Site
|
|||||||
withData(mountedData).block()
|
withData(mountedData).block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Route.mountSnark(
|
|
||||||
data: SiteData,
|
|
||||||
block: context(SiteData, SiteBuilder)() -> Unit,
|
|
||||||
) {
|
|
||||||
block(data, KtorSiteBuilder(data, this@mountSnark))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Application.mountSnark(
|
|
||||||
data: SiteData,
|
|
||||||
block: context(SiteData, SiteBuilder)() -> Unit,
|
|
||||||
) {
|
|
||||||
routing {
|
|
||||||
mountSnark(data, block)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Application.mountSnark(
|
|
||||||
snarkPlugin: SnarkPlugin,
|
|
||||||
block: context(SiteData, SiteBuilder)() -> Unit,
|
|
||||||
) {
|
|
||||||
mountSnark(SiteData.empty(snarkPlugin), block)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
package space.kscience.snark
|
package space.kscience.snark
|
||||||
|
|
||||||
import io.ktor.http.URLBuilder
|
|
||||||
import io.ktor.http.URLProtocol
|
|
||||||
import io.ktor.server.plugins.origin
|
|
||||||
import io.ktor.server.request.ApplicationRequest
|
|
||||||
import io.ktor.server.request.host
|
|
||||||
import io.ktor.server.request.port
|
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.ContextAware
|
import space.kscience.dataforge.context.ContextAware
|
||||||
import space.kscience.dataforge.data.*
|
import space.kscience.dataforge.data.*
|
||||||
@ -93,14 +87,3 @@ internal val Data<*>.published: Boolean get() = meta["published"].string != "fal
|
|||||||
//
|
//
|
||||||
// return readData(parsedData, rootUrl)
|
// return readData(parsedData, rootUrl)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@PublishedApi
|
|
||||||
internal fun SiteData.copyWithRequestHost(request: ApplicationRequest): SiteData {
|
|
||||||
val uri = URLBuilder(
|
|
||||||
protocol = URLProtocol.createOrDefault(request.origin.scheme),
|
|
||||||
host = request.host(),
|
|
||||||
port = request.port(),
|
|
||||||
pathSegments = baseUrlPath.split("/"),
|
|
||||||
)
|
|
||||||
return copy(baseUrlPath = uri.buildString())
|
|
||||||
}
|
|
||||||
|
@ -4,26 +4,44 @@ import kotlinx.html.HTML
|
|||||||
import kotlinx.html.html
|
import kotlinx.html.html
|
||||||
import kotlinx.html.stream.createHTML
|
import kotlinx.html.stream.createHTML
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.isEmpty
|
||||||
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.copyTo
|
import kotlin.io.path.copyTo
|
||||||
import kotlin.io.path.createDirectories
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.relativeTo
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
|
|
||||||
class StaticSiteBuilder(override val data: SiteData, private val path: Path) : SiteBuilder {
|
class StaticSiteBuilder(override val data: SiteData, private val path: Path) : SiteBuilder {
|
||||||
|
private fun Path.copyRecursively(target: Path) {
|
||||||
|
Files.walk(this).forEach { source: Path ->
|
||||||
|
val destination: Path = target.resolve(source.relativeTo(this))
|
||||||
|
source.copyTo(destination,true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun assetFile(remotePath: String, file: Path) {
|
override fun assetFile(remotePath: String, file: Path) {
|
||||||
file.copyTo(path.resolve(remotePath))
|
val targetPath = path.resolve(remotePath)
|
||||||
|
targetPath.parent.createDirectories()
|
||||||
|
file.copyTo(targetPath, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun assetDirectory(remotePath: String, directory: Path) {
|
override fun assetDirectory(remotePath: String, directory: Path) {
|
||||||
directory.copyTo(path.resolve(remotePath))
|
val targetPath = path.resolve(remotePath)
|
||||||
|
targetPath.parent.createDirectories()
|
||||||
|
directory.copyRecursively(targetPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun assetResourceFile(remotePath: String, resourcesPath: String) {
|
override fun assetResourceFile(remotePath: String, resourcesPath: String) {
|
||||||
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(path.resolve(remotePath))
|
val targetPath = path.resolve(remotePath)
|
||||||
|
targetPath.parent.createDirectories()
|
||||||
|
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(targetPath,true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun assetResourceDirectory(resourcesPath: String) {
|
override fun assetResourceDirectory(resourcesPath: String) {
|
||||||
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(path)
|
path.parent.createDirectories()
|
||||||
|
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyRecursively(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun page(route: Name, content: context(SiteData, HTML) () -> Unit) {
|
override fun page(route: Name, content: context(SiteData, HTML) () -> Unit) {
|
||||||
@ -33,7 +51,11 @@ class StaticSiteBuilder(override val data: SiteData, private val path: Path) : S
|
|||||||
content(data, this)
|
content(data, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val newPath = path.resolve(route.toWebPath() + ".html")
|
val newPath = if (route.isEmpty()) {
|
||||||
|
path.resolve("index.html")
|
||||||
|
} else {
|
||||||
|
path.resolve(route.toWebPath() + ".html")
|
||||||
|
}
|
||||||
|
|
||||||
newPath.parent.createDirectories()
|
newPath.parent.createDirectories()
|
||||||
newPath.writeText(htmlBuilder.finalize())
|
newPath.writeText(htmlBuilder.finalize())
|
||||||
@ -44,3 +66,7 @@ class StaticSiteBuilder(override val data: SiteData, private val path: Path) : S
|
|||||||
override fun withData(newData: SiteData): SiteBuilder = StaticSiteBuilder(newData, path)
|
override fun withData(newData: SiteData): SiteBuilder = StaticSiteBuilder(newData, path)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun SnarkPlugin.static(path: Path, block: SiteBuilder.() -> Unit) {
|
||||||
|
StaticSiteBuilder(SiteData.empty(this), path).block()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user