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):
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:
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 😉
cool. let me know if you figure out how to use persistent variables in components 🙂
Will do. What do you mean by persistence? Any examples you have would be cool.
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];
}
}
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];
}
}
Thanks for this idea. If you have some examples for this work, please post that too.
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’;
}
}
}
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’;
}
}
}
Interesting article Wes. Was wondering where I can buy a “belt of awesomeness”? Are they only sold in the UK? Wonder if they have one that would match my “shoes of funkiness”?
This belt was made in Africa 🙂 I think the US equivalent is a stetson o’swellness yeehaa!
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
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
Hey Does this still work?
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?
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?