Add language support

This commit is contained in:
Alexander Nozik 2023-01-08 21:26:11 +03:00
parent f43b23c84f
commit f4201bea7a
5 changed files with 55 additions and 5 deletions

View File

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

View File

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

View File

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

View File

@ -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<String, Meta>
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<String, Meta>, block: SiteBuilder.(language: String) -> Unit) {
languageMap.forEach { (languageKey, languageMeta) ->
val prefix = languageMeta["prefix"].string ?: languageKey
@ -56,4 +60,29 @@ public val WebPage.languages: Map<String, Meta>
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)
}

View File

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