Documentation

Adam Stallard edited this page Jul 3, 2015 · 229 revisions
Clone this wiki locally

Contents

## Basic Modest Modest can be used by simply downloading [modest-preview.js](https://raw.github.com/goalzen/modest/master/lib/modest-preview.js) and including it in an html file.

It allows you to write modest html which reuses html from module-files you create.

### The ``head`` section Modules are included using ```` tags. The name of the module (with an optional .xml at the end) goes between the tags. The optional ``path`` attribute gives the relative location of the module (default is the current location). ``client="true"`` indicates that the module will be available to client-side javascript. (See [Using modest in javascript](#using-modest-in-javascript).)

The head section of a modest html file (a -pre file) might look like this, with jquery (required) included first, then modest-preview.js and finally some included modules.

...
<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script src="modest-preview.js"></script>
    <include path="modules" client="true">animal</include>
  </head>
...

When this file is loaded in a browser or an ide window, it will display as it would if it were compiled.

### The ``modest`` Command Once you are ready to deploy to production, you can compile a modest html file into regular html. To do that, install the modest node package.
  1. Install node.js
  2. Install modest npm install -g modest

then

cd <directory>
modest

or

modest <dir1> <dir2> ...

This will prepare one or more directories for use with modest by copying the "modest-preview.js" script into that directory. It will compile any files ending in -pre (plus an optional extension). For example, index-pre.html would become index.html. It will create a javascript file called modest.js that includes compiled versions of any modules that had client="true" in their include tags. A <script> tag referencing modest.js will be automatically added to the compiled files (after the body tag) so that any javascript included by the compiled files can use the modules. The modest-preview.js <script> tag will be cleaned out, and the compiled html files will be placed next to the -pre files.

#### Command-line Options To see what options are available to the modest command, type ```bash modest --help ``` #### Grunt-modest [Grunt-modest](https://github.com/goalzen/grunt-modest) is an alternative to using the ``modest`` command. ### Directory Structure Since a single ``modest.js`` file is created per directory, directories should be organized so that html files using the same modules are located in the same directory. ### Demo Elements An element marked with the attribute ``demo`` will be included in previews, but excluded from compilation. This lets designers see how programmatically-added elements would look--and communicate this to developers--without having to know about or create helper functions.

example-pre.html

...
<ul id="searchresults">
  <searchresult demo>
    <title>Goalzen</title>
    <url>www.goalzen.org</url>
    <description><lorem/></description>
  </searchresult>
</ul>
...

example.html (output)

...
<ul id="searchresults">
</ul>
...
## Using Modest in Javascript Modest modules and the ``modest`` class with its functions are available to any javascript run in the same context as either ``modest-preview.js`` or ``modest.js``. They are also available to any [preprocessed javascript](#preprocessing-javascript).

On the client-side (using modest.js), only modules that had the client attribute set to true in their include tag are available.

### Functions ### ``render`` To render a modest module in javascript, use the ``modest.render()`` function. ```javascript var out = modest.render('animal'); ``` If the module takes parameters, supply them as an object. ```javascript var out = modest.render('animal', { name: "Lion", weight: "250 kg (550 lb)" }); ``` ### ``data`` To load parameters from a local json file, use ``modest.data()``. ```javascript var out = modest.render('animal', modest.data('cow.json')); ``` ``modest.data()`` will use node.js if it is run as [preprocessed javascript](#preprocessing-javascript), and jquery otherwise. ### ``remoteData`` To load parameters from a remote url, use ``modest.remoteData(_url_)``. ## Creating Modules ### Module Files Modules are usually xml files with an ``.xml`` extension. ([See exceptions](#html-module-files).) They are included in modest html files using ```` tags. (The ``.xml`` extension can be omitted in the include tags.) If they are in a different location than the html file, specify the relative location with the ``path`` attribute.

The content of the module will be substituted whenever a tag with its name is used in modest html.

hello.xml

<p>Hello World.</p>

main-pre.xhtml

<?xml version='1.0' encoding='UTF-8'?>
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <include>hello</include>
  </head>
  <body>
    <hello/>
  </body>
</html>

Would be rendered as

main.xhtml (output)

<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  </head>
  <body>
    <p class="hello">Hello World.</p>
  </body>
</html>

The name of the module is added as a class to its root element. This makes it easy to find in javascript or css.

### Module Parameters Parameters can be handled in different ways, always with the ``uses`` attribute.

Parameter names are case-insensitive.

#### Simple Parameters The simplest use of a parameter is a straight-forward substitution of element content with parameter content.

person.xml

<p>A person named <span uses="name"/>.</p>

example-pre.html

...
<person>
  <name>Bob</name>
</person>
...

example.html (output)

...
<p class="person">A person named <span class="name">Bob</span>.</p>
...

The name of the parameter is added as a class to the element that replaced it.

#### Multiple Parameters The same parameter can be substituted in multiple places.

person.xml

<div>
  <h1 class="title" uses="name"/>
  <p><span class="description" uses="name"/> is <span uses="age"/> years old.</p>
</div>

example-pre.html

...
<person>
  <name>Bob</name>
  <age>24</age>
</person>
...

example.html (output)

...
<div class="person">
  <h1 class="title name">Bob</h1>
  <p><span class="description name">Bob</span> is <span class="age">24</span> years old.</p>
</div>
...

Here, extra (optional) classes were added to the module elements to make it easier to find the different instances of "name."

#### Unused Parameters Elements representing unused parameters are omitted from the output.

animal.xml

<div>
  <h1 uses="name"/>
  <p uses="weight"/>
</div>

example-pre.html

...
<animal>
  <name>Frog</name>
</animal>
...

example.html (output)

...
<div class="animal">
  <h1 class="name">Frog</h1>
</div>
...

See Dependent Elements.

#### Placeholder Parameters Parameters can be left blank so they can be used a placeholders and filled in later.

animal.xml

<div>
  <h1 uses="name"/>
  <p uses="weight"/>
</div>

example-pre.html

...
<animal id="frog">
  <name>Frog</name>
  <weight/>
</animal>
...

example.html (output)

...
<div class="animal" id="frog">
  <h1 class="name">Frog</h1>
  <p class="weight></p>
</div>
...

addWeights.js

...
$('#frog .weight').html(animals['frog'].weight);
...

See Dependent Elements.

#### Attribute Parameters Attributes of module elements can also receive parameters.

animal.xml

<div>
  <a uses="name href=url"/>
</div>

example-pre.html

...
<animal>
  <name>Frog</name>
  <url>"http://en.wikipedia.org/wiki/Frog"</url>
</animal>
...

example.html (output)

...
<div class="animal">
  <a class="name" href="http://en.wikipedia.org/wiki/Frog">Frog</a>
</div>
...

When defining a module, multiple parameters can be used for an element's attributes, and one parameter can be used for its content. Attribute parameters are of the form attribute=parameter. The content parameter is the one parameter that doesn't have an equals sign. The content parameter and the attribute parameters are supplied to the same uses parameter, separated by spaces.

For example:

<input type="checkbox" uses="name=category value=selection description"/>
#### Passthrough Parameters Passthrough parameters make it easy to forward parameters to inner modules.

infoForm.xml

<div>
  <p>Here is the contact information for <span uses="name"/></p>
  <contact>
    <name uses="name"/>
    <cell uses="number"/>
  </contact>
</div>  

contact.xml

<div>
  <p>Name: <span uses="name"/></p>
  <p>Cell: <span uses="cell"/></p>
</div>

example-pre.html

...
<infoForm>
  <name>Jim Bob</name>
  <number>123-456-7890</number>
</infoForm>
...

example.html (output)

...
<div class="infoForm">
  <p>Here is the contact information for <span class="name">Jim Bob</span></p>
  <div class="contact">
    <p>Name: <span class="name">Jim Bob<span/></p>
    <p>Cell: <span class="cell number">123-456-7890</span></p>
  </div>
</div> 
...

The replaced element receives a class from each parameter it passes through.

#### Root Parameters Parameters can be applied to the root element of a module

myLink.xml

<a uses="display href=url"/>

example-pre.html

...
<myLink>
  <display>go here</display>
  <url>http://some_rad-site.com</url>
</myLink>
...

example.html (output)

...
<a class="myLink display" href="http://some_rad-site.com">go here</a>
...

In this case, both the module name and the parameter name are added as classes to the replaced element.

### Dependent Elements Module elements can be displayed depending on the existence of a parameter. #### Plus Parameters A plus parameter causes an element to be displayed only if that parameter is supplied.

contact.xml

<div>
  <p>Name: <span uses="name"/></p>
  <p uses="+cell">Cell: <span uses="cell"/></p>
</div>
#### Minus Parameters A minus parameter causes an element to be displayed only if that parameter is not supplied.

animal.xml

<div>
  <h1 uses="name"/>
  <p>Weight: <span uses="weight"/><span uses="-weight">unknown</span></p>
</div>
### Module Comments Text preceding the root element in a module is ignored, and can be used for comments. A ```` (or any other) tag with the "uses" attribute set to "+" is also ignored. Any tags or text after the root element are ignored.

commentTest.xml

this is a comment
<div id="rootElement"/>
  <p>test</p>
  <comment uses="+">Another comment</comment>
</div>
<span>ignore me.</span>

example-pre.html

...
<commentTest/>
...

example.html (output)

...
<div id="rootElement" class="commentTest">
  <p>test</p>
</div>
...
#### Parameter Declarations Parameters can be declared in the comment section. This makes it easier to see what parameters a module takes.

animal.xml

uses: name, url
<span>
  <a uses="name href=url"/>
</span>
### String templates String templates are useful when text needs to be reused, but it doesn't make sense to put it in its own element. For example #### In attributes __greetButton.xml__ ```xml uses: name Greet ``` The outer double-braces indicate that a string template will be used for the ``onclick`` attribute. ``{{name}}`` will get replaced by the value of the ``name`` parameter.

example-pre.html

...
<greetButton>
  <name>Bob</name>
</greetButton>
...

example.html (output)

...
<button type="button" class="greetButton" onclick="alert('Hello, Bob')">Greet</button>
...
#### For element content A string template can be used to generate an element's content. For example

greeting.xml

<p uses="{{Hello, {{name}}}}"/>

would compile to

<p class="greeting">Hello, Bob</p>

With plain parameter substitution instead

greeting.xml

<p>Hello, <span uses="name"/></p>

would compile to

<p class="greeting">Hello, <span class="name">Bob</span></p> 
## Supplying Module Parameters _Supplying module parameters from javascript is described in [Using Modest in Javascript](#using-modest-in-javascript)_.

The methods for supplying module parameters are listed below in order of preference. If parameters from two methods conflict, the more-preferred method will override the less-preferred method.

  • html tags
  • the data attribute
  • the remotedata attribute
### Html tags This is the method used in the [Module Parameters](#module-parameters) examples. ```html Bob ``` The parameters are supplied by html tags inside the module element. ### The ``data`` attribute The ``data`` attribute gets the parameters from a local file. For example,

bob.json

{ 
  "name" : "Bob"
}

example-pre.html

<person data="bob.json"/>

would result in the same output as the html tags example above.

### The ``remotedata`` attribute The ``remotedata`` attribute is used for loading parameters from a remote url. ```html ``` ## Preprocessing Javascript Modest can preprocess javascript files. When the ``modest`` command is run, it looks for ``<script>`` tags that have the ``pre`` attribute. The javascript will be executed and the script tag will be removed.

example-pre.html

<html>
  <head>
    <include>animal</include>
  </head>
  <body>
    <script src="addCow.js" pre></script>
  </body>
</html>

animal.xml

uses: name, url
<div>
  <a uses="name href=url"/>
</div>

addCow.js

var cow = {
  "name" : "cow",
  "url" : "http://en.wikipedia.org/wiki/Cattle"
};
$(document.body).append(modest.render('animal',cow));

example.html (output)

<html>
  <head>
  </head>
  <body>
    <div class="animal">
      <a class="name" href="http://en.wikipedia.org/wiki/Cattle">cow</a>
    </div>
  </body>
</html>
## HTML, XML, and XHTML ### Compiling Modest creates output that conforms to both HTML and XHTML standards. It will convert void HTML elements to use the optional `` />`` ending to conform to XHTML. (E.g. ```` becomes ````). It will convert self-closing tags to start and end tags to conform to HTML. (E.g. ``<script/>`` becomes ``<script></script>``).

Modest removes XML declarations (e.g. <?xml version="1.0"?>), but preserves doctype declarations (e.g. <!doctype html>).

Though modest output files conform to both standards, input files (-pre files) are assumed to be html. If you want to use XHTML in a modest html (-pre) file, include an XML declaration at the top, e.g.

<?xml version='1.0' encoding='UTF-8'?>

This will alert the JSDOM that it should treat the file as XHTML.

Module files

Module files are XML by default, and if no extension is specified for an included module, .xml is assumed. Most HTML snippets will do fine as an XML module. The exception to this is if you want to use an HTML void element (such as <img>) without the optional /> ending in the tag.

To use a different extension for a module file, specify it in the include tag. For example:

<head>
  <include>image.html</include>
</head>