0

Our public website has some links to downloadable PDFs. We'd like to use "pretty" URLs, but for some reason we're getting a 404 error when using the Site's UrlRewriter.

The resource itself is available at something like:

/resource/Website_ResourceName

When accessed at this URL, the resource downloads as expected.

In the UrlRewriter, I added a rule that checks for the pretty URL and then returns a PageReference to the actual address above:

global with sharing class Website_UrlRewriter implements Site.UrlRewriter {
    Map<String,String> FRIENDLY_URLS = new Map<String,String>{
        '/pretty_resource_name' => '/resource/Website_ResourceName'
    };

    global PageReference[] generateUrlFor(PageReference[] yourSalesforceUrls){ 
        return null;
    }

    global PageReference mapRequestUrl(PageReference friendlyRef) {
        System.debug('**** friendlyRef: ' + friendlyRef);

        // Get the url for our request 
        String url = friendlyRef.getUrl().toLowerCase();

        if ( FRIENDLY_URLS.containsKey(url) ){
            PageReference ref = new PageReference(FRIENDLY_URLS.get(url));
            System.debug('**** uglyRef: ' + ref);
            System.debug('**** content: ' + ref.getContent());
            return ref;
        }

        return null;
    }
}

When I try to access the resource via the pretty URL, I get the following log:

21:01:23.017 (17136662)|CODE_UNIT_STARTED|[EXTERNAL]|core.dns.filter.SiteUrlMapper
21:01:23.024 (24106109)|SYSTEM_MODE_ENTER|false
21:01:23.024 (24160299)|SYSTEM_MODE_EXIT|false
21:01:23.024 (24242464)|SYSTEM_MODE_ENTER|false
21:01:23.024 (24305533)|SYSTEM_MODE_EXIT|false
21:01:23.024 (24325227)|SYSTEM_MODE_ENTER|false
21:01:23.025 (25373838)|SYSTEM_MODE_EXIT|false
21:01:23.026 (26023423)|SYSTEM_MODE_ENTER|false
21:01:23.026 (26144566)|USER_DEBUG|[83]|DEBUG|**** friendlyRef: System.PageReference[/pretty_resource_name]
21:01:23.026 (26437293)|USER_DEBUG|[114]|DEBUG|**** uglyRef: System.PageReference[/resource/Website_ResourceName]
21:01:23.153 (153071380)|USER_DEBUG|[115]|DEBUG|**** content: Blob[306508]
21:01:23.153 (153111859)|SYSTEM_MODE_EXIT|false
21:01:23.153 (153199937)|CODE_UNIT_FINISHED|core.dns.filter.SiteUrlMapper
21:01:23.155 (155600516)|EXECUTION_FINISHED

Note that the pretty URL was correctly translated into the ugly URL, and that the getContent() call on the PageRefernce returned data (meaning it's pointing to something real). But on the page itself, I end up with a 404 error:

Page Not Found: pretty_resource_name 

Stay tuned. Please email us if you need to get in touch.

I can't find any documentation that says what I'm trying to do is not supported. I've verified that the static resource is using public cache control and is available when accessed via the "ugly" URL.

0

2 Answers 2

1

Site.UrlRewriter can only forward to a VisualForce page. So You can use a VisualForce to redirect again to the static resource pdf. Here is how you can do this. The GetResourceURL() method provides the path to the static resource. The action method PageReference redirect() is used to re-direct to static resource from vf page. Hope this helps.

Banzai_UrlRewriter.cls

global with sharing class Banzai_UrlRewriter implements Site.UrlRewriter {
    Map<String,String> FRIENDLY_URLS = new Map<String,String>{
        '/pretty_resource_name' => 'eclipse_cheatsheet' // eclipse_cheatsheet is a statis resource pdf name
    };

    global PageReference[] generateUrlFor(PageReference[] yourSalesforceUrls){ 
        return null;
    }

    global PageReference mapRequestUrl(PageReference friendlyRef) {
        System.debug('**** friendlyRef: ' + friendlyRef);
        Pagereference targetURL=null;
        // Get the url for our request 
        String url = friendlyRef.getUrl().toLowerCase();
        if ( FRIENDLY_URLS.containsKey(url) ){
            targetURL = new PageReference('/Banzai_UrlRewriter?url='+EncodingUtil.urlDecode(GetResourceURL(FRIENDLY_URLS.get(url)),'UTF-8'));
        }
        return targetURL;
    }
    public static String GetResourceURL(String resourceName){
        // Fetching the resource
        List<StaticResource> resourceList= [SELECT Name, NamespacePrefix, SystemModStamp FROM StaticResource WHERE Name = :resourceName];  
        // Checking if the result is returned or not
        if(resourceList.size() == 1){
            // Getting namespace
            String namespace = resourceList[0].NamespacePrefix;
            // Resource URL
            return '/resource/' + resourceList[0].SystemModStamp.getTime() + '/' + (namespace != null && namespace != '' ? namespace + '__' : '') + resourceName;
        }else{
            return '';
        }   
    }
    public PageReference redirect(){
        return new PageReference(ApexPages.currentPage().getParameters().get('url'));
    }    
}

Banzai_UrlRewriter.page

<apex:page controller="Banzai_UrlRewriter" action="{!redirect}"></apex:page>
2
  • I implemented something like this already, but the trouble is that the ugly url is now visible to the user.
    – JDB
    Commented Sep 25, 2015 at 13:04
  • Also, this approach requires far more code than is actually necessary. You can just pass a URL parameter to the visualforce page and then use merge syntax in the action attribute to redirect to the desired resource. See my answer.
    – JDB
    Commented Sep 25, 2015 at 14:48
0

This is the workaround I'm using. This is not what I was ultimately hoping to achieve. Ultimately, I'd like to be able to make the "real" resource URL completely invisible to the end user. This approach replaces the pretty URL with the ugly URL in the user's browser... but at least it gets the end user to the intended destination, so it's half a solution.

UrlRewriter:

global with sharing class Website_UrlRewriter implements Site.UrlRewriter {
    Map<String,String> FRIENDLY_URLS = new Map<String,String>{
        '/pretty_resource_name' => '/ResourceDownloader?name=Website_ResourceName',
    };

    global PageReference[] generateUrlFor(PageReference[] yourSalesforceUrls){ 
        return null;
    }

    global PageReference mapRequestUrl(PageReference friendlyRef) {
        String url = friendlyRef.getUrl().toLowerCase();

        if ( FRIENDLY_URLS.containsKey(url) ){
            PageReference ref = new PageReference(FRIENDLY_URLS.get(url));
            return ref;
        }

        return null;
    }
}

ResourceDownloader:

<apex:page action="{!$Resource[$CurrentPage.Parameters.Name]}"></apex:page>

You must log in to answer this question.

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