Re: Feature Request
I thought you wanted both to store the FTL source code of the nested content (i.e, the raw content), and then also *immediately* execute the nested content. Because then, if you just execute the nested content as normally, with TemplateDirectiveBody.render(Writer), then it will see the same variables as the macro call nested content. If you need to execute the stored nested content at a later point instead, then you can create a Template from the captured FTL source code, and then use Environment.include(Template). Anyway, if it still won't work, can you show the TemplateDirectiveModel implementation on SO? SO is much better for providing help, as people are more likely to find the solution, and also answer can be updated/commented. On Mon, Nov 6, 2023 at 6:31 PM Cavan Morris wrote: > Hey Daniel, > I read the reply and tried creating a TemplateDirectiveModel to handle it > as you suggested. It seemed cleaner than calling internal freemarker > methods. The issue I ran up against was that when rendering the final > output it would miss model attributes that were defined in the external > template. > > So this would work: > > <@content name='help.h2'> > <#assign test='A test string'/> > This is a test: ${test} > > > But this would not: > > <#assign test='A test string'/> > <@content name='help.h2'> > This is a test: ${test} > > > Using my original code I was able to solve that by defining the macro as > below: > > <#macro content name> > <#local temlateSource = hd.processElement(name)/> <-- This calls > the code I originally sent you to get the nested content as a String > or pull it from the DB if available. > <#local inlineTemplate = temlateSource?interpret/> > <@inlineTemplate/> > > > I think because of that I'm going to have to stick with my original > method. Unless I can replicate what macro is doing to get the full > model from the environment. > > > On Sat, Nov 4, 2023 at 5:01 AM Daniel Dekany > wrote: > > > Have you read my answer on SO, i.e., using DirectiveCallPlace (public > > API-s)? Did you try to go in that direction? > > > > On Thu, Nov 2, 2023 at 8:40 PM Cavan Morris > > wrote: > > > > > Thank you Daniel. > > > I was able to solve the problem in my case by creating my own util > class > > in > > > the freemarker.core package inside my own project's source tree. This > > > allowed me to access the package-private deprecated methods that I > > believe > > > are used for <#nested> handling. > > > > > > I plan to clean it up a bit and submit a PR once I have a moment away > > from > > > my current project. My thought is that even though this relies on > > > deprecated methods, those methods are required for <#nested> support so > > if > > > they are refactored in the future there will have to be similar > > > functionality supplied by the refactor. It should be simple to maintain > > my > > > PR in that case. > > > > > > Here is a preview of what I have now. At a minimum it will need some > > > modifications to use the Freemarker logging system and I will need to > > find > > > an appropriate place for it in the existing source. Any thoughts > > > appreciated. > > > > > > public static String getRawMacroContent(boolean trim) { > > > log.trace("Getting Raw Macro Content"); > > > > > > StringBuilder sb = new StringBuilder(); > > > > > > Environment environment = Environment.getCurrentEnvironment(); > > > Macro.Context invokingMacroContext = > > > environment.getCurrentMacroContext(); > > > TemplateObject callPlace = invokingMacroContext.callPlace; > > > TemplateElement[] nestedContentBuffer = callPlace instanceof > > > TemplateElement ? ((TemplateElement) callPlace).getChildBuffer() : > > > null; > > > if (nestedContentBuffer != null) { > > > for (TemplateElement templateElement : nestedContentBuffer) { > > > log.trace("templateElement = {}", templateElement); > > > sb.append(templateElement.getSource()); > > > } > > > } > > > > > > if(trim) { > > > return sb.toString().trim(); > > > } else { > > > return sb.toString(); > > > } > > > } > > > > > > > > > > > > On Thu, Nov 2, 2023 at 10:51 AM Daniel Dekany > > > > wrote: > > > > > > > Kind of a niche use case... I would prefer avoiding much complexity > and > > > > backward compatibility burden for it. But, maybe it's actually > already > > > > doable. See my answer on Stack Overflow. > > > > > > > > On Mon, Oct 30, 2023 at 6:57 PM Cavan Morris < > cavanmor...@softcoil.com > > > > > > > wrote: > > > > > > > > > Hello All, > > > > > I am developing an internal content management system using > > freemarker > > > > > templates and have run across a speed bump I've detailed in > > > > > a stackoverflow question here: > > > > > > > > > > > > > > > > > > > > https://stackoverflow.com/questions/77390595/freemarker-how-to-get-unprocessed-content-of-custom-directive > > > > > > > > > > The long and short of it is that I
Re: Feature Request
Hey Daniel, I read the reply and tried creating a TemplateDirectiveModel to handle it as you suggested. It seemed cleaner than calling internal freemarker methods. The issue I ran up against was that when rendering the final output it would miss model attributes that were defined in the external template. So this would work: <@content name='help.h2'> <#assign test='A test string'/> This is a test: ${test} But this would not: <#assign test='A test string'/> <@content name='help.h2'> This is a test: ${test} Using my original code I was able to solve that by defining the macro as below: <#macro content name> <#local temlateSource = hd.processElement(name)/> <-- This calls the code I originally sent you to get the nested content as a String or pull it from the DB if available. <#local inlineTemplate = temlateSource?interpret/> <@inlineTemplate/> I think because of that I'm going to have to stick with my original method. Unless I can replicate what macro is doing to get the full model from the environment. On Sat, Nov 4, 2023 at 5:01 AM Daniel Dekany wrote: > Have you read my answer on SO, i.e., using DirectiveCallPlace (public > API-s)? Did you try to go in that direction? > > On Thu, Nov 2, 2023 at 8:40 PM Cavan Morris > wrote: > > > Thank you Daniel. > > I was able to solve the problem in my case by creating my own util class > in > > the freemarker.core package inside my own project's source tree. This > > allowed me to access the package-private deprecated methods that I > believe > > are used for <#nested> handling. > > > > I plan to clean it up a bit and submit a PR once I have a moment away > from > > my current project. My thought is that even though this relies on > > deprecated methods, those methods are required for <#nested> support so > if > > they are refactored in the future there will have to be similar > > functionality supplied by the refactor. It should be simple to maintain > my > > PR in that case. > > > > Here is a preview of what I have now. At a minimum it will need some > > modifications to use the Freemarker logging system and I will need to > find > > an appropriate place for it in the existing source. Any thoughts > > appreciated. > > > > public static String getRawMacroContent(boolean trim) { > > log.trace("Getting Raw Macro Content"); > > > > StringBuilder sb = new StringBuilder(); > > > > Environment environment = Environment.getCurrentEnvironment(); > > Macro.Context invokingMacroContext = > > environment.getCurrentMacroContext(); > > TemplateObject callPlace = invokingMacroContext.callPlace; > > TemplateElement[] nestedContentBuffer = callPlace instanceof > > TemplateElement ? ((TemplateElement) callPlace).getChildBuffer() : > > null; > > if (nestedContentBuffer != null) { > > for (TemplateElement templateElement : nestedContentBuffer) { > > log.trace("templateElement = {}", templateElement); > > sb.append(templateElement.getSource()); > > } > > } > > > > if(trim) { > > return sb.toString().trim(); > > } else { > > return sb.toString(); > > } > > } > > > > > > > > On Thu, Nov 2, 2023 at 10:51 AM Daniel Dekany > > wrote: > > > > > Kind of a niche use case... I would prefer avoiding much complexity and > > > backward compatibility burden for it. But, maybe it's actually already > > > doable. See my answer on Stack Overflow. > > > > > > On Mon, Oct 30, 2023 at 6:57 PM Cavan Morris > > > > wrote: > > > > > > > Hello All, > > > > I am developing an internal content management system using > freemarker > > > > templates and have run across a speed bump I've detailed in > > > > a stackoverflow question here: > > > > > > > > > > > > > > https://stackoverflow.com/questions/77390595/freemarker-how-to-get-unprocessed-content-of-custom-directive > > > > > > > > The long and short of it is that I would like to access the RAW, > > > > unprocessed content of the <#nested/> tag in my macro. I've looked > > > through > > > > the source for a way to do this and haven't found one. If it exists > > > > please let me know! > > > > > > > > If not, I think it would be very useful to add this feature. Perhaps > > > > through a simple flag on the existing <#nested> tag? Perhaps with the > > > > addition of a new <#nested_raw> tag? > > > > > > > > Please let me know if you have any questions or if there is a way > that > > I > > > > can help make this happen. > > > > > > > > Thank you! > > > > > > > > > > > > > -- > > > Best regards, > > > Daniel Dekany > > > > > > > > -- > Best regards, > Daniel Dekany >
Re: Feature Request
Have you read my answer on SO, i.e., using DirectiveCallPlace (public API-s)? Did you try to go in that direction? On Thu, Nov 2, 2023 at 8:40 PM Cavan Morris wrote: > Thank you Daniel. > I was able to solve the problem in my case by creating my own util class in > the freemarker.core package inside my own project's source tree. This > allowed me to access the package-private deprecated methods that I believe > are used for <#nested> handling. > > I plan to clean it up a bit and submit a PR once I have a moment away from > my current project. My thought is that even though this relies on > deprecated methods, those methods are required for <#nested> support so if > they are refactored in the future there will have to be similar > functionality supplied by the refactor. It should be simple to maintain my > PR in that case. > > Here is a preview of what I have now. At a minimum it will need some > modifications to use the Freemarker logging system and I will need to find > an appropriate place for it in the existing source. Any thoughts > appreciated. > > public static String getRawMacroContent(boolean trim) { > log.trace("Getting Raw Macro Content"); > > StringBuilder sb = new StringBuilder(); > > Environment environment = Environment.getCurrentEnvironment(); > Macro.Context invokingMacroContext = > environment.getCurrentMacroContext(); > TemplateObject callPlace = invokingMacroContext.callPlace; > TemplateElement[] nestedContentBuffer = callPlace instanceof > TemplateElement ? ((TemplateElement) callPlace).getChildBuffer() : > null; > if (nestedContentBuffer != null) { > for (TemplateElement templateElement : nestedContentBuffer) { > log.trace("templateElement = {}", templateElement); > sb.append(templateElement.getSource()); > } > } > > if(trim) { > return sb.toString().trim(); > } else { > return sb.toString(); > } > } > > > > On Thu, Nov 2, 2023 at 10:51 AM Daniel Dekany > wrote: > > > Kind of a niche use case... I would prefer avoiding much complexity and > > backward compatibility burden for it. But, maybe it's actually already > > doable. See my answer on Stack Overflow. > > > > On Mon, Oct 30, 2023 at 6:57 PM Cavan Morris > > wrote: > > > > > Hello All, > > > I am developing an internal content management system using freemarker > > > templates and have run across a speed bump I've detailed in > > > a stackoverflow question here: > > > > > > > > > https://stackoverflow.com/questions/77390595/freemarker-how-to-get-unprocessed-content-of-custom-directive > > > > > > The long and short of it is that I would like to access the RAW, > > > unprocessed content of the <#nested/> tag in my macro. I've looked > > through > > > the source for a way to do this and haven't found one. If it exists > > > please let me know! > > > > > > If not, I think it would be very useful to add this feature. Perhaps > > > through a simple flag on the existing <#nested> tag? Perhaps with the > > > addition of a new <#nested_raw> tag? > > > > > > Please let me know if you have any questions or if there is a way that > I > > > can help make this happen. > > > > > > Thank you! > > > > > > > > > -- > > Best regards, > > Daniel Dekany > > > -- Best regards, Daniel Dekany
Re: Feature Request
Thank you Daniel. I was able to solve the problem in my case by creating my own util class in the freemarker.core package inside my own project's source tree. This allowed me to access the package-private deprecated methods that I believe are used for <#nested> handling. I plan to clean it up a bit and submit a PR once I have a moment away from my current project. My thought is that even though this relies on deprecated methods, those methods are required for <#nested> support so if they are refactored in the future there will have to be similar functionality supplied by the refactor. It should be simple to maintain my PR in that case. Here is a preview of what I have now. At a minimum it will need some modifications to use the Freemarker logging system and I will need to find an appropriate place for it in the existing source. Any thoughts appreciated. public static String getRawMacroContent(boolean trim) { log.trace("Getting Raw Macro Content"); StringBuilder sb = new StringBuilder(); Environment environment = Environment.getCurrentEnvironment(); Macro.Context invokingMacroContext = environment.getCurrentMacroContext(); TemplateObject callPlace = invokingMacroContext.callPlace; TemplateElement[] nestedContentBuffer = callPlace instanceof TemplateElement ? ((TemplateElement) callPlace).getChildBuffer() : null; if (nestedContentBuffer != null) { for (TemplateElement templateElement : nestedContentBuffer) { log.trace("templateElement = {}", templateElement); sb.append(templateElement.getSource()); } } if(trim) { return sb.toString().trim(); } else { return sb.toString(); } } On Thu, Nov 2, 2023 at 10:51 AM Daniel Dekany wrote: > Kind of a niche use case... I would prefer avoiding much complexity and > backward compatibility burden for it. But, maybe it's actually already > doable. See my answer on Stack Overflow. > > On Mon, Oct 30, 2023 at 6:57 PM Cavan Morris > wrote: > > > Hello All, > > I am developing an internal content management system using freemarker > > templates and have run across a speed bump I've detailed in > > a stackoverflow question here: > > > > > https://stackoverflow.com/questions/77390595/freemarker-how-to-get-unprocessed-content-of-custom-directive > > > > The long and short of it is that I would like to access the RAW, > > unprocessed content of the <#nested/> tag in my macro. I've looked > through > > the source for a way to do this and haven't found one. If it exists > > please let me know! > > > > If not, I think it would be very useful to add this feature. Perhaps > > through a simple flag on the existing <#nested> tag? Perhaps with the > > addition of a new <#nested_raw> tag? > > > > Please let me know if you have any questions or if there is a way that I > > can help make this happen. > > > > Thank you! > > > > > -- > Best regards, > Daniel Dekany >
Re: Feature Request
Kind of a niche use case... I would prefer avoiding much complexity and backward compatibility burden for it. But, maybe it's actually already doable. See my answer on Stack Overflow. On Mon, Oct 30, 2023 at 6:57 PM Cavan Morris wrote: > Hello All, > I am developing an internal content management system using freemarker > templates and have run across a speed bump I've detailed in > a stackoverflow question here: > > https://stackoverflow.com/questions/77390595/freemarker-how-to-get-unprocessed-content-of-custom-directive > > The long and short of it is that I would like to access the RAW, > unprocessed content of the <#nested/> tag in my macro. I've looked through > the source for a way to do this and haven't found one. If it exists > please let me know! > > If not, I think it would be very useful to add this feature. Perhaps > through a simple flag on the existing <#nested> tag? Perhaps with the > addition of a new <#nested_raw> tag? > > Please let me know if you have any questions or if there is a way that I > can help make this happen. > > Thank you! > -- Best regards, Daniel Dekany
RE: Feature Request for builtin "replace"
Hi Denis and Barrie, Thank you both for your answers. Good to see, that there are always a lot of possibilities in Freemarker to solve some problems. -- Mcihael -Original Message- From: Denis Bredelet Sent: Dienstag, 22. Oktober 2019 17:04 To: dev@freemarker.apache.org Subject: Re: Feature Request for builtin "replace" Hi Michael > On 22 Oct 2019, at 15:50, Barrie Selack wrote: > > Michael, > > Could you use remove_begining and remove_ending? > > https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builti > n_remove_ending > > Barrie > > > > On Tue, Oct 22, 2019 at 10:31 AM Riehemann, Michael < > michael.riehem...@coremedia.com> wrote: > >> Hello, >> >> I have a Feature Request for the string built-in "replace". >> >> This built-in has some additional flags, see >> https://freemarker.apache.org/docs/ref_builtins_string.html#ref_built >> in_string_flags >> >> Example: >> We have string, in which we want to remove the first and last >> appearance of a substring. >> The first one is possible, but not the last one. Or do I miss >> something here? You could use a combination of keep_before_last and keep_after_last :) — Denis. >> Code: >> <#assign testString="start some text start end some more lines end again" >> /> >> ${testString?replace("start", "", "f")} = some text start end some >> more lines end again >> >> It would be nice to have a flag "l" to get the last one. >> ${testString?replace("end", "", "l")} = start some text start end >> some more lines again >> >> >> What do you think? >> >> Thanks in advance, >> >> Michael Riehemann >>
Re: Feature Request for builtin "replace"
Hi Michael > On 22 Oct 2019, at 15:50, Barrie Selack wrote: > > Michael, > > Could you use remove_begining and remove_ending? > > https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_remove_ending > > Barrie > > > > On Tue, Oct 22, 2019 at 10:31 AM Riehemann, Michael < > michael.riehem...@coremedia.com> wrote: > >> Hello, >> >> I have a Feature Request for the string built-in "replace". >> >> This built-in has some additional flags, see >> https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_string_flags >> >> Example: >> We have string, in which we want to remove the first and last appearance >> of a substring. >> The first one is possible, but not the last one. Or do I miss something >> here? You could use a combination of keep_before_last and keep_after_last :) — Denis. >> Code: >> <#assign testString="start some text start end some more lines end again" >> /> >> ${testString?replace("start", "", "f")} = some text start end some more >> lines end again >> >> It would be nice to have a flag "l" to get the last one. >> ${testString?replace("end", "", "l")} = start some text start end some >> more lines again >> >> >> What do you think? >> >> Thanks in advance, >> >> Michael Riehemann >>
Re: Feature Request for builtin "replace"
Michael, Could you use remove_begining and remove_ending? https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_remove_ending Barrie On Tue, Oct 22, 2019 at 10:31 AM Riehemann, Michael < michael.riehem...@coremedia.com> wrote: > Hello, > > I have a Feature Request for the string built-in "replace". > > This built-in has some additional flags, see > https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_string_flags > > Example: > We have string, in which we want to remove the first and last appearance > of a substring. > The first one is possible, but not the last one. Or do I miss something > here? > > Code: > <#assign testString="start some text start end some more lines end again" > /> > ${testString?replace("start", "", "f")} = some text start end some more > lines end again > > It would be nice to have a flag "l" to get the last one. > ${testString?replace("end", "", "l")} = start some text start end some > more lines again > > > What do you think? > > Thanks in advance, > > Michael Riehemann >