diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/DataRenderer.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/DataRenderer.kt
index cd1a00f..36c0363 100644
--- a/snark-html/src/main/kotlin/space/kscience/snark/html/DataRenderer.kt
+++ b/snark-html/src/main/kotlin/space/kscience/snark/html/DataRenderer.kt
@@ -7,7 +7,9 @@ import space.kscience.dataforge.data.Data
import space.kscience.dataforge.data.getItem
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.names.Name
-import space.kscience.dataforge.names.appendLeft
+import space.kscience.dataforge.names.asName
+import space.kscience.dataforge.names.plus
+import space.kscience.dataforge.names.removeHeadOrNull
import kotlin.reflect.typeOf
/**
@@ -51,9 +53,15 @@ public interface DataRenderer {
*/
context(SiteBuilder)
public fun buildLanguageMeta(name: Name): Meta = Meta {
+ val currentLanguagePrefix = languages[language]?.get("prefix")?.string ?: language
+ val fullName = (route.removeHeadOrNull(currentLanguagePrefix.asName()) ?: route) + name
languages.forEach { (key, meta) ->
- val languagePrefix = meta["prefix"].string ?: key
- val nameWithLanguage: Name = if (languagePrefix.isBlank()) name else name.appendLeft(languagePrefix)
+ val languagePrefix: String = meta["prefix"].string ?: key
+ val nameWithLanguage: Name = if (languagePrefix.isBlank()) {
+ fullName
+ } else {
+ languagePrefix.asName() + fullName
+ }
if (data.getItem(name) != null) {
key put meta.asMutableMeta().apply {
"target" put nameWithLanguage.toString()
diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt
index b998d5f..fb764ca 100644
--- a/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt
+++ b/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt
@@ -6,6 +6,7 @@ import kotlinx.html.stream.createHTML
import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.meta.Laminate
import space.kscience.dataforge.meta.Meta
+import space.kscience.dataforge.meta.toMutableMeta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.isEmpty
import space.kscience.dataforge.names.plus
@@ -87,8 +88,12 @@ internal class StaticSiteBuilder(
override fun page(route: Name, pageMeta: Meta, content: context(WebPage, HTML) () -> Unit) {
val htmlBuilder = createHTML()
+ val modifiedPageMeta = pageMeta.toMutableMeta().apply {
+ "name" put route.toString()
+ }
+
htmlBuilder.html {
- content(StaticWebPage(pageMeta), this)
+ content(StaticWebPage(Laminate(modifiedPageMeta, siteMeta)), this)
}
val newPath = if (route.isEmpty()) {
diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/WebPage.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/WebPage.kt
index d7f338b..f35ca6f 100644
--- a/snark-html/src/main/kotlin/space/kscience/snark/html/WebPage.kt
+++ b/snark-html/src/main/kotlin/space/kscience/snark/html/WebPage.kt
@@ -56,6 +56,8 @@ public fun WebPage.resolvePageRef(pageName: String): String = resolvePageRef(pag
public val WebPage.homeRef: String get() = resolvePageRef(SiteBuilder.INDEX_PAGE_TOKEN.asName())
+public val WebPage.name: Name? get() = pageMeta["name"].string?.parseAsName()
+
/**
* Resolve a Html builder by its full name
*/
diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/language.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/localization.kt
similarity index 68%
rename from snark-html/src/main/kotlin/space/kscience/snark/html/language.kt
rename to snark-html/src/main/kotlin/space/kscience/snark/html/localization.kt
index eac5566..2f6122d 100644
--- a/snark-html/src/main/kotlin/space/kscience/snark/html/language.kt
+++ b/snark-html/src/main/kotlin/space/kscience/snark/html/localization.kt
@@ -1,5 +1,6 @@
package space.kscience.snark.html
+import space.kscience.dataforge.data.getItem
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string
@@ -13,6 +14,9 @@ public val SiteBuilder.languages: Map
public val SiteBuilder.language: String
get() = siteMeta["site.language"].string ?: "en"
+public val SiteBuilder.languagePrefix: Name
+ get() = languages[language]?.let { it["prefix"].string ?: language }?.parseAsName() ?: Name.EMPTY
+
public fun SiteBuilder.withLanguages(languageMap: Map, block: SiteBuilder.(language: String) -> Unit) {
languageMap.forEach { (languageKey, languageMeta) ->
val prefix = languageMeta["prefix"].string ?: languageKey
@@ -56,4 +60,29 @@ public val WebPage.languages: Map
public fun WebPage.localisedPageRef(pageName: Name, relative: Boolean = false): String {
val prefix = languages[language]?.get("prefix")?.string?.parseAsName() ?: Name.EMPTY
return resolvePageRef(prefix + pageName, relative)
+}
+
+
+/**
+ * Render all pages in a node with given name. Use localization prefix if appropriate data is available.
+ */
+public fun SiteBuilder.localizedPages(
+ dataPath: Name,
+ remotePath: Name = dataPath,
+ dataRenderer: DataRenderer = DataRenderer.DEFAULT,
+) {
+ val item = data.getItem(languagePrefix + dataPath)
+ ?: data.getItem(dataPath)
+ ?: error("No data found by name $dataPath")
+ route(remotePath) {
+ pages(item, dataRenderer)
+ }
+}
+
+public fun SiteBuilder.localizedPages(
+ dataPath: String,
+ remotePath: Name = dataPath.parseAsName(),
+ dataRenderer: DataRenderer = DataRenderer.DEFAULT,
+) {
+ localizedPages(dataPath.parseAsName(), remotePath, dataRenderer = dataRenderer)
}
\ No newline at end of file
diff --git a/snark-ktor/src/main/kotlin/space/kscience/snark/ktor/KtorSiteBuilder.kt b/snark-ktor/src/main/kotlin/space/kscience/snark/ktor/KtorSiteBuilder.kt
index 015f707..86850ed 100644
--- a/snark-ktor/src/main/kotlin/space/kscience/snark/ktor/KtorSiteBuilder.kt
+++ b/snark-ktor/src/main/kotlin/space/kscience/snark/ktor/KtorSiteBuilder.kt
@@ -18,6 +18,7 @@ import kotlinx.html.style
import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.meta.Laminate
import space.kscience.dataforge.meta.Meta
+import space.kscience.dataforge.meta.toMutableMeta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.cutLast
import space.kscience.dataforge.names.endsWith
@@ -97,7 +98,12 @@ public class KtorSiteBuilder(
port = request.origin.port
}
- val pageBuilder = KtorWebPage(url.buildString(), Laminate(pageMeta, siteMeta))
+ val modifiedPageMeta = pageMeta.toMutableMeta().apply {
+ "name" put route.toString()
+ "url" put url.buildString()
+ }
+
+ val pageBuilder = KtorWebPage(url.buildString(), Laminate(modifiedPageMeta, siteMeta))
content(pageBuilder, this)
}
}