If you use the Salesforce Labs app for Public Knowledge Base then you’ve likely noticed the bulky URLs, something in the format of ‘/articles/Article-Type/Article-URL-Name’. This URL structure is great for SEO, but it’s not always necessary when sending a link directly to a colleague or customer. To make sharing articles easier, I created a Visualforce page and controller to provide a shorter link (ex: http://yourcompany.force.com/?
The first step is to create a controller which checks for an existing article that matches the number provided in a URL parameter. It contains a single method that performs a SOQL query to retrieve the article record and then builds the full URL using the information in the KnowledgeArticleVersion to return a page reference to the article.
public class ArticleRedirectController { public PageReference getPKBLink() { String currUrl = ApexPages.currentPage().getUrl(); // Build a page reference to the standard PKB home page with all parameters intact String params = ''; if (currUrl.indexOf('?') != -1) params = currUrl.substring(currUrl.indexOf('?')); PageReference home = new PageReference('/pkb_Home'+params); // Retrieve the article number parameter from the URL and return the standard home page if no article number is found String articleNum = ApexPages.currentPage().getParameters().get('kb'); if (articleNum == null || !articleNum.isNumeric()) return home; // Query for the article version with the matching article number String query = 'SELECT Id,UrlName,ArticleNumber FROM KnowledgeArticleVersion '+ 'WHERE Language = \'en_US\' '+ 'AND IsLatestVersion = true AND '+ 'ArticleNumber LIKE \'%'+articleNum+'\' '+ // Include % so article will be found with leading zeros removed 'AND IsVisibleInPkb = true '+ // Make sure the article is visible in the PKB 'AND PublishStatus = \'Online\' '+ // Make sure the article is published 'LIMIT 2'; // If more than one is matched we will return so limit to 2 // If more or less than one article is found, return the standard PKB home page list<KnowledgeArticleVersion> articles = Database.query(query); if (articles.size() != 1) return home; String urlName = articles[0].UrlName; Id kavId = articles[0].Id; // Build the full article url String articleLink = '/articles/'; // Find the article type by searching the global describe for the sobject with the matching prefix String prefix = ((String)kavId).substring(0,3); map<String,Schema.SObjectType> sObjectMap = Schema.getGlobalDescribe(); for(String sObj : sObjectMap.keySet()){ Schema.DescribeSObjectResult r = sObjectMap.get(sObj).getDescribe(); if(r.getName().contains('__kav') && r.getKeyPrefix().equals(prefix)){ articleLink += r.getName().replace('__kav',''); } } // Complete the full article url and return a page reference to it articleLink += '/' + urlName + '/?l=en_US&fs=Search&pn=1'; return new PageReference(articleLink); } }
Next, I created a Visualforce page which invokes the method in the controller and redirects to the proper page, whether it be the page for the article or the PKB home page. It’s simply a blank page that executes an action on load to perform the redirect as described.
<apex:page action="{!getPKBLink}" controller="ArticleRedirectController"> </apex:page>
To complete the configuration, navigate to the Force.com Site detail page, replace the Active Site Home Page with the new Visualforce page, and enable page access in the Public Access Settings. Now you can link directly to your Knowledge Base with much tidier links that include just the article number: http://yourcompany.force.com/?kb=1000.
Finally, consider adding a formula field to your knowledge article type(s) that outputs a URL to make sharing easier.