waqas
waqas

Reputation: 4505

How to handle strings containing HTML using Angular-Translate?

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.

Upvotes: 59

Views: 62224

Answers (10)

user8462556
user8462556

Reputation: 536

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

Upvotes: 0

Leo
Leo

Reputation: 21

"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>

Upvotes: 2

Camilo Soto
Camilo Soto

Reputation: 559

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

Upvotes: 11

Michael R
Michael R

Reputation: 1607

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

Upvotes: 17

armyofda12mnkeys
armyofda12mnkeys

Reputation: 3472

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>

Upvotes: 3

waqas
waqas

Reputation: 4505

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.

Upvotes: 7

Ya Basha
Ya Basha

Reputation: 1952

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

Upvotes: 2

James
James

Reputation: 1514

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

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

works wonders for me.

Upvotes: 61

A.Infante
A.Infante

Reputation: 433

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>

Upvotes: 22

J.Pip
J.Pip

Reputation: 4623

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>

Upvotes: 0

Related Questions