Thanks for the continued support! Now that sounds more like it! And it actually
works.
Having an other look at the TemplatedMVCHandler class now the line 96 makes
sense:
data.put("this", this);
The handler class itself is added to the data model and I guess FreemarkerUtil
then does it's magic and adds all public methods to the data model. Great stuff
and thanks again! This should be added to the freemarker primer [1]
-will
[1] http://documentation.magnolia-cms.com/reference/freemarker.html
On 03.12.2009, at 21:19, Jan Haderka wrote:
> Ahh, getting closer ... but I must be still missing something :)
> so, getting back to the square one:
> - define your page in config:/modules/your_module/pages/yourPage, you
> specify it's handler (the one that extends TemplatedMVCHandler) as a
> "class" NodeData
> - put the method magnoliaUserForUsernameAndManagerName() into this
> handler directly
> - write the FM page which is called exactly same as your handler class
> incl. the package structure (only the extension is different - the page
> goes by html)
> - access the handler in the FM page by
> ${this.magnoliaUserForUsernameAndManagerName("test","admin")}
>
> What am I missing? Why do you need to override renderHtml() and stuff
> your handler into the context?
> ... yes you can do it, but why? With the above you don't need to
> override anything in the handler just add there your extra methods.
>
> Jan
>
>>
>> And... no, I don't need the current user. The goal would be to get a custom
>> user management page.
>>
>> -will
>>
>> On 03.12.2009, at 19:24, Jan Haderka wrote:
>>
>>>
>>> Maybe I'm missing something obvious, but why don't you simply define a
>>> modelClass for your template (by defining "modelClass" node data in your
>>> template and setting it's value to point to your model). And make use of
>>> the fact that Magnolia will instantiate model class and make it
>>> available for you?
>>>
>>> In the template you then simply call (assuming you make that method
>>> public)
>>> ${model.magnoliaUserForUsernameAndManagerName("userName", "admin")}
>>>
>>> and you don't have to do anything with the context, no overriding
>>> anything, no nothing.
>>>
>>> If your template is of type stk rather then freemarker you might need to
>>> have your model extend different class. See for example
>>> info.magnolia.module.templatingkit.paragraphs.ContentTypeSyndicateModel
>>>
>>> When it comes to getting user object, the ${ctx.user} would be enough if
>>> what you want is current user.
>>>
>>> HTH,
>>> Jan
>>>
>>>
>>>
>>> On Thu, 2009-12-03 at 18:30 +0100, Will Scheidegger wrote:
>>>> Answering my own question... and boy does this seem complicated to me!
>>>> So if there is an easier way then described below _please_ let me
>>>> know.
>>>>
>>>>
>>>> The "method class" I came up with to solve the problem:
>>>>
>>>>
>>>> public class UserForUsernameMethod implements TemplateMethodModel {
>>>>
>>>>
>>>> import freemarker.ext.beans.BeanModel;
>>>> import freemarker.template.DefaultObjectWrapper;
>>>> import freemarker.template.TemplateMethodModel;
>>>> import freemarker.template.TemplateModel;
>>>> import freemarker.template.TemplateModelException;
>>>> import info.magnolia.cms.security.SecuritySupport;
>>>> import info.magnolia.cms.security.User;
>>>> import info.magnolia.cms.security.UserManager;
>>>> import java.util.List;
>>>>
>>>>
>>>> public class UserForUsernameMethod implements TemplateMethodModel {
>>>>
>>>>
>>>> public TemplateModel exec(List args) throws TemplateModelException
>>>> {
>>>> if (args.size() < 1) {
>>>> throw new TemplateModelException("Wrong arguments");
>>>> } else {
>>>> String userManagerName = "admin";
>>>> String userName = (String) args.get(0);
>>>> if (args.size() > 1) {
>>>> userManagerName = (String) args.get(1);
>>>> }
>>>> User user =
>>>> magnoliaUserForUsernameAndManagerName(userName, userManagerName);
>>>> if (user != null) {
>>>> return new BeanModel(user,
>>>> DefaultObjectWrapper.getDefaultInstance());
>>>> } else {
>>>> return TemplateModel.NOTHING;
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>> private User magnoliaUserForUsernameAndManagerName(String
>>>> userName, String userManagerName) {
>>>> UserManager userManager =
>>>> SecuritySupport.Factory.getInstance().getUserManager(userManagerName);
>>>> return userManager.getUser(userName);
>>>> }
>>>> }
>>>>
>>>>
>>>> And to add the method to the model in the template class
>>>> extending TemplatedMVCHandler I had to overwrite the renderHtml()
>>>> method and add the method there:
>>>>
>>>>
>>>> @Override
>>>> public void renderHtml(String view) throws IOException {
>>>> // no rendering if view is null
>>>> if(StringUtils.isEmpty(view)){
>>>> return;
>>>> }
>>>>
>>>>
>>>> String template = this.getTemplateName(view);
>>>> if (template != null) {
>>>>
>>>>
>>>> Map data = new HashMap();
>>>> data.put("this", this);
>>>> data.put("view", view);
>>>> data.put("userForUsername", new UserForUsernameMethod());
>>>>
>>>>
>>>> PrintWriter writer;
>>>>
>>>>
>>>> try {
>>>> writer = getResponse().getWriter();
>>>> }
>>>> catch (IllegalStateException e) {
>>>> // getResponse().getOutputStream() has already been
>>>> called
>>>> writer = new
>>>> PrintWriter(getResponse().getOutputStream());
>>>> }
>>>> FreemarkerUtil.process(template, data, writer);
>>>> }
>>>> }
>>>>
>>>>
>>>> Afterwards, I was able to access the user data in my template:
>>>> test: ${userForUsername("test").password}
>>>>
>>>>
>>>> Quite a bit of work! At the moment, even custom JSP tags seem easier
>>>> to me. But maybe after getting used to this...
>>>>
>>>>
>>>> -will
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On 03.12.2009, at 17:45, Will Scheidegger wrote:
>>>>
>>>>> Dear Magnolians
>>>>>
>>>>> Can someone give me a quick primer on how to call java methods from
>>>>> a Freemarker template? From looking at the documentation one does
>>>>> not seem to be able to simply call a method in an object. It looks
>>>>> like the methods need to be implemented as subclass of
>>>>> "TemplateMethodModel" (see [1]). This seems quite complicated, but I
>>>>> guess I could do that. But then, where is this method added to the
>>>>> data model (i.e. "root.put("methodName", new MethodClass())?
>>>>>
>>>>> To be more specific: I would like to access the user info in a
>>>>> Freemarker template, where I only have the username. So I would need
>>>>> a method which would return the user (object? "data-model"? hash?)
>>>>> when passing in the username. I am using the TemplatedMVCHandler
>>>>> class to display the template. The template displays fine. But now
>>>>> I'm a bit stuck with adding the method...
>>>>>
>>>>> Thanks for the insight!
>>>>> -will
>>>>>
>>>>>
>>>>> [1] http://freemarker.sourceforge.net/docs/pgui_datamodel_method.html
>>>>>
>>>>>
>>>>> ____________________________________________________________________
>>>>> ----------------------------------------------------------------
>>>>> For list details see
>>>>> http://www.magnolia-cms.com/home/community/mailing-lists.html
>>>>> To unsubscribe, E-mail to: <[email protected]>
>>>>> ----------------------------------------------------------------
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> ______________________________________________________________________
>>>> ----------------------------------------------------------------
>>>> For list details see
>>>> http://www.magnolia-cms.com/home/community/mailing-lists.html
>>>> To unsubscribe, E-mail to: <[email protected]>
>>>> ----------------------------------------------------------------
>>>
>>>
>>> ----------------------------------------------------------------
>>> For list details see
>>> http://www.magnolia-cms.com/home/community/mailing-lists.html
>>> To unsubscribe, E-mail to: <[email protected]>
>>> ----------------------------------------------------------------
>>>
>>
>>
>> ----------------------------------------------------------------
>> For list details see
>> http://www.magnolia-cms.com/home/community/mailing-lists.html
>> To unsubscribe, E-mail to: <[email protected]>
>> ----------------------------------------------------------------
>
>
> ----------------------------------------------------------------
> For list details see
> http://www.magnolia-cms.com/home/community/mailing-lists.html
> To unsubscribe, E-mail to: <[email protected]>
> ----------------------------------------------------------------
>
----------------------------------------------------------------
For list details see
http://www.magnolia-cms.com/home/community/mailing-lists.html
To unsubscribe, E-mail to: <[email protected]>
----------------------------------------------------------------