1
0
forked from SPC/spc-site

Multiple engine logic cleanup

This commit is contained in:
Alexander Nozik 2022-06-23 10:44:16 +03:00
parent d657282a33
commit 846c02020b
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
7 changed files with 56 additions and 33 deletions

View File

@ -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(" ")
} }
} }

View File

@ -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 ->

View File

@ -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"""
} }
} }

View File

@ -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"""
} }
} }

View File

@ -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()

View File

@ -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

View File

@ -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()
} }