You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Vjeran Marcinko <vj...@email.t-com.hr> on 2009/06/21 08:19:26 UTC

Type-safe PageLink version

Hello,

I have an idea for PageLink version that would be type-safe because I simply 
love when I don't have to worry about page names or context parameters in my 
templates as much as possible, especially cosidering that I like to refactor 
much...

If PageLink could accept page *instance* as parameter, it could resolve page 
name and also activation context from this instance.
For example, in ViewAllEmployeesPage class I need to provide 
EditEmployeePage instance for each looped employee ID as activation context, 
I could have:


private Employee employee; // looped employee

@InjectPage
private EditEmployeePage editEmployeePage;

public Object getEditEmployeePageInstance() {
    editEmployeePage.onActivate(employee.getId()); // configuring page 
isntance
    return editEmployeePage;
}

It seemed simple enough to write my own TypeSafePageLink that would render 
these links via :
PageRenderLinkSource.createPageRenderLinkWithContext(Class pageClass, 
Object... context);
...but I got in problem how to extract this activation context parameter 
from page instance parameter ?
Any Tapestry utility method for this somewhere?

Actually, documentation of current PageLink states that:
".If no context is supplied, then the target page itself will supply the 
context via a passivate event."
I'm little confused how can PageLink resolve activation context from target 
page specified with only its name, when one would actually need an 
*instance* of configured page to extract its activation context via 
"passivate" event? Or I have mixed up some things here?

Regards,
Vjeran


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Type-safe PageLink version

Posted by Sergey Didenko <se...@gmail.com>.
Vjeran, thanks a lot.

I am really surprised to see that line

 "Link link = pageRenderLinkSource.createPageRenderLink( page.getClass() );"

indeed passes page context! I see this is documented

 http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/services/PageRenderLinkSource.html#createPageRenderLink(java.lang.Class)

but it's still very unusual that page.getClass() is not just Page.class

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Type-safe PageLink version

Posted by Vjeran Marcinko <vj...@email.t-com.hr>.
Stupid me, it seems that PageRenderLinkSource by default does what I'm 
trying to achieve. It automaticaly adds activation context to render request 
URL if no context specified.

I guess the thing works in such way that when during some request one asks 
for some page via @InjectPage annotation, then this instance is also 
thread-bound for all further possible fetching specified with same page name 
(or class) during this request. So, when page with same name is specified as 
parameter to PageRenderLinkSource methods, then tih service fetches this 
same page instance and reads its activation context via "passivate" event.

Anyway, for anyone interested, tihs new type-safe version of PageLink is 
trivial now:

public class SafePageLink extends AbstractLink {
    @Parameter(required = true, allowNull = false)
    private Object page;

    @Inject
    private PageRenderLinkSource pageRenderLinkSource;

    void beginRender(MarkupWriter writer) {
        if (isDisabled()) {
            return;
        }
        Link link = 
pageRenderLinkSource.createPageRenderLink(page.getClass());
        writeLink(writer, link);
    }

    void afterRender(MarkupWriter writer) {
        if (isDisabled()) {
            return;
        }
        writer.end(); // <a>
    }
}

And now you can have page links without worrying about page name or its 
context values. Just use for eg:

    @InjectPage
    private EditUser editUser;

    public EditUserPage getEditUserPage() {
        return editUserPage.configured(user.getId());
    }

...and in template:

<t:safepagelink t:page="editUserPage">Edit</t:safepagelink>

...instead of shorter, but type-nonsafe:

<t:pagelink t:page="admin/user/edituserpage" 
context="user.id">Edit</t:pagelink>

Cheers,
Vjeran

----- Original Message ----- 
From: "Vjeran Marcinko" <vj...@email.t-com.hr>
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Sunday, June 21, 2009 1:14 PM
Subject: Re: Type-safe PageLink version


> Your example captures somewhat my idea, but not quite...
> Most importantly context values are not type-safe in your example because
> they are given via String value without being ever sure that
> EditEmployeePage requires only one context value and of what type it is.
> When calling method onActivate(..) or some other for purpose of 
> configuring
> it, then compiler takes care that everything is correct.
>
> My whole intention is to make PageLink's render request type-safe exactly 
> in
> the same way when one returns configured target page from action event
> handler (ActionLink) that will serve for redirect response URL generation
> (render request).
>
> Actually, I tried to develop my own SafePageLink component, but I lack the
> way of resolving context from page instance:
>
> public class SafePageLink extends AbstractLink {
>    @Parameter(required = true, allowNull = false)
>    private Object page;
>
>    @Inject
>    private PageRenderLinkSource pageRenderLinkSource;
>
>    void beginRender(MarkupWriter writer) {
>        Object[] context = ?????
>        Link link =
> pageRenderLinkSource.createPageRenderLinkWithContext(page.getClass(),
> context);
>        writeLink(writer, link);
>    }
> ....
>
> And then one just needs to have:
>
> <t:safepagelink t:page="editEmployeePage">Create</t:safepagelink>
>
> in template, and in page class:
>
> @InjectPage
> private EditEmployeePage editEmployeePage;
>
> public Object getEditEmployeePageInstance() {
>   // configuring EditEmployeePage page instance via onActivate let's say
>   return editEmployeePage;
> }
>
> It's exactly the same way as I'm returning configured target page inside
> action event handler. Maybe I should dig into ActionLink sorce to see how 
> it
> fetches activation context (via "passivate" event somehow).
>
> -Vjeran
>
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Type-safe PageLink version

Posted by Vjeran Marcinko <vj...@email.t-com.hr>.
Your example captures somewhat my idea, but not quite...
Most importantly context values are not type-safe in your example because 
they are given via String value without being ever sure that 
EditEmployeePage requires only one context value and of what type it is. 
When calling method onActivate(..) or some other for purpose of configuring 
it, then compiler takes care that everything is correct.

My whole intention is to make PageLink's render request type-safe exactly in 
the same way when one returns configured target page from action event 
handler (ActionLink) that will serve for redirect response URL generation 
(render request).

Actually, I tried to develop my own SafePageLink component, but I lack the 
way of resolving context from page instance:

public class SafePageLink extends AbstractLink {
    @Parameter(required = true, allowNull = false)
    private Object page;

    @Inject
    private PageRenderLinkSource pageRenderLinkSource;

    void beginRender(MarkupWriter writer) {
        Object[] context = ?????
        Link link = 
pageRenderLinkSource.createPageRenderLinkWithContext(page.getClass(), 
context);
        writeLink(writer, link);
    }
....

And then one just needs to have:

<t:safepagelink t:page="editEmployeePage">Create</t:safepagelink>

in template, and in page class:

@InjectPage
private EditEmployeePage editEmployeePage;

public Object getEditEmployeePageInstance() {
   // configuring EditEmployeePage page instance via onActivate let's say
   return editEmployeePage;
}

It's exactly the same way as I'm returning configured target page inside 
action event handler. Maybe I should dig into ActionLink sorce to see how it 
fetches activation context (via "passivate" event somehow).

-Vjeran


----- Original Message ----- 
From: "Onno Scheffers" <on...@piraya.nl>
To: "Tapestry users" <us...@tapestry.apache.org>
Sent: Sunday, June 21, 2009 10:32 AM
Subject: Re: Type-safe PageLink version


>I usually use something like this:
>
> @Component(parameters = { "page=prop:editEmployeePage", "context=prop:
> employee.id })
> private PageLink pageLink;
>
> @Inject
> private ComponentClassResolver resolver;
>
> @Cached
> public String getEditEmployeePage() {
>   resolver.resolvePageClassNameToPageName(EditEmployeePage.class);
> }
>
> regards,
>
> Onno
>
> 2009/6/21 Vjeran Marcinko <vj...@email.t-com.hr>
>
>> Hello,
>>
>> I have an idea for PageLink version that would be type-safe because I
>> simply love when I don't have to worry about page names or context
>> parameters in my templates as much as possible, especially cosidering 
>> that I
>> like to refactor much...
>>
>> If PageLink could accept page *instance* as parameter, it could resolve
>> page name and also activation context from this instance.
>> For example, in ViewAllEmployeesPage class I need to provide
>> EditEmployeePage instance for each looped employee ID as activation 
>> context,
>> I could have:
>>
>>
>> private Employee employee; // looped employee
>>
>> @InjectPage
>> private EditEmployeePage editEmployeePage;
>>
>> public Object getEditEmployeePageInstance() {
>>   editEmployeePage.onActivate(employee.getId()); // configuring page
>> isntance
>>   return editEmployeePage;
>> }
>>
>> It seemed simple enough to write my own TypeSafePageLink that would 
>> render
>> these links via :
>> PageRenderLinkSource.createPageRenderLinkWithContext(Class pageClass,
>> Object... context);
>> ...but I got in problem how to extract this activation context parameter
>> from page instance parameter ?
>> Any Tapestry utility method for this somewhere?
>>
>> Actually, documentation of current PageLink states that:
>> ".If no context is supplied, then the target page itself will supply the
>> context via a passivate event."
>> I'm little confused how can PageLink resolve activation context from 
>> target
>> page specified with only its name, when one would actually need an
>> *instance* of configured page to extract its activation context via
>> "passivate" event? Or I have mixed up some things here?
>>
>> Regards,
>> Vjeran
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Type-safe PageLink version

Posted by Onno Scheffers <on...@piraya.nl>.
I usually use something like this:

@Component(parameters = { "page=prop:editEmployeePage", "context=prop:
employee.id })
private PageLink pageLink;

@Inject
private ComponentClassResolver resolver;

@Cached
public String getEditEmployeePage() {
   resolver.resolvePageClassNameToPageName(EditEmployeePage.class);
}


regards,

Onno



2009/6/21 Vjeran Marcinko <vj...@email.t-com.hr>

> Hello,
>
> I have an idea for PageLink version that would be type-safe because I
> simply love when I don't have to worry about page names or context
> parameters in my templates as much as possible, especially cosidering that I
> like to refactor much...
>
> If PageLink could accept page *instance* as parameter, it could resolve
> page name and also activation context from this instance.
> For example, in ViewAllEmployeesPage class I need to provide
> EditEmployeePage instance for each looped employee ID as activation context,
> I could have:
>
>
> private Employee employee; // looped employee
>
> @InjectPage
> private EditEmployeePage editEmployeePage;
>
> public Object getEditEmployeePageInstance() {
>   editEmployeePage.onActivate(employee.getId()); // configuring page
> isntance
>   return editEmployeePage;
> }
>
> It seemed simple enough to write my own TypeSafePageLink that would render
> these links via :
> PageRenderLinkSource.createPageRenderLinkWithContext(Class pageClass,
> Object... context);
> ...but I got in problem how to extract this activation context parameter
> from page instance parameter ?
> Any Tapestry utility method for this somewhere?
>
> Actually, documentation of current PageLink states that:
> ".If no context is supplied, then the target page itself will supply the
> context via a passivate event."
> I'm little confused how can PageLink resolve activation context from target
> page specified with only its name, when one would actually need an
> *instance* of configured page to extract its activation context via
> "passivate" event? Or I have mixed up some things here?
>
> Regards,
> Vjeran
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>