forked from SPC/spc-site
Spliting site and the snark project complete
This commit is contained in:
parent
eb81d46238
commit
5e93f982f8
@ -29,6 +29,7 @@ dependencies {
|
||||
|
||||
implementation("io.ktor:ktor-server-netty:$ktorVersion")
|
||||
implementation("io.ktor:ktor-server-http-redirect:$ktorVersion")
|
||||
implementation("ch.qos.logback:logback-classic:1.2.11")
|
||||
|
||||
testImplementation("io.ktor:ktor-server-tests:$ktorVersion")
|
||||
}
|
||||
@ -43,7 +44,7 @@ apiValidation{
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers"
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers"
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
data/common/android-chrome-192x192.png
Normal file
BIN
data/common/android-chrome-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
data/common/android-chrome-512x512.png
Normal file
BIN
data/common/android-chrome-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
BIN
data/common/apple-touch-icon.png
Normal file
BIN
data/common/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
data/common/favicon-16x16.png
Normal file
BIN
data/common/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 810 B |
BIN
data/common/favicon-32x32.png
Normal file
BIN
data/common/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
data/common/favicon.ico
Normal file
BIN
data/common/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
1
data/common/site.webmanifest
Normal file
1
data/common/site.webmanifest
Normal file
@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
@ -1,7 +1,7 @@
|
||||
package html5up.forty
|
||||
|
||||
import kotlinx.html.*
|
||||
import space.kscience.snark.html.Page
|
||||
import space.kscience.snark.html.WebPage
|
||||
|
||||
|
||||
internal fun FlowContent.fortyMenu() {
|
||||
@ -200,7 +200,7 @@ internal fun FlowContent.fortyFooter() {
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) internal fun BODY.fortyScripts() {
|
||||
context(WebPage) internal fun BODY.fortyScripts() {
|
||||
script {
|
||||
src = resolveRef("assets/js/jquery.min.js")
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package html5up.forty
|
||||
|
||||
import kotlinx.html.*
|
||||
import space.kscience.snark.html.Page
|
||||
import space.kscience.snark.html.WebPage
|
||||
|
||||
context(Page) internal fun HTML.landing(){
|
||||
context(WebPage) internal fun HTML.landing(){
|
||||
head {
|
||||
title {
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package html5up.forty
|
||||
|
||||
import kotlinx.html.*
|
||||
import space.kscience.snark.html.Page
|
||||
import space.kscience.snark.html.WebPage
|
||||
|
||||
context(Page) internal fun HTML.fortyPage(){
|
||||
context(WebPage) internal fun HTML.fortyPage(){
|
||||
head {
|
||||
title {
|
||||
}
|
||||
|
@ -5,10 +5,8 @@ import io.ktor.server.application.log
|
||||
import kotlinx.css.CssBuilder
|
||||
import kotlinx.html.CommonAttributeGroupFacade
|
||||
import kotlinx.html.style
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.snark.html.SnarkPlugin
|
||||
import space.kscience.snark.ktor.snarkSite
|
||||
import space.kscience.snark.SnarkEnvironment
|
||||
import space.kscience.snark.ktor.site
|
||||
import java.net.URI
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
@ -49,11 +47,6 @@ const val BUILD_DATE_FILE = "/buildDate"
|
||||
fun Application.spcModule() {
|
||||
// install(HttpsRedirect)
|
||||
|
||||
val context = Context("spc-site") {
|
||||
plugin(SnarkPlugin)
|
||||
}
|
||||
val snark = context.fetch(SnarkPlugin)
|
||||
|
||||
val dataPath = Path.of("data")
|
||||
|
||||
// Clear data directory if it is outdated
|
||||
@ -88,20 +81,20 @@ fun Application.spcModule() {
|
||||
dataPath.resolve(DEPLOY_DATE_FILE).writeText(date)
|
||||
}
|
||||
|
||||
snarkSite(snark) {
|
||||
SnarkEnvironment.default.site {
|
||||
val homeDataPath = resolveData(
|
||||
this@spcModule.javaClass.getResource("/home")!!.toURI(),
|
||||
dataPath / "home"
|
||||
)
|
||||
|
||||
spcHome(rootPath = homeDataPath)
|
||||
spcHome(dataPath = homeDataPath)
|
||||
|
||||
val mastersDataPath = resolveData(
|
||||
this@spcModule.javaClass.getResource("/magprog")!!.toURI(),
|
||||
dataPath / "magprog"
|
||||
)
|
||||
|
||||
spcMaster(dataPath = mastersDataPath)
|
||||
spcMasters(dataPath = mastersDataPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
context(Page) private fun FlowContent.spcSpotlightContent(
|
||||
context(WebPage) private fun FlowContent.spcSpotlightContent(
|
||||
landing: HtmlData,
|
||||
content: Map<Name, HtmlData>,
|
||||
) {
|
||||
|
@ -15,7 +15,7 @@ import java.nio.file.Path
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
|
||||
context(Page) internal fun HTML.spcPageContent(
|
||||
context(WebPage) internal fun HTML.spcPageContent(
|
||||
meta: Meta,
|
||||
title: String = meta["title"].string ?: SPC_TITLE,
|
||||
fragment: FlowContent.() -> Unit,
|
||||
@ -65,7 +65,7 @@ internal val FortyDataRenderer: DataRenderer = { name, data ->
|
||||
}
|
||||
|
||||
|
||||
context(Page) private fun HTML.spcHome() {
|
||||
context(WebPage) private fun HTML.spcHome() {
|
||||
spcHead()
|
||||
body("is-preload") {
|
||||
wrapper {
|
||||
@ -252,13 +252,14 @@ context(Page) private fun HTML.spcHome() {
|
||||
|
||||
}
|
||||
|
||||
internal fun SiteBuilder.spcHome(rootPath: Path, prefix: Name = Name.EMPTY) {
|
||||
internal fun SiteBuilder.spcHome(dataPath: Path, prefix: Name = Name.EMPTY) {
|
||||
|
||||
val homePageData = snark.readDirectory(rootPath.resolve("content"))
|
||||
val homePageData = snark.readDirectory(dataPath.resolve("content"))
|
||||
|
||||
route(prefix, homePageData, setAsRoot = true) {
|
||||
assetDirectory("assets", rootPath.resolve("assets"))
|
||||
assetDirectory("images", rootPath.resolve("images"))
|
||||
file(dataPath.resolve("assets"))
|
||||
file(dataPath.resolve("images"))
|
||||
file(dataPath.resolve("../common"), "")
|
||||
|
||||
page { spcHome() }
|
||||
|
||||
|
@ -15,7 +15,7 @@ import space.kscience.dataforge.names.plus
|
||||
import space.kscience.dataforge.names.withIndex
|
||||
import space.kscience.snark.*
|
||||
import space.kscience.snark.html.*
|
||||
import space.kscience.snark.html.Page
|
||||
import space.kscience.snark.html.WebPage
|
||||
import java.nio.file.Path
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
@ -37,14 +37,14 @@ import kotlin.collections.set
|
||||
private val HtmlData.imagePath: String? get() = meta["image"]?.string ?: meta["image.path"].string
|
||||
private val HtmlData.name: String get() = meta["name"].string ?: error("Name not found")
|
||||
|
||||
context(Page) class MagProgSection(
|
||||
context(WebPage) class MagProgSection(
|
||||
val id: String,
|
||||
val title: String,
|
||||
val style: String,
|
||||
val content: FlowContent.() -> Unit,
|
||||
)
|
||||
|
||||
context(Page) private fun wrapSection(
|
||||
context(WebPage) private fun wrapSection(
|
||||
id: String,
|
||||
title: String,
|
||||
sectionContent: FlowContent.() -> Unit,
|
||||
@ -55,7 +55,7 @@ context(Page) private fun wrapSection(
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) private fun wrapSection(
|
||||
context(WebPage) private fun wrapSection(
|
||||
block: HtmlData,
|
||||
idOverride: String? = null,
|
||||
): MagProgSection = wrapSection(
|
||||
@ -73,7 +73,7 @@ private val PROGRAM_PATH: Name = CONTENT_NODE_NAME + "program"
|
||||
private val RECOMMENDED_COURSES_PATH: Name = CONTENT_NODE_NAME + "recommendedCourses"
|
||||
private val PARTNERS_PATH: Name = CONTENT_NODE_NAME + "partners"
|
||||
|
||||
context(Page) private fun FlowContent.programSection() {
|
||||
context(WebPage) private fun FlowContent.programSection() {
|
||||
val programBlock = data.resolveHtml(PROGRAM_PATH)!!
|
||||
val recommendedBlock = data.resolveHtml(RECOMMENDED_COURSES_PATH)!!
|
||||
div("inner") {
|
||||
@ -90,7 +90,7 @@ context(Page) private fun FlowContent.programSection() {
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) private fun FlowContent.partners() {
|
||||
context(WebPage) private fun FlowContent.partners() {
|
||||
//val partnersData: Meta = resolve<Any>(PARTNERS_PATH)?.meta ?: Meta.EMPTY
|
||||
val partnersData: Meta = runBlocking { data.getByType<Meta>(PARTNERS_PATH)?.await() } ?: Meta.EMPTY
|
||||
div("inner") {
|
||||
@ -120,7 +120,7 @@ context(Page) private fun FlowContent.partners() {
|
||||
// val photo: String? by meta.string()
|
||||
//}
|
||||
|
||||
context(Page) private fun FlowContent.team() {
|
||||
context(WebPage) private fun FlowContent.team() {
|
||||
val team = data.findByContentType("magprog_team").values.sortedBy { it.order }
|
||||
|
||||
div("inner") {
|
||||
@ -175,7 +175,7 @@ context(Page) private fun FlowContent.team() {
|
||||
// }
|
||||
}
|
||||
|
||||
context(Page) private fun FlowContent.mentors() {
|
||||
context(WebPage) private fun FlowContent.mentors() {
|
||||
val mentors = data.findByContentType("magprog_mentor").entries.sortedBy { it.value.id }
|
||||
|
||||
div("inner") {
|
||||
@ -213,7 +213,7 @@ context(Page) private fun FlowContent.mentors() {
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) internal fun HTML.magProgHead(title: String) {
|
||||
context(WebPage) internal fun HTML.magProgHead(title: String) {
|
||||
head {
|
||||
this.title = title
|
||||
meta {
|
||||
@ -237,10 +237,31 @@ context(Page) internal fun HTML.magProgHead(title: String) {
|
||||
href = resolveRef("assets/css/noscript.css")
|
||||
}
|
||||
}
|
||||
link {
|
||||
rel = "apple-touch-icon"
|
||||
sizes = "180x180"
|
||||
href = "/apple-touch-icon.png"
|
||||
}
|
||||
link {
|
||||
rel = "icon"
|
||||
type = "image/png"
|
||||
sizes = "32x32"
|
||||
href = "/favicon-32x32.png"
|
||||
}
|
||||
link {
|
||||
rel = "icon"
|
||||
type = "image/png"
|
||||
sizes = "16x16"
|
||||
href = "/favicon-16x16.png"
|
||||
}
|
||||
link {
|
||||
rel = "manifest"
|
||||
href = "/site.webmanifest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) internal fun BODY.magProgFooter() {
|
||||
context(WebPage) internal fun BODY.magProgFooter() {
|
||||
footer("wrapper style1-alt") {
|
||||
id = "footer"
|
||||
div("inner") {
|
||||
@ -281,13 +302,14 @@ context(Page) internal fun BODY.magProgFooter() {
|
||||
|
||||
context(SnarkContext) private val HtmlData.mentorPageId get() = "mentor-${id}"
|
||||
|
||||
internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asName()) {
|
||||
internal fun SiteBuilder.spcMasters(dataPath: Path, prefix: Name = "magprog".asName()) {
|
||||
|
||||
val magProgData: DataTree<Any> = snark.readDirectory(dataPath.resolve("content"))
|
||||
|
||||
route(prefix, magProgData, setAsRoot = true) {
|
||||
assetDirectory("assets", dataPath.resolve("assets"))
|
||||
assetDirectory("images", dataPath.resolve("images"))
|
||||
file(dataPath.resolve("assets"))
|
||||
file(dataPath.resolve("images"))
|
||||
file(dataPath.resolve("../common"), "")
|
||||
|
||||
page {
|
||||
val sections = listOf<MagProgSection>(
|
@ -1,14 +1,14 @@
|
||||
package ru.mipt.spc
|
||||
|
||||
import kotlinx.html.*
|
||||
import space.kscience.snark.html.Page
|
||||
import space.kscience.snark.html.WebPage
|
||||
import space.kscience.snark.html.homeRef
|
||||
import space.kscience.snark.html.resolvePageRef
|
||||
|
||||
|
||||
internal const val SPC_TITLE = "Scientific Programming Centre"
|
||||
|
||||
context(Page) internal fun HTML.spcHead(title: String = SPC_TITLE) {
|
||||
context(WebPage) internal fun HTML.spcHead(title: String = SPC_TITLE) {
|
||||
head {
|
||||
title {
|
||||
+title
|
||||
@ -24,10 +24,31 @@ context(Page) internal fun HTML.spcHead(title: String = SPC_TITLE) {
|
||||
noScript {
|
||||
link(rel = "stylesheet", href = resolveRef("assets/css/noscript.css"))
|
||||
}
|
||||
link {
|
||||
rel = "apple-touch-icon"
|
||||
sizes = "180x180"
|
||||
href = "/apple-touch-icon.png"
|
||||
}
|
||||
link {
|
||||
rel = "icon"
|
||||
type = "image/png"
|
||||
sizes = "32x32"
|
||||
href = "/favicon-32x32.png"
|
||||
}
|
||||
link {
|
||||
rel = "icon"
|
||||
type = "image/png"
|
||||
sizes = "16x16"
|
||||
href = "/favicon-16x16.png"
|
||||
}
|
||||
link {
|
||||
rel = "manifest"
|
||||
href = "/site.webmanifest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) internal fun FlowContent.spcHomeMenu() {
|
||||
context(WebPage) internal fun FlowContent.spcHomeMenu() {
|
||||
nav {
|
||||
id = "menu"
|
||||
ul("links") {
|
||||
@ -39,7 +60,7 @@ context(Page) internal fun FlowContent.spcHomeMenu() {
|
||||
}
|
||||
li {
|
||||
a {
|
||||
href = resolvePageRef("magprog")
|
||||
href = resolvePageRef("magprog.index")
|
||||
+"""Master"""
|
||||
}
|
||||
}
|
||||
@ -51,7 +72,7 @@ context(Page) internal fun FlowContent.spcHomeMenu() {
|
||||
}
|
||||
li {
|
||||
a {
|
||||
href = resolvePageRef("consulting")
|
||||
href = resolvePageRef("consulting.index")
|
||||
+"""Consulting"""
|
||||
}
|
||||
}
|
||||
@ -79,7 +100,7 @@ context(Page) internal fun FlowContent.spcHomeMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) internal fun FlowContent.spcFooter() {
|
||||
context(WebPage) internal fun FlowContent.spcFooter() {
|
||||
footer {
|
||||
id = "footer"
|
||||
div("inner") {
|
||||
@ -129,7 +150,7 @@ context(Page) internal fun FlowContent.spcFooter() {
|
||||
}
|
||||
}
|
||||
|
||||
context(Page) internal fun FlowContent.wrapper(contentBody: FlowContent.() -> Unit) {
|
||||
context(WebPage) internal fun FlowContent.wrapper(contentBody: FlowContent.() -> Unit) {
|
||||
div {
|
||||
id = "wrapper"
|
||||
// Header
|
||||
|
@ -1,15 +1,13 @@
|
||||
package ru.mipt.spc
|
||||
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.snark.html.SnarkPlugin
|
||||
import space.kscience.snark.html.renderStatic
|
||||
import space.kscience.snark.SnarkEnvironment
|
||||
import space.kscience.snark.html.static
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.toPath
|
||||
|
||||
fun main() {
|
||||
Global.fetch(SnarkPlugin).renderStatic(Path.of("build/out")) {
|
||||
spcHome(rootPath = javaClass.getResource("/home")!!.toURI().toPath())
|
||||
spcMaster(dataPath = javaClass.getResource("/magprog")!!.toURI().toPath())
|
||||
SnarkEnvironment.default.static(Path.of("build/out")) {
|
||||
spcHome(dataPath = javaClass.getResource("/home")!!.toURI().toPath())
|
||||
spcMasters(dataPath = javaClass.getResource("/magprog")!!.toURI().toPath())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user