IRequestHandler and INavigationContributor must be implemented in the same component?

11 views
Skip to first unread message

Filipe Correia

unread,
Mar 5, 2013, 6:59:40 AM3/5/13
to Trac Development
Hi,

So, I think I've found a bug!

I'm developing a plugin that implements IRequestHandler and
INavigationContributor. My "process_request()" method calls
"add_script()" a couple of times. For reasons I don't fully
understand, the "get_active_navigation_item()" method gets called in
these situations, but I'm assuming it's by design.

Note that "process_request()" belongs to the IRequestHandler extension
point, and "get_active_navigation_item()" belongs to the
INavigationContributor extension point.

The issue is, I need to implement these extensions points in two
distinct Component classes. But when I split the Component class in
two (one for each extension point) the "get_active_navigation_item()"
is no longer called, so the item that I'm adding to the mainnav no
longer shows highlighted...

I am sure that both Component classes are being picked up by trac as
the other methods of the extensions points are being invoked (e.g.,
the get_navigation_items() method is being called).

I've tracked this as far as trac.web.chrome.py. I think the relevant
lines are these:

if contributor is handler:
active =
contributor.get_active_navigation_item(req)

I can't figure out where the "handler" value comes from, but I've
confirmed that it is never an instance of the component implementing
INavigationContributor.

Any help appreciated.

thanks in advance!

Filipe Correia

Ethan Jucovy

unread,
Mar 5, 2013, 8:14:52 AM3/5/13
to trac...@googlegroups.com
On Tue, Mar 5, 2013 at 6:59 AM, Filipe Correia <fcor...@gmail.com> wrote:
I'm developing a plugin that implements IRequestHandler and
INavigationContributor. My "process_request()" method calls
"add_script()" a couple of times. For reasons I don't fully
understand, the "get_active_navigation_item()" method gets called in
these situations, but I'm assuming it's by design.

Note that "process_request()" belongs to the IRequestHandler extension
point, and "get_active_navigation_item()" belongs to the
INavigationContributor extension point.

The issue is, I need to implement these extensions points in two
distinct Component classes. But when I split the Component class in
two (one for each extension point) the "get_active_navigation_item()"
is no longer called, so the item that I'm adding to the mainnav no
longer shows highlighted...

This sounds a lot like http://trac.edgewall.org/ticket/9528.  There's an explanation and a patch at http://trac.edgewall.org/ticket/10953#comment:8 (which has been closed as a duplicate) -- the patch would solve this problem, but causes some subtle side effects that may not be acceptable.

I haven't refreshed my memory lately, but I think the best/only workaround is to delay your add_script() calls somehow until post_process_request(), perhaps by setting some state on your component or on the request object itself (but **not** on request.chrome!) during process_request() and then checking for that state in post_process_request().

More eyes on #9528 would be great too, if you want to try coming up with a better patch. :-)

-Ethan

Filipe Correia

unread,
Mar 5, 2013, 8:32:34 AM3/5/13
to Trac Development
Hi,

On Mar 5, 1:14 pm, Ethan Jucovy <ethan.juc...@gmail.com> wrote:
> On Tue, Mar 5, 2013 at 6:59 AM, Filipe Correia <fcorr...@gmail.com> wrote:
> > The issue is, I need to implement these extensions points in two
> > distinct Component classes. But when I split the Component class in
> > two (one for each extension point) the "get_active_navigation_item()"
> > is no longer called, so the item that I'm adding to the mainnav no
> > longer shows highlighted...
>
> This sounds a lot like http://trac.edgewall.org/ticket/9528.

Indeed!

> I haven't refreshed my memory lately, but I think the best/only workaround
> is to delay your add_script() calls somehow until post_process_request(),
> perhaps by setting some state on your component or on the request object
> itself (but **not** on request.chrome!) during process_request() and then
> checking for that state in post_process_request().

Ok, I see. I think I'll keep IRequestHandler and
INavigationContributor in the same Component, even though it implies
other issues for my plugin, but it seems like the cleanest solution
(even if not necessarily very clean :)


> More eyes on #9528 would be great too, if you want to try coming up with a
> better patch. :-)

:)
I don't think I will be able to, not for the next couple of months at
least, but it's good to know someone already figured out what's
causing this.


Thank you Ethan!

Filipe


Reply all
Reply to author
Forward
0 new messages