Skip to content

Commit 590f939

Browse files
committed
Fix templating of properties
1 parent c3ac180 commit 590f939

File tree

12 files changed

+116
-49
lines changed

12 files changed

+116
-49
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
layout: doc-page
3+
title: "Import Implied"
4+
---
5+
16
The contents of this page have [moved](./given-imports.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
layout: doc-page
3+
title: "Inferable-By-Name Parameters"
4+
---
5+
16
The contents of this page have [moved](./by-name-context-parameters.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
layout: doc-page
3+
title: "Inferable Params"
4+
---
5+
16
The contents of this page have [moved](./using-clauses.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
layout: doc-page
3+
title: "Givens"
4+
---
5+
16
The contents of this page have [moved](./givens.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
layout: doc-page
3+
title: "Query Types Spec"
4+
---
5+
16
The contents of this page have [moved](./context-functions-spec.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
---
2+
layout: doc-page
3+
title: "Query Types"
4+
---
5+
16
The contents of this page have [moved](./context-functions.md).

scala3doc/src/dotty/dokka/site/StaticPageNode.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ case class StaticPageNode(
2222
) extends ContentPage:
2323
override def getDocumentable: Documentable = null
2424

25-
def title(): String = template.title()
26-
def hasFrame(): Boolean = template.hasFrame()
25+
def title(): String = template.title
26+
def hasFrame(): Boolean = template.hasFrame
2727

2828
override def modified(
2929
name: String,
@@ -38,4 +38,4 @@ case class StaticPageNode(
3838

3939
def resources(): List[String] = getContent match
4040
case p: PartiallyRenderedContent => p.resolved.resources
41-
case _ => Nil
41+
case _ => Nil

scala3doc/src/dotty/dokka/site/StaticSiteContext.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
3232
lazy val layouts: Map[String, TemplateFile] =
3333
val layoutRoot = new File(root, "_layouts")
3434
val dirs: Array[File] = Option(layoutRoot.listFiles()).getOrElse(Array())
35-
dirs.map { it => loadTemplateFile(it) }.map { it => it.name() -> it }.toMap
35+
dirs.map { it => loadTemplateFile(it) }.map { it => it.name -> it }.toMap
3636

3737
lazy val sideBarConfig =
3838
val sidebarFile = root.toPath.resolve("sidebar.yml")
@@ -111,7 +111,7 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
111111
val path = if isBlog then "blog" else url.stripSuffix(".html") + ".md"
112112
val file = root.toPath.resolve(path) // Add support for .html files!
113113
val LoadedTemplate(template, children, tFile) = loadTemplate(file.toFile, isBlog).get // Add proper logging if file does not exisits
114-
LoadedTemplate(template.copy(settings = template.settings + ("title" -> List(title))), children, tFile)
114+
LoadedTemplate(template.copy(settings = template.settings + ("title" -> title)), children, tFile)
115115
case Sidebar.Category(title, nested) =>
116116
// Add support for index.html/index.md files!
117117
val fakeFile = new File(root, title)
@@ -141,9 +141,9 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
141141
)
142142
StaticPageNode(
143143
myTemplate.templateFile,
144-
myTemplate.templateFile.title(),
144+
myTemplate.templateFile.title,
145145
content,
146146
JSet(dri),
147147
JList(),
148148
(myTemplate.children.map(templateToPage)).asJava
149-
)
149+
)

scala3doc/src/dotty/dokka/site/common.scala

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ val defaultMarkdownOptions: DataHolder =
4040
"https://github.global.ssl.fastly.net/images/icons/emoji/"
4141
)
4242

43-
def emptyTemplate(file: File): TemplateFile = TemplateFile(file, isHtml = true, "", Map())
43+
def emptyTemplate(file: File): TemplateFile = TemplateFile(
44+
file = file,
45+
isHtml = true,
46+
rawCode = "",
47+
settings = Map.empty
48+
)
4449

4550
final val ConfigSeparator = "---"
4651
final val LineSeparator = "\n"
@@ -61,11 +66,19 @@ def loadTemplateFile(file: File): TemplateFile = {
6166
val yamlCollector = new AbstractYamlFrontMatterVisitor()
6267
yamlCollector.visit(configParsed)
6368

69+
extension (v: java.util.List[String]) def getSettingValue: String | List[String] =
70+
if v.size == 1 then v.get(0) else v.asScala.toList
71+
72+
val globalKeys = Set("extraJS", "extraCSS", "layout", "hasFrame")
73+
val (global, inner) = yamlCollector.getData.asScala.toMap.transform((_, v) => v.getSettingValue)
74+
.partition((k,_) => globalKeys.contains(k))
75+
val settings = global ++ Map("page" -> inner)
76+
6477
TemplateFile(
6578
file = file,
66-
file.getName.endsWith(".html"),
79+
isHtml = file.getName.endsWith(".html"),
6780
rawCode = content.mkString(LineSeparator),
68-
settings = yamlCollector.getData.asScala.toMap.transform((_, v) => v.asScala.toList)
81+
settings = settings,
6982
)
7083
}
7184

scala3doc/src/dotty/dokka/site/processors.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class SiteResourceManager(ctx: Option[StaticSiteContext]) extends BaseStaticSite
4444
val modified = input.transformContentPagesTree {
4545
case it: StaticPageNode =>
4646
it.copy(getEmbeddedResources =
47-
if it.template.hasFrame() then it.getEmbeddedResources ++ it.resources().asJava
47+
if it.template.hasFrame then it.getEmbeddedResources ++ it.resources().asJava
4848
else it.resources().asJava
4949
)
5050
case it => it

scala3doc/src/dotty/dokka/site/templates.scala

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ import com.vladsch.flexmark.parser.{Parser, ParserEmulationProfile}
1515
import com.vladsch.flexmark.util.options.{DataHolder, MutableDataSet}
1616
import com.vladsch.flexmark.html.HtmlRenderer
1717
import liqp.Template
18+
import java.util.{ Map => JMap, HashMap => HMap, ArrayList, Collection }
1819

1920
import scala.collection.JavaConverters._
2021
import scala.io.Source
2122

2223
case class RenderingContext(
23-
properties: Map[String, Object],
24-
layouts: Map[String, TemplateFile] = Map(),
25-
resolving: Set[String] = Set(),
26-
resources: List[String] = Nil
27-
):
24+
properties: Map[String, Element],
25+
layouts: Map[String, TemplateFile] = Map(),
26+
resolving: Set[String] = Set(),
27+
resources: List[String] = Nil
28+
):
2829

2930
def nest(code: String, file: File, resources: List[String]) =
3031
copy(
@@ -33,8 +34,8 @@ case class RenderingContext(
3334
resources = this.resources ++ resources
3435
)
3536

36-
case class ResolvedPage(val code: String, val resources: List[String] = Nil)
37-
37+
case class ResolvedPage(code: String, resources: List[String] = Nil)
38+
type Element = String | List[String] | Object // Object represents Map[String, Element] since it is not possible to get circullar dependency
3839
/**
3940
* case class for the template files.
4041
* Template file is a file `.md` or `.html` handling settings.
@@ -44,53 +45,76 @@ case class ResolvedPage(val code: String, val resources: List[String] = Nil)
4445
* @param settings The config defined in the begging of the file, between the pair of `---` (e.g. layout: basic).
4546
*/
4647
case class TemplateFile(
47-
val file: File,
48-
val isHtml: Boolean,
49-
val rawCode: String,
50-
val settings: Map[String, List[String]]
51-
):
52-
53-
private def stringSetting(name: String): Option[String] =
54-
settings.get(name) map {
55-
case List(single) => single.stripPrefix("\"").stripSuffix("\"")
56-
case nonSingle =>
57-
throw new RuntimeException(s"Setting $name is a not a singlel-ement list but $nonSingle")
58-
}
59-
60-
61-
private def listSetting(name: String): List[String] = settings.getOrElse(name, Nil)
62-
63-
def name(): String = stringSetting("name").getOrElse(file.getName.stripSuffix(if (isHtml) ".html" else ".md"))
64-
65-
def title(): String = stringSetting("title").getOrElse(name())
66-
67-
def layout(): Option[String] = stringSetting("layout")
68-
69-
def hasFrame(): Boolean = !stringSetting("hasFrame").contains("false")
70-
48+
file: File,
49+
isHtml: Boolean,
50+
rawCode: String,
51+
settings: Map[String, Element],
52+
name: String,
53+
title: String,
54+
hasFrame: Boolean,
55+
resources: List[String],
56+
layout: Option[String],
57+
):
7158
def isIndexPage() = file.isFile && (file.getName == "index.md" || file.getName == "index.html")
7259

73-
def resolveToHtml(ctx: StaticSiteContext): ResolvedPage =
74-
val props = Map("page" -> JMap("title" -> title()))
75-
resolveInner(RenderingContext(props, ctx.layouts))
60+
def resolveToHtml(ctx: StaticSiteContext): ResolvedPage = resolveInner(RenderingContext(settings, ctx.layouts))
7661

7762
private[site] def resolveInner(ctx: RenderingContext): ResolvedPage =
7863
if (ctx.resolving.contains(file.getAbsolutePath))
7964
throw new RuntimeException(s"Cycle in templates involving $file: ${ctx.resolving}")
8065

81-
val layoutTemplate = layout().map(name =>
66+
val layoutTemplate = layout.map(name =>
8267
ctx.layouts.getOrElse(name, throw new RuntimeException(s"No layouts named $name in ${ctx.layouts}")))
8368

69+
def toJava(m: Any): Any = m match
70+
case sm: Map[_, _] => sm.map(kv => (kv._1, toJava(kv._2))).asJava
71+
case sl: Iterable[_] => new ArrayList(sl.map( toJava ).asJava.asInstanceOf[Collection[_]])
72+
case _ => m
73+
8474
// Library requires mutable maps..
85-
val mutableProperties = new java.util.HashMap[String, Object](ctx.properties.asJava)
75+
val mutableProperties = new HMap[String, Object](toJava(ctx.properties).asInstanceOf[JMap[String, Object]])
8676
val rendered = Template.parse(this.rawCode).render(mutableProperties)
8777
// We want to render markdown only if next template is html
8878
val code = if (isHtml || layoutTemplate.exists(!_.isHtml)) rendered else
8979
val parser: Parser = Parser.builder().build()
9080
HtmlRenderer.builder(defaultMarkdownOptions).build().render(parser.parse(rendered))
9181

92-
val resources = listSetting("extraCSS") ++ listSetting("extraJS")
9382
layoutTemplate match
9483
case None => ResolvedPage(code, resources ++ ctx.resources)
9584
case Some(layoutTemplate) =>
9685
layoutTemplate.resolveInner(ctx.nest(code, file, resources))
86+
87+
object TemplateFile:
88+
extension (settings: Map[String, Element]):
89+
private def stringSetting(name: String): Option[String] = settings.getOrElse(name, null).match {
90+
case List(elem: String) => Some(elem)
91+
case elem: String => Some(elem)
92+
case _ => None
93+
}.map(_.stripPrefix("\"").stripSuffix("\""))
94+
95+
private def listSetting(name: String): Option[List[String]] = settings.getOrElse(name, null).match {
96+
case elem: List[_] => Some(elem.asInstanceOf[List[String]])
97+
case elem: String => Some(List(elem))
98+
case _ => None
99+
}
100+
101+
def apply(
102+
file: File,
103+
isHtml: Boolean,
104+
rawCode: String,
105+
settings: Map[String, Element],
106+
): TemplateFile = {
107+
val name = settings.stringSetting("name").getOrElse(file.getName.stripSuffix(if (isHtml) ".html" else ".md"))
108+
109+
TemplateFile(
110+
file = file,
111+
isHtml,
112+
rawCode = rawCode,
113+
settings = settings,
114+
name = name,
115+
title = settings.getOrElse("page", settings).asInstanceOf[Map[String, Object]].stringSetting("title").getOrElse(name),
116+
hasFrame = !settings.stringSetting("hasFrame").contains("false"),
117+
resources = (settings.listSetting("extraCSS") ++ settings.listSetting("extraJS")).flatten.toList,
118+
layout = settings.stringSetting("layout")
119+
)
120+
}

scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
256256
override def buildHtml(page: PageNode, resources: JList[String], kotlinxContent: FlowContentConsumer): String =
257257
val (pageTitle, noFrame) = page match
258258
case static: StaticPageNode =>
259-
(static.template.title(), !static.hasFrame())
259+
(static.template.title, !static.hasFrame())
260260
case _ =>
261261
(page.getName, false)
262262

0 commit comments

Comments
 (0)