This example shows how to create the simplest possible web site - one that it would be much easier to create by hand! You get to see some of the commands and basic method of using the MillScript. In this example, we are going to build a web site that has a single HTML page with the words "hello, world!" on it.
The first thing we need to do is create a working directory for our website files. Typically we would give this web site the same name as its domain name. We also need to tell the millscript system about it. The things we type are prefixed by the "$" prompt. End of line comments are prefixed with "#".
$ website --new hello.com
Checking whether hello.com is free ... ok
Creating folders :-
.website ... ok
.website/cache ... ok
.website/conf ... ok
inventory ... ok
.website/classes ... ok
output ... ok
.website/var ... ok
done
Now let's go to our new web site.
$ cd hello.com
$
The first thing we need to do is write a template that will generate
our page. We keep our templates, and many other resources, in a
directory called inventory. You'll find this directory
was created when the web site structure was built for you. This
template will be written in XHTML and stored in
inventory/hello.tp. The .tp file extension
tells the MillScript interpreter that the contents are a template.
<!-- This is the content for inventory/hello.tp -->
<html>
<body>Hello, World!</body>
</html>
The next thing we need to do is write the top-level script in
MillScript. This will have to instantiate the template and generate a
page by using the page function. By default, the MillScript
will look for a file called "site.ms". Here's our "site.ms" file.
The .ms file extension tells the MillScript interpreter
that this is a script.
# This is a MillScript end-of-line comment
htmlFile(
"hello", # name the HTML file, .html will be added
hello() # instantiate the template
);
At this point we are able to run the MillScript itself. It will produce
its output in the "output" directory. It is perhaps a bit annoying
that the output directory is fixed but, in my opinion, this reduces
the chance of dreadful mistakes. Since we are in the website
directory and want to mill the script "site.ms" we can run build
site.ms without further ado. The build command picks up the
right defaults from the context.
$ build site.ms
Lots of output
$
If You may prefer the "website" program to go about its work quietly
unless it finds an error. In this case you can use the
--quiet option (shorthand -q). We'll use it to clean out
the directory we just created.
$ website --quiet --purge
Are you sure you want to purge? (y/n) y
$
In addition, shorthand options can be combined. Instead of writing --quiet and --new snafoo.com you can abbreviate it to this
$ website -q -n snafoo.com
$
and you can push the two options together and write
$ website -qn snafoo.com
$
When the "website" program sees an option that begins with only one
"-" it explodes the remaining letters into their longhand version. In
other words writing -qn is exactly the same as writing
-u -p which is the same as writing --unattended
--purge. And because this expansion is checked prior to
anything else being done the accidental omission of a "-" is unlikely
to cause damage.
$ website -unattended --purge snafu.com
Unknown option "d" in compact argument "-unattended"
$
In this example we illustrate how to insert ad hoc material into a web site. To do this we will simply repeat the first example except we will substitute your name for the word "world".
The MillScript System provides a simple but powerful insertion method. When it is generating a page, if it encounters the custom tag
<item val=<em>script</em>/>
it will replace the tag with the result of the expression. Possibly the most common expression is a variable.
This feature combines very nicely with autoloading. When the compiler encounters an unknown global variable it searches the inventory for a file with a matching name. If it finds a file whose name, excluding any extension, is the same as the variable, it loads the file. If everything goes to plan, this will define the variable and compilation can continue.
In this case, we will add a file called "yourname.txt" to the
inventory. The .txt extension tells the MillScript
compiler that the file is raw ASCII text.
The "site.ms" file remains the same as above but the file "hello.tp" needs to be altered to include our name.
<html>
<body>Hello, <item val="yourname"/>!</body>
</html>
You do not have to supply the ".txt" extension - in fact you shouldn't. The extension is worked out by Millscript by inspecting the files in the Inventory. By omitting the extension this gives you the freedom to change from GIF to JPG (for example) without altering a line of code.
Now, we should create the file "yourname.txt" with your own name in it - or the file "yourname.gif" with a picture of yourself. It is your choice. In either case, Millscript will pick up the appropriate file and do the right thing.
To create your web site you simply run Millscript exactly as before,(build site.ms).
Before we go any further, it would be a good idea to have quick review of some of the basic elements of MillScript. We'll need to be able to define functions and use them, declare variables and use if-forms. For a more extended introduction you can read the MillScript Language Summary.
We define functions in MillScript with the function
syntax. Let's write a function that is passed two arguments and
returns their sum :-
function add( x, y ) =>
x + y
endfunction;
Here's another function that checks out whether a string is non-empty.
function nonempty( s ) =>
s /= ""
endfunction;
There are several points to note:
=> symbol is used to separate the definition
part from the main body of the function.
return statement to return
results from a function.
;). These
are required only to improve error reporting.
function has to be paired up with
endfunction, for example. Other important examples are
if/endif and
for/endfor. This is a bit more verbose
than, say, JavaScript but it is a lot more robust against simple
mistakes.
add( 1, 2 )
1.add( 2 )
var syntax. This is
written like this :-
var x = nonempty( "foo" );
If you do not want to subsequently update the variable you should
consider the alternative const declaration. This marks
the variable so that any attempt to update it will generate a
complaint.
If-expressions are easy to understand. You can use them as statements or expressions.
# use as statement.
if x < y then
println( "x < y" );
else
# use as an expression.
var d = if x - y > 1 then "big" else "small" endif;
println( "the difference is ", d );
endif
For loops are very sophisticated in MillScript - in fact they are one the most powerful looping constructs found in any programming language (to the best of my knowledge). For our examples, we only need to know a little bit about them.
We can use them to iterate over all the numbers between two limits, the elements of a list or the key-value pairs of a map. Here's some simple examples.
# Iterate from 1 to 10.
for i from 1 to 10 do
.... code involving i ...
endfor;
# Iterate over the elements in a list L
for e in L do
.... code involving e ...
endfor;
# Iterate over the key/value pairs of a map M
for k & v in M do
.... code involving k and v...
endfor;
For loops declare their loop variables for you. In fact it is not possible to introduce an uninitialized variable in MillScript! Furthermore, these loop variables are declared as "const" so they are protected against accidental assignment.