-
Notifications
You must be signed in to change notification settings - Fork 0
Documentation
- Basic Modest
- Using Modest in Javascript
- Creating Modules
- Supplying Module Parameters
- Preprocessing Javascript
- HTML, XML, and XHTML
Modest can be used by simply downloading 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.
Modules are included using <include><include/>
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.)
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 include
d 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.
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.
- Install node.js
- 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.
To see what options are available to the modest command, type
modest --help
Grunt-modest is an alternative to using the modest
command.
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.
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>
...
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.
On the client-side (using modest.js
), only modules that had the client
attribute set to true
in their include
tag are available.
To render a modest module in javascript, use the modest.render()
function.
var out = modest.render('animal');
If the module takes parameters, supply them as an object.
var out = modest.render('animal', { name: "Lion", weight: "250 kg (550 lb)" });
To load parameters from a local json file, use modest.data()
.
var out = modest.render('animal', modest.data('cow.json'));
modest.data()
will use node.js if it is run as preprocessed javascript, and jquery otherwise.
To load parameters from a remote url, use modest.remoteData(_url_)
.
Modules are usually xml files with an .xml
extension. (See exceptions.) They are included in modest html files using <include></include>
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.
Parameters can be handled in different ways, always with the uses
attribute.
Parameter names are case-insensitive.
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."
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.
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.
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 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.
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.
Module elements can be displayed depending on the existence of a parameter.
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>
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>
Text preceding the root element in a module is ignored, and can be used for comments. A <comment>
(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>
...
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 are useful when text needs to be reused, but it doesn't make sense to put it in its own element. For example
greetButton.xml
uses: name
<button type="button" uses="onclick={{alert('Hello, {{name}}')}}">Greet</button>
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>
...
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>
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
This is the method used in the Module Parameters examples.
<person>
<name>Bob</name>
</person>
The parameters are supplied by html tags inside the module element.
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 is used for loading parameters from a remote url.
<person remotedata="http://dataserver/person/bob"/>
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>
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. <img>
becomes <img />
). 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 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>