Howto: Communicate between template- and inner- pages.

This post is as much about me asking a question as it is about providing a solution, so don’t let me down community. I got your back, but you’ve got to scratch mine too.. A little to the left, ah yeah, that’s it. The topics in question here are page templates, their controllers, and the pages (and the controllers) that use the template. But first let’s start with what I’ve discovered.

I like using page templates, they make my life easier. If I’m creating a site I probably want to have some consistency of navigation, page header, search etc. across all my web pages. So let’s assume I have the following setup:

1. A VisualForce page I use as a template.

2. A controller for this page that handles navigation, searching etc.

3. Several ‘inner’ VisualForce pages that use this template.

4. A controller for each of these pages.

If we consider the situation in which we have a ‘News’ area on the template page, and each inner page’s controller feeds different types of information to this area based on the page in question, we quickly realise that we have a teeny-tiny snag. How do we get our template page-controller to speak to the inner page-controller?

This curious problem had me befuddled because it’s not as clear-cut as the page-component controller comms situation. I realise this is quite a complex situation to consider without some visuals, so I’ve put this together (with yEd BTW. A tool every developer should have in their belt of awesomeness):

Variable X needs to be displayed in the template page, but belongs to the inner page's controller.

Like a lot of my discoveries, this one happened by accident [insert several jokes about my competence(or lack thereof) here]. It seems that if you declare a variable in the template page-controller that has the same name and access modifier as in the inner page-controller, the value of the variable within the template page-controller assumes the value of the inner page-controller’s variable. I just typed that up and even I don’t understand, so without further ado, here’s another picture:

Template page controller has an entirely separate variable X, but it shares the name and access modifier of the variable within the inner page controller.. and somehow also assumes its value.

Unfortunately I can’t see what’s going on behind the scenes so I can only hazard a guess at how this works.. I think that somehow this is behaving similarly to the “session”-type situation you can create with Apex Controllers (See the Force.com Cookbook Wizard Tutorial). I also think that it wasn’t made to work this way, but I’m glad it does otherwise I’d have to extend the Page-Component controller architecture to serve my needs. I could be wrong though, and if I am please let me know.

Oh and, Salesforce, please don’t fix this, it’s not a bug, it’s a feature 😉

14 thoughts on “Howto: Communicate between template- and inner- pages.”

  1. Components can take a peek at the current page they’re being invoked on for conditional branching, like page specific news items.

    public string PageName{
    get{
    List path = Apexpages.currentPage().getUrl().split(‘/’);
    return path[path.size()-1];
    }
    }

    Reply
  2. Components can take a peek at the current page they’re being invoked on for conditional branching, like page specific news items.

    public string PageName{
    get{
    List path = Apexpages.currentPage().getUrl().split(‘/’);
    return path[path.size()-1];
    }
    }

    Reply
  3. I have been doing some testing around the same issues recently, here are my finding…
    BTW some of the technique I used were gained here so I feel kind of obligated.

    Hope this helps…

    -Tom

    1. keep it all on one form. (make use of where needed)
    otherwise you end up with multiple view states. (the only way I could pass data between multiple viewstates and keep them consistent on callbacks was to use currentpage.get/setparameter())

    Example TEMPLATE:

    2. On your inner page, extend from a Base class to store you global variables, you can also extend the templates controller and/or the components with this base class, but not sure if its necessary since it will have already been constructed by the inner page, and you should (not tested) be able to access via MyBase.staticCalltoGetlang()

    public virtual class MyBase {
    static boolean initialized=false;
    static string s_isoLang;

    public string isoLang {
    GET {return s_isoLang;}
    SET {if (value!=null) s_isoLang=value;
    }
    }

    public static string staticCalltoGetlang() {
    return s_isoLang;
    }

    public PageBase() {
    if (!initialized) {
    s_isoLang = System.currentPageReference().getParameters().get(‘l’);
    if (s_isoLang==null) s_isoLang=’en’;
    }
    }

    }

    Reply
  4. I have been doing some testing around the same issues recently, here are my finding…
    BTW some of the technique I used were gained here so I feel kind of obligated.

    Hope this helps…

    -Tom

    1. keep it all on one form. (make use of where needed)
    otherwise you end up with multiple view states. (the only way I could pass data between multiple viewstates and keep them consistent on callbacks was to use currentpage.get/setparameter())

    Example TEMPLATE:

    2. On your inner page, extend from a Base class to store you global variables, you can also extend the templates controller and/or the components with this base class, but not sure if its necessary since it will have already been constructed by the inner page, and you should (not tested) be able to access via MyBase.staticCalltoGetlang()

    public virtual class MyBase {
    static boolean initialized=false;
    static string s_isoLang;

    public string isoLang {
    GET {return s_isoLang;}
    SET {if (value!=null) s_isoLang=value;
    }
    }

    public static string staticCalltoGetlang() {
    return s_isoLang;
    }

    public PageBase() {
    if (!initialized) {
    s_isoLang = System.currentPageReference().getParameters().get(‘l’);
    if (s_isoLang==null) s_isoLang=’en’;
    }
    }

    }

    Reply
  5. I like what your getting at Wes, being a semi-pro web developer I’m definitely interested in making this sort of construction more practical in use (talking about best practices etc.)

    I will watch your blog for any updates!

    Jordan

    Reply
  6. I like what your getting at Wes, being a semi-pro web developer I’m definitely interested in making this sort of construction more practical in use (talking about best practices etc.)

    I will watch your blog for any updates!

    Jordan

    Reply
  7. Looks like this does not work anymore, the template controller (& its variables) is a separate instance, is there any other way to communicate between template & inner page?

    Reply
  8. Looks like this does not work anymore, the template controller (& its variables) is a separate instance, is there any other way to communicate between template & inner page?

    Reply

Leave a Comment