How to handle strings containing HTML using Angular-Translate?

JavascriptAngularjs

Javascript Problem Overview


Is there a way to tell angular and angular-translate to handle strings which contains HTML content.

I have add_card-title = "To make ordering even quicker, <span class="nowrap">add a card now</span>" as my Lang string. When i use it in my template by writing <p>{{'add_card-title' | translate}}</p> I get string as it is.

Output: To make ordering even quicker, <span class="nowrap">add a card now</span> expected output: To make ordering even quicker, add a card now

I know i can use ng-html-bind-unsafe but it is not helping.

Not working:

<p ng-html-bind-unsafe="{{'add_card-title' | translate}}"></p>

Is there any way to achieve it?

Here is my plunker: http://plnkr.co/edit/nTmMFm9B94BmbTgo2h8H?p=preview

For reference you can see this issue: https://github.com/PascalPrecht/angular-translate/issues/173

note: i do not want to invlove controller to handle it.

Javascript Solutions


Solution 1 - Javascript

You can do this out of box with angular-translate 2.0 these days.

<p translate="{{ 'PASSED_AS_INTERPOLATION' }}"></p> 

works wonders for me.

Solution 2 - Javascript

You have to use the ng-bind-html directive without curly braces ({{ }})

To know the configuration needed in order to use that directive (ngBindHtml), follow this link: https://docs.angularjs.org/api/ng/directive/ngBindHtml

After ngSanitize is included, the following code should work:

<p ng-bind-html="'add_card-title' | translate"></p>

Solution 3 - Javascript

This works for me... the HTML is interpreted for nice styling (e.g. bold, italics, etc.)

<p translate="translationId"></p>

However, I also needed to ensure that I wasn't using escape strategy in the provider setup. That messed me up for a while.

  • Works: $translateProvider.useSanitizeValueStrategy( 'sanitize' );
  • Nope: $translateProvider.useSanitizeValueStrategy( 'escape' );

https://angular-translate.github.io/docs/#/guide/19_security

Using: angular-translate v2.13.1

Solution 4 - Javascript

You can use <p [innerHTML]="'add_card-title' | translate"></p>

Solution 5 - Javascript

I have found the solution. I was using AngularJS v1.2.0-rc.3 which has got ng-html-bind-unsafe deprecated. Now angular has ng-bind-html instead of ng-html-bind-unsafe. But one has to inject angular-sanitize as a dependency to get it working.

I replaced

<p ng-html-bind-unsafe="{{'add_card-title' | translate}}"></p>

with

<p ng-bind-html="'{{'add_card-title' | translate}}'"></p>

and things started working.

Solution 6 - Javascript

By default AngularJS escape and code it displays for safety reasons, you need to tell angular of the strings you don't want to escape, in older times before AngularJS 1.2 developers could do that by using ng-bind-html-unsafe but in AngularJS 1.2 that has been deprecated.

To use html tags in strings, in AngularJS 1.2+, you need to download angular-sanitize module and include it in your application dependencies.

Any string contains html code you can display it by using ng-bind-html Automatically uses $sanitize, in your case it will be ng-bind-html="'add_card-title' | translate"

For reference:

On Medium

AngularJS Documentation

Solution 7 - Javascript

Here are many ways to mix up html (along with scope variables, along with interpretion if you need things like ng-click in your html translations):

http://plnkr.co/edit/OnR9oA?p=preview

<div>{{'TESTING1_SIMPLE_VAR_REPLACE' | translate: '{name: "John Smith", username: "john.smith12"}'}}</div>
<div translate='TESTING1_SIMPLE_VAR_REPLACE' translate-values='{ name: "Jake Smith", username: "jake-smith-101"  }'></div> 
<div translate="TESTING1_SIMPLE_VAR_REPLACE_NA" translate-value-name="{{name}}" translate-value-username="{{username}}" translate-default="Hello {{name}} ({{username}})"></div>

<br/><br/>
<div>{{'TESTING1_SIMPLEHTML' | translate}}</div><!-- doesn't compile the html -->
<div translate="TESTING1_SIMPLEHTML" translate-default='DEFAULT(not used since there is a translation): This <b>translation</b> has a <a href="http://google.com" target="_blank">link</a>.'></div><!-- this and below compile the html -->
<div translate="TESTING1_SIMPLEHTML_NA" translate-default="DEFAULT(used since translation not available): This <b>translation</b> has a <a href='http://google.com' target='_blank'>link</a>."></div>
Uses ng-bind-html and sanitize: <div ng-bind-html="'TESTING1_SIMPLEHTML' | translate"></div>


<br/><br/>
<div translate="TESTING2_SCOPE" translate-values="{timer: timer}" translate-default="DEFAULT(not used since there is a translation): Seconds: <a href='http://google.com' target='_blank'>{{timer}} seconds</a>."></div>
<div translate="TESTING2_SCOPE" translate-value-timer="{{timer}}"></div>
<div translate="TESTING2_SCOPE_NA" translate-default="DEFAULT(used since translation not available): Seconds: <a href='http://google.com' target='_blank'>{{timer}} seconds</a>."></div>

<br/><br/>
<div compile-unsafe="'TESTING3_COMPILE' | translate"></div><!-- old way to do before angular 2.0-->
<div translate="TESTING3_COMPILE" translate-compile></div>
<div translate="{{'TESTING3_COMPILE_SCOPE'}}" translate-compile translate-value-name="{{name}}" translate-value-username="{{username}}" ></div> <!-- not sure of advantage of this style, but saw an example of it -->
<div translate="TESTING3_COMPILE_SCOPE"       translate-compile translate-value-name="{{name}}" translate-value-username="{{username}}" ></div> 
<div translate="TESTING3_COMPILE_SCOPE"       translate-compile translate-values='{ name: "Jake Smith", username: "jake-smith-101"  }' ></div>

Solution 8 - Javascript

"lng_pageFooter" : "Copyright © • 2018 • My Company • Powered by <a href=\"http://www.mycompany.com\">My Company™</a>"
...
$translateProvider.useSanitizeValueStrategy('escape');
....
app.filter('trusted', ['$sce', function($sce) {
    var div = document.createElement('div');
    return function(text) {
        div.innerHTML = text;
        return $sce.trustAsHtml(div.textContent);
    };
}])
....
<span ng-bind-html="'lng_pageFooter' | translate | trusted"></span>

Solution 9 - Javascript

I tried both your answers and none of them worked on 1.0.7 so for everyone that's working pre 1.2 you can do it like this

<p ng-html-bind-unsafe="'add_card_title' | translate"></p>

Solution 10 - Javascript

Simply use innerHtml. Eg <p [innerHtml]="'lorem.ipsum' | translate"></p>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwaqasView Question on Stackoverflow
Solution 1 - JavascriptJamesView Answer on Stackoverflow
Solution 2 - JavascriptA.InfanteView Answer on Stackoverflow
Solution 3 - JavascriptMichael RView Answer on Stackoverflow
Solution 4 - JavascriptCamilo SotoView Answer on Stackoverflow
Solution 5 - JavascriptwaqasView Answer on Stackoverflow
Solution 6 - JavascriptYa BashaView Answer on Stackoverflow
Solution 7 - Javascriptarmyofda12mnkeysView Answer on Stackoverflow
Solution 8 - JavascriptLeoView Answer on Stackoverflow
Solution 9 - JavascriptJ.PipView Answer on Stackoverflow
Solution 10 - Javascriptuser8462556View Answer on Stackoverflow