2022-05-13 17:21:06 +03:00
|
|
|
package ru.mipt.spc
|
|
|
|
|
|
|
|
import html5up.forty.fortyScripts
|
|
|
|
import io.ktor.server.application.Application
|
2022-06-20 17:10:37 +03:00
|
|
|
import io.ktor.server.routing.route
|
|
|
|
import io.ktor.server.routing.routing
|
2022-05-13 17:21:06 +03:00
|
|
|
import kotlinx.html.*
|
|
|
|
import space.kscience.dataforge.context.Context
|
2022-06-20 17:10:37 +03:00
|
|
|
import space.kscience.dataforge.context.error
|
2022-05-13 17:21:06 +03:00
|
|
|
import space.kscience.dataforge.context.fetch
|
2022-06-20 17:10:37 +03:00
|
|
|
import space.kscience.dataforge.context.logger
|
2022-06-22 12:18:35 +03:00
|
|
|
import space.kscience.dataforge.data.Data
|
2022-05-21 13:38:15 +03:00
|
|
|
import space.kscience.dataforge.meta.Meta
|
2022-05-13 17:21:06 +03:00
|
|
|
import space.kscience.dataforge.meta.get
|
|
|
|
import space.kscience.dataforge.meta.string
|
2022-06-22 12:18:35 +03:00
|
|
|
import space.kscience.dataforge.names.Name
|
|
|
|
import space.kscience.dataforge.names.asName
|
|
|
|
import space.kscience.dataforge.names.startsWith
|
2022-05-21 19:21:21 +03:00
|
|
|
import space.kscience.dataforge.values.string
|
2022-05-13 17:21:06 +03:00
|
|
|
import space.kscience.snark.*
|
|
|
|
import java.nio.file.Path
|
2022-06-22 12:18:35 +03:00
|
|
|
import kotlin.reflect.typeOf
|
2022-05-13 17:21:06 +03:00
|
|
|
|
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
context(SiteData) internal fun HTML.spcPageContent(
|
2022-05-21 13:38:15 +03:00
|
|
|
meta: Meta,
|
|
|
|
title: String = meta["title"].string ?: SPC_TITLE,
|
|
|
|
fragment: FlowContent.() -> Unit,
|
|
|
|
) {
|
2022-05-13 17:21:06 +03:00
|
|
|
spcHead(title)
|
|
|
|
body("is-preload") {
|
|
|
|
wrapper {
|
|
|
|
div("alt") {
|
|
|
|
id = "main"
|
|
|
|
// One
|
|
|
|
section {
|
|
|
|
div("inner") {
|
|
|
|
header("major") {
|
|
|
|
h1 { +title }
|
|
|
|
}
|
2022-05-21 19:21:21 +03:00
|
|
|
meta["image"]?.let { imageMeta ->
|
2022-05-21 20:10:44 +03:00
|
|
|
val imagePath =
|
|
|
|
imageMeta.value?.string ?: imageMeta["path"].string ?: error("Image path not provided")
|
2022-05-21 19:21:21 +03:00
|
|
|
val imageClass = imageMeta["position"].string ?: "main"
|
|
|
|
span("image $imageClass") {
|
2022-05-13 17:21:06 +03:00
|
|
|
img {
|
|
|
|
src = resolveRef(imagePath)
|
|
|
|
alt = imagePath
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-21 13:38:15 +03:00
|
|
|
fragment()
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fortyScripts()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-21 13:38:15 +03:00
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
internal fun SiteBuilder.spcPage(subRoute: Name, meta: Meta, fragment: FlowContent.() -> Unit) {
|
2022-06-20 17:10:37 +03:00
|
|
|
page(subRoute) {
|
|
|
|
spcPageContent(meta, fragment = fragment)
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
internal fun SiteBuilder.spcPage(
|
|
|
|
subRoute: Name,
|
|
|
|
dataPath: Name = subRoute,
|
2022-05-21 13:38:15 +03:00
|
|
|
more: FlowContent.() -> Unit = {},
|
|
|
|
) {
|
2022-06-22 12:18:35 +03:00
|
|
|
val data = data.resolveHtml(dataPath)
|
2022-05-13 17:21:06 +03:00
|
|
|
if (data != null) {
|
2022-05-21 13:38:15 +03:00
|
|
|
spcPage(subRoute, data.meta) {
|
|
|
|
htmlData(data)
|
|
|
|
more()
|
|
|
|
}
|
2022-05-13 17:21:06 +03:00
|
|
|
} else {
|
2022-06-20 17:10:37 +03:00
|
|
|
logger.error { "Content for page with path $dataPath not found" }
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
2022-06-15 14:53:36 +03:00
|
|
|
}
|
2022-05-13 17:21:06 +03:00
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
|
|
internal val FortyDataRenderer: SiteBuilder.(Data<*>) -> Unit = { data ->
|
|
|
|
if(data.type == typeOf<HtmlFragment>()) {
|
|
|
|
data as Data<HtmlFragment>
|
|
|
|
page {
|
|
|
|
spcPageContent(data.meta) {
|
|
|
|
htmlData(data)
|
|
|
|
}
|
2022-06-15 14:53:36 +03:00
|
|
|
}
|
|
|
|
}
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
///**
|
|
|
|
// * Route a directory
|
|
|
|
// */
|
|
|
|
//internal fun SiteBuilder.spcDirectory(
|
|
|
|
// subRoute: String,
|
|
|
|
// dataPath: Name = subRoute.replace("/", ".").parseAsName(),
|
|
|
|
//) {
|
|
|
|
// data.filterByType<HtmlFragment> { name, _ -> name.startsWith(dataPath) }.forEach { html ->
|
|
|
|
// val pageName = if (html.name.lastOrNull()?.body == SiteData.INDEX_PAGE_NAME) {
|
|
|
|
// html.name.cutLast()
|
|
|
|
// } else {
|
|
|
|
// html.name
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// spcPage(pageName.tokens.joinToString(separator = "/"), html.meta) {
|
|
|
|
// htmlData(html)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
internal fun SiteBuilder.spcPage(
|
2022-05-21 13:38:15 +03:00
|
|
|
name: Name,
|
|
|
|
more: FlowContent.() -> Unit = {},
|
|
|
|
) {
|
2022-06-22 12:18:35 +03:00
|
|
|
spcPage(name, name, more)
|
2022-05-21 13:38:15 +03:00
|
|
|
}
|
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
context(SiteData, HTML) private fun HTML.spcHome() {
|
2022-05-13 17:21:06 +03:00
|
|
|
spcHead()
|
|
|
|
body("is-preload") {
|
|
|
|
wrapper {
|
|
|
|
// Banner
|
|
|
|
section("major") {
|
|
|
|
id = "banner"
|
|
|
|
div("inner") {
|
|
|
|
header("major") {
|
|
|
|
h1 { +"""Scientific Programming Centre""" }
|
|
|
|
}
|
|
|
|
div("content") {
|
|
|
|
p {
|
2022-05-21 20:10:44 +03:00
|
|
|
+"Programming in Science"
|
2022-05-25 21:23:56 +03:00
|
|
|
br {}
|
2022-05-21 20:10:44 +03:00
|
|
|
entity(Entities.nbsp)
|
|
|
|
+"and Science in Programming"
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
ul("actions") {
|
|
|
|
li {
|
|
|
|
a(classes = "button next scrolly") {
|
|
|
|
href = "#master"
|
|
|
|
+"""Activities"""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Main
|
|
|
|
div {
|
|
|
|
id = "main"
|
2022-05-25 21:23:56 +03:00
|
|
|
section {
|
|
|
|
div("inner") {
|
|
|
|
a(href = "https://mipt.ru/education/departments/fpmi/") {
|
|
|
|
span("image left") {
|
|
|
|
img {
|
|
|
|
src = "images/FPMI.jpg"
|
|
|
|
alt = "FPMI"
|
2022-06-08 18:37:54 +03:00
|
|
|
height = "60"
|
|
|
|
width = "60"
|
2022-05-25 21:23:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p {
|
|
|
|
+"Centre was created in 2022 based on the Phystech School of Applied Mathematics and Informatics at MIPT"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
section {
|
|
|
|
div("inner") {
|
|
|
|
header("major") {
|
|
|
|
h2 { +"Science + education + industry" }
|
|
|
|
}
|
|
|
|
p {
|
|
|
|
+"""
|
|
|
|
Our mission is to bring together science, education and industry and
|
|
|
|
work on better software solutions for science and better science in
|
|
|
|
software development.
|
|
|
|
""".trimIndent()
|
|
|
|
}
|
|
|
|
// ul("actions") {
|
|
|
|
// li {
|
|
|
|
// a(classes = "button next") {
|
|
|
|
// href = "landing.html"
|
|
|
|
// +"""Get Started"""
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 17:21:06 +03:00
|
|
|
section("tiles") {
|
|
|
|
id = "master"
|
|
|
|
article {
|
|
|
|
span("image") {
|
|
|
|
img {
|
|
|
|
src = resolveRef("images/pic01.jpg")
|
|
|
|
alt = ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
header("major") {
|
|
|
|
h3 {
|
|
|
|
a(classes = "link") {
|
|
|
|
href = resolveRef("magprog")
|
2022-06-08 18:37:54 +03:00
|
|
|
+"""Master's program"""
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
}
|
2022-06-08 18:37:54 +03:00
|
|
|
p { +"""Master's program: "Scientific programming" """ }
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
article {
|
|
|
|
span("image") {
|
|
|
|
img {
|
|
|
|
src = resolveRef("images/pic02.jpg")
|
|
|
|
alt = ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
header("major") {
|
|
|
|
h3 {
|
|
|
|
a(classes = "link") {
|
|
|
|
href = resolveRef("research")
|
|
|
|
+"""Research"""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p {
|
2022-05-21 19:21:21 +03:00
|
|
|
+"""Fundamental and applied research in analysis, scientific software design and data acquisition and control systems."""
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
article {
|
|
|
|
span("image") {
|
|
|
|
img {
|
|
|
|
src = resolveRef("images/pic03.jpg")
|
|
|
|
alt = ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
header("major") {
|
|
|
|
h3 {
|
|
|
|
a(classes = "link") {
|
|
|
|
href = resolveRef("consulting")
|
|
|
|
+"""Consulting"""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p { +"""Consultations, review and support of scientific software systems.""" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
article {
|
|
|
|
span("image") {
|
|
|
|
img {
|
|
|
|
src = resolveRef("images/pic04.jpg")
|
|
|
|
alt = ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
header("major") {
|
|
|
|
h3 {
|
|
|
|
a(classes = "link") {
|
|
|
|
href = resolveRef("team")
|
|
|
|
+"""Team"""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// article {
|
|
|
|
// span("image") {
|
|
|
|
// img {
|
|
|
|
// src = "images/pic05.jpg"
|
|
|
|
// alt = ""
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// header("major") {
|
|
|
|
// h3 {
|
|
|
|
// a(classes = "link") {
|
|
|
|
// href = "landing.html"
|
|
|
|
// +"""Consequat"""
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// p { +"""Ipsum dolor sit amet""" }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// article {
|
|
|
|
// span("image") {
|
|
|
|
// img {
|
|
|
|
// src = "images/pic06.jpg"
|
|
|
|
// alt = ""
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// header("major") {
|
|
|
|
// h3 {
|
|
|
|
// a(classes = "link") {
|
|
|
|
// href = "landing.html"
|
|
|
|
// +"""Etiam"""
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// p { +"""Feugiat amet tempus""" }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fortyScripts()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun Application.spcHome(context: Context, rootPath: Path, prefix: String = "") {
|
|
|
|
|
|
|
|
val snark = context.fetch(SnarkPlugin)
|
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
val homePageContext = snark.readDirectory(rootPath.resolve("content"), prefix)
|
2022-05-13 17:21:06 +03:00
|
|
|
|
|
|
|
routing {
|
|
|
|
route(prefix) {
|
2022-06-21 10:52:24 +03:00
|
|
|
snarkSite(homePageContext) {
|
2022-06-22 12:18:35 +03:00
|
|
|
assetDirectory("assets", rootPath.resolve("assets"))
|
|
|
|
assetDirectory("images", rootPath.resolve("images"))
|
2022-05-13 17:21:06 +03:00
|
|
|
|
2022-06-20 17:10:37 +03:00
|
|
|
page { spcHome() }
|
2022-05-13 17:21:06 +03:00
|
|
|
|
2022-06-22 12:18:35 +03:00
|
|
|
pages("consulting", dataRenderer = FortyDataRenderer)
|
|
|
|
//pages("ru.consulting".parseAsName(), dataRenderer = FortyDataRenderer)
|
2022-05-21 13:38:15 +03:00
|
|
|
|
2022-05-21 19:21:21 +03:00
|
|
|
spcSpotlight("team") { _, m -> m["type"].string == "team" }
|
2022-06-15 14:53:36 +03:00
|
|
|
spcSpotlight("research") { name, m -> name.startsWith("projects".asName()) && m["type"].string == "project" }
|
2022-05-13 17:21:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|