UNPKG

slush-markoa

Version:
369 lines (267 loc) 8.56 kB
<%= 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`. ### 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 ``` ### Development `gulp watch` To watch `.jade` and `.styl` files to convert into `.marko` and `.css` respectively. ### Mounting app on Markoa server *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); ``` ### App file structure ```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 ``` ### Generating apps `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 ``` ### Generating tags `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 ``` #### Single tag example - 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> ``` ### Marko taglibs Each app has its own taglib file. This file can reference multiple folders if needed. `marko-taglib.json` example: ```json { "tags-dir": ["./components", "./modules"] } ``` #### Multiple tags - 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 #52](https://github.com/marko-js/marko-widgets/issues/52#issuecomment-130434352) ### Full page setup ```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 libs 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 #110](https://github.com/marko-js/marko/issues/110#issuecomment-125969373) 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! ### Widgets in the client app 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 %>