New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple DirectoryCodeResolver #191
Comments
Oh, good question, I think it depends on what you'd like to achieve. Are the multiple source directories independent and separate of each other? In this case you could create a template engine for each directory. We do this at work for web / mail / pdf templates, that use entirely different layouts and must not depend on each other. Or, do you want to build a modular structure with templates in different directories, but still be able to reuse templates from other modules? This is a feature that's still missing in jte. |
It's the difficult one - directories in different modules :) This is what I've done so far: import gg.jte.CodeResolver
class MultipleCodeResolver(
private val defaultResolver: CodeResolver,
private val resolverForNames: Map<CodeResolver, Set<String>>
) : CodeResolver {
// inverse of resolverForNames
private val nameToResolver: Map<String, CodeResolver>
init {
val allNames = resolverForNames.values.flatten().toSet()
require(resolverForNames.values.sumOf { it.size } == allNames.size) { "at least one name is not unique" }
nameToResolver = resolverForNames.entries.flatMap { (resolver, paths) -> paths.map { it to resolver } }.toMap()
}
override fun resolve(name: String): String = nameToResolver.getOrDefault(name, defaultResolver).resolve(name)
override fun getLastModified(name: String) = nameToResolver.getOrDefault(name, defaultResolver).getLastModified(name)
override fun resolveAllTemplateNames() =
(resolverForNames.keys + defaultResolver).flatMap { it.resolveAllTemplateNames() }
override fun exists(name: String) = nameToResolver.getOrDefault(name, defaultResolver).exists(name)
}
Not tested, but something like this should work. |
But do the modules call templates only within the module, or also templates from other modules? If it’s the first case you could go with option 1 and have a template engine per module. If not, the ideal way would be to teach jte template modules, especially the IntelliJ plugin, so that it can help with auto complete. |
I have Gradle module A including jte templates from modules B and C (if that answers your question). So you think this is a valid scenario and something you could add in? |
I’m not sure how easy this will be 😅 Does module A also have jte templates itself? |
No - module A doesn't have templates of its own. |
Just to clarify - this is a single multi-module, multi-jar Gradle project. The new module will be like a mega-jar containing the other apps in some way. |
Hmm, in this case I would recommend to have a template engine for each module. Then you can include the jte precompiler gradle plugin to module B and C and expose the method to render a template for module A. |
I'm using Javalin which can only accept one template engine (I believe). |
The Javalin jte plugin is just a very small amount of glue code around jte. It shouldn‘t be a problem to replace it with your custom logic that decides which module is used for template rendering. |
OK - thanks for the tip. I'll have a look (tomorrow) and let you know how it goes. |
@casid It's something we should probably build, as we'll also need it at work sooner or later, I guess. |
OK - I've done as you suggested. Same idea, but less code. I'll leave it up to you whether you close or turn into a proper issue. I'll follow and will use whatever you decide to do. 👍 |
code without the object MultiTemplateEngineJte : FileRenderer {
private var defaultEngine: TemplateEngine? = null
private var pathsToEngine: Map<String, TemplateEngine>? = null
@JvmStatic
fun configure(defaultEngine: TemplateEngine, enginesForFilePaths: Map<TemplateEngine, Set<String>>) {
require(enginesForFilePaths.values.sumOf { it.size } == enginesForFilePaths.values.flatten().toSet().size) {
"at least one file path is not unique"
}
this.defaultEngine = defaultEngine
pathsToEngine = enginesForFilePaths.entries.flatMap { (engine, paths) -> paths.map { it to engine } }.toMap()
}
override fun render(filePath: String, model: Map<String, Any?>, ctx: Context): String {
val stringOutput = StringOutput()
pathsToEngine!!.getOrDefault(filePath, defaultEngine)!!.render(filePath, model, stringOutput)
return stringOutput.toString()
}
} |
I'm writing a "combined" app which uses JTEs from multiple source directories. There doesn't seem to be any way to do this at present.
As far as I can tell, I'd need to create a
MultipleDirectoryCodeResolver
, which would contain multipleDirectoryCodeResolver
s and then have a way to differentiate which one to use based on the file name.It's a bit weird. Does that sound like what you'd do?
Don't suppose this would be of interest to you at all?
The text was updated successfully, but these errors were encountered: