slush-markoa
Version:
Markoa app generator
369 lines (267 loc) • 8.56 kB
Markdown
<%= appName %>
==============
<%= appDescription %>
Getting started
---------------
Run `slush markoa:layout` generator to configure layout with Stylus.
Then run `gulp jade:marko` to compile all `.jade` files into `.marko` files.
Now run `node index.js` to launch the server application. Notice the console debug messages and make sure the index route is added. Open the Chrome browser at `localhost:4000`
Now shut down the node process and try with `browser-refresh`.
Install browser-refresh globally on your system
`npm install browser-refresh -g`
Start your server using browser-refresh:
`browser-refresh index.js`
Now whenever you change a `.marko` file directly or via jade compilation it will reload the browser!
Compile apps
------------
You can now run:
`node compile-apps.js`
This will "compile" the apps and prepare widget maps and generate appropriate `browser.json` files for use with lasso, the asset dependency manager/injector ;)
Install
-------
Install `<%= appNameSlug %>` in a project where you want to mount the app:
```bash
$ npm install <%= appNameSlug %> --save
```
`gulp watch`
To watch `.jade` and `.styl` files to convert into `.marko` and `.css` respectively.
*Work in Progress (WIP)*
Ideally you should be able to mount the app like this:
```js
let myApp = require('<%= appNameSlug %>');
let apps = ['index'];
myApp.mountIn(myAppContainer, apps);
```
You can also use the `mounter.js` directly:
```js
let apps = ['index', 'projects'];
let mount = require('./mounter')(appContainer)
mount(apps);
```
```sh
/apps
/_global
/components
...
/data
index.js
/layouts
_default_page.jade
/index
/components
/tags
/project-feed
template.jade
marko-taglib.json
/layouts
_page.jade
/data
global.js
index.js
/page
index.jade
index.marko
index.browser.json
marko-taglib.json
/repositories
/teams
...
marko-taglib.json
```
`slush markoa:app`
This geneator will create an app under apps/[app-name] similar to the default `index` app generated by the default marko generator. Use this generator each time you want to add an app!
```
/[app]
/components
/project-feed
template.marko
/layouts
base.jade
/data
global.js
index.js
/page
meta.js
app.jade
app.marko
/dependencies
app.browser.json
marko-taglib.json
```
`slush markoa:tag`
This geneator will create an app under apps/[app-name] similar to the default `index` app generated by the default marko generator. Use this generator each time you want to add an app!
If no app name is given, the tag becomes global
```
/apps
/_global
/components
/[tag]
template.marko
template.jade
marko-tag.json
marko-taglib.json
```
If an app name is given, the tag is registered for that app
```
/apps
/[app]
/components
/[tag]
template.marko
```
- What is the name of your tag or tags (, separated) ? `top-menu`
- For which app (empty: global) ?
Creates the global tag `top-menu` under `apps/_global`
```sh
- template.jade
- template.marko
- renderer.js
- marko-tag.json
```
Example `ui-tabs`
Example: `ui-tabs/marko-tag.json`
```json
{
"@orientation": "string",
"@tabs <tab>[]": {
"@title": "string"
}
}
```
`renderer.js` references `template.marko` (see below)
```js
var template = require('./template.marko');
exports.renderer = function(input, out) {
template.render(input, out);
};
```
`ui-tabs/template.marko`
```html
<div class="tabs">
<ul class="nav nav-tabs">
<li class="tab" for="tab in data.tabs">
<a href="#$tab.link">
$tab.title
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane" for="tab in $data.tabs">
<invoke function="tab.renderBody(out)"/>
</div>
</div>
</div>
```
Each app has its own taglib file. This file can reference multiple folders if needed.
`marko-taglib.json` example:
```json
{
"tags-dir": ["./components", "./modules"]
}
```
- What is the name of your tag or tags (, separated) ? `top-menu, side-bar, session-bar`
- For which app (empty: global) ? `index`
Creates the tags: `top-menu`, `side-bar` and `session-bar` for the app `apps/index`
### Marko Widgets
[Marko Widgets](https://github.com/marko-js/marko-widgets) are special kinds of tags that support dynamic rendering and data binding etc. much like Reactive widgets/components from other frameworks such as React components. However Marko Widgets support both client and server side rendering amongst many other benefits, such as much lower footprint (kb) and higher server rendering performance (x10) than typical React components.
To create one or more widgets:
`slush markoa:widget`
Name the widget or list widgets to be created, just like for a tag. The simplest Widget template looks something like this:
```html
<div w-bind>
Hello $data.name
</div>
```
With a corresponding "ViewModel" or Widget controller:
```js
module.exports = require('marko-widgets').defineComponent({
template: require('./template.marko'),
getTemplateData: function(state, input) {
return {
name: input.name || 'unknown name'
};
},
init: function() {
var el = this.el; // The root DOM element that the widget is bound to
console.log('Initializing widget: ' + el.id);
}
});
```
Read more about how to get the full benefits of reactive Widgets for client and server on the [Marko Widgets page](https://github.com/marko-js/marko-widgets). Enjoy :)
Noe: For more Widget insights, also see [Issue
```html
<lasso-page name="index" package-path="./browser.json" />
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Marko Widgets: Bind</title>
<lasso-head/>
</head>
<body>
<h1>Marko Widgets: Bind</h1>
<div class="my-component" w-bind="./widget">
<h2>Click Me</h2>
</div>
<lasso-body/>
<init-widgets/>
</body>
</html>
```
The `browser.json` that includes the required client-side code is shown below:
`src/pages/index/browser.json`
```json
{
"dependencies": [
"require: marko-widgets",
"require: ./widget"
]
}
```
Tag lib definition files `marko-taglib.json` also supports importing other taglibs. This is very useful for making global/share taglibs available locally or merge several taglibs into one...
`"taglib-imports": ["./my-taglib", "other-taglib", "../../package.json"]`
The "taglib-imports" property allows another taglib to be imported into this taglib so that the tags defined in the imported taglib will be part of this taglib.
If a taglib import refers to a package.json file then we read the package.json file and automatically import *all* of the taglibs from the installed modules found in the "dependencies" section
For more, see [Issue
Since every markoa app has a `marko-taglib.json` file in the root, we can do:
`"taglib-imports": ["account", "casino", ...]` to import the global tag libs from each of the other apps ;) So all apps contribute to the shared lib of global tags!
Just include the same app on the client and use the simple `widget.find` API
```js
var myApp = require('./my-marko-app');
// find a globally registered widget
var myWidget = myApp.widget.find('my-widget');
// or retrieve an application specific widget, appName is 2nd argument
var myProjectWidget = myApp.widget.find('my-projects', 'projects');
myWidget.render({
name: 'John'
})
.appendTo(document.body)
.getWidget();
// Changing the props will trigger the widget to re-render
// with the new props and for the DOM to be updated:
widget.setProps({
name: 'Jane'
});
```
Wauw!!!
Contributing
------------
See the [CONTRIBUTING Guidelines](https://github.com/<%= userName %>/<%= appNameSlug %>/blob/master/CONTRIBUTING.md)
Support
-------
If you have any problem or suggestion please open an issue [here](https://github.com/<%= userName %>/<%= appNameSlug %>/issues).
License
-------
Copyright (c) 2015, <%= authorName %>