diff --git a/documentation/_includes/html_include_from_includes_dir.html b/documentation/_includes/html_include_from_includes_dir.html
new file mode 100644
index 0000000..b4588d8
--- /dev/null
+++ b/documentation/_includes/html_include_from_includes_dir.html
@@ -0,0 +1,7 @@
+
File, I am your HTML include
+
+html html html html html html html
+
+html html html html html html html
+
+
diff --git a/documentation/_includes/md_include_from_includes_dir.md b/documentation/_includes/md_include_from_includes_dir.md
new file mode 100644
index 0000000..5debf2b
--- /dev/null
+++ b/documentation/_includes/md_include_from_includes_dir.md
@@ -0,0 +1,7 @@
+### File, I am your MD include
+
+md md md md md md md md md md md md
+
+md md md md md md md md md md md md
+
+ ---
diff --git a/documentation/docs/static-page/includes_html.html b/documentation/docs/static-page/includes_html.html
new file mode 100644
index 0000000..3557190
--- /dev/null
+++ b/documentation/docs/static-page/includes_html.html
@@ -0,0 +1,7 @@
+---
+title: Includes HTML
+---
+
+{% myinclude md_include_from_includes_dir.md %}
+
+{% myinclude html_include_from_includes_dir.html %}
diff --git a/documentation/docs/static-page/includes_md.md b/documentation/docs/static-page/includes_md.md
new file mode 100644
index 0000000..86b1386
--- /dev/null
+++ b/documentation/docs/static-page/includes_md.md
@@ -0,0 +1,7 @@
+---
+title: Includes MD
+---
+
+{% myinclude md_include_from_includes_dir.md %}
+
+{% myinclude html_include_from_includes_dir.html %}
diff --git a/src/main/kotlin/com/virtuslab/dokka/site/StaticSiteContext.kt b/src/main/kotlin/com/virtuslab/dokka/site/StaticSiteContext.kt
index 1fcdc92..d0d5dd6 100644
--- a/src/main/kotlin/com/virtuslab/dokka/site/StaticSiteContext.kt
+++ b/src/main/kotlin/com/virtuslab/dokka/site/StaticSiteContext.kt
@@ -32,6 +32,11 @@ class StaticSiteContext(val root: File, cxt: DokkaContext) {
dirs.map { loadTemplateFile(it) }.map { it.name() to it }.toMap()
}
+ private val includes: Map by lazy {
+ val includeRoot = File(root, "_includes")
+ val dirs: Array = includeRoot.listFiles() ?: emptyArray()
+ dirs.map { loadTemplateFile(it) }.map { it.file.name to it.rawCode }.toMap()
+ }
private fun isValidTemplate(file: File): Boolean =
(file.isDirectory && !file.name.startsWith("_")) ||
@@ -124,7 +129,13 @@ class StaticSiteContext(val root: File, cxt: DokkaContext) {
val properties = myTemplate.templateFile.layout()
?.let { mapOf("content" to myTemplate.templateFile.rawCode) } ?: emptyMap()
- myTemplate.templateFile.resolveMarkdown(RenderingContext(properties, layouts))
+ val ctx = RenderingContext(
+ properties = properties,
+ layouts = layouts,
+ includes = includes
+ )
+
+ myTemplate.templateFile.resolveMarkdown(ctx)
} catch (e: Throwable) {
val msg = "Error rendering $myTemplate: ${e.message}"
println("ERROR: $msg") // TODO (#14): provide proper error handling
diff --git a/src/main/kotlin/com/virtuslab/dokka/site/templates.kt b/src/main/kotlin/com/virtuslab/dokka/site/templates.kt
index 397fefb..944bffa 100644
--- a/src/main/kotlin/com/virtuslab/dokka/site/templates.kt
+++ b/src/main/kotlin/com/virtuslab/dokka/site/templates.kt
@@ -14,6 +14,9 @@ import com.vladsch.flexmark.parser.ParserEmulationProfile
import com.vladsch.flexmark.util.options.DataHolder
import com.vladsch.flexmark.util.options.MutableDataSet
import liqp.Template
+import liqp.TemplateContext
+import liqp.nodes.LNode
+import liqp.tags.Tag
import java.io.File
import java.util.*
@@ -38,6 +41,7 @@ val defaultMarkdownOptions: DataHolder =
data class RenderingContext(
val properties: Map,
+ val includes: Map = emptyMap(),
val layouts: Map = emptyMap(),
val resolving: Set = emptySet(),
val markdownOptions: DataHolder = defaultMarkdownOptions,
@@ -105,12 +109,14 @@ data class TemplateFile(
fun hasFrame(): Boolean = stringSetting("hasFrame") != "false"
- fun resolveMarkdown(ctx: RenderingContext): PreResolvedPage =
- resolveInner(
- ctx = ctx.copy(properties = HashMap(ctx.properties) + ("page" to mapOf("title" to title()))),
+ fun resolveMarkdown(ctx: RenderingContext): PreResolvedPage {
+ val properties = HashMap(ctx.properties) + ("page" to mapOf("title" to title())) + HashMap(ctx.includes)
+ return resolveInner(
+ ctx = ctx.copy(properties = properties),
stopAtHtml = true,
!isHtml // This is toplevel template
)
+ }
fun resolveToHtml(ctx: RenderingContext, hasMarkdown: Boolean): PreResolvedPage =
resolveInner(ctx, stopAtHtml = false, hasMarkdown)
@@ -130,6 +136,7 @@ data class TemplateFile(
return if (stopAtHtml && isHtml) {
PreResolvedPage(ctx.properties["content"].toString(), LayoutInfo(this, ctx), hasMarkdown)
} else {
+ Tag.registerTag(MyInclude())
val rendered =
Template.parse(this.rawCode).render(HashMap(ctx.properties)) // Library requires mutable maps..
val code = if (!isHtml) rendered else {
@@ -166,8 +173,23 @@ fun loadTemplateFile(file: File): TemplateFile {
return TemplateFile(
file = file,
- file.name.endsWith(".html"),
+ isHtml = file.name.endsWith(".html"),
rawCode = content.joinToString(LineSeparator),
settings = yamlCollector.data
)
}
+
+
+class MyInclude : Tag() {
+ override fun render(context: TemplateContext, vararg nodes: LNode): Any = try {
+ if (nodes.size > 1) {
+ println("ERROR: Multiple include nodes") // TODO (#14): provide proper error handling
+ }
+ nodes[0].render(context)
+ val includeResource = super.asString(context.get(nodes[0].toString()))
+ Template.parse(includeResource, context.flavor).render(context.variables)
+ } catch (e: Exception) {
+ println("ERROR: include rendering failure: $e") // TODO (#14): provide proper error handling
+ ""
+ }
+}