3

In our app, we used a shortcut of referring to an object's detail page by appending its Id field to a leading slash (/). It seemed like the right thing to do at the time, since the Apex code new ApexPages.StandardController( someObject).view() was generating the same URL.

There are even answers to some questions on this site (1, 2) recommending the same technique.

Unfortunately, when you view those pages as part of the new Salesforce Communities feature, the links don't work. They break out of the /CommunityName/ prefix in all URLs for your Community.

I've found a workaround (see answer below), but I'm wondering if there are any better methods for fixing this problem.

  • Why do you need an entire page for this? Would it be too difficult to just use an extension? Or a helper class that generates the same URL logic for you? Are you aware of {!URLFOR($Action.Object.View, recordId, null)}? – sfdcfox Aug 31 '13 at 1:47
  • @sfdcfox, the URLFOR($Action... technique will work in instances where the object type is known and the record ID is known when the page is rendered. It won't work when building URLs in Javascript (after loading records via Ajax) or when a variable contains an Id that could be for one of multiple object types. I will try it out in the instances where it applies, as it's a cleaner solution. – tomlogic Aug 31 '13 at 2:15
  • For the JavaScript case, maybe you could use Visualforce remoting? I haven't tried it with communities, but I would imagine that the function would still work. I'm just trying to think of ways to avoid the extra redirect. – sfdcfox Aug 31 '13 at 2:40
  • I'm glad you posted this. We're about ready to begin our test phase and have been using ID's for everything too! This info will be good to have in case we need it. I've been writing countless triggers to create URL links between custom mirrored objects using ID's which is working at the moment, but will be really PO'd if they're no good a few weeks from now!!! – crmprogdev Aug 31 '13 at 15:11
  • We might need to change our JSON to send the URL instead of the Id of the record. It just seems so wasteful to repeat so much data (the URL prefix) for each record. An option would be to pass the base URLs for each object type, and link them up in the Javascript. – tomlogic Aug 31 '13 at 16:19
7

The solution I came up with was to use a dedicated Visualforce Page and Controller to look up the detail page for the given Id, and then redirect to it. I felt this was a better solution than hard-coding the detail page, since we should respect the object's settings. In my pages and components, I use {!$Page.Detail}?id={!foo.Id} as the URL.

Detail.page:

<apex:page controller="DetailLookupController" action="{!lookupDetail}" title="Detail Page">
    <apex:form >
        <apex:pageBlock >
            <apex:pageMessage summary="An error occurred while attempting to locate the selected report.  If this problem persists please contact your system administrator." severity="error" strength="3" />
            <apex:pageMessages />
        </apex:pageBlock>
    </apex:form>
</apex:page>

DetailLookupController.cls:

public with sharing class DetailLookupController {
    public PageReference lookupDetail() {
        // try to find the object referenced
        try {
            Id obj = (Id) ApexPages.currentPage().getParameters().get('id');

            return new ApexPages.StandardController(
                    obj.getSObjectType().newSObject( obj)).view();
        }
        catch (Exception e) { /* ignore exceptions */ }

        return null;
    }
}

This results in a slight delay for the redirect, but works reliably for both standard and custom objects. It even works when dynamically building links in Javascript:

'<a href="{!$Page.Detail}?id=' + aData.Id + '">' + aData.Name +'</a>'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.