Amitay
Amitay

Reputation: 478

Ractive partial external file

I have a pretty complicated web page i am trying to build with Ractive,
It contains many partial templates.
I am trying to load a partial from a separate file just to keep my code clean.

Example:

<script id='content' type='text/ractive'>
 Hello!
</script>

http://jsfiddle.net/efrsmqhd/

How can i put 'content' into a separate file?

Upvotes: 1

Views: 1598

Answers (2)

Rich Harris
Rich Harris

Reputation: 29605

When Ractive tries to find a partial - let's say {{>foo}} - it first looks for ractive.partials.foo. Then it looks for ractive.partials[valueOfFoo] - so if ractive.get('foo') === 'bar', it will look for ractive.partials.bar.

Only when those have failed will it look for <script id='foo'>. So you can pass in your partials explicitly, like so:

var ractive = new Ractive({
  el: 'main',
  template: '{{>foo}}',
  partials: {
    foo: '<p>this is a <strong>foo</strong> partial</p>'
  }
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<main></main>

The prototype of ractive.partials is Ractive.partials, so if you have several Ractive instances on the page, they can share partials like so:

Ractive.partials.foo = '<p>this is a <strong>foo</strong> partial</p>';

var ractive = new Ractive({
  el: 'main',
  template: '{{>foo}}'
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<main></main>

So keeping your partials in separate files is as straightforward as loading them via AJAX and passing them in when you call new Ractive(). Of course, if you have lots of separate files, that becomes trickier, because you have to load them all before you can call new Ractive(). There are a number of ways to coordinate all that asynchronous activity, but the easiest way is to use Promises - here's an example that uses the window.fetch polyfill:

var ractive, partials = {}, promises;

promises = [ 'foo', 'bar', 'baz' ].map( function ( name ) {
  return fetch( 'templates/' + name + '.html' ).then( function ( response ) {
    return response.text().then(function(text) {
      partials[ name ] = text;
    });
  });
});

Promise.all( promises ).then( function () {
  ractive = new Ractive({
    el: 'body',
    template: '#template',
    partials: partials
  });
});

Upvotes: 8

Rob
Rob

Reputation: 1636

Thanks Rich - this is exactly what I've been looking for. Not seen fetch before. However, I wasn't receiving the fetched html body. Instead, I received some weird looking nested object* containing the html on a key called [[PromisesValue]]. So I refactored things slightly.

This returns the response.text, and then puts it onto partials. I now have all my templates (about 30 so far) in separate files :D

 promises = [  'foo' , 'bar' ,'baz' ].map( function ( name ) {
      return fetch( 'templates/' + name + '.html' ).then( function ( response ) {
         return response.text()
      }).then(function(body) {
        partials[name] = body;
      });
    });


    Promise.all( promises ).then( function () { ...

*it looked weird in Chromes debugger. My next job is to grok ractive components :)

Upvotes: 0

Related Questions