Skip to content

Commit 48c5c49

Browse files
committed
Add new handlebars helper
1 parent 2ca0f18 commit 48c5c49

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

documentation/pages/custom-html.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,22 @@ Include partials:
272272
{{include "partials/sidebar.hbs"}}
273273
```
274274

275+
### `md` (inline markdown)
276+
277+
Render inline Markdown from a string (links, bold, italics, ~~strikethrough~~):
278+
279+
```handlebars
280+
{{{md post.metadata.captionText}}}
281+
```
282+
283+
Useful for nested frontmatter fields, e.g.:
284+
285+
```handlebars
286+
{{#each post.metadata.timeline}}
287+
<span class="caption-text">{{{md captionText}}}</span>
288+
{{/each}}
289+
```
290+
275291
### `datasource`
276292

277293
All templates receive a `datasource` object that mirrors the generated JSON files, so you can render galleries, quote blocks, or entity lists during server-side rendering without additional fetches:

resources/META-INF/services/com.potomushto.statik.template.helpers.HandlebarsHelperRegistrar

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ com.potomushto.statik.template.helpers.FormatDateHelperRegistrar
77
com.potomushto.statik.template.helpers.GroupByHelperRegistrar
88
com.potomushto.statik.template.helpers.IncludeHelperRegistrar
99
com.potomushto.statik.template.helpers.LimitHelperRegistrar
10+
com.potomushto.statik.template.helpers.MarkdownHelperRegistrar
1011
com.potomushto.statik.template.helpers.SafeHelperRegistrar
1112
com.potomushto.statik.template.helpers.SortByHelperRegistrar
1213
com.potomushto.statik.template.helpers.SubstringHelperRegistrar
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.potomushto.statik.template.helpers
2+
3+
import com.github.jknack.handlebars.Handlebars
4+
import com.github.jknack.handlebars.Helper
5+
import com.vladsch.flexmark.ext.autolink.AutolinkExtension
6+
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
7+
import com.vladsch.flexmark.html.HtmlRenderer
8+
import com.vladsch.flexmark.parser.Parser
9+
10+
class MarkdownHelperRegistrar : HandlebarsHelperRegistrar {
11+
private val parser = Parser.builder()
12+
.extensions(listOf(
13+
AutolinkExtension.create(),
14+
StrikethroughExtension.create()
15+
))
16+
.build()
17+
18+
private val renderer = HtmlRenderer.builder()
19+
.extensions(listOf(
20+
AutolinkExtension.create(),
21+
StrikethroughExtension.create()
22+
))
23+
.build()
24+
25+
override fun register(handlebars: Handlebars, context: HelperRegistrationContext) {
26+
handlebars.registerHelper("md", Helper<Any?> { value, _ ->
27+
val text = value?.toString()?.trim().orEmpty()
28+
if (text.isEmpty()) {
29+
return@Helper ""
30+
}
31+
32+
val html = renderer.render(parser.parse(text))
33+
val inline = stripSingleParagraph(html)
34+
Handlebars.SafeString(inline)
35+
})
36+
}
37+
38+
private fun stripSingleParagraph(html: String): String {
39+
val trimmed = html.trim()
40+
if (!trimmed.startsWith("<p>") || !trimmed.endsWith("</p>")) {
41+
return trimmed
42+
}
43+
44+
val firstClose = trimmed.indexOf("</p>")
45+
if (firstClose != trimmed.length - 4) {
46+
return trimmed
47+
}
48+
49+
val nextOpen = trimmed.indexOf("<p>", startIndex = 3)
50+
if (nextOpen != -1) {
51+
return trimmed
52+
}
53+
54+
return trimmed.substring(3, trimmed.length - 4).trim()
55+
}
56+
}

0 commit comments

Comments
 (0)