Question

I use angular-translate and showdown.js in my app (showdown is a port of markdown). I would like to run the output of a translated string through markdown. Do you have any suggestions of how to achieve that?

Let's say I have the string

This is a [link](www.google.com).

Running it through markdown would give

This is a link.

My goal is to have strings like this in my translation files, and run the translated text though markdown. I use a angular-markdown directive which is used like this:

<markdown>This is a [link](www.google.com).</markdown>

But combining markdown and angular-translate like this

<p><markdown>{{ 'MARKDOWNTEST' | translate }}</markdown></p>

outputs

<p>{{ 'MARKDOWNTEST' | translate }}</p>
Was it helpful?

Solution

I made a directive as Alp suggested. In case someone else comes across this problem, here is my solution:

First the markdown directive:

.directive('markdown', ['$sanitize',function ($sanitize) {
    var converter = new Showdown.converter();
    return {
        restrict: 'AE',
        link: function (scope, element, attrs) {
            if (attrs.markdown) {
                scope.$watch(attrs.markdown, function (newVal) {
                    var html = newVal ? $sanitize(converter.makeHtml(newVal)) : '';
                    element.html(html);
                });
            } else {
                var html = $sanitize(converter.makeHtml(element.text()));
                element.html(html);
            }
        }
    };
}])

And the transdown directive which translates the key and then uses the markdown directive on the output.

.directive('transdown', ['$translate', function ($translate) {
    'use strict';
    return {
        restrict: 'AE',
        replace: true,
        scope: {
            key: '@'
        },
        template: "<span markdown='translation'></span>",
        link: function(scope, element, attrs){
            scope.$watch('key', function(n,o){
                if( n !== undefined ){
                    $translate(n).then(function(res){
                        scope.translation = res;
                    });
                }
            });
        }
    };
}]);

OTHER TIPS

You could create a translate directive:

<translate key="MARKDOWNTEST" />

And in the directive you programmatically call the translate function of the i18n service and set the element's contents.

Using the same exact libraries, this works for me :

<div btf-markdown="'MARKDOWNTEST' | translate"></div>

No need for 2 directives, nor to rewrite the original.

Aside : If you need to use regular html tags inside your strings, you'll have to skip $sanitize.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top