Real Dreams
Real Dreams

Reputation: 18038

How to use {{{}}} syntax for trusted html?

Handlebar's {{expression}} form HTML-escapes values returned while its {{{expression}}} form does not. Is there any way to add this feature to AngualarJS templates so that we can use {{expression}} for regular sanitized output and {{{expression}}} for trusted, non-escaped HTML expressions?

By the way, I am familiar with ng-bind-html directive.

Upvotes: 5

Views: 1728

Answers (3)

New Dev
New Dev

Reputation: 49620

This is really an unnecessary problem, and what follows, is an even more unnecessary solution :) But just for fun, you could do something like the following: parse the HTML and replace all found instances of {{{ and }}} with ng-bind-html. I reused the filter approach above to actually do $sce.trustAsHtml:

app.directive("trust", function($compile){
  return {
    terminal: true,
    priority: 4000,
    link: function(scope, elem){
      var html = elem.html();
      var re = /({{{)([^}]+)(}}})/g;
      var newHtml = html.replace(re, '<span ng-bind-html="$2 | trustAsHtml"></span>');
      elem.html(newHtml);
      elem.removeAttr("trust");
      $compile(elem)(scope);
    }
  };
})
.filter('trustAsHtml', function($sce) { return $sce.trustAsHtml; });

Usage is:

<div trust>
  {{{html()}}}
  <div>
    {{{foo}}}
  </div>
</div>

plunker

Upvotes: 0

Jean-Baptiste Louazel
Jean-Baptiste Louazel

Reputation: 525

If you really want to use {{{}}}, it is possible:

var myApp = angular.module('myApp', [], function($interpolateProvider) {
    $interpolateProvider.startSymbol('{{{');
    $interpolateProvider.endSymbol('}}}');
});

However it is not possible to do that only for trusted html. All of your delimiters will change.

Upvotes: -1

Michael Oryl
Michael Oryl

Reputation: 21662

Answer: The short answer is no. I've never come across such a configuration. You can't get {{{}}} to work in Angular.

Helpful workaround: It is not possible to get unescaped/unsanitized HTML into a view through the scope without using the ng-bind-html directive. You could add either a helper function to your controller or add a filter that might make it a little easier to use ng-bind-html (Plunk here), but you still seem to need ng-bind-html:

var app = angular.module('plunker', ['ngSanitize']);

app.controller('MyController', function($scope, $sce) {
  $scope.someHtmlContent = "Label: <input name='test'>";

  $scope.h = function(html) {
    return $sce.trustAsHtml(html);
  };
}); 

app.filter('trustAsHtml', function($sce) { return $sce.trustAsHtml; });

Then you would use it like this:

<body ng-controller="MyController">
  <div ng-bind-html="someHtmlContent | trustAsHtml"> 
  </div>

  <div ng-bind-html="h(someHtmlContent)"> 
  </div>
</body>

Upvotes: 4

Related Questions