4

in Ruby on Rails, we have a before_filter we can put on the base controller and it will be called before any controller and/or page is invoked. This filter has the ability to redirect.

In visual force we have to wire pages to controllers, some pages don't have controllers.

If we wanted to have a check be called before any page or controller is called, with the ability to redirect, is this possible? If not possible, has anyone built a framework to make this work?

We were thinking of using the page action to call some common controller function, but this wouldn't work well if there was already an action for that page.

Some common uses for this are authorization, forcing password resets, agreements to be acknowledged, etc.

1
  • It looks like you need to implement a dispatcher Page using the action attribute, a Custom controller implementing the action, defined and then depending on your use case, redirect to the respective page. In this case you would need to customize all links/actions to use your Dispatcher Page, allowing you to also define parameters like the page to redirect to. However you need to be careful to not end up with loops i.e. redirecting to the dispatcher over and over again.
    – ManSpan
    Nov 11, 2013 at 17:06

2 Answers 2

1

Something like this ought to do the trick if you have access to the Apex Pages, otherwise there is no way to accomplish this on Salesforce. Start with a base class for your controllers.

public virtual with sharing class BaseController {

    public PageReference load()
    {
        PageReference redirect = null;
        // Perform generic page load logic?
        Agreement__c agreement = Agreement__c.getInstance();
        if(agreement.Agree__c == false)
        {
            // Create URL to agreement page and pass the page to return to
            redirect = Page.agreement;
            redirect.getParameters().put('retUrl', ApexPages.currentPage().getUrl());
            return redirect;
        }
        // Allow the page controller to perform any of its own logic
        return onLoad();
    }

    /**
     * Classes override this to implement their own page load logic
     **/
    public virtual PageReference onLoad() 
    {
        return null;
    }
}

You can then either use this controller base class as a base class for existing controllers, note the means to have them still provide their own on load logic if needed. Otherwise you can simply reference the base class itself on the page. The additional requirement regardless is for the page developer to include the action attribute.

A page that does not have its own controller load logic...

<apex:page standardController="Test__c" extensions="MyPageController" action="{!load}">
    <apex:pageMessages />
</apex:page>

public with sharing class MyPageController extends BaseController {

    public MyPageController(ApexPages.StandardController stdControlelr)
    {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, 'Page with controller witn no custom load logic.'));                
    }
}

A page and controller that has its own on load logic...

<apex:page standardController="Test__c" extensions="MyPageCustomLoadController" action="{!load}">
    <apex:pageMessages />
</apex:page>

public with sharing class MyPageCustomLoadController extends BaseController {

    public MyPageCustomLoadController(ApexPages.StandardController stdControlelr)
    {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, 'Page with controller and custom load logic.'));        
    }

    public override PageReference onLoad()
    {
        // Do something interesting here!
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, 'Custom page load called.'));
        return null;
    }
}

Finally a page that does not have its own controller and simply uses the base one....

<apex:page controller="BaseController" action="{!load}">
    <apex:pageMessage title="Page with no controller" severity="Info"/>
</apex:page>

You can also use the above without the standardController attribute and use the base class with custom controllers.

Hope this helps a little!

2
  • ok, so if my page had an action already called foo, then I would just add the onLoad method to that controller and call foo?
    – Joelio
    Nov 15, 2013 at 13:18
  • Yes, the wiring is the same on the page regardless. If a page already has its own load logic you just need to refactor it a little to place it in the onLoad method. Nov 15, 2013 at 13:21
1

I don't know if this is exactly what you are looking for but in the past I had a scenario where we wanted certain users to have the Standard view ofr a custom object, and some to have a VF page. I coded the action into the VF page (not always a best practice, but worked well for this scenario)

So in my Vf page, the page tag looked liked this

<apex:page standardController="MyCustomObject__c" extensions="MyExtension" 
        action="{!if($Profile.Name !='System Administrator' && $Profile.Name !='FP Management', 
        null, urlFor($Action.MyCustomObject__c.View, MyCustomObject__c.Id, null, true))}">

This checks for the current Users profile (but you could adjust the logic accordingly), and either loads the VF page with the extension listed (an action of Null just loads the Vf page as is), or it redirects to the standard page with the URLfor method.

You could adjust this to redirect in both cases, so you could have a separate VF page, instead of using the current page that has the action on it. This would allow you to have a separate action on the load of that page.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .