Problem
I'm implementing translations for my Angular 6 application. It needs to support static texts of the app in multiple languages. I don't need dynamic translations during runtime - I just need producing an app with texts in a language chosen during build.
Angular has the whole page on internationalization, but it focuses solely on situations where all the texts are hard coded in the templates, like in the code below:
<p>This is a hard coded text</p>
That's hardly a situation in my template. Additionally it seems to me impossible or extremely dirty to write the whole application with all the texts hard-coded in templates, so if that's the only mechanism available for translation, then it seems completely useless to me.
In my components I very often have texts bound to some JavaScript variables (or to be precise object properties), like in the code below:
<li *ngFor="let navigationEntry of navigationEntries">
<a [href]="navigationEntry.url">
{{ navigationEntry.text }}
</a>
</li>
Let's say the variable is still static, just being stored in the component or a service, e.g.:
navigationEntries: Array = [
{
url: "/",
text: "Home",
},
{
url: "/login",
text: "Login",
},
{
url: "/admin",
text: "Admin panel",
},
];
Question
Is there a way to use Angular native translation (internationalization) mechanisms to translate the anchor texts (or actually the text properties of the navigationEntries members) during build time? The structure of the JavaScript data and the HTML of the template can change.
If Angular native internationalization mechanisms can't handle that (but then I wonder what's their use at all), then what are other solutions that could help with implementing such translations? I found ngx-translate library, but it's providing translations which can be dynamically changed at runtime and ideally I wouldn't like to add that unnecessary overhead of dynamic solution watching on all the translated texts.
Yes, you can use Angular native translation mechanim to do this. We use the following pattern a lot to get around the missing dynamic translations in angular i18n:
You have an array of messages, and then use it with ngFor and ngSwitch to template the messages, something like this for your example:
<li *ngFor="let navigationEntry of navigationEntries">
<ng-container [ngSwitch]="navigationEntry.text">
<a [href]="navigationEntry.url" *ngSwitchCase="'Home'" i18n="##home">
Home
</a>
<a [href]="navigationEntry.url" *ngSwitchCase="'Login'" i18n="##login">
Login
</a>
<a [href]="navigationEntry.url" *ngSwitchCase="'Admin panel'" i18n="##adminPanel">
Admin panel
</a>
<ng-container>
</li>
It's somewhat verboose - but it works for a surprising amount of use cases.
Note, the i18n id (the string following the ##) is just an unique id, which is used in the xlf translation file. The string can be anything, I use the message itself, if possible, for readability and reuse.
Related
I have a legacy PHP app which I would like to slowly migrate to Vue. The PHP app renders a bunch of HTML and javascript files in quite a tangled fashion, i.e.
foo.js.php
...
<script src="mysite.com/some_js_file.js" />
...
const a = '<?=$variable_from_php?>';
so in the end, the browser obviously doesn't know how the js files are constructed, but can run them. What I'd like to do is from the outer layer Vue app, request the index page for a certain sub-section of the legacy app, and render that to a Vue node, as a micro-frontend of sorts. When I request each index, it will of course, contain a header with numerous other imports (scripts/styles) that that micro-frontend needs to function. So, two parts to this question: 1) what would be the best (or maybe least terrible) way to do this in Vue. Using v-html? iframe? (please say no iframes) And 2) will there be any showstopper security problems with this approach (since I'm basically saying fetch all the JS in the header and run it). Let me know if this question makes sense. Thanks!
Maybe you need like to : a module php or component as template.php(php server)
export const templateOfAdvanceTemplatePage = `
<div class="content edit-page management">
<md-card class="page-card">
<?php echo "My Component" ?>
</md-card>
</div>
And from node server
import * as url from "url";
var templateOfAdvanceTemplatePage = url.parse("http://www.website.com/template.php");
export default {
template: templateOfAdvanceTemplatePage,
...
}
for more information import vue here, and php as javascript file here
Vue.js can be used in two separate ways: For more complex applications you would use a build process and pre-compile the templates from the source, which are usually Single File Components SFC; *.vue files. The templates would then become render functions and no HTML is ending up in the output assets. There is, however, another way of defining Vue components. You can define them inline with the runtime-only bundle of Vue. For migrations and smaller applications this approach would be advised. You would need to include the compiler. See also the Vue documentation about that topic Vue v2 and Vue v3). If you are importing Vue as a module and are missing the compiler, see here.
If you want to render dynamically generated HTML from PHP as a Vue template, you would need the second approach. Keep in mind that, with this approach, you would always need to have the generated PHP output to be in sync with the Vue components. And you would need to fully trust the HTML, you are generating with PHP, otherwise you will risk injections.
There is, however, still another problem: You need the generated PHP output HTML as a string within JavaScript and it should not be interpreted by the browser (ideally) or removed again from the DOM. So, you need to decide (based on your project) how you want to generate the HTML so that it can be read in as a JavaScript string. Here are some approaches:
Generate the HTML directly into the page. Then, define which element you want to target, get the HTML with .innerHTML and delete the node from HTML (drawback: you will render the HTML twice, might produce short visual glitches).
Fetch the HTML via XHR from a separate page. You will directly have the HTML as a string in the response (see e.g. fetch).
Render <script type="text/x-template" id="static-html-content"></script> around the generated HTML content. Then, you do not need the HTML as string and you can directly use the id as reference (use template: '#static-html-content'). See the documentation of X-Templates in Vue.
Then, you can use the runtime-only version of Vue and define your components. Here is a live example:
const Counter = {
// retrieve and add your template string here
template: `
<div class="counter">
This is a counter: {{ counter }}
<button #click="counter++">Increase Counter</button>
</div>
`,
data: function() {
return {
counter: 0
}
}
};
const App = {
components: { Counter },
template: `
<div class="app">
This is the app component.
<hr />
<counter />
</div>
`
};
new Vue({
el: '#element',
template: '<App />',
components: { App }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="element"></div>
Another approach would be to just render the HTML string within a component with the v-html attribute. The main drawback of this solution is, however, that the content is then not reactive. You cannot change your internal component data and expect the template to react to the changes. Therefore, you are missing out on the main benefits of Vue, but you are not restricted to a template which matches your components internal structure.
A similar question was also posed in the Vue forum: link
TL;DR
I need to make Angular evaluate/parse HTML elements with Angular markup that are dynamically added to the DOM by treant-js.
[UPDATE 30/09/17]
I've followed the solution proposed there (which involves dynamic module/component creation). However, there are more and more issues with this implementation.
First, I'm injecting to the sub-component the needed dependances declared for the parent module (Router, ActivatedRoute, etc.):
this.addComponent(
this.treeContainer.nativeElement.outerHTML,
{},
this.conversation.threads,
this.route,
this.router,
this.ws
);
This seems wrong to me, because the most logical way would be to inject these dependancies directly into the dynamic component (with imports in the dynamic module), but I couldn't manage to do this.
Also, because treant-js needs to directly attach to the DOM the new HTML components it creates (I guess in order to bind the events properly), I'm unable to retrieve the HTML string before it's in the DOM. So, the ugly fix I found was:
to extract the HTML string with this.treeContainer.nativeElement.outerHTML(see the code snippet above) then send it as the template parameter for the dynamic component ;
since there would be 2 trees (because of 1.), to remove the initial treeContainer handled by treant-js: $(this.treeContainer.nativeElement).remove();.
Where then are we?
Besides the issues mentionned earlier, the solution I've tried is not at all acceptable. It seems that treant-js needs to attach its HTML elements to the DOM for event bindings and tree storage/management, so when I duplicate the HTML string of the tree to form the template of a dynamic component, this 2nd tree is well evaluated by Angular, but not under treant-js framework anymore (e.g.: some functionalities like collapsable handles would no longer work).
To sum up: I'm unable to have both Angular and treant-js working at the same time to handle my tree markup.
Moreover, the ugly trick I use to avoid having duplicate trees causes other issues, when it comes to re-generate the tree, whether it be from a dynamic update (new node created by user interaction), or from navigating to the same page multiple times (routing).
Last but not least, I can't even use some Angular markup like ngModel which come from imported modules (e.g. FormsModule): I get an error saying ngModelisn't bound to input element. The module is of course imported in my parent component, and I tried to import it in the dynamic module as well:
private addComponent(template: string, properties: any = {}, threads: Thread[],
route: ActivatedRoute, router: Router, ws: WebSocketService) {
#Component({template})
class TemplateComponent implements OnInit {
//...
#NgModule({
declarations: [TemplateComponent],
imports: [FormsModule]
})
class TemplateModule {}
const module = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
const factory = module.componentFactories.find(componentFactory =>
componentFactory.componentType === TemplateComponent
);
const component = this.container.createComponent(factory);
Object.assign(component.instance, properties);
Unless I find soon a way to make both Angular and treant-js work together smoothly, I may have to use another library such as angular-tree-component or ng2-tree. The big downside then is that I may miss some visual functionalities (like tree orientation) and interactivity I found easy to implement with treant-js.
[First post]
I'm new in Angular2, so there are certainly concepts I still don't understand correctly. I'm using treant-js in my own Angular2 project, and I'm stuck at making Angular2 evaluate/compile the directives in the generated HTML by treant-js.
I've seen this : Integrating Treant-js in Angular2 Project to integrate treant-js into the project, but I can only use some static HTML instead of routerLink, ngIf or ngFor for instance.
I call buildConversationTree in the ngInit of my component :
buildConversationTree() {
const config = {
container: '#tree',
connectors: {
type: 'step'
},
node: {
HTMLclass: 'thread-node',
collapsable: true
},
levelSeparation: 45
};
let treeConfig = this.buildNodes(this.conversation.threads);
treeConfig.unshift(config);
const tree = new Treant(treeConfig, this.onTreeLoaded, $);
}
Basically, the buildNodesmethod generate the HTML for each node of the tree, by calling the nodeHTMLmethod :
nodeHTML(data) {
return `
<div id="thread${data.id}" class="thread-node-wrapper">
<a class="main-link" routerLink="../thread/${data.id}">
Lorem ipsum
</a>
</div>
`;
}
I've got a simple template for my component:
<div class="tree-container">
<div id="tree"></div>
</div>
which becomes after the tree generation:
<div class="tree-container">
<div id="tree" class=" Treant Treant-loaded"><svg height="598" version="1.1" width="633" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="overflow: hidden; position: relative;"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaƫl 2.1.4</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></defs></svg><div class="node thread-node" style="left: 191.5px; top: 224px;">
<div id="thread60" class="thread-node-wrapper">
<a class="main-link" routerlink="../thread/60">
Lorem ipsum
</a>
</div>
</div></div>
</div>
And the routerlink="../thread/60"remains uncompiled/recognized by Angular.
In Angular.js:
Back in Angular.js (which was used for the project before), we would solve the problem using $compile :
var treeIsLoaded = function () {
// ...
var e = $('#tree')[0];
$compile(e)($scope);
if (!$scope.$$phase) {
$rootScope.safeApply();
}
// ...
};
and all the directives like ng-click, ng-show, etc., worked out, so I'm a bit puzzled about how hard it is to make it work in Angular2.
What I tried:
https://angular.io/guide/dynamic-component-loader, but unsuccessfully, even by importing the tree from another component didn't solve the issue. My guess is that the directives are not directly coded in the template itself but generated by treant-js, which is a 3rd library manipulating the DOM outside of the Angular framework ;
How can I use/create dynamic template to compile dynamic Component with Angular 2.0?, but I'm not sure this solution shall solve my issue, I'm a bit afraid of its complexity to be honest ;
angular 2 html binding, I tried to manually copy/paste the view element into a named template with ViewContainerRef members in my component, but it would work.
I'm using React and created a small page that has 4 components (React classes, what is the preferred term? I'll call them components in this post):
Component Breakdown
a parent "App" component that includes and manages the other components
a "Form" component that lets the user interact with the page
a "String View" component that displays the input from the form as text
a "Visual View" (I know, bad name...) component that interprets the string view and performs actions to adjust the visual.
Dataflow
The communication of these components using states and props is as follows:
The Form has onChange handlers that pass the new state to the App
The App funnels the state data to the String View
The String View updates and passes the updated state to the App
The App funnels the new state data to the Visual View
Finally, the Visual View now updates based on the new state.
Sample Code
var App = React.createClass({
handleFormChange: function(formData) {
this.setState({formData:formData});
},
handleStringChange: function(stringData) {
this.setState({stringData:stringData});
},
render: function() {
return (
<div className="app">
<FormView onFormChange={this.handleFormChange}/>
<StringView formData={this.state.formData} onStringChange={this.handleStringChange}/>
<VisualView stringData={this.state.stringData}/>
</div>
);
}
});
var FormView = React.createClass({
handleFormChange: function(e) {
this.props.onFormChange(e.target.value);
}
render: function() {
return(
<div className="formView">
<select onChange={this.handleFormChange}>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
);
}
});
var StringView = React.createClass({
componentDidUpdate: function() {
this.props.onStringChange({newString:'newStringState'});
},
render: function() {
this.props.formData;
// process formData and update state
return (
<div className="stringView">
{this.props.formData}
</div>
);
}
});
var VisualView = React.createClass({
render: function() {
var selection = this.props.stringData,
output = '';
if (selection === 1) {
output = 'Hooray, 1!';
} else {
output = 'Yes! 2!';
}
return (
<div className="stringView">
{output}
</div>
);
}
});
Questions
Is this the correct dataflow paradigm that React is trying to enforce (components only talk to parents, not siblings)?
Compared to how I would have written this in just regular JavaScript, this seems terribly constrained. Am I missing the big picture? Is this dataflow paradigm designed to prevent future problems (if so, which ones? Any that can't be solved with disciplined regular JavaScript?), or is there some other purpose that I'm missing?
I'm getting a lot of repeated function names (handleFormChange for example, it's used in App and Form View), is there a good way to make these distinguishable? Or, are repeated function names across components desirable?
When the components actually build, the JSX stuff gets transpiled down into real JavaScript. Is there an advantage to using JSX? Would writing components in the already transpiled JavaScript have an advantage?
To start, I think it is ok to call "components", and I've seen lot of people call that way. I will answer your questions below, in an order that I think is better to make my answers make sense.
When the components actually build, the JSX stuff gets transpiled down into real JavaScript. Is there an advantage to using JSX? Would writing components in the already transpiled JavaScript have an advantage?
JSX kinda mixes JavaScript and HTML, so, it makes your code "friendly". You will create your components, and just "call" them as HTML tags. Below you can see the difference between writing JSX and pure JavaScript.
return <div className="my-component"><p>Awesome</p></div>;
return ReactDOM.div({
className: 'my-component'
}, ReactDOM.p({}, "Awesome"));
I don't know you, but I would get tired to write this amount of code just to render a div with a paragraph.
You can check more benefits of using it here:
https://hchen1202.gitbooks.io/learning-react-js/content/benefits_of_jsx.html
I'm getting a lot of repeat function names (handleFormChange for example, it's used in App and Form View), is there a good way to make these distinguishable? Or, are repeated function names across components desirable?
It is not bad, also, your app is a "demo" one, if it would be a "real" one, it would have some better names for the components (i.e. <FormView> would be <ContactForm>) and maybe your method names would be different. But it is not bad at all. For example, inside <ContactForm> you may call the submit handler as onSubmit, but outside (the prop that you pass), you may call onContactFormSubmit, or, in a more semantic way, onContactFormFilled.
If your application starts to grow and you have lots of things repeated in the same component (that is the case of your <App>), you may try to split your components, therefore, each of your component will "know" about a "domain", and it would not appear to have lots of repeated stuff.
Is this the correct dataflow paradigm that React is trying to enforce (components only talk to parents, not siblings)?
First of all, React doesn't "enforce" anything, as some people say, React is the "v" in MVC, so, you have your "presentation" layer described as components, and the data may flow in the way you want.
But you got a point when you say "components only talk to parents, not siblings", because that is the way you can "communicate" between your components when you have multiple components. Since a component can't see its sibling, you need someone to orchestrate this communication, and, in this case, this is the parent's job.
There are other ways to make components "talk" to each other (i.e. using refs), but having a parent to orchestrate is, IMO, the most reliable (and better testable) one.
Compared to how I would have written this in just regular JavaScript, this seems terribly constrained. Am I missing the big picture? Is this dataflow paradigm designed to prevent future problems (if so, which ones? Any that can't be solved with disciplined regular JavaScript?), or is there some other purpose that I'm missing?
I decided to answer that as the last one, to sum up some things.
IMO, React is just great, you start to have your "logic" in the right place (a component), and you can just compose things in order to make your page work well (and by well I mean it is orchestrated correctly).
React also makes it easier to "think" about how you will build your interfaces. This Pete Hunt's blog post is amazing, and you should check it out:
https://facebook.github.io/react/docs/thinking-in-react.html
If you would be writing your code with plain JavaScript, you would have to handle DOM in some way (i.e. using a template engine) and your code would end up mixing DOM manipulation with your application logic. React just abstracts that for you. You can only care about presenting stuff. Another advantage is that, when everything is a component, you can reuse those components, it doesn't matter where they are located. If you pass the props correctly, your component will work as expected.
I know it seems exhaustive to write those components, but as you start to write more components you start to see lots of benefits. One of them is to nevermore wonder about how to present your data (no more concatenating HTML strings or calling template functions). Another one is that it is easy to "split" your interfaces, what makes your code easier to maintain (and that is not straightforward when using plain JavaScript).
To be honest, this application you wrote is really simple, and you may not see lots of advantages of using React for building it. I think you should try to create a more "complex" one, and compare it with plain JavaScript. By "complex", I mean "user interface" complex. For example, create a form that allows user to submit multiple "people". And "people" should have "name" and multiple "pet" (which also have a name). You will see how hard is it to handle "add" and "remove" operations in this case, and how easy React handle that kind of thing.
I think that is it, I hope you and React "click". It changed my mind about how to create complex user interfaces.
I am trying to understand the concept behind logic-less temlpates, but I'm finding myself hitting a wall.
I want to implement a simple navigation bar, e.g. "Home, About, Contact" links at the top of every page, and the "current" one should be highlighted with a different class (I'm using bootstrap). But how can I do this in a sensible fashion? So far I have:
Move the nav to every template, and copy the whole thing (not DRY, ugly).
Use keys instead of values, i.e. render('home', { on_home_page: true }); with <a href="/" {{#on_home_page}}class="active"{{/on_home_page}}>Home</a>. This is better, but still annoying that I have to create N variables to hold 1-variable worth of data.
create the nav in the controller, i.e. pass in { 'Home': {link: '/', active: false}, 'About: {link: '/about', active: true} } or similar. I dislike this because it has the opposite problem of logic-less templates. Now I have HTML-ful controllers...
Given the above options, I like (2) the best. But what I would prefer is some way to have a single variable to check, like:
// controller
render('about', {active: 'about'});
render('home', {active: 'home'});
// mustache nav
<a href="/" {{#if active == 'home'}}class="active"{{/if}}>Home</a>
<a href="/about" {{#if active == 'about'}}class="active"{{/if}}>About</a>
I'm sure this comes up all the time for mustache experts --- what's the best way to deal with it?
There's no way to deal with this using vanilla Mustache.
You have two options that let your JSON data and template stay clean:
1- using Mustache, write a helper function so that you can use it like this:
var selected_item = function(param) {
if (param == this.active) {
return 'active';
}
};
(disclaimer: I wrote this helper out of the top of my head, might not work as-is but I think you get the point)
Home
About
then mix-in that helper into your JSON data, best way probably being overloading Mustache.render so that every call to render adds your helper into the mix. Notice that leaving the class="" part outside of the helper allows you to have multiple different classes on each menu item while still having your "logic" for the active part.
2- switch to Handlebars which allows for this kind of basic logic. Handlebars is a superset of Mustache, stuff that works on vanilla Mustache will directly work in Handlebars so upgrading is easy. Be careful though, that once you have upgraded and modified your templates to work with Handlebars there's no turning back.
I just wrote a post on this. Click here or on the banner:
The basic idea for doing this with vanilla moustache and NodeJS is like so:
app.get('/Portfolio', function(req, res) {
res.render('portfolio.html', {
Portfolio: 'class="current"',
});
});
app.get('/Blog', function(req, res) {
res.render('blog.html', {
Blog: 'class="current"',
});
});
Notice how each separate route sends a different moustache variable. If a user goes to /Portfolio the {{{Portfolio}}} variable will exist but the {{{Blog}}} variable won't.
Using this idea, set up your navigation links like so:
<div id="nav">
<ul>
<li><a href="/Portfolio" {{{ Portfolio }}}>Portfolio</a></li>
<li><a href="/Blog" {{{ Blog }}}>Blog</a></li>
</ul>
</div>
Create the .current class
#nav li a.current {
font-weight: 900;
}
Now the link will be highlighted dependent on the routing call made.
I am mostly wondering how to organize things like modal windows, and dynamic pages like profiles. Should the viewModel only contain one profile view or contain all profiles loaded? This here just doesnt seem very "clean".
viewModel = {
profile: ko.observableArray([
new ProfileViewModel()
//... any others loaded
])
, createPostModal: {
input: ko.observable()
, submit: //do something to submit...
}
}
<div data-bind="foreach: profile"><!-- profile html --></div>
<div data-bind="with: createPostModal"></div>
This way doesn't seem very consistent. Is there anybody who has built a single page app with knockout that can offer some advice? Code samples would be appreciated.
We are just starting down this path at work, and so are not quite sure what we're doing. But here's the idea we have.
The page should be composed of any number of "components," possibly nested. Each component has a view model and one public method, renderTo(el), which essentially does
ko.applyBindings(viewModelForThisComponent, el)
It also could have the ability to render subcomponents.
Constructing or updating a component consists of giving it a model (e.g. JSON data from the server), from which it will derive the appropriate view model.
The app is then created by nesting a bunch of components, starting with a top-level application component.
Here is an example for a "hypothetical" book-managing application. The components are LibraryUI (displays a list of all book titles) and DetailsUI (a section of the app that displays details on a book).
function libraryBookViewModel(book) {
return {
title: ko.observable(book.title),
showDetails: function () {
var detailsUI = new BookDetailsUI(book);
detailsUI.renderTo(document.getElementById("book-details"));
}
};
}
function detailsBookViewModel(book) {
return {
title: ko.observable(book.title),
author: ko.observable(book.author),
publisher: ko.observable(book.publisher)
};
}
function LibraryUI(books) {
var bookViewModels = books.map(libraryBookViewModel);
var viewModel = {
books: ko.observableArray(bookViewModels);
};
this.renderTo = function (el) {
ko.applyBindings(viewModel, el);
};
}
function BookDetailsUI(book) {
var viewModel = detailsBookViewModel(book);
this.renderTo = function (el) {
ko.applyBindings(viewModel, el);
};
}
Note how we could make the book details appear in a jQuery UI dialog, instead of in a singleton #book-details element, by changing the showDetails function to do
var dialogEl = document.createElement("div");
detailsUI.renderTo(dialogEl);
$(dialogEl).dialog();
There are 3 frameworks out there that help with creating SPAs using Knockoutjs.
Durandal
Pagerjs
KnockBack
I have used Durandal and I really like it. Easy to use and has a lot of nice configurations so you can plug-in your own implementations. Also, Durandal is created by the same creator of Caliburn which was an very popular framework for building Silverlight/WPF applications.
Now in 2014, you probably want to use Knockout's component feature and Yeoman to scaffold your initial ko project. See this video: Steve Sanderson - Architecting large Single Page Applications with Knockout.js
[update april 5, 2013] at time of writing this answer was valid. Currently I would also suggest the Durandal JS approach as the way to go. Or check John Papa's Hot Towel or Hot Towelette SPA templates if you are using ASP.NET MVC. This also uses Durandal.
Original answer below:
I would like to point out Phillipe Monnets 4 part series about Knockout.js to you. He is the first Blogger I encounterd who splits up his example project in multiple files. I really like most of his ideas. The only thing I missed, was how to handle ajax / rest retrieved collections by using some kind of Repository / Gateway pattern. It's a good read.
Link to part 1: http://blog.monnet-usa.com/?p=354
Good luck!
I just open-sourced the mini SPA framework I put together with Knockout being the major component.
knockout-spa
A mini (but full-fledged) SPA framework built on top of Knockout, Require, Director, Sugar.
https://github.com/onlyurei/knockout-spa
Live Demo:
http://knockout-spa.mybluemix.net
Features
Routing (based on Flatiron's Director): HTML5 history (pushState) or hash.
Highly composable and reusable: pick modules/components for a page in the page-specific JS and they will be auto-wired for the page's HTML template
SEO ready (prerender.io)
Fast and lightweight (85 KB of JS minified and gizpped)
Two-tier bundle build for JS for production: common module that will be used by most pages, and page-specific modules that will be lazy-loaded
Organized folder structure to help you stay sane for organizing and reusing JS, CSS, HTML
Using Knockout 3.3.0+ so ready for Knockout's flavor of web component and custom tags (http://knockoutjs.com/documentation/component-overview.html)
All documentation are in the major dependencies' own homepages, so that you don't need to completely learn a new framework
Knockout http://knockoutjs.com
Require http://requirejs.org
Director https://github.com/flatiron/director
jQuery http://jquery.com
Sugar http://sugarjs.com