I have a Visualforce Page running on a Force.com Site that looks like this:

<apex:page standardController="Page__c" extensions="RootTemplateExtension">
    {!URLFOR($Page.Master, null, ["id"="a00b000000IovF1"])}

And I've got a Site.UrlRewriter implementation that looks like this:

global List<PageReference> generateUrlFor(List<PageReference> salesforceRefs) {
    //TODO bulkify this

    List<PageReference> friendlyRefs = new List<PageReference>();
    for (PageReference salesforceRef : salesforceRefs) {
        String salesforceUrl = salesforceRef.getUrl();
        Map<String,String> salesforceParams = salesforceUrl.getParameters();

        //note URLFOR does not output '/apex' prefix in context of Force.com Sites
        String master = Page.Master.getUrl().replace('/apex', '');

        if (salesforceUrl.startsWith(master) && salesforceParams.containsKey('id')) {
            Id pageId = salesforceUrl.getParameters().get('id');
            Page__c page = [SELECT Id, Name FROM Page__c WHERE Id = :pageId];

            PageReference friendlyRef = new PageReference('/' + page.Name);

    return friendlyRefs;

I've even got a TEST that shows this should work

static testmethod void testGenerateUrlForSummary() {
    //arrange rewriter and page
    Site.UrlRewriter rewriter = new UrlRewriter();
    Page__c page = new Page__c(Name = 'Summary');
    insert page;

    //arrange url ('/ns__Master?id=a01000000000AAA')
    String url = System.Page.Master.getUrl().replace('/apex', ''); //drop prefix
    PageReference salesforceRef = new PageReference(url);
    salesforceRef.getParameters().put('id', page.Id);

    PageReference friendlyRef = rewriter.generateUrlFor(new List<PageReference>{salesforceRef})[0];

    String expectedUrl = '/Summary';
    String actualUrl = friendlyRef.getUrl();
    System.assertEquals(expectedUrl, actualUrl, 'Summary url not generated.');

But for the life of me I can't see it happen in the actual Force.com Site. I've carpet bombed the code with System.debug but all I can eyeball is that startsWith is not true as expected.

Any ideas?

  • 1
    just a suggestion did you try startsWithIgnoreCase? could be a case sensitivity issue?
    – Rao
    Oct 27 '14 at 17:41
  • Thanks @rao! You are correct, Apex PageReference is generated with lowercase m first letter Oct 27 '14 at 22:22

On a Force.com Site, the implementation of URLFOR() and Page.Master.getUrl() differ:

URLFOR() returns an all-lowercase string without /apex prefix.

PageReference.getUrl returns a first-letter-capitalized string with /apex prefix.

public class UrlForController {
    public String getApexUrl() {
        return Page.MaStEr.getUrl();

<apex:page controller="UrlForController">
        //all lowercase "/master"

        //capitalizes first letter only "/apex/Master"

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.