Foros de discusión

Cannot access variable exposed using TemplateContextContributor

Peter Helgren, modificado hace 6 años.

Cannot access variable exposed using TemplateContextContributor

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
So, as I understand the TemplateContextContributor, you can expose variables basically like so:


@Component(
	immediate = true,
	property = {"type=" + TemplateContextContributor.TYPE_GLOBAL},
	service = TemplateContextContributor.class
)
public class MyTemplateContextContributor
	implements TemplateContextContributor {

	@Override
	public void prepare(
		Map<string, object> contextObjects, HttpServletRequest request) {

		contextObjects.put("className", "This is a sample class name");
		contextObjects.put("lectureDate", "Today!");
	}

}
</string,>


So I thought I could then reference those variables in my Freemarker Template like so:

${lectureDate}

${className}

But the Freemarker template processor throws an error:


FreeMarker template error:
The following has evaluated to null or missing:
==&gt; lectureDate  [in template.......

So even though the module containing the TemplateContextContributor is loaded and active, something is still missing. Do I need to reference a tag lib or a module path or something. Plenty of info on creating the module to implement the TemplateContextContributor but precious few examples of how to *consume* a TemplateContextContributor.

What am I missing here?
thumbnail
David H Nebinger, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Liferay Legend Mensajes: 14915 Fecha de incorporación: 2/09/06 Mensajes recientes
I think if you tried a page-level FTL eval (i.e. a theme), you would see your additional values.

I just don't think they get injected into, say, an ADT dealing with individual assets.

Admittedly I'm not 100% sure on this though...









Come meet me at the 2017 LSNA!
thumbnail
Christoph Rabel, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Liferay Legend Mensajes: 1554 Fecha de incorporación: 24/09/09 Mensajes recientes
According to the documentation it should be injected in all templates:

Are you working with templates that aren’t themes (e.g., ADTs, DDM templates, etc.)? You can change the context in which your variables are injected by modifying the property attribute in the @Component annotation. If you want your variable available for all templates, change it to
property = {"type=" + TemplateContextContributor.TYPE_GLOBAL}


Didn't try it so far, since we were lazy and just enabled serviceLocator, but it would be really swell to have some of our services available everywhere. We have an imageoptimizer, a cacheservice and a searchhelper that we really need in several templates.
thumbnail
Christoph Rabel, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Liferay Legend Mensajes: 1554 Fecha de incorporación: 24/09/09 Mensajes recientes
I gave it a quick try just now with CE GA3 and it works for me. I just used the IDE to create a template-context-contributor project and deployed it. sample_text is there and printed in the ADT.

Which version do you use?
thumbnail
Amos Fong, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Liferay Legend Mensajes: 2047 Fecha de incorporación: 7/10/08 Mensajes recientes
For TemplateContextContributor, It will not be available in web content templates though. I ran into this issue as well. Not sure if this is considered a bug or not.

For me I was trying to inject a service util. I ended making it an osgi component and was able to access it with serviceLocator. For things like strings, I think there were easier methods like adding it as a request attribute, but I don't remember off the top of my head.
thumbnail
Christoph Rabel, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Liferay Legend Mensajes: 1554 Fecha de incorporación: 24/09/09 Mensajes recientes
Yes, you are right. Since the tomcat was still running, I tested it just now.
It works in an ADT, but doesn't work in Webcontent.

You think of this:
${request.setAttribute("myvar", myvar)}
in an ADT and read it in a webcontent template using
<#assign myvar = request.attributes.myvar!"" >

Of course, that only works, if the webcontent is rendered by the ADT and isn't displayed "standalone" e.g. by Webcontent display. We tried that to do something like:

if(myvar == "listitem")
// Render webconent as a listitem
else if (myvar == "card")
// Render webconent as a carditem
else
// Render full content

But we have discarded that idea now, the templates grow very large and we just move a lot of complexity from the ADT to the webcontent template. Of course, it has the advantage that we don't need to parse the variables from the xml.
Peter Helgren, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
So, is there no solution for getting MVC portlet objects into a Freemarker template? At a big picture level, I have several modules that produce objects that have Portal-wide use. For example we have a member database that contains all the information on our class members and that data is available in an SB Module. Is there no way to access that data in an MVC portlet that uses FTL as the "form" ? Since I never used an LR "standard" UI method maybe I just have more learning curve to deal with here but I would think that data retrieved in an MVC portlet would then be displayed in a UI form (Freemarker in my case) . That is what I am after here and I can't quite understand how to do it. I have always used Freemarker, but within my own servlets using my own MVC components. I would prefer to follow more LR 7 conventions, if possible.
Anton Truong, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

New Member Mensajes: 5 Fecha de incorporación: 12/01/17 Mensajes recientes
Hi there,

so there are no possibilities to use the template context contributor to inject variables into a web-content template (I mean no an ADT)?

I tested it within in an ADT -> works!
But in a web-content template -> not working!

Another question, is it possible to work with variables while creating a web content. E.g. as an editor I want to create a new News-article:

${company_name} has announced.....

And the result would be like:

ImagineCompany has announced....
Peter Helgren, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Regular Member Mensajes: 124 Fecha de incorporación: 14/11/13 Mensajes recientes
Thanks. So I am on CE GA3 as well....maybe I misunderstand how this works.....

Freemarker is a template engine so I assume that a Freemarker data model object that is exposed in a TemplateContextContributor is available to all Freemarker "templates" i.e. an .ftl file. I use Freemarker templates instead of JSP's for all my MVC portlets and I assumed (always dangerous) that a Freemarker template AKA an FTL file, is what the TemplateContextContributor can provide variables for. Indeed the opening paragraph in this LDN article (https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/context-contributors) states EXACTLY what I want. However, how Liferay defines a "template" and how I define it may be two different things...

I am simply trying to make variables from my portlets available in my views which are Freemarker templates. So, am I misunderstand the concept of "template" when it come to the TemplateContextContributor? Are these "templates" something different from what I would consider a template in the Freemarker vernacular?
thumbnail
David H Nebinger, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

Liferay Legend Mensajes: 14915 Fecha de incorporación: 2/09/06 Mensajes recientes
Peter Helgren:
Freemarker is a template engine so I assume that a Freemarker data model object that is exposed in a TemplateContextContributor is available to all Freemarker "templates" i.e. an .ftl file.


Yeah, no. Certain contexts will be available in different spots. For example, there's FTL handling at the theme level which, of course, may not have details about individual portlet requests and stuff.

But the FTL context within an ADT and a web content template, they have a different context than the theme (and a different context from each other). You could also have an FTL portlet which of course will also have a different context.

I think that's the basis behind the difference we've seen where the context contributors apply, since scope can be different at different levels it may be difficult to deterministically identify when to use a contributor and when not to. That would possibly be the nature of the "bug", if it is considered to be one.

I use Freemarker templates instead of JSP's for all my MVC portlets and I assumed (always dangerous) that a Freemarker template AKA an FTL file, is what the TemplateContextContributor can provide variables for. Indeed the opening paragraph in this LDN article (https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/context-contributors) states EXACTLY what I want. However, how Liferay defines a "template" and how I define it may be two different things...







Come meet me at the 2017 LSNA!
thumbnail
Allen Ziegenfus, modificado hace 6 años.

RE: Cannot access variable exposed using TemplateContextContributor

New Member Mensajes: 11 Fecha de incorporación: 29/12/15 Mensajes recientes
It looks like this is being fixed:

https://issues.liferay.com/browse/LPS-76631