Benjamin Netter
Benjamin Netter

Reputation: 1551

Handlebars helpers as tags

Using a regular expression, I'm replacing **text in bold** to <strong>text in bold</strong> in a string, then displaying message using the {{{message}}} on my EmberJS templates. Problem is I also want to replace #anyhashtag with {{#link-to "hashtag" "anyhashtag"}} and it only works with {{message}}.

So my idea was creating a {{strong}}text in bold{{/strong}} helper which would also be more secure, but apparently helpers only works like {{strong "text in bold"}} which won't work if I have links in bold or more complex strings.

Can I do a helper that works like my idea?

Thanks!

Upvotes: 1

Views: 1794

Answers (1)

panta82
panta82

Reputation: 2721

It's a bit confusing question, but I think this is what you're asking for:

Ember.Handlebars.registerHelper("strong", function (options) {
  options.hash.layout = Ember.Handlebars.compile("<strong>{{yield}}</strong>");
  return Ember.Handlebars.helpers.view.call(this, Ember.View, options);
});

Working demo.


Actually, a better variant would be this:

Ember.Handlebars.registerHelper("strong", function (options) {
  options.hash.tagName = "strong";
  return Ember.Handlebars.helpers.view.call(this, Ember.View, options);
});

This avoids wrapping <strong> into a <div>. The first version would be useful if you needed a more complicated wrapper. Updated demo.


It seems you're trying to create a dynamic template from user-provided content. You can't do that by plugging a template string into a {{{}}} construct. 'Triple-mustache' is used for raw html output, it doesn't have a capability of processing additional template code inside it.

Unfortunately, you also can't compile it directly through property. Handlebars compiler is actually producing a function, that then needs to be called with a bunch of Ember-related context stuff in order to generate html.

The best way (that I know of) to get all this sorted out is, once again, through a view. Like this:

App.ApplicationController = Ember.Controller.extend({
  text: "text in bold",

  html: function() {
    return Ember.Handlebars.compile("{{#strong}}" + this.get('text') + "{{/strong}}");
  }.property("text")
});
<script type="text/x-handlebars">
  <div>Working: {{#strong}}text in bold{{/strong}}</div>
  <div>Working: {{view Ember.View template=html tagName="span"}}</div>
</script>

This will display the correct value, but won't update if you change it. To get live update, do this:

App.UpdatableView = Ember.View.extend({
  templateChanged: function () {
    this.rerender();
  }.observes("template")
});
<script type="text/x-handlebars">
  <div>Working: {{#strong}}text in bold{{/strong}}</div>
  <div>Working: {{view App.UpdatableView templateBinding=html tagName="span"}}</div>

  <!-- Type here to see changes -->
  {{input type="text" value=text}}
</script>

Updated live demo here.

UPDATE: Of course, now that I understand what you're trying to do, I realize you don't really need the first part of the answer, with {{strong}} helper.

Upvotes: 2

Related Questions