Namespace Prefix in JavaScript and Apex within Installed Package

There are ways to surface the namespace itself from within Apex (doesn't help us in JavaScript, yet).

  1. Deriving the namespace prefix itself:

    String rawPrefix = MyClass.class.getName().substringBefore('MyClass').substringBefore('.');
    //this gives '' in any development org
    //and gives 'ns' in the packaging org
    
  2. Getting a single token which can be used to qualify Apex Classes:

    String dotPrefix = MyClass.class.getName().substringBefore('MyClass');
    //this gives '' in any development org
    //and gives 'ns.' in the packaging org
    
  3. Getting a single token to qualify Salesforce Objects:

    String barPrefix = SObjectType.MyObject__c.Name.substringBefore('MyObject__c');
    //this gives '' in any development org
    //and gives 'ns__' in the packaging org
    

As long as there's a Class or SObject in the package, this gets a handle on the namespace prefix. But doesn't help for Custom Button code which only has formula context. I tried a similar approach:

var ns = "{!$ObjectType.MyObject__c.Name}";
// I had thought the above would give MyObject__c in any development org
// and would give ns__MyObject__c in the packaging org
// and SUBSTR() and LEFT() and ISBLANK() etc etc etc could be used to deal with the prefix

var result = sforce.apex.execute(
    ns + "WebServiceClass",
    "someWebServiceMethod",
    {"arg1": "foo", "arg2": "bar"}
);

However $ObjectType is unavailable in Formula context much like $Page and $Resource, grrr!

But Hierarchy Custom Settings are available in formula context. So in combination, one could use the Apex code above to derive the namespace prefix. Then use a Post Install Script to automatically populate an org-wide Custom Setting instance to make it accessible in formula context.

public void onInstall(InstallContext context) {
    //fetch custom setting or create it for the first time
    NamespaceSettings__c ns = NamespaceSettings__c.getOrgDefaults();
    if (setting == null) ns = new NamespaceSettings__c()

    //ns
    ns.RawPrefix__c = MyClass.class.getName().substringBefore('MyClass').substringBefore('.'),

    //ns.
    ns.DotPrefix__c = MyClass.class.getName().substringBefore('MyClass'),

    //ns__
    ns.BarPrefix__c = MyObject.Tax__c.Name.substringBefore('MyObject')

    //write the values away
    upsert ns;
}

Then the webservice invocation can look more like this:

var result = sforce.apex.execute(
    "{!$Setup.NamespaceSettings__c.DotPrefix__c}WebServiceClass",
    "someWebServiceMethod",
    {"arg1": "foo", "arg2": "bar"}
);

Which meets the requirements of: all code namespace agnostic, no precompile, and no manual steps after install. Having shared this would be grateful for any improvements or to hear lessons learned etc.


The most straightforward approach to finding an Org's Namespace Prefix in Apex / SOQL is to simply query the Organization object's NamespacePrefix field:

Organization org = [ 
   select NamespacePrefix from Organization limit 1
]; 

String ns = org.NamespacePrefix == null ? '' : org.NamespacePrefix: 

// returns your namespace in Packaging/Patch/Scratch DE Org with a namespace
// returns '' in all other orgs

If only $Organization.NamespacePrefix was a thing, that would eliminate the need for the Hierarchy Custom Setting approach for Formula Fields --- I've posted an Idea about this:

https://success.salesforce.com/ideaView?id=0873A0000003XISQA2