Geoff, I always try to follow you suggested pattern, but unfortunately I don't think it's always possible. I'd like to present a use case scenario and perhaps maybe you guys can break me out of my current design rut.
*Use case 1* 1. My navigation bar is contained within my layout component which is available to all pages. The navigation bar contains an ajax link called login. When the user clicks the login link, it triggers an event in the layout.java called onShowLoginRegister. Layout.java public void onShowLoginRegister() { function = Function.LOGIN; if (request.isXHR()) { ajaxResponseRenderer.addRender(loginRegisterModalZone); } } 2. Also contained within layout is a component called LoginRegister which is nested within a modal dialog box surrounded by a zone which is triggered by the onShowLoginRegister response. <t:zone t:id="loginRegisterModalZone"> <t:if test="isFunction('login')"> <t:modaldialog title="Sign in or Register" modalId="loginModal"> <t:loginregister/> </t:modaldialog> </t:if> </t:zone> 3. LoginRegister contains all the authentication code enabling users to log in inline despite what page they may be on. 4. When the user has been successfully authenticated, I then trigger another event in the layout to close the LoginRegister modal dialog as well as update the the user name in the navbar via a zone. LoginRegister.java Object onSuccessFromLoginForm() { // We want to tell our containing page explicitly what person we've updated, so we trigger a new event with a // parameter. It will bubble up because we don't have a handler method for it. componentResources.triggerEvent(LOGIN, null, null); // We don't want the original event to bubble up, so we return true to // say we've handled it. return true; } Layout.java void onLoginFromLoginRegister() { modalDialog.hide(); if (request.isXHR()) { ajaxResponseRenderer.addRender(loginRegisterModalZone).addRender(loginNavZone); } } So far everything works perfectly. Now comes the tricky part, updating page content. Now lets say I'm on a page that has actions or other content hidden to a non authenticated user. When I log in through my loginregister modal dialog, not only do I need to update the username contained within the layout navbar component, I also need to update a zone contained within the page to show actions now available to the authenticated user. Now I know you say everything should be controlled through the page, but in this scenario the event is being fired from the navbar contained within the layout component. MyPage.tml <t:layout> //actionZone should be triggered when the user has been successfully authenticated by loginregister. Ideally it should be updated with ajaxResponseRenderer within onLoginFromLoginRegister() <t:zone t:id="actionZone"> <t:if test="authenticated"> //some actions that need to be displayed to authenticated users. </t:if> </t:zone> </t:layout How would you recommend updating a zone within the page? If I moved the LoginRegister into the page, I would then be required to have to do that to every page in the application which seems like the wrong approach. *Use case 2* 1. Now my last use case might be an instance where an action contained within a page or component requires authentication. When you click the action, I need to fire the onShowLoginRegister() event contained within layout. Example, When a user starts to post a new listing, but have yet to login or register a new account. When the user completes the creation of their listing, prior to saving the listing to the database I prompted the LoginRegister dialog box for them to either login in or create a new account. Once they are authenticated I call the onLoginFromLoginRegister event along with a callback to redirect the user to the next page. LoginRegister.java //note: LoginType args actually exist in use case 1, but were removed to simplify my example. They are only used to pick proper ajaxResponseRenderer in the onLoginFromLoginRegister method. boolean onSuccessFromLoginForm(LoginType loginType) { // We want to tell our containing page explicitly what person we've updated, so we trigger a new event with a // parameter. It will bubble up because we don't have a handler method for it. componentResources.triggerEvent(LOGIN, new Object[] { loginType }, null); // We don't want the original event to bubble up, so we return true to // say we've handled it. return true; } Layout.java void onLoginFromLoginRegister(LoginType loginType) { modalDialog.hide(); if (request.isXHR()) { if(LoginType.LOGIN.equals(loginType)) { ajaxResponseRenderer.addRender(loginRegisterModalZone).addRender(loginNavZone); } else if(LoginType.LOGIN_CREATE_LISTING.equals(loginType)) { ajaxResponseRenderer.addRender(loginRegisterModalZone).addRender(loginNavZone).addCallback(redirectToPhotos()); } } } private JavaScriptCallback redirectToPhotos() { return new JavaScriptCallback() { @Override public void run(JavaScriptSupport javascriptSupport) { javascriptSupport.addScript("$(\"#form\").submit();"); } }; } I guess I'm just not sure how you can accomplish both use cases without running into an area where a component would not need to command it's container. I'm very interested in hearing your thoughts. I'm not opposed to changing my design to make everything work properly.