2

I am getting data from a custom field(Article__c) on a Knowledge Article which contains HTML data. When I serialize this data and return it to a VF page I am getting HTML characters that should be encoded as › or — that are simply outputting the characters - I need these to be encoded.

Sample Output

<strong>Settings</strong> › <strong>Account Settings</strong> › <strong>Users</strong>

Expected Output

<strong>Settings</strong> &rsaquo; <strong>Account Settings</strong> &rsaquo; <strong>Users</strong>

Apex

public with sharing class angularArticle {
  public String getArticleJSON() {
    list<Public__kav> articles = [SELECT Article__c,Id,Summary,Title,UrlName FROM Public__kav];
    String articleJSON = JSON.serialize(articles);
    return articleJSON;
  }
}

Visualforce

<apex:page controller="angularArticle" showheader="false" applyBodyTag="false" applyhtmlTag="false" standardStylesheets="false">
<html ng-app="app">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
  </head>
  <body>
    {{ article }}
  </body>
  <script type="text/javascript">
    var app = angular.module('app', []);
        app.run(function($rootScope) {
            $rootScope.article = {!articleJSON};
        });
  </script>
</html>
</apex:page>
  • It's not clear what you mean when you say that the page is "simply outputting the characters" - could you give a specific example of the expected and actual outputs? – Rob Oct 1 '15 at 16:05
  • @Rob added current/expected to the question – TheEks Oct 1 '15 at 16:15
3

JSON is a protocol that is used for a large variety of purposes, not just for injecting HTML into a page; it's primary purpose is for scripting. As such, it doesn't know about, nor care about, encoding HTML entities. In other words, you're going about this the wrong way. That method will lead only to pain and misery. Instead, you'll want to encode the articles after injection, or fix them up on the server beforehand. For example:

// Apex Code
for(Public__Kav record: articles) {
    record.Article__c = record.Article__c.escapeHTML4();
}

Or, you can escape them on the client-side afterwards:

// JavaScript
[].forEach.call($rootScope.article, function(element, index) {
    var div = document.createElement('div');
    div.textContent = element.Article__c;
    $rootScope.article[index].Article__c = div.innerHTML;
});

This script should work fairly well for escaping the values, as we basically trick the browser into doing it for us. Requires IE 9 or higher, and all other modern browsers.

0

If you simple want to encode your characters, you can use escapeHTML4() method of string class in Salesforce.

Example

String notEscaped = JSON.serialize(mydata);
String escaped = notEscaped.escapeHTML4();
return escaped;

I was having somewhat same problem few days ago when I was trying to return my data from controller to JS code in VF page. Escaping the entities didn't helped so I ended up converting data from controller in base64 format and in my JavaScript, I used

atob() and btoa() 

functions to decode the data.

I hope this helps you.

Salesforce string class documentation

P.S. The escapeHTML4 function replaces all HTML 4 entities including ampersand. If you want to replace only < and > , you may use String.replace function.

  • Unfortunately since I am returning JSON, not just a string, encoding/escaping with escapeHTML4() encodes the entire response, not just the data inside the JSON. In order to use this method I would have to set each field I am returning from the list as it's own string – TheEks Oct 1 '15 at 16:22
  • Then I believe using String.replace will be easier. – manjit5190 Oct 1 '15 at 16:29

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.