New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embedding ractive code in html pages #299
Comments
You can, but with a caveat. The <div id='myTemplate'>
{{#items}}
<div>{{name}}</div>
{{/items}}
</div> // These two are equivalent
ractive = new Ractive({
el: 'body',
template: document.getElementById( 'myTemplate' ).innerHTML
});
ractive = new Ractive({
el: 'body',
template: '#myTemplate'
}); Here comes the caveat: when you put template code inside an element, it has to be valid HTML. Certain things that are perfectly normal Mustache templates (e.g. a repeating section of rows inside a table) aren't valid HTML, and the browser will 'helpfully' try and 'correct' it before you get For that reason, it's recommended to put your templates inside a <script id='myTemplate' type='text/ractive'>
{{#items}}
<div>{{name}}</div>
{{/items}}
</script> Let me know if this answers the question |
You are mis-understanding my question. Do you follow? Here is the code again, all of which is in a SINGLE html file called widget.html :
|
A-ha! I understand perfectly. This is an excellent idea - I've been wondering about how best to package components up for distribution, and this is much better than anything I'd thought of so far. So the short answer is no, this isn't supported right now. But once the 0.3.8 release is out the door, this will be high up the priority list. I've spend the last couple of hours hacking around with this idea and it's coming together pretty nicely. For my future reference as much as anything, I'll describe the state I've got to. I've got a series of <link rel='ractive' href='widget.html'> ...containing this sort of thing: <div class='widget'>
<h2>This is an imported widget!</h2>
<p>Message: {{message}}</p>
</div>
<style>
.widget {
color: blue;
}
</style>
<script>
module.exports = function ( Ractive, template ) {
return Ractive.extend({
template: template,
init: function () {
// custom component logic...
},
data: {
message: 'This is the default message'
}
});
};
</script> Once they get fetched, the contents are parsed with Ractive's parser. Any top-level style and script tags are removed from the parsed template. The styles are added to the document (no scoping, unfortunately - if styles are included with a component they will have to rely on namespacing). The scripts are treated similarly, except that before executing the code (which is wrapped inside a IIFE to prevent global namespace pollution), we do factory = window.module.exports;
Component = factory( Ractive, parsedTemplate ); Then, the component is attached to There are a few things still to work out. In particular, doing things this way means that components are fetched asynchronously, so we need to figure out whether to delay execution of the application until all components are ready (or jimmy them into a previously rendered instance once they become ready, or whatever). There's also the question of optimising apps built this way to minimise network requests in production (though the good news is that this current system would work beautifully with an AMD module loader or Browserify transform). Many thanks for making this suggestion. |
Thanks Rich, and thanks to you for building Ractive, it's my preferred reactive framework, and I've evaluated most of them over the past 12+ years that I've been building reactive applications. In response to your solution, let's identify 2 different, though related, requirements. The first requirement is to have the entire widget, or component, described in a single file, including html, js, and css (nice inclusion btw). ie: a single-file component. In my view, embedding the javascript inside the html has some subtle advantages, such as decreasing the explicit binding required to bind the model to the view (let's table that discussion for now). The second requirement is to find the best way to include that component, html or other template, in the javascript application, preferably with scope isolation. I view this as a separate problem, and have chosen to go in a different direction, namely: to preprocess the html file into a javascript template file, see option 5 below: Here are some of the alternatives I've seen for getting an html template to the server:
I'll have a working version of option 5 working soon. Dave |
We agree that preprocessing is a must for serious applications - AJAXing in a load of template files is far from ideal. The approach I take in my own apps is to use a custom AMD module loader, which loads templates with AJAX and processes them on the client during development, but precompiles and bundles them up with the rest of the application JS at build time, e.g. views/templates/widget.html <div class='widget'>
<h2>I'm a widget</h2>
<button on-click='activate'>Activate me</button>
</div> views/Widget.js define([ 'Ractive', 'rv!./templates/widget' ], function ( Ractive, template ) {
return Ractive.extend({
template: template,
init: function () {
this.on( 'activate', function () {
alert( 'activating' );
});
}
});
}); app.js define([ 'views/Widget' ], function ( Widget ) {
var app = new Widget({
el: 'body'
});
}); The CSS lives separately, of course. Now, we're in a position to have a (say) I'll address the suggestions in turn:
Yep, not a fan, though some people will always prefer the familiar...
A step up from bog-standard ajax, but I prefer
It would be great if JS had decent multi-line string support, and even better if editors could handle the mixed syntax. Sadly I don't think this is realistic, especially for non-CoffeeScript people
I've been thinking about this option recently (see #238), but at present Ractive's innards are fairly tightly coupled to the variant of Mustache that it implements. Basically, templating engines like Underscore's have a much easier job - they're just creating a function that produces a string from some data. Ractive's parser has to create an abstract syntax tree and turn it into a JSON representation that is 'hydrated' at runtime to become the parallel DOM that manages the data-binding etc. For that reason, allowing full-blown logic to dictate the structure of the template, as opposed to the content of it (i.e. expressions), may not be possible. It would be good to support other languages in future though.
Bingo. To my mind this is what we're talking about with the The fs.readFile( 'template.html', function ( err, result ) {
var parsed = Ractive.parse( result.toString() );
fs.writeFile( 'template.json', JSON.stringify( parsed ) );
}); ...just not with the CSS and custom component logic baked in. (Incidentally the
This doesn't actually do anything special, I just like the semantics as using Look forward to seeing your option 5 implementation - between us we should be able to nail this. |
Meanwhile, @jrburke is looking at how to solve a similar problem with Web Components. Well worth learning from his research. |
Thanks, my initial impression is that his solution is way more complex than In the meantime, I do have the browserification of 'plain' html templates I'll try tackle the embedded script tags issue next week. Best Dave On Sat, Dec 14, 2013 at 8:22 AM, Rich Harris notifications@github.comwrote:
|
Hi @davidmoshal - I was doing some work yesterday that would really benefit from component imports, so after a bit of hacking I've added the feature to the dev branch. Would love to hear your thoughts, things you'd do differently etc - I've started a fresh thread (#366) so that newcomers can get straight to the examples. Thanks! Will close this issue in favour of that one. |
Hi @Rich-Harris I've been playing with Vue.js recently, seem really similar to this idea we bounced around in 2014. In fact one of the examples above looks just like a .vue file ! Dave Moshal |
Yep! A lot of Vue's ideas are heavily influenced by Ractive, including this one – we've been using single-file components since long before .vue files existed. We just never did a good job of advertising it 😁 |
We should have! Vue.js is the second most starred front-end framework on Github (after AngularJS). Dave |
Hi, am wondering if it's possible to embed Ractive code inside an html template.
e.g:
ie: the ractive code is embedded in an html page, which contains the template, so that all of the code can be in one place?
The text was updated successfully, but these errors were encountered: