TagBuilder implemented and available in templates, parts, and specialPages.

This commit is contained in:
Jesse Brault 2023-02-12 16:17:24 +01:00
parent 34d9cd52b0
commit 936587d0b5
9 changed files with 175 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package com.jessebrault.ssg.part
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder
import com.jessebrault.ssg.text.EmbeddableText
import groovy.text.GStringTemplateEngine
import groovy.text.TemplateEngine
@ -26,6 +27,7 @@ class GspPartRenderer implements PartRenderer {
def result = engine.createTemplate(part.text).make([
binding: binding,
globals: globals,
tagBuilder: new DynamicTagBuilder(),
text: text
])
new Tuple2<>([], result.toString())

View File

@ -3,6 +3,7 @@ package com.jessebrault.ssg.specialpage
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.part.EmbeddablePartsMap
import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder
import com.jessebrault.ssg.text.EmbeddableTextsCollection
import com.jessebrault.ssg.text.Text
import groovy.text.GStringTemplateEngine
@ -25,6 +26,7 @@ class GspSpecialPageRenderer implements SpecialPageRenderer {
parts: new EmbeddablePartsMap(parts, globals, { Collection<Diagnostic> partDiagnostics ->
diagnostics.addAll(partDiagnostics)
}),
tagBuilder: new DynamicTagBuilder(),
texts: new EmbeddableTextsCollection(texts, globals, { Collection<Diagnostic> textDiagnostics ->
diagnostics.addAll(textDiagnostics)
})

View File

@ -0,0 +1,77 @@
package com.jessebrault.ssg.tagbuilder
import org.codehaus.groovy.runtime.InvokerHelper
class DynamicTagBuilder implements TagBuilder {
@Override
String create(String name) {
"<$name />"
}
@Override
String create(String name, Map<String, ?> attributes) {
def formattedAttributes = attributes.collect {
if (it.value instanceof String) {
it.key + '="' + it.value + '"'
} else if (it.value instanceof Integer) {
it.key + '=' + it.value
} else if (it.value instanceof Boolean && it.value == true) {
it.key
} else {
it.key + '="' + it.value.toString() + '"'
}
}.join(' ')
"<$name $formattedAttributes />"
}
@Override
String create(String name, String body) {
"<$name>$body</$name>"
}
@Override
String create(String name, Map<String, ?> attributes, String body) {
def formattedAttributes = attributes.collect {
if (it.value instanceof String) {
it.key + '="' + it.value + '"'
} else if (it.value instanceof Integer) {
it.key + '=' + it.value
} else if (it.value instanceof Boolean && it.value == true) {
it.key
} else {
it.key + '="' + it.value.toString() + '"'
}
}.join(' ')
"<$name $formattedAttributes>$body</$name>"
}
@Override
Object invokeMethod(String name, Object args) {
def argsList = InvokerHelper.asList(args)
return switch (argsList.size()) {
case 0 -> this.create(name)
case 1 -> {
def arg0 = argsList[0]
if (arg0 instanceof Map) {
this.create(name, arg0)
} else if (arg0 instanceof String) {
this.create(name, arg0)
} else {
throw new MissingMethodException(name, this.class, args, false)
}
}
case 2 -> {
def arg0 = argsList[0]
def arg1 = argsList[1]
if (arg0 instanceof Map && arg1 instanceof String) {
this.create(name, arg0, arg1)
} else {
throw new MissingMethodException(name, this.class, args, false)
}
}
default -> throw new MissingMethodException(name, this.class, args, false)
}
}
}

View File

@ -0,0 +1,8 @@
package com.jessebrault.ssg.tagbuilder
interface TagBuilder {
String create(String name)
String create(String name, Map<String, ?> attributes)
String create(String name, String body)
String create(String name, Map<String, ?> attributes, String body)
}

View File

@ -3,6 +3,7 @@ package com.jessebrault.ssg.template
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.part.EmbeddablePartsMap
import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder
import com.jessebrault.ssg.text.EmbeddableText
import com.jessebrault.ssg.text.FrontMatter
import com.jessebrault.ssg.text.Text
@ -35,6 +36,7 @@ class GspTemplateRenderer implements TemplateRenderer {
frontMatter: frontMatter,
globals: globals,
parts: new EmbeddablePartsMap(parts, globals, onDiagnostics, embeddableText),
tagBuilder: new DynamicTagBuilder(),
text: embeddableText
])
new Tuple2<>(diagnostics, result.toString())

View File

@ -68,4 +68,12 @@ class GspPartRendererTests {
assertEquals('Hello, World!', r.v2)
}
@Test
void tagBuilderAvailable() {
def part = new Part('', null, '<%= tagBuilder.test() %>')
def r = this.renderer.render(part, [:], [:], null)
assertTrue(r.v1.isEmpty())
assertEquals('<test />', r.v2)
}
}

View File

@ -75,4 +75,12 @@ class GspSpecialPageRendererTests {
assertEquals('<p><strong>Hello, World!</strong></p>\n', r.v2)
}
@Test
void tagBuilderAvailable() {
def specialPage = new SpecialPage('<%= tagBuilder.test() %>', null, null)
def r = this.renderer.render(specialPage, [], [], [:])
assertTrue(r.v1.isEmpty())
assertEquals('<test />', r.v2)
}
}

View File

@ -0,0 +1,54 @@
package com.jessebrault.ssg.tagbuilder
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
class TagBuilderTests {
private final TagBuilder tagBuilder = new DynamicTagBuilder()
@Test
void simple() {
assertEquals('<test />', this.tagBuilder.create('test'))
}
@Test
void withAttributes() {
assertEquals('<test test="abc" />', this.tagBuilder.create('test', [test: 'abc']))
}
@Test
void withBody() {
assertEquals('<test>test</test>', this.tagBuilder.create('test', 'test'))
}
@Test
void withAttributesAndBody() {
assertEquals(
'<test test="abc">test</test>',
this.tagBuilder.create('test', [test: 'abc'], 'test')
)
}
@Test
void dynamicSimple() {
assertEquals('<test />', this.tagBuilder.test())
}
@Test
void dynamicWithAttributes() {
assertEquals('<test test="abc" />', this.tagBuilder.test([test: 'abc']))
}
@Test
void dynamicWithBody() {
assertEquals('<test>test</test>', this.tagBuilder.test('test'))
}
@Test
void dynamicWithAttributesAndBody() {
assertEquals('<test test="abc">test</test>', this.tagBuilder.test([test: 'abc'], 'test'))
}
}

View File

@ -136,4 +136,18 @@ class GspTemplateRendererTests {
assertEquals('Hello, World!', r.v2)
}
@Test
void tagBuilderAvailable() {
def template = new Template('<%= tagBuilder.test() %>', null, null)
def r = this.renderer.render(
template,
new FrontMatter(null, [:]),
mockBlankText(),
[],
[:]
)
assertTrue(r.v1.isEmpty())
assertEquals('<test />', r.v2)
}
}