forked from SPC/spc-site
Multiple engine logic cleanup
This commit is contained in:
parent
d657282a33
commit
846c02020b
@ -183,7 +183,8 @@ context(SiteData) private fun FlowContent.mentors() {
|
|||||||
mentors.forEach { (name, mentor) ->
|
mentors.forEach { (name, mentor) ->
|
||||||
section {
|
section {
|
||||||
id = mentor.id
|
id = mentor.id
|
||||||
a(classes = "image", href = resolveRef("mentor-${mentor.id}")) {
|
val ref = resolvePage("mentor-${mentor.id}")
|
||||||
|
a(classes = "image", href = ref) {
|
||||||
mentor.imagePath?.let { photoPath ->
|
mentor.imagePath?.let { photoPath ->
|
||||||
img(
|
img(
|
||||||
src = resolveRef(photoPath),
|
src = resolveRef(photoPath),
|
||||||
@ -197,7 +198,7 @@ context(SiteData) private fun FlowContent.mentors() {
|
|||||||
div("content") {
|
div("content") {
|
||||||
div("inner") {
|
div("inner") {
|
||||||
h2 {
|
h2 {
|
||||||
a(href = resolveRef("mentor-${mentor.id}")) { +mentor.name }
|
a(href = ref) { +mentor.name }
|
||||||
}
|
}
|
||||||
val info = resolveHtml(name.withIndex("info"))
|
val info = resolveHtml(name.withIndex("info"))
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
@ -376,7 +377,7 @@ internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asNa
|
|||||||
mentors.forEach {
|
mentors.forEach {
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
href = resolveRef(it.mentorPageId)
|
href = resolvePage(it.mentorPageId)
|
||||||
+it.name.substringAfterLast(" ")
|
+it.name.substringAfterLast(" ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ context(SiteData, FlowContent) private fun spcSpotlightContent(
|
|||||||
//TODO add smart SNARK ordering
|
//TODO add smart SNARK ordering
|
||||||
section("spotlights") {
|
section("spotlights") {
|
||||||
content.entries.sortedBy { it.value.meta["order"].int ?: Int.MAX_VALUE }.forEach { (name, data) ->
|
content.entries.sortedBy { it.value.meta["order"].int ?: Int.MAX_VALUE }.forEach { (name, data) ->
|
||||||
val ref = resolveRef(name)
|
val ref = resolvePage(name)
|
||||||
section {
|
section {
|
||||||
id = data.meta["id"].string ?: name.toString()
|
id = data.meta["id"].string ?: name.toString()
|
||||||
data.meta["image"]?.let { imageMeta: Meta ->
|
data.meta["image"]?.let { imageMeta: Meta ->
|
||||||
|
@ -150,7 +150,7 @@ context(SiteData, HTML) private fun spcHome() {
|
|||||||
header("major") {
|
header("major") {
|
||||||
h3 {
|
h3 {
|
||||||
a(classes = "link") {
|
a(classes = "link") {
|
||||||
href = resolveRef("magprog")
|
href = resolvePage("magprog")
|
||||||
+"""Master's program"""
|
+"""Master's program"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ context(SiteData, HTML) private fun spcHome() {
|
|||||||
header("major") {
|
header("major") {
|
||||||
h3 {
|
h3 {
|
||||||
a(classes = "link") {
|
a(classes = "link") {
|
||||||
href = resolveRef("research")
|
href = resolvePage("research")
|
||||||
+"""Research"""
|
+"""Research"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ context(SiteData, HTML) private fun spcHome() {
|
|||||||
header("major") {
|
header("major") {
|
||||||
h3 {
|
h3 {
|
||||||
a(classes = "link") {
|
a(classes = "link") {
|
||||||
href = resolveRef("consulting")
|
href = resolvePage("consulting")
|
||||||
+"""Consulting"""
|
+"""Consulting"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ context(SiteData, HTML) private fun spcHome() {
|
|||||||
header("major") {
|
header("major") {
|
||||||
h3 {
|
h3 {
|
||||||
a(classes = "link") {
|
a(classes = "link") {
|
||||||
href = resolveRef("team")
|
href = resolvePage("team")
|
||||||
+"""Team"""
|
+"""Team"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package ru.mipt.spc
|
|||||||
import kotlinx.html.*
|
import kotlinx.html.*
|
||||||
import space.kscience.snark.SiteData
|
import space.kscience.snark.SiteData
|
||||||
import space.kscience.snark.homeRef
|
import space.kscience.snark.homeRef
|
||||||
|
import space.kscience.snark.resolvePage
|
||||||
import space.kscience.snark.resolveRef
|
import space.kscience.snark.resolveRef
|
||||||
|
|
||||||
|
|
||||||
@ -39,25 +40,25 @@ context(SiteData) internal fun FlowContent.spcHomeMenu() {
|
|||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
href = resolveRef("magprog")
|
href = resolvePage("magprog")
|
||||||
+"""Master"""
|
+"""Master"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
href = resolveRef("research")
|
href = resolvePage("research")
|
||||||
+"""Research"""
|
+"""Research"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
href = resolveRef("consulting")
|
href = resolvePage("consulting")
|
||||||
+"""Consulting"""
|
+"""Consulting"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
href = resolveRef("team")
|
href = resolvePage("team")
|
||||||
+"""Team"""
|
+"""Team"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ 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
|
||||||
import space.kscience.dataforge.data.DataTree
|
import space.kscience.dataforge.data.DataTree
|
||||||
|
import space.kscience.dataforge.meta.Laminate
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.parseAsName
|
import space.kscience.dataforge.names.parseAsName
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -56,8 +57,8 @@ public inline fun SiteBuilder.route(route: String, block: SiteBuilder.() -> Unit
|
|||||||
public fun SiteBuilder.mountSite(route: Name, dataRoot: DataTree<*>, block: SiteBuilder.() -> Unit) {
|
public fun SiteBuilder.mountSite(route: Name, dataRoot: DataTree<*>, block: SiteBuilder.() -> Unit) {
|
||||||
val mountedData = data.copy(
|
val mountedData = data.copy(
|
||||||
data = dataRoot,
|
data = dataRoot,
|
||||||
baseUrlPath = data.baseUrlPath.removeSuffix("/") + "/" + route.toWebPath(),
|
baseUrlPath = data.resolveRef(route.tokens.joinToString(separator = "/")),
|
||||||
meta = dataRoot.meta // TODO consider meshing sub-site meta with the parent site
|
meta = Laminate(dataRoot.meta, data.meta) //layering dataRoot meta over existing data
|
||||||
)
|
)
|
||||||
route(route) {
|
route(route) {
|
||||||
withData(mountedData).block()
|
withData(mountedData).block()
|
||||||
|
@ -6,11 +6,8 @@ import space.kscience.dataforge.data.*
|
|||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.*
|
||||||
import space.kscience.dataforge.names.NameToken
|
import space.kscience.snark.SiteData.Companion.INDEX_PAGE_TOKEN
|
||||||
import space.kscience.dataforge.names.plus
|
|
||||||
import space.kscience.dataforge.names.startsWith
|
|
||||||
import space.kscience.snark.SiteData.Companion.INDEX_PAGE_NAME
|
|
||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
@ -18,7 +15,7 @@ data class SiteData(
|
|||||||
val snark: SnarkPlugin,
|
val snark: SnarkPlugin,
|
||||||
val data: DataTree<*>,
|
val data: DataTree<*>,
|
||||||
val baseUrlPath: String,
|
val baseUrlPath: String,
|
||||||
override val meta: Meta = data.meta,
|
override val meta: Meta,
|
||||||
) : ContextAware, DataTree<Any> by data {
|
) : ContextAware, DataTree<Any> by data {
|
||||||
|
|
||||||
override val context: Context get() = snark.context
|
override val context: Context get() = snark.context
|
||||||
@ -28,33 +25,49 @@ data class SiteData(
|
|||||||
companion object {
|
companion object {
|
||||||
fun empty(
|
fun empty(
|
||||||
snark: SnarkPlugin,
|
snark: SnarkPlugin,
|
||||||
baseUrlPath: String = "/",
|
baseUrlPath: String = "",
|
||||||
meta: Meta = Meta.EMPTY,
|
meta: Meta = Meta.EMPTY,
|
||||||
): SiteData {
|
): SiteData {
|
||||||
|
//TODO use empty data from DF
|
||||||
val emptyData = object : DataTree<Any> {
|
val emptyData = object : DataTree<Any> {
|
||||||
override val items: Map<NameToken, DataTreeItem<Any>> get() = emptyMap()
|
override val items: Map<NameToken, DataTreeItem<Any>> get() = emptyMap()
|
||||||
override val dataType: KType get() = typeOf<Any>()
|
override val dataType: KType get() = typeOf<Any>()
|
||||||
override val meta: Meta get() = meta
|
override val meta: Meta get() = meta
|
||||||
}
|
}
|
||||||
return SiteData(snark, emptyData, baseUrlPath)
|
return SiteData(snark, emptyData, baseUrlPath, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
const val INDEX_PAGE_NAME: String = "index"
|
const val INDEX_PAGE_TOKEN: String = "index"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a resource full path by its name
|
* Resolve a resource full path by its name
|
||||||
*/
|
*/
|
||||||
fun SiteData.resolveRef(name: String): String = "${baseUrlPath.removeSuffix("/")}/$name"
|
fun SiteData.resolveRef(name: String): String = if (baseUrlPath.isEmpty()) {
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
"${baseUrlPath.removeSuffix("/")}/$name"
|
||||||
|
}
|
||||||
|
|
||||||
fun SiteData.resolveRef(name: Name): String = "${baseUrlPath.removeSuffix("/")}/${name.tokens.joinToString("/")}"
|
/**
|
||||||
|
* Resolve a page designated by given name. Depending on rendering specifics, some prefixes or suffixes could be added.
|
||||||
|
*/
|
||||||
|
fun SiteData.resolvePage(name: Name): String =
|
||||||
|
resolveRef(name.tokens.joinToString("/")) + (meta["pageSuffix"].string ?: "")
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fun SiteData.resolvePage(name: String): String = resolvePage(name.parseAsName())
|
||||||
|
|
||||||
|
val SiteData.homeRef get() = resolvePage(Name.EMPTY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a Html builder by its full name
|
* Resolve a Html builder by its full name
|
||||||
*/
|
*/
|
||||||
fun DataTree<*>.resolveHtml(name: Name): HtmlData? {
|
fun DataTree<*>.resolveHtml(name: Name): HtmlData? {
|
||||||
val resolved = (getByType<HtmlFragment>(name) ?: getByType<HtmlFragment>(name + INDEX_PAGE_NAME))
|
val resolved = (getByType<HtmlFragment>(name) ?: getByType<HtmlFragment>(name + INDEX_PAGE_TOKEN))
|
||||||
|
|
||||||
return resolved?.takeIf {
|
return resolved?.takeIf {
|
||||||
it.published //TODO add language confirmation
|
it.published //TODO add language confirmation
|
||||||
@ -71,7 +84,6 @@ fun DataTree<*>.resolveAllHtml(predicate: (name: Name, meta: Meta) -> Boolean):
|
|||||||
//TODO add language confirmation
|
//TODO add language confirmation
|
||||||
}.asSequence().associate { it.name to it.data }
|
}.asSequence().associate { it.name to it.data }
|
||||||
|
|
||||||
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
|
||||||
|
@ -3,23 +3,24 @@ package space.kscience.snark
|
|||||||
import kotlinx.html.HTML
|
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.meta.Meta
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.isEmpty
|
import space.kscience.dataforge.names.isEmpty
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.copyTo
|
import kotlin.io.path.*
|
||||||
import kotlin.io.path.createDirectories
|
|
||||||
import kotlin.io.path.relativeTo
|
|
||||||
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) {
|
private fun Path.copyRecursively(target: Path) {
|
||||||
Files.walk(this).forEach { source: Path ->
|
Files.walk(this).forEach { source: Path ->
|
||||||
val destination: Path = target.resolve(source.relativeTo(this))
|
val destination: Path = target.resolve(source.relativeTo(this))
|
||||||
|
if(!destination.isDirectory()) {
|
||||||
|
//avoid re-creating directories
|
||||||
source.copyTo(destination, true)
|
source.copyTo(destination, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun assetFile(remotePath: String, file: Path) {
|
override fun assetFile(remotePath: String, file: Path) {
|
||||||
val targetPath = path.resolve(remotePath)
|
val targetPath = path.resolve(remotePath)
|
||||||
@ -68,5 +69,12 @@ class StaticSiteBuilder(override val data: SiteData, private val path: Path) : S
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun SnarkPlugin.static(path: Path, block: SiteBuilder.() -> Unit) {
|
fun SnarkPlugin.static(path: Path, block: SiteBuilder.() -> Unit) {
|
||||||
StaticSiteBuilder(SiteData.empty(this), path).block()
|
val base = SiteData.empty(
|
||||||
|
this,
|
||||||
|
baseUrlPath = path.absolutePathString(),
|
||||||
|
meta = Meta {
|
||||||
|
"pageSuffix" put "/index.html"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
StaticSiteBuilder(base, path).block()
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user