最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using handlebars or markdown to output a model property - Stack Overflow

programmeradmin4浏览0评论

I have a model which defines a property with either markdown or html content.

I am wondering whether using a markdown JS library to output the info or use handlebars to generate the html output inside the view.

Any remendations, examples will be appreciated.

I have a model which defines a property with either markdown or html content.

I am wondering whether using a markdown JS library to output the info or use handlebars to generate the html output inside the view.

Any remendations, examples will be appreciated.

Share Improve this question edited Mar 29, 2012 at 13:36 Adrien Schuler 2,4251 gold badge22 silver badges32 bronze badges asked Mar 28, 2012 at 18:14 ppcanoppcano 2,8611 gold badge26 silver badges19 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Using a Markdown converter worked for me.

Here is my view code:

App.ActivityDetailsView = Em.View.extend(
  templateName :        'activity-details',
  classNames :          ['details rounded shadow'],
  rawDescriptionBinding:   'App.activityDetailsController.description',

  description: (->
    converter = new Markdown.Converter().makeHtml
    return converter(@rawDescription)
  ).property('rawDescription')

)

Here is the template code (note the triple handlebars {{{}}} for raw html):

  <script type="text/x-handlebars" data-template-name="activity-details">
    {{{description}}}
  </script>

Here is a link to more details and the showdown.js script

Ember remends that you use your controller to decorate your model. Given this model, we want to render each of these blog posts using the appropriate rendering engine:

[
  { id: 1, isMD: false, md_or_html: "<p>This is HTML.</p>" },
  { id: 2, isMD: true, md_or_html: "*This is MD.*" }
]

You'll start by creating a route which returns that model:

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return [
          { id: 1, isMD: false, md_or_html: "<p>This is HTML.</p>" },
          { id: 2, isMD: true, md_or_html: "*This is MD.*" }
        ];
    }
});

Just having the model returned doesn't mean that things get rendered. You also need to make sure the template for the index route attempts to put something on the page:

<script type="text/x-handlebars" data-template-name="index">
  <ul>
    {{#each}}
      <li>{{output}}</li>
    {{/each}}
  </ul>
</script>

You'll note that we haven't yet created an output property, though we've included it in our template. We need to decorate our model to add the processed HTML or Markdown output:

App.IndexController = Ember.ArrayController.extend({
  itemController: 'post'
});

App.PostController = Ember.ObjectController.extend({
  output: function() {
    var result;

    if (this.get('isMD')) {
      var converter = new Markdown.Converter();
      result = converter.makeHtml(this.get('md_or_html'));
    } else {
      result = this.get('md_or_html');
    }

    /*
    IMPORTANT!!! Ember automatically escapes HTML upon insertion.
    To actually embed the result as HTML you will need tell Ember
    that the value is safe to embed as HTML.

    DO NOT RETURN SafeStrings UNLESS THE VALUE IS TRUSTED AND SANITIZED!
    */
    return new Handlebars.SafeString(result);
  }.property('isMD', 'md_or_html')
});

We can't just add the output property to PostController and have everything work without telling IndexController to use PostController for each item in the model. This is acplished by setting itemController on IndexController (think: "what controller to use for each item"). This allows us to decorate each blog post individually with the output property. We use a puted property to tell Ember that the value of output is dependent upon whether or not the post isMD and the body of the post. If either changes we want Ember to re-render the output.

The plete example includes additional ments and details about how to extend the pattern for introspection into the post body to determine if it is HTML or MD.

I encountered a similar case that I handled with a dynamically inserted handlebars template: I have a field containing a template which may have content bound to application values.

Ember.View.create({
    tagName: 'span',
    classNames: ['dynamic-content'],
    template: Ember.Handlebars.pile(App.preCompileTemplate(template)),
    context: someContextObject
});

The App.preCompileTemplate function replaces bindings with valid handlebars expressions, but you could also imagine using Markdown here:

App.preCompileTemplate = function(template) {
    return template.replace /{(.*?)}/g, '{{context.$1}}'
}

Using the context object scopes the values that you bind into the template.

发布评论

评论列表(0)

  1. 暂无评论