GithubHelp home page GithubHelp logo

Comments (11)

cjroebuck avatar cjroebuck commented on May 3, 2024

I agree. I also think template could be a function if someone is using precompiled templates, such as what templatify provides.

from backbone.marionette.

mxriverlynn avatar mxriverlynn commented on May 3, 2024

I'm open to ideas for this... the current implementation met my needs at the time. I'm not quite sure what it would take to make this work with the scenarios you're both describing, because that's not how I do things. But I would love to see some code samples / pull requests and get this working for all of these ideas. :)

from backbone.marionette.

redsquare avatar redsquare commented on May 3, 2024

Just a few quick thoughts. Would a templateType make sense? It could accept the following 'external', 'jq object', 'selector' or 'text'. If no type is specified marionette can take a best guess (much like jquery does with ajax responses when you dont specify a type). At the moment I am trying to handle the various types myself in custom methods however I am sure most users will encounter this so it makes sense for marionette to take the pain. Not sure how we would go about caching, its easy with a url or id selector but with raw text it could get a little ugly.

from backbone.marionette.

baalexander avatar baalexander commented on May 3, 2024

I agree with @redsquare that the big issue is handling '#someId' and '<div><p>Hello</p></div>' correctly (selector vs HTML).

I was originally thinking a rule like "use selector if starts with a . or #, otherwise HTML". But there's plenty of exceptions and I'm sure that would break compatibility for people. Specifying a template type property may work.

from backbone.marionette.

mxriverlynn avatar mxriverlynn commented on May 3, 2024

hi all,

v0.6.2 was pushed up to the master branch as a release a few hours ago, and it contains a few small fixes to help out with this.

The biggest change for templates is that the TemplateCache.get method now passes a raw string back to you instead of a jquery object. This doesn't 100% solve the problem of doing something like using RequireJS to load external templates, though because it still tries to run the contents of the template attribute on the view, through the TemplateCache.get method. To fix this, you have to replace the getTemplate method on the view.

it's a bit stupid, but it's easy:

Backbone.Marionette.ItemView.prototype.getTemplate = function(){
  return this.template;
}

Put that code in your app once before any of your views render, and the view's template attribute will be returned as a raw string.

Of course, you'll still need to override the renderTemplate method on the view, too:

Backbone.Marionette.ItemView.prototype.renderTemplate(template, data){
  // compile your template, render it with the data, and return the raw HTML that was rendered
}

I know it's not the ideal solution at this point, but it's at least a good start in the right direction I think. I'd love to hear ideas on how we can continue to make this better and make it easier.

Thanks for all the discussion and support on this, so far, as well. :)

from backbone.marionette.

powmedia avatar powmedia commented on May 3, 2024

+1 on this issue, I'm using RequireJS and the text plugin to load templates so need to be able to pass strings. I think @redsquare 's template type solution could be a good approach as it keeps it extensible too.

from backbone.marionette.

mxriverlynn avatar mxriverlynn commented on May 3, 2024

Hi again,

I've been working on some new functionality that, as a side effect, may have solved this problem. Specifically, I've extracted a Marionette.Renderer object out of all the views and created a single place to call to render your views. The Renderer is now responsible for calling the TemplateCache as well, which means if you are using a pre-compiled / pre-loaded template that doesn't need the additional cache layer, you should be able to replace a single method to work the way you want, like this:

Backbone.Marionette.Renderer.render = function(template, data){
  return _.template(template, data);
};

This will completely override how the rendering for all of the view types is handled, and assumes that you are configuring a template on each of your views or passing it in as a constructor option.

The code is up in the dev branch right now. If anyone paying attention to this issue could take a few minutes and see if this is going to solve the problem, I would appreciate it.

from backbone.marionette.

baalexander avatar baalexander commented on May 3, 2024

First, thanks for your responsiveness on this project @derickbailey!

I looked over the dev code, but I'm not sure about the role renderer will play in the future. Are you planning for it to be used by ItemView only?

Also, overriding Renderer.render() to return _.template() could cause issues with ItemView.render() expecting a promise. Though this could be wrapped in a deferred object of course.

Finally, here's what we've been using to use the template as is:

Backbone.Marionette.TemplateCache.loadTemplate = function(template, callback) {
  callback.call(this, template);
}

from backbone.marionette.

mxriverlynn avatar mxriverlynn commented on May 3, 2024

I looked over the dev code, but I'm not sure about the role renderer will play in the future. Are you planning for it to be used by ItemView only?

It's being used in both the ItemView and CompositeView already. I pulled it out of the ItemView specifically because I needed it in the CompositeView and didn't want to duplicate things. That it might also help solve this problem is only a happy side effect, not the original intention.

Also, overriding Renderer.render() to return _.template() could cause issues with ItemView.render() expecting a promise.

ah! you're right. thanks for catching that! I've updated the dev branch to correct this. The ItemView.render method creates it's own promise, and I'm using the $.when/then on the result of the call to Renderer.render, so that it can be synchronous or async as needed.

Finally, here's what we've been using to use the template as is

My hope is that the new version will prevent you from having to do this. You shouldn't be forced in to using the TemplateCache and overriding it like this. With the change to the use of Renderer.render, does it look like you'll be able to get away from this, and only have to override Renderer.render? If not, any additional feedback on how I can approach this would be appreciated.

from backbone.marionette.

tabouassaleh avatar tabouassaleh commented on May 3, 2024

Current, in my backbone/requirejs app, I write views as:

define(['jquery',  'underscore', 'backbone', 'text!templates/my-template.html'], function ($, _, Backbone, myTemplate) {
    var MyView = Backbone.View.extend({
        template: _.template(myTemplate);
        ....
        render: function() {
            ...
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        }
    });
    return MyView;
});

I'm willing to test the dev branch, but I need some guidance as to how to change my code to make the templates work with Marionette.

from backbone.marionette.

mxriverlynn avatar mxriverlynn commented on May 3, 2024

FYI, I've added the following to the readme to document the best approaches to this, using the new v0.7.0 release:

Pre-Loaded Templates With RequireJS

It's common for developers to use RequireJS to pre-load the entire
template that is needed. When the template is pre-loaded like this,
the use of a jQuery selector is not needed.

If you wish to replace the entire rendering process, based on the
assumption that you will always pre-load the entire template for
your view, it can be done by replacing the render method on the
Renderer object:

Backbone.Marionette.Renderer.render = function(template, data){
  return _.template(template, data);
};

This will skip the TemplateCache usage entirely, and all of the
other code that is usually run, and return the compiled template
immediately.

Caching Pre-Compiled Templates

There's a performance hit in replacing the entire render
function of the Renderer object as shown in the example
above. You should only have to compile a template once, and you should
be caching the pre-compiled template after that.

To accomplish this, avoid replacing the render function. Instead
use a combination of the renderTemplate function and the
TemplateCache.loadTemplate function.

Backbone.Marionette.TemplateCache.loadTemplate(template, callback){
  // pre-compile the template and store that in the cache.
  var compiledTemplate = _.template(template);
  callback.call(this, compiledTemplate);
};

Backbone.Marionette.Renderer.renderTemplate = function(template, data){
  // because `template` is the pre-compiled template object,
  // we only need to execute the template with the data
  return template(data);
}

from backbone.marionette.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.