I think I understand your idea about templates being in both locations, and
I think it is a reasonable approach.

My thought is that in the case that you have multiple data models, it would
probably be clearer to have all of the templates one directory and bind
them to the appropriate data model explicitly.

And in the case that you have a single data model, you could provide this
shortcut to not needing to bind it explicitly to all of your templates
through some configuration option.  And in this case, there wouldn't be the
need to have the templates in the generator directory.

The consistent aspect of that approach is that the templates are always in
the /templates directory, and a "generator" has a consistent definition of
a configuration file that binds a data model to a template.

The consistent aspect of the templates in the generator directory approach
is that things that generate files are always in the same location (the
generators directory), and we could enforce the property that one source
file is generated for every file in the generators directory.


On Fri, Aug 17, 2018 at 1:32 AM, Daniel Dekany <[email protected]> wrote:

> Friday, August 17, 2018, 12:36:51 AM, Ben Jackson wrote:
>
> > Here is my summary of the conversation and my take on it.
> >
> > There are two primary use cases discussed in the thread.
> >
> > 1. Multiple templates instantiated in multiple ways (with multiple "data
> > models").  This was our use case.
> > 2. A bunch of templates being instantiated based on a single shared "data
> > model"
> >
> > So how to best bring together the "data model" and the "template" to fit
> > these use cases with minimal overhead?
> > There is the generic way which is to list out all of the templates and
> data
> > models in separate locations, and then to bring together the templates
> and
> > data models via some configuration. In this world, a structure might be:
> >
> > (@daniel you seem concerend by the default location being
> /src/main/freemarker,
> > do you have a better idea in mind?)
>
> My approach is that this is a product, and products has a somewhat
> unique (basically means searchable) name. Calling this just the
> "Apache FreeMarker Maven Plugin" is problematic for that reason. For
> starters, it's functionality is not very much Maven specific, so it
> might as well will be callable from Gradle, or directly from command
> line (if you modularize it like that). Also there are a few other
> FreeMarker Maven Plugins, which makes searching for related content on
> the web hard. If we have a product name, then it's also obvious what
> the directory name will be. So, let's say, it's "Apache FreeMarker
> FGen" (maybe a stupid name, but just as an example), then, you have
> /src/main/fgen, and when someone sees it and Googles it, he will find
> what that does.
>
> > /src/main/generated/freemarker/dataModels  - data models
> > /src/main/generated/freemarker/templates  - freemarker templates
> > /src/main/generated/freemarker/generators - json, one per output file
>
> Note that it wasn't the structure I have suggested, just in case you
> (or someone) have missed that. What I said that for case #2, you
> simply put templates into generators/. And of course you can have both
> ftl and json files inside generators/, each generating its output file
> in its own way.
>
> As of dataModel-s, the part of the content the json files is also part
> of the data-model, so it's not the best name. It's rather
> "shared-dataModel", and in case you specify that directly in the
> pom.xml, you don't even need that. And of course, we are talking about
> a layered data-model, where there's a shared data model that's visible
> from everywhere, and it the case of a json generator file it can adds
> another layer on top of that.
>
> > The issue with this more generic structure is that in exchange for this
> > flexibility, you might have a bunch of extra files.  For example, in the
> > special case #2, one needs twice as many files in the above structure.
> >
> > So instead of the above structure, the suggestion in the thread is to
> embed
> > both of the common use cases into the plugin in a way that they "play
> nice"
> > together.
> > Create a generators directory and have the plugin interpret how to
> generate
> > the source based on the type of thing in that directory.
> >
> > I think that we could instead ask how we might deviate from the above
> > generic structure that allows a many-to-many mapping while reusing both
> > data models
> > and templates in such a way that the two special cases can be naturally
> > supported.
> >
> > The first enhancement is that a generator could optionally embed the data
> > model.  This handles case #1 if you do not want
> > to reuse data models. It also naturally comes from enhancing the
> > json structure in the way that Daniel suggested:
> >
> > {
> >   "templateName": "foo.ftl",
> >   "otherFutureMavenPluginKey": "something",
> >   "dataModel": {
> >      /* your application-specific stuff */
> >     "myString": "a string",
> >     "myNumber": 1,
> >     ...
> >   }
> > }
> >
> > Here the other option would be for "dataModel" to refer to a file in the
> > "dataModel" directory.
>
> Sure that's a more generic solution. Though usually you don't want to
> use a json generator file if you don't want a data-model that's
> specific to that generator file.
>
> > I would say that instead of overloading the "generators" directory to
> also
> > include templates,
>
> To clarify, there are templates in the templates\ directory, and then
> there can be templates in the generator/ directory. They are
> completely separate matters. In the 2nd case, they are just a type of
> a generator files, like json-s are.
>
> > we allow the plugin to operate in an alternate mode,
> > enabled by configuration, say by setting a "defaultDataModel" parameter.
> In
> > this mode, we generate sources for all templates in the template
> directory
> > from a common data model.
>
> My idea was that the we only ever generate output files for what's in
> the generator directory. There can be files both in generators/ and
> templates/, but hey have a different role. Templates in templates/ are
> just dependencies of some generators/ (the jsons, in this case), or
> maybe they can be #import-ed from templates in generators/.
>
> > In this use case, the project would only use
> > this structure only:
> >
> > /src/main/generated/freemarker/dataModel.xml
>
> NYW, I think for a dataModel it's important that it can come from
> various places, like even from a database. So we should keep that in
> mind.
>
> > /src/main/generated/freemarker/templates/...
> >
> > Having said all of this, I think the changes we would make in the short
> > term would be to update the json structure to include the dataModel as a
> > subtree, and to change the default locations to use the /generated
> > subdirectory rather than /data, and whatever suggestion is appropriate.
> >
> > -Ben
> >
> > On Thu, Aug 16, 2018 at 4:18 PM, Ben Jackson <[email protected]>
> wrote:
> >
> >> Yes, this makes sense.
> >>
> >> -Ben
> >>
> >> On Thu, Aug 16, 2018 at 2:56 PM, Daniel Dekany <[email protected]>
> wrote:
> >>
> >>> Wednesday, August 15, 2018, 10:52:41 PM, Mark Malynn wrote:
> >>>
> >>> [snip]
> >>> >  3) I agree that using the well known json field 'templateName' seems
> >>> > 'hacky' (from a freemarker point of view). However, from the point of
> >>> view
> >>> > of the maven plugin it works nice. It provides the flexibility I need
> >>> with
> >>> > the minimum fuss. I will entertain another mechanism as long as it
> >>> supports
> >>> > my main use case.
> >>> [snip]
> >>>
> >>> The problem with that is that it doesn't work if you happen to need a
> >>> "tempalteName" field in your actual data. Yes, that's unlikely, but
> >>> take it as a demonstration of why it's not correct. The "correct"
> solution
> >>> is like this:
> >>>
> >>> {
> >>>   "templateName": "foo.ftl",
> >>>   "otherFutureMavenPluginKey": "something",
> >>>   "dataModel": {
> >>>      /* your application-specific stuff */
> >>>     "myString": "a string",
> >>>     "myNumber": 1,
> >>>     ...
> >>>   }
> >>> }
> >>>
> >>> Note how it allows adding new keys (like "otherFutureMavenPluginKey")
> >>> without breaking backward compatibility.
> >>>
> >>> --
> >>> Thanks,
> >>>  Daniel Dekany
> >>>
> >>>
> >>
> >>
> >> --
> >> Benjamin Grant Jackson
> >>
> >
> >
> >
>
> --
> Thanks,
>  Daniel Dekany
>
>


-- 
Benjamin Grant Jackson

Reply via email to