<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>lua nova</title>
	<atom:link href="http://luanova.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://luanova.org</link>
	<description>welcome to the moon</description>
	<lastBuildDate>Thu, 20 May 2010 16:18:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Authentication-based permission groups in Sputnik</title>
		<link>http://luanova.org/authentication-based-permission-groups-in-sputnik/</link>
		<comments>http://luanova.org/authentication-based-permission-groups-in-sputnik/#comments</comments>
		<pubDate>Thu, 20 May 2010 07:17:34 +0000</pubDate>
		<dc:creator>jimwhitehead</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[sputnik]]></category>

		<guid isPermaLink="false">http://luanova.org/?p=63</guid>
		<description><![CDATA[Sputnik is a novel document-storage-based wiki written in Lua which has been previously featured on LuaNova. Today I&#8217;d like to share my experiences adding authentication-based permission groups to my running Sputnik installation at wowprogramming.com. Over the course of the past two months I have had two spam posts on our forums which were fixed by [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sputnik.freewisdom.org/">Sputnik</a> is a novel document-storage-based wiki written in Lua which
has been previously featured on LuaNova. Today I&#8217;d like to share my
experiences adding authentication-based permission groups to my
running Sputnik installation at <a href="http://wowprogramming.com">wowprogramming.com</a>. Over the
course of the past two months I have had two spam posts on our forums
which were fixed by removing those nodes from the document store, but
this left me with a question of what to do with the user account that
posted the spam message.</p>

<p>First, I should state that we have had very few instances of spam on
our site. Any user accounts must be verified by email and require the
user to input a captcha from the <a href="http://recaptcha.net/">reCaptcha</a> project. Once this is done,
the user is free to make edits to the API documentation and to post
new topics and replies on the discussion forums. However, the process
of posting spam on the site is very difficult to automate due to the
honeypots, field hashing, and post tokens that a default Sputnik
installation employs. That&#8217;s not to say that the software is
bullet-proof, but in practice it seems to work for my needs on a real
site.</p>

<p>The first few accounts, I simply removed from my authentication system
via a simple mysql query (although removing it from a default
installation would be a easier, a simple edit of the sputnik/passwords
node.) But then I realised I was giving up information about the
spammers, including the email addresses they were using to register,
something I could share with some of the spam registration databases
that exist. It was clear that I needed an easier way to stop those
user accounts from posting on the site without simply nuking their
user accounts from the system. Really what I wanted was a way to &#8216;ban&#8217;
a user account and prevent them from making edits on the site.</p>

<h2>Permissions in Sputnik</h2>

<p>Each node in a Sputnik document store is a Lua script that is compiled
and assembled into a Lua object at runtime. Consider the following
simple node:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    title <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Some Page&quot;</span>
    content <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>This is a simple test node <span style="color: #b1b100;">for</span> a Sputnik installation.
&nbsp;
    Hello World<span style="color: #66cc66;">!</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>


<p>Sputnik nodes can be more than just a symbolic representation of text
data. For example, you can restrict the permissions of a node by
adding a permissions field. Consider the following definition:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    permissions    <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
      deny<span style="color: #66cc66;">&#40;</span>all_users, all_actions<span style="color: #66cc66;">&#41;</span>
      allow<span style="color: #66cc66;">&#40;</span>all_users, show<span style="color: #66cc66;">&#41;</span>  <span style="color: #808080; font-style: italic;">-- show, show_content, cancel</span>
      allow<span style="color: #66cc66;">&#40;</span>Authenticated, edit_and_save<span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">-- edit, save, preview</span>
      allow<span style="color: #66cc66;">&#40;</span>all_users, <span style="color: #ff0000;">&quot;post&quot;</span><span style="color: #66cc66;">&#41;</span>  <span style="color: #808080; font-style: italic;">-- needed for login</span>
      allow<span style="color: #66cc66;">&#40;</span>all_users, <span style="color: #ff0000;">&quot;rss&quot;</span><span style="color: #66cc66;">&#41;</span>
      allow<span style="color: #66cc66;">&#40;</span>Admin, all_actions<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>


<p>When this field is loaded, it&#8217;s obviously a string that we can then
further process. Specifically, we load it in an environment where a
few helpers functions are defined. The all_users function returns true
for all users, all_actions does the same for all action types.
Authenticated is a special function that returns true if the current
user is authenticated, while Anonymous can be used when the user is
not logged in. There&#8217;s also a special function called Admin that
queries the authentication metadata for the current user and checks if
the is_admin flag is set.</p>

<p>When I started looking for a way to ban users, I started looking in
this section of the code and found the following gem that Yuri sneaked
in after the definition for the Admin group:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">      <span style="color: #b1b100;">local</span> groups <span style="color: #66cc66;">=</span> self.saci.permission_groups <span style="color: #808080; font-style: italic;">-- just a local alias</span>
      <span style="color: #808080; font-style: italic;">-- Define group &quot;Admin&quot; as any user that has is_admin set to true</span>
      groups.Admin <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>user<span style="color: #66cc66;">&#41;</span>
         <span style="color: #b1b100;">return</span> user <span style="color: #b1b100;">and</span> self.auth:get_metadata<span style="color: #66cc66;">&#40;</span>user, <span style="color: #ff0000;">&quot;is_admin&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;true&quot;</span>
      <span style="color: #b1b100;">end</span>
&nbsp;
      <span style="color: #808080; font-style: italic;">-- Define any group that starts with &quot;is.&lt;group&gt;&quot; as including all users</span>
      <span style="color: #808080; font-style: italic;">-- for whom &quot;is_&lt;group&gt;&quot; is set to true. For example, if is_clown is set</span>
      <span style="color: #808080; font-style: italic;">-- to true than user is a member of group &quot;is.clown&quot; and we can set:</span>
      <span style="color: #808080; font-style: italic;">--</span>
      <span style="color: #808080; font-style: italic;">--     allow(is.clown, &quot;show&quot;)</span>
      <span style="color: #808080; font-style: italic;">--</span>
      <span style="color: #b1b100;">local</span> groups_mt <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
         __index <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">table</span>, key<span style="color: #66cc66;">&#41;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>user<span style="color: #66cc66;">&#41;</span>
                      <span style="color: #b1b100;">return</span> user <span style="color: #b1b100;">and</span> self.auth:get_metadata<span style="color: #66cc66;">&#40;</span>user,
    <span style="color: #ff0000;">&quot;is_&quot;</span>..key<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;true&quot;</span>
                   <span style="color: #b1b100;">end</span>
         <span style="color: #b1b100;">end</span>
      <span style="color: #66cc66;">&#125;</span>
      groups.is <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">setmetatable</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>, groups_mt<span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Bingo! With this bit of code, without making any changes to the
Sputnik core, I had a way to ban users in my system, by setting the
<strong>is_banned</strong> flag in their authentication metadata. For a simple
authentication system (the default) this is just a matter of setting
the given flag in the user&#8217;s authentication entry, whereas in a mysql
authentication system I just add a row to the database. This was only
part of the puzzle, since Sputnik doesn&#8217;t know anything about the new
user group. I had to make a few edits to the @Root prototype to add
the following at the end:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    deny<span style="color: #66cc66;">&#40;</span>is.banned, edit_and_save<span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Since earlier in the permissions script the edit_and_save permissions
are granted to all authenticated users, I needed to make sure the
denial runs after that point, since the final &#8216;permission&#8217; is what
really matters. Since I have custom forums in my system, I needed to
make the same one-line change in a few other places.</p>

<p>It took a total of about 6 minutes to familiarize myself with the code
and make the necessary changes, and now I have an easy way to ban a
user from being able to post anywhere on my website.</p>

<p>Down with the spammers!</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/authentication-based-permission-groups-in-sputnik/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Porting Lua to RISC OS</title>
		<link>http://luanova.org/porting-lua-to-risc-os/</link>
		<comments>http://luanova.org/porting-lua-to-risc-os/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 10:20:37 +0000</pubDate>
		<dc:creator>wra1th</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://luanova.org/?p=53</guid>
		<description><![CDATA[I do not expect many users of Lua will have heard of the operating system known as RISC OS. They are more likely, though, to have heard of the ARM processor architecture. The Wikipedia article on the ARM does not mention that the ARM CPU and RISC OS were in fact originally created for each [...]]]></description>
			<content:encoded><![CDATA[<p>I do not expect many users of Lua will have heard of the
operating system known as RISC OS. They are more likely,
though, to have heard of the ARM processor architecture.
The <a href="http://en.wikipedia.org/wiki/ARM_architecture">Wikipedia article</a> on the ARM
does not mention that the ARM CPU and RISC OS were
in fact originally created for each other by Acorn Computers
Ltd, in Cambridge (UK) in 1988. The article on
<a href="http://en.wikipedia.org/wiki/RISC_OS">RISC OS</a>
gives the full story.</p>

<p>RISC OS offers a very simple interface to user software, via
the ARM&#8217;s SWI (SoftWare Interrupt) instruction. Data is passed
between the user&#8217;s software and the operating system in ARM
registers; that data may consist of pointers to buffers in
memory that hold further data. RISC OS has always contained the
BBC BASIC programming language. This offers the user means
of accessing the operating system using:</p>

<ul>
<li><strong>DIM</strong> &#8212; to reserve a block of memory of a given size and pass
back its address;</li>
<li>Indirection operators ! (for words), ? (for bytes) and $ (for strings);</li>
<li><strong>SYS</strong> &#8212; to call an SWI with given values in the registers on entry
and variables to receive register values on exit;</li>
<li>an inbuilt ARM assembler and a <strong>CALL</strong> command to link to assembled code.</li>
</ul>

<p>With these facilities BBC BASIC is sufficiently powerful to enable
a user to control every aspect of her machine, if she is equipped
with the RISC OS PRMs (Programming Reference Manuals) -
these give details, for each of the modules constituting RISC OS, the
protocols and input/output details for each of the SWIs available,
and of the messages by which the kernel communicates with the modules.</p>

<p>Acorn Computers Ltd started out as manufacturers of laboratory equipment.
Their computers (with the exception of the RISCix work stations)
were always intended as single-user machines over which the user has
total control. Security? An irrelevance in those days. Just as
today&#8217;s motorist almost certainly does not carry a set of tappet-calipers
in his hip-pocket and has never disassembled a carburettor on the
kitchen table, so modern computer-owners are unlikely to want to
know about SWIs or programming. But RISC OS developed in an era
when computers had only just become affordable, and there was a sizable
minority of people who wanted not just to do things with their
computer but to understand how it did them, and how they could control it.
In the end it was the association with education that did for Acorn
Computers Ltd and for RISC OS, after ARM Holdings Ltd had been split off.</p>

<p>Porting Unix or Windows software to RISC OS is fraught with problems.
RISC OS uses cooperative, not preemptive, multitasking. The RISC OS
filing system is fundamentally different, too, and not just
syntactically (a dot is the directory separator symbol). Filer objects
have a filetype attribute that is not part of the object&#8217;s name.</p>

<p>RISC OS filing systems were designed on the supposition that they
were part of a graphical user interface &#8211; the GUI is not just
something tacked on later to a commandline interface. When a user
clicks on the icon of an object in a directory-window the window
manager broadcasts a message to all running tasks:</p>

<pre><code>An object at coordinates (x,y) with pathname obj_name and
filetype obj_type has just been clicked on. Are any of you
guys interested?
</code></pre>

<p>If a task is interested it sends back an acknowledgment (so that
the broadcast is aborted) and has its way with the object. If no
task replies, the taskmanager looks to see if a system command
(a sort of environment macro) <strong>Alias$@RunType_xxx</strong> has been defined,
where xxx are the hexadecimal digits of <strong>obj_type</strong>. If it has,
it is executed with <strong>obj_name</strong> as a commandline argument.
This command generally starts up a task and passes on its argument
to it. There is a special type for command files &#8211; known as
&#8220;obeyfiles&#8221;. An obeyfile always &#8220;knows&#8221; where it is because the
operating system sets the variable <strong>Obey$Dir</strong> to the pathname of the
directory containing it when it is executed. Textfiles constitute
a special type. Holding down the SHIFT key when clicking a file
will always open it in a text editor (even if the user has not
installed a text editor &#8211; there is a basic multifile texteditor
incorporated in the OS, so fundamental is the role of editing
ASCII text &#8211; the same principle applies to graphics, both
bit-mapped and vector). Each type of object is displayed by
its own icon, apart from application directories.</p>

<p>RISC OS has two types of directory. There are ordinary directories,
and there are application directories.</p>

<ul>
<li><p>Click on the icon of an ordinary directory with the left mouse
button and its window will open; with the right mouse button and
the currently open directory window containing it will simultaneously
close &#8211; this makes navigation and the avoidance of window clutter
very simple and direct &#8211; no opening of menus needed.</p></li>
<li><p>Application directories behave differently. Their appearance is
governed by a file inside them called !Sprites &#8211; a bit-mapped graphics
file. Click an application directory and the obeyfile !Run inside it
will be executed. To open an application directory like an
ordinary directory you must depress the SHIFT key when you click.</p></li>
</ul>

<p>The point about application directories is that they can be treated
as a package. There is no such thing as installing or deinstalling
or registering an application. You simply load the application
directory to wherever you want in the filing system and it will
be launched when you click on it. To deinstall, simply delete it.
This independence of position is achieved by a file called !Boot
within an application. It is executed when the window manager is
first made aware of the application&#8217;s existence by the opening of
the window of the directory containing it; this action can be
suppressed by holding down the CTRL key when opening a directory
window. The !Boot file will define system variables and macros
which will inform user software about where the application
is, and anything else they need to know of it. Alternatively the
user can &#8220;filer_boot&#8221; and &#8220;filer_run&#8221; applications from obeyfiles
that are inserted into the boot sequence. This is done by loading the
obeyfiles into appropriate places in the directory !Boot that must
reside at the top level of any RISC OS filing system. Only the !Boot
directory is off-limits for the user&#8217;s personal whims (though even
that is highly customizable). In other words, the filing system is
not a thing of labyrinthine complexity that belongs to the manufacturer
or to tradition. It belongs to the user. This is made possible by the
relocatability of applications.</p>

<p>In the RISC OS GUI, the window on top of the window stack is not
necessarily the window with the input focus. I often find myself
inputting text even though the window containing it is partially
obscured by another window that I need to be reading at the same time,
to compose my input. If I drag a window with the left-hand button
it will come to the top of the window stack, and so be dragged over
any other windows. If I drag with the right-hand button it will retain
its position in the window stack, and so be dragged behind some
windows and over others. The single most exasperating and thoughtless
aspect in Microsoft Windows, to my mind, is the way windows leap to
the top, obscuring what you need to be reading. Real desktops do not
behave in this way, unless somebody has left the door open and there
is a gale blowing through. It is a small detail, but a crucial one.
I have not sufficient experience to know which Linux window managers,
if any, get this right.</p>

<p>Of course, applications in read-only filing systems may need to
rent space for their configuration files on another, writable filing
system. RISC OS is usually held in ROM, so startup and switchoff are
immediate. I can switch on both my computers, one RISC OS, an Iyonix,
and the other Windows XP, an Advent 4211 notebook, at the
same time, and by the time the Advent is ready to use I have
read my emails, replied to them and switched off the Iyonix.</p>

<p>I mention all these details so that readers who are only familiar with
Windows or Unix will understand that there are other operating systems
which present a very different user experience. Many of the worries
and tools to deal with them (defragmenting the hard disc, installing
and removing packages, viruses, rootkits) that the Windows or Unix user
must take into consideration do not exist for the RISC OS user.
The other side of the coin is that RISC OS cannot deliver much that
is now taken for granted &#8211; its user base is too small to catch up.</p>

<p>As BASICs go, BBC BASIC is very good. There is a version for Windows,
I believe, with many improvements. It is almost unfair to call it
BASIC, because the facilities I cited above give it a whiff of
BCPL. Recall that BCPL was developed in Cambridge and was the grand-daddy
of C. BCPL was untyped. Although I am an admirer of BBC BASIC, I am not
blind to its limitations as a programming language. For a long time I
wondered if it were possible to have the best of both worlds:
something that incorporated the advances in programming language design
since 1964, BASIC&#8217;s year of birth, and yet retained the integration
with the operating system and the ease of use which BBC BASIC can
boast. I spent many years on different attempts to realize this dream.
Then I came across Lua.</p>

<p>Lua is portable to any platform with an ANSI C compiler. Lua is a
modern phenomenon, if we take the development of C as the watershed
dividing ancient from modern. Lua is safe, and it can make no
assumptions about its host platform; it certainly cannot peek
or poke memory. RISC OS is unsafe, tied to the ARM architecture, and
uses memory references. It is written mostly in ARM assembler; it
conflates 32-bit integers with addresses, with file-handles,
task-handles, task-manager messages, &#8230; . It is in some ways a
relic of the age before C. To marry Lua with RISC OS, to produce
what I called in an unimaginative moment, RiscLua, these contradictions
had to be squared.</p>

<p>The first problem is that ARM CPUs tend not to have floating-point
hardware. Continual conversion between doubles and 32-bit integers would
be a burden. This problem is solved by #defining LUA_NUMBER to int
and leaving out the math library. I also extended the Lua VM with bit
operations, putting them on an equal footing with the other arithmetic
operations. For those that have to use floating point numbers I
put in a library implementing doubles in the heap.</p>

<p>To integrate Lua with RISC OS, something along the lines of BBC BASIC&#8217;s
DIM,!,?,$ and SYS was needed. To begin with I used userdata for holding
the values of addresses. Then I could reserve blocks of garbage-collectible
memory, and I could check that references were within set bounds. One
downside was that the error-checking slowed things down. Much worse was
the problem of how to convert the data returned in a register from an
SWI call. To what sort of Lua value should it be converted? An integer,
a userdatum holding an address, a file-handle, a string, &#8230;. ? Eventually
I realised that this problem had no universal solution. The only answer
was to play as dirty as BBC BASIC; to abandon userdata and simply conflate
integers with addresses. This made RiscLua less safe, but faster,
and allowed a syntax for indirection that was very close to that
of BBC BASIC &#8211; an advantage for users more accustomed to BBC BASIC
than to anything else. The latest versions of RiscLua have a riscos
library containing <strong>dim</strong>, <strong>sys</strong>, <strong>!</strong>, <strong>?</strong> and <strong>$</strong> (these are allowable in variable
names in RiscLua). Where BBC BASIC might have <strong>x!4</strong> RiscLua can have <strong>![x+4]</strong>.
The symbols <strong>!</strong>,<strong>?</strong> and <strong>$</strong> in the riscos environment are just empty tables
with metamethods: <strong>__index</strong> peeks and <strong>__newindex</strong> pokes. The <strong>sys</strong> function
has one little twist that <strong>SYS</strong> does not have: a nil argument for a register
value means &#8220;use the value returned for that register by the previous
call to sys&#8221;. This is useful because the register usage for SWI calls
in RISC OS has been carefully optimized to minimize shuffling data
between registers, something which can be exploited by this syntax.</p>

<p>There are a few other extensions: backslash is sugar for <strong>function</strong> and &#8216;=>&#8217; is sugar
for <strong>return</strong>.</p>

<p><img src="http://mysite.mweb.co.za/residents/sdonovan/lua/untangle.png"/></p>

<p>This is a
texteditor window displaying a short RiscLua script that uses Roberto&#8217;s
lpeg library to run code enclosed in <strong>&lt;lua&gt; &#8230; &lt;/lua&gt;</strong> tags (with the
remainder of the text taking the value &#8220;text&#8221;). The point of the picture
is the third icon with the green arrow pointing down.
If you shift-drag the icon of a scriptfile onto the green arrow of
a texteditor window, the script is run (with <strong>arg[1]</strong> holding the
name of a pseudofile containing the contents of the window) and the
contents of the window are replaced by the standard output of the
script. This provides the texteditor with a convenient facility -
any scripting language can be used so long as the texteditor has been
configured to understand the right command line syntax for it.
In this case, shift dragging &#8220;untangle&#8221; onto the green arrow of a
window containing &#8220;&lt;lua&gt;print(text:upper())&lt;/lua&gt;hello&#8221; would
convert its contents to &#8220;HELLO&#8221;. Yes, I know it is contrived, but
I hope it shows the general principle.</p>

<p><img src="http://mysite.mweb.co.za/residents/sdonovan/lua/screen.png"/></p>

<p>This shows the final dialogue box when the
following program is run.</p>

<pre><code>-- Fred, tiny wimp program using error dialogue
require "wimp.task"
do
 local dim,! in riscos
 local buffer, wimp_msgs = dim(256), dim(4)
 local title$ = dim "Fred\r"
 local ask = "Count is %d. CANCEL to stop now?"
 local goodbye = "You reached %d. Goodbye."
 local flags = 23  -- for dialogue window
 ![wimp_msgs] = 0  -- no wimp messages
 fred = task.new(title$,wimp_msgs,buffer)   -- create task "fred"
 in fred do
  count = 0                      -- give it a counter
  handler[0] = \ (self)      -- give it a null-event handler
    count = count + 1
    local click = self:report(ask:format(count),flags)
    =&gt; (click ~= 1)          -- OK button to continue
  end -- handler
  preclosedown = \ (self)     -- give it a farewell action
     self:report(goodbye:format(count))
  end -- preclosedown
 end -- do
 fred:init()                   -- register it
 fred:run()                    -- run it
end -- do
</code></pre>

<p>This is a toy example of a RiscLua wimp program. It puts up a
window with two buttons, CANCEL for stopping, OK for carrying
on, and it increments a counter showing the number of times OK is
clicked. I hope the program is not too opaque. Note the use of
Peter Shook&#8217;s patch in <strong>local dim,! in riscos</strong> and the convenient
syntax provided by lexical environments in <strong>in fred do &#8230; end</strong>.
The wimp.task library provides a single function <strong>task.new</strong> which
returns a table, with methods &#8220;init&#8221;, &#8220;run&#8221;, &#8220;preclosedown&#8221;, etc
and a table, &#8220;handler&#8221; of event-handlers, indexed by the event-codes
sent by the taskmanager. Nothing much surprising about this
approach.</p>

<p>I will not pretend that RiscLua can do all the things that BBC BASIC
can do. It has no inbuilt ARM assembler, it does not have
extensive commands for sound or graphics. But there are things that
make RiscLua, for me, much more satisfying to use. It is more
expressive, more modular, more consistent and more concise. It
fulfils my quest, and still offers plenty of opportunities for
further development.</p>

<p>RiscLua and its sources are available at http://lua.riscos.org.uk/ .</p>

<p><a href="http://www.wra1th.plus.com/">Gavin Wraith</a></p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/porting-lua-to-risc-os/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Guardian of the Imperial Inkstand</title>
		<link>http://luanova.org/imperialguardian/</link>
		<comments>http://luanova.org/imperialguardian/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 12:34:33 +0000</pubDate>
		<dc:creator>wra1th</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://luanova.org/?p=46</guid>
		<description><![CDATA[Some experiences of using Lua to create and maintain websites for other people. Making a website just for yourself is one matter; doing it for others brings into play a range of quite separate considerations, that affect even the technical matters of design and implementation. You are the pig in the middle, the bacon in [...]]]></description>
			<content:encoded><![CDATA[<p><em>Some experiences of using Lua to create and maintain websites
for other people</em>.</p>

<p>Making a website just for yourself is one matter; doing it for others
brings into play a range of quite separate considerations, that affect
even the technical matters of design and implementation. You are the
pig in the middle, the bacon in the sandwich, sitting between the site
on one side and its commissioners on the other. I am a slow learner, but
after a dozen years of experience of different commissions I have come to
some definite general conclusions.</p>

<p>First, even for modest websites, plenty of time is needed for preparation,
before you even start thinking about design or implementation; time for
establishing a proper protocol between yourself and those who have
commissioned you. Ensure that all communications between yourself and them
pass through a single intermediary, a spokesperson who can shield you from
the disagreements and internal rivalries into which it may be fatal to be
drawn. Your commissioners may well have a committee charged with
responsibility for the proposed website, and it will probably delegate its
duties to a number of people: Mr X the timetable, Miss Y the graphics,
Dr Z the document archive, &#8230; . Fine. Nice to know you, Mr X, Miss Y,
Dr Z, &#8230;
Have nothing to do with these arrangements. Insist that they all communicate
only through the spokesperson. The spokesperson will have to channel
information in both directions. That way, with any luck, you will not
have to explain more than a dozen times why web pages look different in
different browsers, and why enormous TIFF files intended for high quality
printing are not appropriate for graphics on web pages, because they
will take rather a long time to download.</p>

<p>To be realistic, it is too much to expect the more important members
of the website committee to stick to this regime. In any case, out
of friendliness they may want to express themselves personally. It
is for that reason that I recommend that during the development phase
of the website each page should contain within its header the tags</p>

<pre><code>&lt;meta  http-equiv="pragma" content="no-cache" /&gt;
&lt;meta  http-equiv="cache-control" content="no-cache" /&gt;
</code></pre>

<p>because otherwise you will have the committee chairman sending you
messages accusing you of not getting on with the job: &#8220;Hi Gavin,
Mr X says he sent you that stuff about emergency car-parking
three weeks ago and it still is not up on the website.&#8221;; and then
you will have to explain to a deeply suspicious technophobe all about
how browsers cache webpages and that he is still looking at the pages
that his browser cached three weeks ago, and no, you cannot tell him
how to clear the cache for himself because you do not know what operating
system or browser he is using (&#8220;operating system? what is that,
old boy?&#8221;).</p>

<p>I struck an extraordinary glitch when I was making the <a href="http://www.wra1th.plus.com/byzcong/">website</a> for the
twenty-first International Congress of Byzantine Studies, which took
place in London from 21 to 26 August 2006. It was a prestigious affair,
with the Prince of Wales as patron and a long list of eminent sponsoring
organizations. Clarence House had been persuaded to send me a facsimile
of a signed letter of welcome from HRH, in receipt of which I had to
sign an undertaking that I would not permit any improper use of it. I
put a link to it from the sponsors&#8217; page.</p>

<p>The organizing committee of the conference had obtained a lovely jpeg
from the British Museum, of a Byzantine wooden carving of an angel.
They used this to make a poster. I used a jpeg of that to make
the entry page of the site. Clicking on the angel was to bring one
to a page listing the sponsors, including HRH, and inviting the viewer
to choose either the English or the French version of the website.
In my innocence, I called the page &#8220;sponsor.html&#8221;. When it was up for
review by the organizing committee I began to get puzzled queries from
them. &#8220;I clicked on the angel, and nothing happened&#8221;, about half of them
reported. I had no problem, nor did the other half. It was very mysterious.
Eventually research showed the culprit to be an arrogant piece of Norton
AntiVirus software running on the computers of some committee members.
It had decided that &#8220;sponsor&#8221; was obscene or dangerous, apparently.
Thus was HRH&#8217;s letter censored by Norton. In the end I changed the file&#8217;s
name to &#8220;spons.html&#8221; and the problem went away. The moral, I suppose,
is that you have to fathom some pretty sick minds if your webpages
are to be viewable by the public.</p>

<p>It is time to turn from the human to the coding side of things. I have
always believed that the best principle is to keep all as simple as
possible. As none of my sites have been designed for huge traffic I have
always shunned client-side scripting. It is usually unnecessary. One
should also keep in mind that many users may not have the latest browser.
In any case, adoption of WAI (the <a href="http://www.w3.org/WAI/">Web Accessibility Initiative</a> ) is
mandatory for .gov.uk websites, and it makes sense for any site
that is to be used by the public, especially an academic public
that is not likely to have the latest hardware.</p>

<p>I always create my websites on my own machine. I generally divide
the directory for website-creation into two subdirectories: &#8220;site&#8221;,
to contain all the stuff to be uploaded to the server, and &#8220;data&#8221;
to hold the gubbins from which the website is to be created, usually
as a &#8220;make&#8221; project. The contents of the webpages I classify into
three groups:</p>

<ol>
<li><strong>furniture</strong> &#8211; the graphics and css stuff that determine a common theme;</li>
<li><strong>permanent content</strong> &#8211; usually text;</li>
<li><strong>formatted mutable data</strong> &#8211; usually held as a textual database, as lists of labelled records, for ease of updating with a text editor.</li>
</ol>

<p>I use Lua format for the databases and Lua scripts to input from the
data-directory and output the finished pages to the site-directory.
To begin with, for the Art Historians&#8217; Millennium bash, I used a Lua
program, called Weave, which I had developed for creating web pages.
Over time I improved it by generalizing to the production of any
sort of marked-up text. Eventually it simply got replaced by a Lua
library. I must make another blog about this, because Lua&#8217;s way
with strings was a key factor in the design of this software.
I also produced a Lua program, Infuse, to perform the abstract
task of pouring content into template files &#8211; a sort of mail-merge.
It was the actual experience of coping with the commissioned websites
that drove me to keep reinventing. The frustrating thing was that I
dared not change over to a newer regime until the project was completed.
By starting sufficiently early I could create my templates for
the approval of the commissioners, before the flood of content
hit me. It was important to have a design sufficiently flexible to
cope with sudden changes of tack. The Lua format for labelled
records was good in this respect, because extra fields could always
be added. By contrast, CSV format would have been hopeless.</p>

<p>Lua&#8217;s extreme portability was handy. My own machine ran neither
Windows, Linux nor MacOS. Yet when I did a website for an artist,
whose agent needed to take over the running of it, even though the
agent used Windows, there was no problem getting everything working
on his machine.</p>

<p>For the Byzantine Congress I was told that I had been appointed
&#7952;&#960;&#8054; &#964;&#959;&#8160; &#954;&#945;&#957;&#953;&#954;&#955;&#949;&#8055;&#959;&#965; ,
guardian of the imperial inkstand, so named because it was in the shape
of a little dog (canicula). To find out more about this prestigious
office, use Google.</p>

<p><a href="http://www.wra1th.plus.com/">Gavin Wraith</a></p>

<h2>Ropes are better than Strings: A Technical Appendix</h2>

<p>In Lua strings are immutable values. This means that you
should avoid building up strings out of small pieces,
because although they will eventually be garbage-collected,
all the intermediate stages of your construction will still be
there taking up storage. Building up a string of n characters
by consecutive concatenations will use a number of bytes
varying quadratically with n. So concatenations are something
to be avoided. What about the construction of web pages,
where markup and text must be intertwined? Surely that will
involve lots of concatenations?</p>

<p>Actually, no &#8211; it need not. Whether we think of an html document
as text with markup inserted, or whether we think of it as a
structure of nested tag-pairs with text inserted, either way we
are led to the concept of strings-with-holes. To be more formal
we define the datatype of &#8220;ropes&#8221; recursively by:</p>

<pre><code>rope = string | list of rope
</code></pre>

<p>In Lua syntax, a rope either looks like</p>

<pre><code>[[ ..... ]]
</code></pre>

<p>or like</p>

<pre><code>{ ........ }
</code></pre>

<p>where the contents of the braces are a comma separated list of
ropes.</p>

<p>Put another way, a rope is a tree whose leaves are strings. We
can think of it as a string that has been broken apart leaving gaps.
If we walk over a rope, depth first, printing out the leaves to a file,
then we can construct our marked-up text without doing any
string-concatenation at all.</p>

<p>So this code</p>

<pre><code>&lt;a href="http://luanova.org/"&gt;LuaNova&lt;/a&gt;
</code></pre>

<p>can be obtained by printing out the rope</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">     <span style="color: #66cc66;">&#123;</span>
     <span style="color: #66cc66;">&#123;</span>
      <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&lt;</span>a <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
      <span style="color: #66cc66;">&#123;</span>
       <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;]],
       [[http://luanova.org/]],
       [[&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
      <span style="color: #66cc66;">&#125;</span>,
      <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     <span style="color: #66cc66;">&#125;</span>,
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>LuaNova<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&lt;/</span>a<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>If we define</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">     link <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>url<span style="color: #66cc66;">&#41;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>label<span style="color: #66cc66;">&#41;</span>
                    <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#123;</span>
     <span style="color: #66cc66;">&#123;</span>
      <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&lt;</span>a <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
      <span style="color: #66cc66;">&#123;</span>
       <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;]],
       url,
       [[&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
      <span style="color: #66cc66;">&#125;</span>,
      <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     <span style="color: #66cc66;">&#125;</span>,
     label,
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&lt;/</span>a<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">end</span></pre></div></div>


<p>then our rope is just the value of</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    link <span style="color: #ff0000;">&quot;http://luanova.org/&quot;</span> <span style="color: #ff0000;">&quot;LuaNova&quot;</span></pre></div></div>


<p>There are two sorts of markup: &#8220;monotags&#8221; and &#8220;tags&#8221;.</p>

<p>By a monotag I mean something like</p>

<pre><code>&lt;tag_name attr /&gt;
</code></pre>

<p>and we can implement this as a function from ropes to ropes:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>attr<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;&lt;tag_name &quot;</span>,attr,<span style="color: #ff0000;">&quot; /&gt;&quot;</span><span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">end</span></pre></div></div>


<p>By a tag I mean something like</p>

<pre><code>&lt;tag_id attr&gt;stuff&lt;/tag_id&gt;
</code></pre>

<p>which we can implement as a function from ropes to functions from
ropes to ropes:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">     <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>attr<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>stuff<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">return</span>
             <span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;&lt;tag_id &quot;</span>,attr,<span style="color: #ff0000;">&quot;&gt;&quot;</span>,stuff,<span style="color: #ff0000;">&quot;&lt;/tag_id&gt;&quot;</span><span style="color: #66cc66;">&#125;</span>
             <span style="color: #b1b100;">end</span>
     <span style="color: #b1b100;">end</span></pre></div></div>


<p>To simplify construction of webpages I invented a little language,
which I called <em>Weave</em>, as a fragment of Lua using strings and ropes
and named functions for the tags and monotags of HTML (see <a href="http://www.lua.org/notes/ltn010a.html">Lua technical
note 30</a> .)
After a while I broadened Weave&#8217;s abilities
so that it could cope with any sort of markup and no longer had
HTML&#8217;s tags and monotags built in. I introduced empty tables called
&#8220;TAG&#8221; and &#8220;MONOTAG&#8221; with metatables, so that using the __index key
I could define tag and monotag functions with notations like
&#8220;TAG.a&#8221; and &#8220;MONOTAG.img&#8221; and so on. This was more flexible, but it
did mean that the user had to define her own tags before building
a webpage. That did not matter, because by then CSS had appeared and
most webpages needed only a handful of tags and monotags. Eventually
I did away with Weave as a separate entity and simply used the Lua
module &#8220;xhtml&#8221; instead.</p>

<p>To create a very trivial webpage &#8220;foo.html&#8221; in the current directory,
run a Lua script as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">     #<span style="color: #66cc66;">!</span> lua
     <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">&quot;xhtml&quot;</span>
     <span style="color: #b1b100;">do</span>
     <span style="color: #b1b100;">local</span> mydoc <span style="color: #66cc66;">=</span> BEGIN <span style="color: #ff0000;">&quot;foo.html&quot;</span>
     <span style="color: #b1b100;">local</span> hstyle <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>style<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text-align: centre;&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
     <span style="color: #b1b100;">local</span> myheader, link <span style="color: #66cc66;">=</span> xhtml.TAG.h1, xhtml.link
     mydoc.BODY <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
                   myheader <span style="color: #66cc66;">&#40;</span>hstyle<span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;Try this&quot;</span><span style="color: #66cc66;">;</span>
                   link <span style="color: #ff0000;">&quot;http://luanova.org/&quot;</span> <span style="color: #ff0000;">&quot;Lua Nova&quot;</span><span style="color: #66cc66;">;</span>
                  <span style="color: #66cc66;">&#125;</span>
     END<span style="color: #66cc66;">&#40;</span>mydoc<span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">-- write the rope out to file</span>
     <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- do</span></pre></div></div>


<p>OK, this takes almost as long as creating the webpage by hand, for
this trivial example. But it should not take too much imagination
to see the possibilities. Practically every webpage I have created
for the last ten years has used this method.</p>

<p>Here are the relevant modules:</p>

<p><strong>weave.lua</strong></p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">     <span style="color: #808080; font-style: italic;">--[[
         The rope datatype is defined recursively:
&nbsp;
         data rope = string | list of rope.
&nbsp;
       Use:  status,err = rope.walk(rope,function)
             print(table.concat(err,&quot;.&quot;))
       Error message prints out index at each level.
     ]]</span>
     <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">pcall</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">pcall</span>
     <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">type</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">type</span>
     <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">ipairs</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">ipairs</span>
     <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">tostring</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">tostring</span>
     <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">assert</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">assert</span>
     <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">setmetatable</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">setmetatable</span>
     <span style="color: #b1b100;">local</span> open <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">io.open</span>
&nbsp;
     module <span style="color: #ff0000;">&quot;weave&quot;</span>
&nbsp;
     <span style="color: #808080; font-style: italic;">-- ropes -------</span>
&nbsp;
     <span style="color: #b1b100;">local</span> t_err <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&lt;bad type: %s&gt;&quot;</span>
     <span style="color: #b1b100;">local</span> a_err <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&lt;bad arg: %s&gt;&quot;</span>
&nbsp;
     walk <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>x,f<span style="color: #66cc66;">&#41;</span>  <span style="color: #808080; font-style: italic;">-- apply f to leaves of tree x, depth first</span>
          <span style="color: #b1b100;">local</span> g
          g <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>x,e<span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">-- e = error stack</span>
             <span style="color: #b1b100;">local</span> x_type, status <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
             <span style="color: #b1b100;">if</span> x_type <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;string&quot;</span> <span style="color: #b1b100;">then</span>
              status <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">pcall</span><span style="color: #66cc66;">&#40;</span>f,x<span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">if</span> <span style="color: #b1b100;">not</span> status <span style="color: #b1b100;">then</span> e<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#e<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> a_err:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
                  <span style="color: #b1b100;">return</span> status,e
              <span style="color: #b1b100;">elseif</span> x_type <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;table&quot;</span> <span style="color: #b1b100;">then</span>
                  e<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#e<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>
                  <span style="color: #b1b100;">for</span> i,y <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">ipairs</span><span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
                    e<span style="color: #66cc66;">&#91;</span>#e<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">tostring</span><span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span>
                    status <span style="color: #66cc66;">=</span> g<span style="color: #66cc66;">&#40;</span>y,e<span style="color: #66cc66;">&#41;</span>
                    <span style="color: #b1b100;">if</span> <span style="color: #b1b100;">not</span> status <span style="color: #b1b100;">then</span> <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">nil</span>,e <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
                  <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- for</span>
                  e<span style="color: #66cc66;">&#91;</span>#e<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">nil</span>
                  <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">true</span>
                <span style="color: #b1b100;">else</span>
                  e<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#e<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> t_err:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>x_type<span style="color: #66cc66;">&#41;</span>
                  <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">nil</span>,e
                <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
              <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
              <span style="color: #b1b100;">return</span> g<span style="color: #66cc66;">&#40;</span>x,<span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">end</span>
&nbsp;
       <span style="color: #b1b100;">local</span> file_err <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;cannot open %s&quot;</span>
       out <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>x,file<span style="color: #66cc66;">&#41;</span>
             <span style="color: #b1b100;">local</span> o <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">assert</span><span style="color: #66cc66;">&#40;</span>open<span style="color: #66cc66;">&#40;</span>file,<span style="color: #ff0000;">&quot;w&quot;</span><span style="color: #66cc66;">&#41;</span>,file_err:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>file<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
             <span style="color: #b1b100;">local</span> f <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span>
                       o:<span style="color: #b1b100;">write</span><span style="color: #66cc66;">&#40;</span>s <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span>
                       <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">true</span>
                       <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
             <span style="color: #b1b100;">local</span> status,err <span style="color: #66cc66;">=</span> walk<span style="color: #66cc66;">&#40;</span>x,f<span style="color: #66cc66;">&#41;</span>
             o:close<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
             <span style="color: #b1b100;">return</span> status,err
             <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
&nbsp;
       <span style="color: #808080; font-style: italic;">------ markup stuff --------------</span>
       <span style="color: #808080; font-style: italic;">--[[
       Two types of tag:
&nbsp;
         monotag    &lt;foo attributestring /&gt;
         tag    &lt;foo attributestring&gt; rope &lt;/foo&gt;
&nbsp;
       where attributestring could be empty.
         ]]</span>
&nbsp;
       <span style="color: #b1b100;">local</span> monotagger <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
       __index <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>_,tag<span style="color: #66cc66;">&#41;</span>
                 <span style="color: #b1b100;">assert</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>tag<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;string&quot;</span><span style="color: #66cc66;">&#41;</span>
                 <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>attr<span style="color: #66cc66;">&#41;</span>
                        <span style="color: #b1b100;">local</span> o <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;&lt;&quot;</span>,tag<span style="color: #66cc66;">&#125;</span>
                        <span style="color: #b1b100;">if</span> attr <span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>#attr <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">then</span>
                          o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot; &quot;</span>
                          o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> attr
                        <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
                        o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot; /&gt;&quot;</span>
                        <span style="color: #b1b100;">return</span> o
                        <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
                  <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
                 <span style="color: #66cc66;">&#125;</span>
&nbsp;
       <span style="color: #b1b100;">local</span> bitagger <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
       __index <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>_,tag<span style="color: #66cc66;">&#41;</span>
                 <span style="color: #b1b100;">assert</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>tag<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;string&quot;</span><span style="color: #66cc66;">&#41;</span>
                 <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>attr<span style="color: #66cc66;">&#41;</span>
                        <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>rope<span style="color: #66cc66;">&#41;</span>
                         <span style="color: #b1b100;">local</span> o <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;&lt;&quot;</span>,tag<span style="color: #66cc66;">&#125;</span>
                         <span style="color: #b1b100;">if</span> attr <span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>#attr <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">then</span>
                          o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot; &quot;</span>
                          o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> attr
                         <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
                         o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&gt;&quot;</span>
                         o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> rope
                         o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&lt;/&quot;</span>
                         o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> tag
                         o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&gt;&quot;</span>
                         <span style="color: #b1b100;">return</span> o
                  <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">end</span>
                  <span style="color: #66cc66;">&#125;</span>
       MONOTAG, TAG <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>,<span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
       <span style="color: #b1b100;">setmetatable</span><span style="color: #66cc66;">&#40;</span>MONOTAG,monotagger<span style="color: #66cc66;">&#41;</span>
       <span style="color: #b1b100;">setmetatable</span><span style="color: #66cc66;">&#40;</span>TAG,bitagger<span style="color: #66cc66;">&#41;</span></pre></div></div>


<p><strong>xhtml.lua</strong></p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">       <span style="color: #808080; font-style: italic;">--[[ The xhtml library exports
&nbsp;
         TAG, MONOTAG, BEGIN, END, TEXT, SPACE, REM and link
&nbsp;
       ]]</span>
&nbsp;
&nbsp;
       <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">&quot;weave&quot;</span>
&nbsp;
       <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">assert</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">assert</span>
       <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">type</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">type</span>
       <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">pairs</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">pairs</span>
       <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">print</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">print</span>
       <span style="color: #b1b100;">local</span> this <span style="color: #66cc66;">=</span> arg<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span>
       <span style="color: #b1b100;">local</span> leaf <span style="color: #66cc66;">=</span> this:match<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>([^<span style="color: #000099; font-weight: bold;">\\</span>]*)$&quot;</span><span style="color: #66cc66;">&#41;</span>
       <span style="color: #b1b100;">local</span> weave <span style="color: #66cc66;">=</span> weave
       <span style="color: #b1b100;">local</span> walk <span style="color: #66cc66;">=</span> weave.walk
       <span style="color: #b1b100;">local</span> out <span style="color: #66cc66;">=</span> weave.out
&nbsp;
       <span style="color: #b1b100;">local</span> concat <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">table.concat</span>
&nbsp;
       module <span style="color: #ff0000;">&quot;xhtml&quot;</span>
&nbsp;
       MONOTAG <span style="color: #66cc66;">=</span> weave.MONOTAG
       TAG <span style="color: #66cc66;">=</span> weave.TAG
&nbsp;
       <span style="color: #b1b100;">local</span> doctype <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
       <span style="color: #66cc66;">&lt;!</span>DOCTYPE html PUBLIC <span style="color: #ff0000;">&quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
       <span style="color: #ff0000;">&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;</span><span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
       <span style="color: #b1b100;">local</span> HTML <span style="color: #66cc66;">=</span> TAG.html <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
       xmlns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:lang<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;en&quot;</span> lang<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;en&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
       <span style="color: #b1b100;">local</span> nl <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
       BEGIN <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>filename<span style="color: #66cc66;">&#41;</span>
               <span style="color: #b1b100;">if</span> filename <span style="color: #b1b100;">then</span>
                 <span style="color: #b1b100;">assert</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>filename<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;string&quot;</span>,<span style="color: #ff0000;">&quot;BEGIN takes a string or nil&quot;</span><span style="color: #66cc66;">&#41;</span>
               <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
               <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#123;</span> FILE <span style="color: #66cc66;">=</span> filename <span style="color: #b1b100;">or</span> this..<span style="color: #ff0000;">&quot;.html&quot;</span><span style="color: #66cc66;">;</span> <span style="color: #66cc66;">&#125;</span>
               <span style="color: #b1b100;">end</span>
&nbsp;
       <span style="color: #b1b100;">local</span> META,LINK <span style="color: #66cc66;">=</span> MONOTAG.meta,MONOTAG.link
       <span style="color: #b1b100;">local</span> HEAD,BODY,TITLE <span style="color: #66cc66;">=</span> TAG.head <span style="color: #ff0000;">&quot;&quot;</span>,TAG.body,TAG.title <span style="color: #ff0000;">&quot;&quot;</span>
       <span style="color: #b1b100;">local</span> css <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>rel<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> media<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screen&quot;</span> href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
       END <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>rope<span style="color: #66cc66;">&#41;</span>
             <span style="color: #b1b100;">local</span> file <span style="color: #66cc66;">=</span> rope.FILE
             <span style="color: #b1b100;">local</span> style <span style="color: #66cc66;">=</span> rope.STYLE
             <span style="color: #b1b100;">local</span> doc <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
              rope.DOCTYPE <span style="color: #b1b100;">or</span> doctype<span style="color: #66cc66;">;</span>
              nl<span style="color: #66cc66;">;</span>
              HTML <span style="color: #66cc66;">&#123;</span>
               nl<span style="color: #66cc66;">;</span>
               HEAD <span style="color: #66cc66;">&#123;</span>
                nl<span style="color: #66cc66;">;</span>
                TITLE <span style="color: #66cc66;">&#40;</span>rope.TITLE <span style="color: #b1b100;">or</span> leaf<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">;</span>
                nl<span style="color: #66cc66;">;</span>
                META <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Generator&quot;</span> content<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Lua&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">;</span>
                nl<span style="color: #66cc66;">;</span>
                META <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;MSSmartTagsPreventParsing&quot;</span> content<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;TRUE&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">;</span>
                nl<span style="color: #66cc66;">;</span>
                rope.HEAD <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">;</span>
                style <span style="color: #b1b100;">and</span> LINK <span style="color: #66cc66;">&#123;</span>css<span style="color: #66cc66;">;</span>style<span style="color: #66cc66;">;</span><span style="color: #ff0000;">'&quot;'</span><span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">;</span>
                    <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">;</span>
                nl<span style="color: #66cc66;">;</span>
                BODY <span style="color: #66cc66;">&#40;</span>rope.ATTR <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>rope.BODY <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">;</span>
                nl<span style="color: #66cc66;">;</span>
                  <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">;</span>
                          <span style="color: #66cc66;">&#125;</span>
              status, err <span style="color: #66cc66;">=</span> out<span style="color: #66cc66;">&#40;</span>doc,file<span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">if</span> <span style="color: #b1b100;">not</span> status <span style="color: #b1b100;">then</span> <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span>concat<span style="color: #66cc66;">&#40;</span>err,<span style="color: #ff0000;">'.'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
              <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">--function</span>
&nbsp;
       <span style="color: #b1b100;">local</span> entity <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
         <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;&lt;&quot;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&amp;lt;&quot;</span>,
         <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;&gt;&quot;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&amp;gt;&quot;</span>,
         <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;&amp;&amp;&quot;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&amp;amp;&quot;</span>,
                      <span style="color: #66cc66;">&#125;</span>
       <span style="color: #b1b100;">local</span> catchall <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;(.)&quot;</span>
       <span style="color: #b1b100;">local</span> entify <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>c<span style="color: #66cc66;">&#41;</span>
                      <span style="color: #b1b100;">local</span> n,fmts <span style="color: #66cc66;">=</span> c:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>,<span style="color: #ff0000;">&quot;&amp;#%s;&quot;</span>
                      <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#40;</span>n <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">127</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">and</span> fmts:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">or</span> c
                      <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
&nbsp;
       TEXT <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>rope<span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">local</span> o <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
              <span style="color: #b1b100;">local</span> f <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span>
                  <span style="color: #b1b100;">local</span> status <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;string&quot;</span>
                  <span style="color: #b1b100;">if</span> status <span style="color: #b1b100;">then</span>
                    <span style="color: #b1b100;">for</span> symb,ent <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span><span style="color: #66cc66;">&#40;</span>entity<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
                      s <span style="color: #66cc66;">=</span> s:<span style="color: #b1b100;">gsub</span><span style="color: #66cc66;">&#40;</span>symb,ent<span style="color: #66cc66;">&#41;</span>
                    <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- for</span>
                    s <span style="color: #66cc66;">=</span> s:<span style="color: #b1b100;">gsub</span><span style="color: #66cc66;">&#40;</span>catchall,entify<span style="color: #66cc66;">&#41;</span>
                    o<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>+#o<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> s
                  <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- if</span>
                   <span style="color: #b1b100;">return</span> status
                 <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
              walk<span style="color: #66cc66;">&#40;</span>rope,f<span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">return</span> o
              <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
&nbsp;
       SPACE <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span>
               <span style="color: #b1b100;">assert</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;number&quot;</span>,<span style="color: #ff0000;">&quot;SPACE takes a number&quot;</span><span style="color: #66cc66;">&#41;</span>
               <span style="color: #b1b100;">local</span> s <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&amp;nbsp;&quot;</span>
               <span style="color: #b1b100;">return</span> s:rep<span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span>
               <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
&nbsp;
       REM <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&lt;!-- &quot;</span><span style="color: #66cc66;">;</span>s<span style="color: #66cc66;">;</span><span style="color: #ff0000;">&quot; --&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #66cc66;">;</span> <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span>
       link <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>url<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">return</span> TAG.a <span style="color: #66cc66;">&#123;</span> <span style="color: #ff0000;">'href=&quot;'</span><span style="color: #66cc66;">;</span> url<span style="color: #66cc66;">;</span> <span style="color: #ff0000;">'&quot;'</span><span style="color: #66cc66;">;</span> <span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;">-- function</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://luanova.org/imperialguardian/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>An introduction to Orbit</title>
		<link>http://luanova.org/orbit1-2/</link>
		<comments>http://luanova.org/orbit1-2/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 16:57:41 +0000</pubDate>
		<dc:creator>stevejdonovan</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[Kepler]]></category>
		<category><![CDATA[orbit]]></category>
		<category><![CDATA[web frameworks]]></category>

		<guid isPermaLink="false">http://luanova.org/?p=41</guid>
		<description><![CDATA[Installing Orbit Orbit is a lightweight framework for Web applications written in Lua. Unlike Sputnik, Orbit gives you the basic tools for constructing applications built on WSAPI. If you want authentication, standard look-and-feel, wiki-like functionality, you are better off starting with Sputnik; but Orbit is a satisfying way to build web applications from scratch. The [...]]]></description>
			<content:encoded><![CDATA[<h2>Installing Orbit</h2>

<p><a href="http://orbit.luaforge.net/">Orbit</a> is a lightweight framework for Web applications written in Lua. Unlike <a href="http://luanova.org/sputnik/">Sputnik</a>, Orbit gives you the basic tools for constructing applications built on <a href="http://wsapi.luaforge.net/">WSAPI</a>.  If you want authentication, standard look-and-feel, wiki-like functionality, you are better off starting with Sputnik; but Orbit is a satisfying way to build web applications from scratch.</p>

<p>The easiest way to install Orbit on a Unix machine is using <a href="http://luarocks.org/">LuaRocks</a>, but here for a change I will assume that you already have <a href="http://luaforwindows.luaforge.net/">Lua for Windows</a> which already has most of the dependencies for Orbit.  Then download <a href="http://mysite.mweb.co.za/residents/sdonovan/lua/orbit-2.0.2-all.zip"> orbit-2.0.2-all.zip</a>, unzip it somewhere preserving folder names, and run  <strong>lua install-orbit.lua</strong> from this directory in a command prompt.</p>

<p>The examples in this tutorial are then in the <strong>orbit-2.0.2\samples\basic</strong> folder.</p>

<h2>The Basics</h2>

<p>The simplest Orbit application is one that serves up a single HTML page:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">-- basic1.lua</span>
    <span style="color: #b1b100;">require</span><span style="color: #ff0000;">&quot;orbit&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">-- declaration</span>
    module<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;basic1&quot;</span>, package.seeall, orbit.new<span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">-- handler</span>
    <span style="color: #b1b100;">function</span> index<span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">return</span> render_index<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">-- dispatch</span>
    basic1:dispatch_get<span style="color: #66cc66;">&#40;</span>index, <span style="color: #ff0000;">&quot;/&quot;</span>, <span style="color: #ff0000;">&quot;/index&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">-- render</span>
    <span style="color: #b1b100;">function</span> render_index<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
       <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
        <span style="color: #66cc66;">&lt;</span>head<span style="color: #66cc66;">&gt;&lt;/</span>head<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Pretty Easy<span style="color: #66cc66;">!&lt;/</span>h2<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;/</span>html<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>An Orbit application is a Lua module, declared in the usual way except for the extra &#8216;orbit.new&#8217;. Lua&#8217;s <strong>module</strong> function can take a number of extra arguments, which are all functions which modify the module table in some way: <strong>package.seeall</strong> makes the global environment accessible to the module, and <strong>orbit.new</strong> adds some extra methods to the new module (you may think of this as &#8216;inheritance&#8217;.)</p>

<p>Any HTML request is mapped onto handler functions &#8211; in this case, the result of doing a GET request on &#8216;/&#8217; or &#8216;/index&#8217;. <strong>index</strong> just asks <strong>render_index</strong> to actually generate the HTML for this particular page. You can then run this application using the default Xavante server:</p>

<pre><code>c:\basic&gt; orbit basic1.lua
Starting Orbit server at port 8080
</code></pre>

<p>And you can view the result by going to <strong>http://localhost:8080</strong> in your favourite browser.</p>

<p>Not perhaps very impressive, seeing as the result could be achieved by a simple static page, but the render function can return <em>any</em> dynamically created string. And this example will work with Xavante, FastCGI or CGI, because Orbit is a WSAPI application.</p>

<p>All the usual web request variables are parsed and available to you. The <strong>web</strong> variable returned from the handler contains a table <strong>GET</strong> which has all the parameters passed to the server from a <strong>GET</strong> request. Call this script with <strong>http://localhost:8080/?cat=felix&amp;dog=fido</strong> and you will see that <strong>cat</strong> and <strong>dog</strong> are fields of <strong>web.GET</strong>, appropriately translated from URL encoding.</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">-- basic3.lua</span>
    <span style="color: #b1b100;">require</span><span style="color: #ff0000;">&quot;orbit&quot;</span>
&nbsp;
    module<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;basic3&quot;</span>, package.seeall, orbit.new<span style="color: #66cc66;">&#41;</span>
&nbsp;
    basic3:dispatch_get<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">local</span> ls <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
        <span style="color: #b1b100;">for</span> k,v <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span><span style="color: #66cc66;">&#40;</span>web.GET<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
            <span style="color: #b1b100;">table.insert</span><span style="color: #66cc66;">&#40;</span>ls,<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'&lt;li&gt;%s = %s&lt;/li&gt;'</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>k,v<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">end</span>
        ls <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'&lt;ul&gt;'</span>..<span style="color: #b1b100;">table.concat</span><span style="color: #66cc66;">&#40;</span>ls,<span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #66cc66;">&#41;</span>..<span style="color: #ff0000;">'&lt;/ul&gt;'</span>
        <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
        <span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;&lt;</span>head<span style="color: #66cc66;">&gt;&lt;/</span>head<span style="color: #66cc66;">&gt;&lt;</span>body<span style="color: #66cc66;">&gt;</span>
        Web Variables <span style="color: #66cc66;">&lt;</span>br<span style="color: #66cc66;">/&gt;</span>
        <span style="color: #66cc66;">%</span>s
        <span style="color: #66cc66;">&lt;/</span>body<span style="color: #66cc66;">&gt;&lt;/</span>html<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>ls<span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span>, <span style="color: #ff0000;">&quot;/&quot;</span>, <span style="color: #ff0000;">&quot;/index&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>This is not a pretty script; it&#8217;s only virtue is that it is short. It is ugly for two basic reasons; first, generating HTML with regular string operations is awkward, and second, it does not separate the logical parts out neatly. The HTML problem will be discussed in the next section, but the next example separates the various operations into their own sections.</p>

<p>This also shows how Orbit can serve up static content as well, in this case anything inside the <strong>/images</strong> directory:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">-- basic2.lua</span>
    <span style="color: #b1b100;">require</span><span style="color: #ff0000;">&quot;orbit&quot;</span>
&nbsp;
    module<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;basic2&quot;</span>, package.seeall, orbit.new<span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">function</span> index<span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">return</span> render_index<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">collectgarbage</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;count&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    basic2:dispatch_get<span style="color: #66cc66;">&#40;</span>index, <span style="color: #ff0000;">&quot;/&quot;</span>, <span style="color: #ff0000;">&quot;/index&quot;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #808080; font-style: italic;">-- any file in this directory will be served statically</span>
    basic2:dispatch_static <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/images/.+&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">local</span> template <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
    <span style="color: #66cc66;">&lt;</span>head<span style="color: #66cc66;">&gt;&lt;/</span>head<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">%</span>s
    <span style="color: #66cc66;">&lt;/</span>html<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
    <span style="color: #b1b100;">function</span> render_page<span style="color: #66cc66;">&#40;</span>contents<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> template:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>contents<span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    <span style="color: #b1b100;">function</span> render_index<span style="color: #66cc66;">&#40;</span>mem<span style="color: #66cc66;">&#41;</span>
       <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
        <span style="color: #66cc66;">&lt;</span>img src<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/images/lua.png&quot;</span><span style="color: #66cc66;">/&gt;</span>
        <span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Memory used by Lua is <span style="color: #66cc66;">%</span>6.0f kB<span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>
       <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>mem<span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>Note that <strong>dispatch_static</strong> is passed a Lua <em>string pattern</em>, not a file mask; in this case, anything in the directory.</p>

<p>We are now presenting true dynamic content (the amount of memory managed by Lua) and made a first start to prettifying the result. It is convenient to only generate the &#8216;inner&#8217; HTML and use a template to generate the full page, so <strong>render_page</strong> has been factored out.</p>

<p>Orbit follows the Model-View-Controller (MVC) pattern that separates an application into three distinct parts. The Controller acts as the executive, the Model manages the data, and the View presents the data to the user; here the dispatch rules calls <strong>index</strong> which uses the renderer <strong>render_index</strong> to present the HTML form of the data. This pattern comes from a basic principle, <a href="http://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns</a>. You do not want to mix database access, application logic and visual presentation together because the result is not clear and may become unmaintainable quickly.</p>

<h2>HTML the Orbit Way</h2>

<p>The HTML problem is usually solved using templates, such as <a href="http://cosmo.luaforge.net/">Cosmo</a> as discussed in the last <a href="http://luanova.org/sputnik">article</a> on Sputnik. Orbit provides another option, which is that Lua code can generate HTML:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">-- html1.lua</span>
    <span style="color: #b1b100;">require</span><span style="color: #ff0000;">&quot;orbit&quot;</span>
&nbsp;
    <span style="color: #b1b100;">function</span> generate<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> html <span style="color: #66cc66;">&#123;</span>
            head<span style="color: #66cc66;">&#123;</span>title <span style="color: #ff0000;">&quot;HTML Example&quot;</span><span style="color: #66cc66;">&#125;</span>,
            body<span style="color: #66cc66;">&#123;</span>
                h2<span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;Here we go again!&quot;</span><span style="color: #66cc66;">&#125;</span>
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    orbit.htmlify<span style="color: #66cc66;">&#40;</span>generate<span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span>generate<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #66cc66;">==&gt;</span>
    C:\basic<span style="color: #66cc66;">&gt;</span>lua html1.lua
    <span style="color: #66cc66;">&lt;</span>html <span style="color: #66cc66;">&gt;&lt;</span>head <span style="color: #66cc66;">&gt;&lt;</span>title <span style="color: #66cc66;">&gt;</span>HTML Example<span style="color: #66cc66;">&lt;/</span>title<span style="color: #66cc66;">&gt;&gt;&lt;/</span>head<span style="color: #66cc66;">&gt;&lt;</span>body <span style="color: #66cc66;">&gt;&lt;</span>h2 <span style="color: #66cc66;">&gt;</span>
    Here we go again<span style="color: #66cc66;">!&lt;/</span>h2<span style="color: #66cc66;">&gt;&lt;/</span>body<span style="color: #66cc66;">&gt;&lt;/</span>html<span style="color: #66cc66;">&gt;</span></pre></div></div>


<p>This certainly reads better if you are used to Lua, but the magic involved needs some explanation. You may imagine that Orbit has introduced a whole bunch of little functions into the module, but this is not how it is done.  Instead, <strong>orbit.htmlify</strong> modifies the environment of the function <strong>generate</strong> so that any undefined variable is assumed to be a HTML tag and becomes a suitable function. So you can generate anything, even with unknown tags. So if <strong>generate</strong> was:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span> generate<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> sensors <span style="color: #66cc66;">&#123;</span>
            sensor <span style="color: #66cc66;">&#123;</span>name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;one&quot;</span><span style="color: #66cc66;">&#125;</span>,
            sensor <span style="color: #66cc66;">&#123;</span>name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;two&quot;</span><span style="color: #66cc66;">&#125;</span>,
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>Then the result would be this syntactically valid XML:</p>

<pre><code>&lt;sensors &gt;&lt;sensor name="one"&gt;&lt;/sensor&gt;
&lt;sensor name="two"&gt;&lt;/sensor&gt;&lt;/sensors&gt;
</code></pre>

<p>In presenting the resulting markup I&#8217;ve inserted a few line breaks for making reading a bit easier.  Naturally you might like to <a href="http://n2.nabble.com/Orbit-htmlify-beautification-tc3889818.html#a3889818">beautify</a> the output for debugging purposes; web browsers do not care. <a href="http://infohound.net/tidy/">HTML Tidy</a> is another option. which will also give you a host of other diagnostic checks.</p>

<p>One problem to watch out for is that a mistyped tag name will give you odd HTML, not a Lua error. And there are some HTML tags which are valid Lua globals, such as <strong>table</strong> &#8211; the solution is to say <strong>H(&#8216;table&#8217;)</strong>, etc.  But HTML can now be generated without making your eyes bleed, as with the ugly web variables script. This little snippet uses the fact that tag functions take table arguments:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span> generate <span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">local</span> list <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
        <span style="color: #b1b100;">for</span> name,value <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span><span style="color: #66cc66;">&#40;</span>web.GET<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
            <span style="color: #b1b100;">table.insert</span><span style="color: #66cc66;">&#40;</span>list,li<span style="color: #66cc66;">&#40;</span>name..<span style="color: #ff0000;">&quot; = &quot;</span>..value<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">end</span>
        <span style="color: #b1b100;">return</span> ul<span style="color: #66cc66;">&#40;</span>list<span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>Any technique can produce over-elaborate code, as this program which generates an HTML form formatted with a table:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">require</span><span style="color: #ff0000;">&quot;orbit&quot;</span>
&nbsp;
    <span style="color: #b1b100;">function</span> wrap <span style="color: #66cc66;">&#40;</span>inner<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> html<span style="color: #66cc66;">&#123;</span> head<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, body<span style="color: #66cc66;">&#40;</span>inner<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    <span style="color: #b1b100;">function</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> wrap<span style="color: #66cc66;">&#40;</span>form <span style="color: #66cc66;">&#40;</span>H<span style="color: #ff0000;">'table'</span> <span style="color: #66cc66;">&#123;</span>
            tr<span style="color: #66cc66;">&#123;</span>td<span style="color: #ff0000;">&quot;First name&quot;</span>,td<span style="color: #66cc66;">&#40;</span> input<span style="color: #66cc66;">&#123;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'text'</span>, name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'first'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span>,
            tr<span style="color: #66cc66;">&#123;</span>td<span style="color: #ff0000;">&quot;Second name&quot;</span>,td<span style="color: #66cc66;">&#40;</span>input<span style="color: #66cc66;">&#123;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'text'</span>, name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'second'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span>,
            tr<span style="color: #66cc66;">&#123;</span> td<span style="color: #66cc66;">&#40;</span>input<span style="color: #66cc66;">&#123;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'submit'</span>, value<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Submit!'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>,
                td<span style="color: #66cc66;">&#40;</span>input<span style="color: #66cc66;">&#123;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'submit'</span>,value<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Cancel'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#125;</span>,
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
&nbsp;
    orbit.htmlify<span style="color: #66cc66;">&#40;</span>wrap,test<span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span>test<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Not quite eye-bleeding, but getting there!  The solution is to capture common patterns in a library. The <strong>util</strong> module in the <strong>basic</strong> folder makes for much more readable code:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span> show_form <span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> wrap<span style="color: #66cc66;">&#40;</span>form <span style="color: #66cc66;">&#123;</span>
            htable <span style="color: #66cc66;">&#123;</span>
                <span style="color: #66cc66;">&#123;</span>text<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;First name&quot;</span>,<span style="color: #ff0000;">'first'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span>,
                <span style="color: #66cc66;">&#123;</span>text<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Second name&quot;</span>,<span style="color: #ff0000;">'second'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span>,
                <span style="color: #66cc66;">&#123;</span>submit <span style="color: #ff0000;">'Submit'</span>, submit <span style="color: #ff0000;">'Cancel'</span><span style="color: #66cc66;">&#125;</span>,
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<h2>Databases the Orbit Way</h2>

<p>Orbit can create an Object-Relational Mapping (ORM) between the tables of a relational database and Lua tables. The restriction is that the SQL table is required to have a numeric key called <strong>id</strong>. In the following discussion, we must switch between two very different meanings of the word <strong>table</strong>, so I&#8217;ll use &#8216;array&#8217; to mean &#8216;an array-like Lua table&#8217; and &#8216;map&#8217; to mean &#8216;a hash-like Lua table&#8217;.</p>

<p>Consider the following SQL table definition found in the <strong>blog</strong> example database:</p>

<pre><code>CREATE TABLE blog_post
       ("id" INTEGER PRIMARY KEY NOT NULL,
       "title" VARCHAR(255) DEFAULT NULL,
       "body" TEXT DEFAULT NULL,
       "n_comments" INTEGER DEFAULT NULL,
       "published_at" DATETIME DEFAULT NULL);
</code></pre>

<p>This code uses LuaSQL&#8217;s sqlite3 driver to dump out a particular row of this table by defining a mapper:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">-- ORM1.lua</span>
    <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">&quot;orbit&quot;</span>
    <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">&quot;luasql.sqlite3&quot;</span>
    <span style="color: #b1b100;">local</span> env <span style="color: #66cc66;">=</span> luasql.sqlite3<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">function</span> dump <span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">if</span> #t <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #b1b100;">then</span>
            <span style="color: #b1b100;">for</span> _,row <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">ipairs</span><span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
                dump<span style="color: #66cc66;">&#40;</span>row<span style="color: #66cc66;">&#41;</span>
            <span style="color: #b1b100;">end</span>
        <span style="color: #b1b100;">else</span>
            <span style="color: #b1b100;">for</span> field,value <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span><span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
                <span style="color: #b1b100;">if</span> <span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>value<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">'string'</span> <span style="color: #b1b100;">then</span>
                    value <span style="color: #66cc66;">=</span> value:sub<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">60</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #b1b100;">end</span>
                <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span>field,<span style="color: #b1b100;">type</span><span style="color: #66cc66;">&#40;</span>value<span style="color: #66cc66;">&#41;</span>,value<span style="color: #66cc66;">&#41;</span>
            <span style="color: #b1b100;">end</span>
            <span style="color: #b1b100;">print</span> <span style="color: #ff0000;">'-----'</span>
        <span style="color: #b1b100;">end</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    mapper <span style="color: #66cc66;">=</span> orbit.model.new<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    mapper.conn <span style="color: #66cc66;">=</span> env:connect<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;../blog/blog.db&quot;</span><span style="color: #66cc66;">&#41;</span>
    mapper.driver <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;sqlite3&quot;</span>
    mapper.table_prefix <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'blog_'</span>
&nbsp;
    posts <span style="color: #66cc66;">=</span> mapper:new <span style="color: #ff0000;">'post'</span>  <span style="color: #808080; font-style: italic;">-- maps to blog_post table</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">-- print out the second post</span>
    second <span style="color: #66cc66;">=</span> posts:find<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    dump<span style="color: #66cc66;">&#40;</span>second<span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #66cc66;">==&gt;</span>
    published_at	number	<span style="color: #cc66cc;">1096923480</span>
    title	<span style="color: #b1b100;">string</span>	The Care And Feeding Of Your Sleeping Bicycle
    id	number	<span style="color: #cc66cc;">2</span>
    n_comments	number	<span style="color: #cc66cc;">0</span>
    body	<span style="color: #b1b100;">string</span>
    Thunder, thunder, thundercats, Ho<span style="color: #66cc66;">!</span> Thundercats are on the m
    <span style="color: #808080; font-style: italic;">-----</span></pre></div></div>


<p><strong>posts:find(2)</strong> gets the database row with <strong>id</strong> equal to 2 and returns a map with corresponding fields and values.</p>

<p>SQL is a more strongly-typed language than Lua, so that both <strong>published_at</strong> and <strong>n_comments</strong> are mapped to the <strong>number</strong> type. However, the mapper does preserve this information in its field <strong>meta</strong>; for instance, <strong>mapper.meta.published_at.type</strong> is &#8216;datetime&#8217;.</p>

<p>Orbit&#8217;s ORM mappers simplify database access by bridging the gap between the underlying database and the language; the most involved code here is just to dump out Lua maps and arrays.</p>

<p>As always, the interactive prompt is the best way to explore the available mapper methods:</p>

<pre><code>C:\basic&gt;lua -lmapper
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
&gt; posts = mapper:new 'post'
&gt; dump(posts:find_first('n_comments &gt; 0'))
published_at    number  1097769720
title   string  'Star Wars' As Written By A Princess
id      number  4
n_comments      number  1
body    string
Ten years ago a crack commando unit was sent to prison by a
-----
</code></pre>

<p><strong>find_first</strong> also returns a row, but by an explicit condition; <strong>find_all</strong> is similar, but returns an array of all matching rows. Note that the condition is a SQL expression, not Lua; this is effectively a more friendly way to create an SQL query:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    dump<span style="color: #66cc66;">&#40;</span>posts:find_all<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;id = ? or id = ?&quot;</span>,
        <span style="color: #66cc66;">&#123;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">4</span>,order <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;published_at asc&quot;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>ORM mapping works particularly nicely with dynamic languages, but there are some downsides.  consider the case that the table <strong>blog_post</strong> had many thousands of rows; the default mapper will grab all the columns, including the potentially rather large <strong>body</strong>. So opportunities for optimizing queries are lost, if we were only interested in searching the title for a match. It&#8217;s possible to reorganize things so that <strong>blog_post</strong> only contained &#8216;meta&#8217; data about each post (plus perhaps a short summary) and a new table <strong>blog_text</strong> would contain the actual text of each post, indexable using the same id.</p>

<h2>Putting it Together</h2>

<p>The next example will bring together these three concerns: request pattern matching (Controller), ORM mapping to a database (Model) and Orbit htmlification (View). It uses the database from the blog example but presents it in summary form.  For each row, it puts out a nicely formatted summary.  The actual rows are selected by a user set of keywords.</p>

<p>All our HTML-generating functions begin with &#8216;render_&#8217;. <strong>orbit.htmlify</strong> can be called in another way, where you give the module first, and then specify a string pattern to match the functions in the module that you want to htmlify.</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">	orbit.htmlify<span style="color: #66cc66;">&#40;</span>blog1,<span style="color: #ff0000;">'render_.+'</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Initially, the actual model-controller part of the application is simply this:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span> index<span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">return</span> render_index<span style="color: #66cc66;">&#40;</span>posts:find_all<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    blog1:dispatch_get<span style="color: #66cc66;">&#40;</span>index, <span style="color: #ff0000;">&quot;/&quot;</span>, <span style="color: #ff0000;">&quot;/index&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>And the view part:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">function</span> limit <span style="color: #66cc66;">&#40;</span>s,maxlen<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">if</span> #s <span style="color: #66cc66;">&gt;</span> maxlen <span style="color: #b1b100;">then</span>
            <span style="color: #b1b100;">return</span> s:sub<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>,maxlen<span style="color: #66cc66;">&#41;</span>..<span style="color: #ff0000;">'...'</span>
        <span style="color: #b1b100;">else</span>
            <span style="color: #b1b100;">return</span> s
        <span style="color: #b1b100;">end</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    <span style="color: #b1b100;">function</span> render_page<span style="color: #66cc66;">&#40;</span>contents<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> html <span style="color: #66cc66;">&#123;</span>
            head <span style="color: #66cc66;">&#123;</span> title <span style="color: #ff0000;">'Blog Example'</span> <span style="color: #66cc66;">&#125;</span>,
            body <span style="color: #66cc66;">&#40;</span>contents<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    <span style="color: #b1b100;">function</span> render_post<span style="color: #66cc66;">&#40;</span>post<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">return</span> div <span style="color: #66cc66;">&#123;</span>
            h3 <span style="color: #66cc66;">&#40;</span>post.id .. <span style="color: #ff0000;">' '</span> .. post.title<span style="color: #66cc66;">&#41;</span>,
            p <span style="color: #66cc66;">&#40;</span>limit<span style="color: #66cc66;">&#40;</span>post.body,<span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>,
            em<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">os.date</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'%a %b %d %H:%M %Y'</span>,post.published_at<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>,
            <span style="color: #ff0000;">' '</span>,post.n_comments,<span style="color: #ff0000;">' comments'</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    <span style="color: #b1b100;">function</span> render_index<span style="color: #66cc66;">&#40;</span>posts<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">local</span> res <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
        <span style="color: #b1b100;">for</span> i,post <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">ipairs</span><span style="color: #66cc66;">&#40;</span>posts<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
            res<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> render_post<span style="color: #66cc66;">&#40;</span>post<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">end</span>
        <span style="color: #b1b100;">return</span> render_page<span style="color: #66cc66;">&#40;</span>res<span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>The heart of the view is <strong>render_post</strong>, which formats each row from the model. You will only achieve date formatting happiness once you have learned the formating characters for <strong>os.date</strong>; these are the same as those used in the C <a href="http://msdn.microsoft.com/en-us/library/fe06s4ak%28VS.80%29.aspx">strftime</a> function.</p>

<p>All in all, not bad for a 55-line program. The next step is to add simple keyword searching, which takes an extra line:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span> index<span style="color: #66cc66;">&#40;</span>web<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">local</span> keyword <span style="color: #66cc66;">=</span> web.GET.keyword <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">''</span>
      <span style="color: #b1b100;">if</span> keyword <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">''</span> <span style="color: #b1b100;">then</span> <span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
      <span style="color: #b1b100;">else</span>
        <span style="color: #b1b100;">return</span> render_index<span style="color: #66cc66;">&#40;</span>posts:find_all<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'title like ?'</span>,<span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">'%'</span>..keyword..<span style="color: #ff0000;">'%'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">end</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>The SQL <strong>like</strong> operator works with patterns, so that finding a title containing the word &#8216;Chicken&#8217; would be &#8220;title like &#8216;%Chicken%&#8217;&#8221;, where &#8216;%&#8217; means &#8216;any sequence of characters&#8217;.  The keyword is passed as a GET request variable: enter the following URL to see the results of the search: <strong>http://localhost:8080/?keyword=Chicken</strong>.</p>

<p>It would be useful to have <em>some</em> user interface, especially when we start passing multiple keywords.  <strong>render_index</strong> becomes:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    <span style="color: #b1b100;">function</span> render_index<span style="color: #66cc66;">&#40;</span>posts<span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">local</span> res <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
        append<span style="color: #66cc66;">&#40;</span>res,p <span style="color: #66cc66;">&#40;</span>form <span style="color: #66cc66;">&#123;</span>
            input <span style="color: #66cc66;">&#123;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'text'</span>,name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'keyword'</span><span style="color: #66cc66;">&#125;</span>,
            input <span style="color: #66cc66;">&#123;</span><span style="color: #b1b100;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'submit'</span>,value<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Submit'</span><span style="color: #66cc66;">&#125;</span>,
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        append<span style="color: #66cc66;">&#40;</span>res,hr<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        append<span style="color: #66cc66;">&#40;</span>res,h2<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Found %d posts'</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span>#posts<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">for</span> _,post <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">ipairs</span><span style="color: #66cc66;">&#40;</span>posts<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
            append<span style="color: #66cc66;">&#40;</span>res,render_post<span style="color: #66cc66;">&#40;</span>post<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">end</span>
        <span style="color: #b1b100;">return</span> render_page<span style="color: #66cc66;">&#40;</span>res<span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">end</span></pre></div></div>


<p>By default, HTML forms submit their values to the same URL as the page, so this works fine.</p>

<p>This introduction was intended to help you begin reading the Orbit samples, documentation and tutorials. In the next in this series, we will discuss building more complicated applications, caching generated pages, and Orbit Pages, which is a powerful Lua-powered template engine for generating HTML.</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/orbit1-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sputnik: An Introduction I</title>
		<link>http://luanova.org/sputnik/</link>
		<comments>http://luanova.org/sputnik/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 06:08:07 +0000</pubDate>
		<dc:creator>stevejdonovan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[web frameworks]]></category>
		<category><![CDATA[Wiki]]></category>

		<guid isPermaLink="false">http://luanova.org/?p=21</guid>
		<description><![CDATA[Beyond WikiWiki Sputnik is a second-generation extensible wiki engine written in Lua. First generation wikis (like the original WikiWIki) opened our eyes to the possibility of easy collaborative content generation, with automatic revision control. However, anybody who has been involved with a Wiki knows that they are not self-organizing, and so behind any Wiki is [...]]]></description>
			<content:encoded><![CDATA[<h2>Beyond WikiWiki</h2>

<p><a href="http://sputnik.freewisdom.org/">Sputnik</a> is a second-generation extensible wiki engine written in Lua. First generation wikis (like the original <a href="http://c2.com/cgi/wiki">WikiWIki</a>) opened our eyes to the possibility of easy collaborative content generation, with automatic revision control.  However, anybody who has been involved with a Wiki knows that they are not self-organizing, and so behind any Wiki is a core of busy elves correcting and &#8216;refactoring&#8217; content.  Plus, all content is usually in the form of marked-up text, plus uploaded binary data like images.  For instance,  Wiki pages often turn into discussions, but there is usually no way to structure these discussions and no support for creating them.</p>

<p>A second-generation wiki allows for &#8216;virtual&#8217; pages, pages with explicit data fields, structured discussions, complete control of permissions, and namespace management.  The site designer can choose the right balance between freedom and structure that is appropriate for the community and its common purpose.</p>

<h2>Frameworks and Libraries</h2>

<p>There are two basic approaches to software development; either start small, pulling as much functionality in using libraries, or to start with a framework, which does most of the job, and customize it to fit your functionality.  Frameworks have a bad <a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12">reputation</a> because framework developers can get just a little mad in the process of writing them.  But if you want something that can do wiki-like things, manage the content and control the revisions, handle authentication, then it&#8217;s time to get a Wiki framework, because these are not easy applications to get right. As the <a href="http://gitorious.org/sputnik?page=4">Sputnik git page</a> says, &#8220;Sputnik provides a good foundation for anything that&#8217;s kind of like a wiki but not quite.&#8221;</p>

<p>It is true that the first trade-off is the freedom to do things <em>your</em> way, since you must learn how the framework does things, and cooperate with it. In a way, it is like collaboration with another developer on a project which you have just joined.  I am assuming here that you want to get something done, which is not a million miles from a Wiki, and don&#8217;t want to rewrite a whole bunch of wheels, just maybe update the hubcaps.  A better analogy would be this: if you want to equip a kitchen, then using a framework that includes the kitchen sink is appropriate (and not just a joke). Maybe you just want different fittings for your kitchen sink.</p>

<h2>Getting Sputnik</h2>

<p><a href="http://sputnik.freewisdom.org/en/Installation">Installing Sputnik</a> is straightforward, providing you are on a Unix-like platform (like Linux or OS X) although it does also run on Windows.  In this introduction, I assume that it is an Unix environment (although out of convenience, not religious fervour; it is very easy to get a Linux virtual machine and set it up for Sputnik testing.)   After following instructions, you will have a Sputnik install in <strong>~/sputnik</strong>, no special permissions necessary.  Starting the webserver is then just:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  ~<span style="color: #000000; font-weight: bold;">/</span>sputnik$ .<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>sputnik.lua start-xavante sputnik.ws</pre></div></div>


<p>Sputnik comes with the <a href="http://www.keplerproject.org">Kepler stack</a>, including the Lua webserver Xavante.  This is quite good enough for testing and experimentation.</p>

<p>A useful change is to first edit <strong>sputnik.ws</strong> and set <strong>BASE_URL</strong> to &#8216;/&#8217; and to add <strong>SHOW_STACK_TRACE = true</strong>. Sputnik will then give you Lua error traces when some hitch occurs. Then just open <strong>http://localhost:8080</strong> in your favourite browser and start playing. Create a special user <strong>Admin</strong> to view and edit the configuration nodes.</p>

<p>All Sputnik configuration is via nodes with Lua content. For instance, <strong>sputnik/config</strong>  assigns a set of fields to values. If you are editing this file (as Admin) and make a syntax error (such as <strong>&#8216;Sputnik&#8221;</strong>, mismatching string delimiters) the edit field will turn pink. <strong>sputnik/navigation</strong> controls the navigation bar menu:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  NAVIGATION <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
     <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;index&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Start&quot;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;snippets&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Snippets&quot;</span><span style="color: #66cc66;">&#125;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tags&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Tags&quot;</span><span style="color: #66cc66;">&#125;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;sputnik&quot;</span>,title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Configure&quot;</span><span style="color: #66cc66;">&#125;</span>,
     <span style="color: #66cc66;">&#125;</span>,
     <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;News&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Timeline&quot;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;News&quot;</span><span style="color: #66cc66;">&#125;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Future Plans&quot;</span><span style="color: #66cc66;">&#125;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;history&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Recent Wiki Edits&quot;</span><span style="color: #66cc66;">&#125;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;history/edits_by_recent_users&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Edits by Recent Users&quot;</span><span style="color: #66cc66;">&#125;</span>,
       <span style="color: #66cc66;">&#123;</span>id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;history.rss&quot;</span>, title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;RSS Feed&quot;</span><span style="color: #66cc66;">&#125;</span>,
     <span style="color: #66cc66;">&#125;</span>,
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>Creating a new node is easy; if you ask for a node <strong>test</strong> then it will tell you that this node does not exist, but then will give you several types to choose from.  The &#8216;Basic&#8217; type is a plain Wiki page, and the link provided is something like <strong>http://localhost:8080/?p=test.edit&amp;prototype=</strong>.  In general, a Sputnik request has a <em>node id</em> (&#8216;test&#8217;), an <em>action</em> (&#8216;edit&#8217;) and <em>parameters</em> (&#8216;prototype=&#8217;)</p>

<p>If you click on this link you can edit your new Wiki node.  The markup used is <a href="http://daringfireball.net/projects/markdown/">Markdown</a> which has a clean, readable syntax. In addition, Sputnik supports Wiki links; a link to your new page would be <strong>[[test]]</strong> and a link with some text would be <strong>[[test|My First Page]]</strong> . There is a convenient toolbar providing the most common operations when editing.</p>

<h2>Customizing Sputnik</h2>

<p>A lot can be done with basic Sputnik, just by editing the configuration nodes.  (And, yes, the configuration nodes are Wiki nodes, so you can revert to an earlier version.)  Also, like any modern Web framework, style and functionality are kept separate as CSS and HTML; these <a href="http://sputnik.freewisdom.org/en/Sightings">Sputnik sites</a> show that you can get just about any look and feel.</p>

<p>Since the configuration is done with Lua data, it <em>technically</em> involves programming, but not in any serious sense of the word.  Lua is particularly well-suited to expressing configuration, since it was originally conceived as a data-description language.  This data is converted into Lua table structures using Lua itself, using a <a href="http://lua-users.org/wiki/SandBoxes">sandbox</a> so that it will not execute any dangerous stuff.</p>

<p>The first &#8216;real&#8217; customization we will do is make a whole set of pages default to a particular node type. That is, any node like <strong>pages/GeneralInfo</strong> or <strong>pages/Introduction</strong> will be created as &#8216;Basic&#8217; nodes.</p>

<p>If Sputnik cannot find a node, it will first attempt to find a <em>node default</em> with that name.  The request for &#8216;pages&#8217; results in Sputnik attempting to load a Lua module like so: <strong>require &#8220;sputnik.node_defaults.pages&#8221;</strong>. So we have to create a file <strong>pages.lua</strong> in a directory so that Sputnik can resolve this module.</p>

<p>Sputnik itself is distributed as a <a href="www.luarocks.org">LuaRocks</a> application. In my system, the Sputnik package sits at <strong>~/sputnik/rocks/sputnik/9.03.16-0/lua</strong> &#8211; call this <strong>$SPUTNIK</strong>.  The relevant package directory structure is:</p>

<pre><code>    sputnik
        actions
        hooks
        node_defaults
        ....
</code></pre>

<p>It <em>is</em> possible to customize Sputnik by putting a suitable <strong>pages.lua</strong> in <strong>$SPUTNIK/sputnik/node_defaults</strong>, but that is a road of misery that will end in tears.  However, it&#8217;s useful to acquaint yourself with the contents of this directory because it defines the standard namespaces.</p>

<p>The best quick solution is to add directories to the <strong>LUA_PATH</strong> environment variable before launching Sputnik:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  ~<span style="color: #000000; font-weight: bold;">/</span>sputnik$ <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LUA_PATH</span>=<span style="color: #ff0000;">&quot;;;<span style="color: #007800;">$HOME</span>/sputnik/examples/?.lua&quot;</span></pre></div></div>


<p>Then create a directory <strong>~/sputnik/examples/sputnik/node_defaults</strong> containing this file, <strong>pages.lua</strong>:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  NODE <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
     title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Pages&quot;</span>,
     content <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
     child_defaults <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          any<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'prototype = &quot;&quot;'</span>
      <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>It is structured as a Lua module, which contains a single exported table, <strong>NODE</strong> .  The definition of the field <strong>child_defaults</strong> may appear a little hairy at first, but it&#8217;s now time to get the three different ways to do string literals in Lua straight.  Whether you use single or double quotes for a string, does not matter; it is a convenience so that you can embed the other kind of quotes: <strong>&#8216;prototype = &#8220;&#8221;&#8216;</strong>. This string is then further embedded in a Lua &#8216;long string&#8217; literal.</p>

<p>After restarting Sputnik, go to <strong>pages</strong>: nothing much to see at this point &#8211; but note that Sputnik can find the node. If you go to <strong>pages/Introduction</strong> you will get another blank page with a title, which you can edit directly as a Wiki page.  The <strong>child_defaults</strong> field tells Sputnik that any &#8216;child&#8217; of <strong>pages</strong> like <strong>pages/Introduction</strong> has a particular prototype value which corresponds to the &#8216;Basic&#8217; node type.</p>

<p>If you enter this text</p>

<pre><code>    Some text for the Introduction node. See [[pages/Basic]]
</code></pre>

<p>and save, the result will have a link to a new page, which you can in turn edit.</p>

<p>To see how Sputnik saves pages by default, look at the <strong>~/sputnik/wiki-data</strong> directory. There will be a subdirectory <strong>pages%2FIntroduction</strong> with files <strong>000001</strong> and <strong>index</strong>. (The subdirectory is just the URL-encoded form of &#8216;pages/Introduction&#8217; ).  <strong>index</strong> will contain something like this:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  add_version<span style="color: #66cc66;">&#123;</span>
  version   <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;000001&quot;</span>,
  timestamp <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;2009-11-01 14:33:07&quot;</span>,
  author    <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
  comment   <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
   <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;minor&quot;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
   <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;ip&quot;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;127.0.0.1&quot;</span>,
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>And <strong>000001</strong> contains the node text:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  title          <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;pages/Introduction&quot;</span>
  category       <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>
  content        <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span>Some text <span style="color: #b1b100;">for</span> the Introduction node. See <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>pages<span style="color: #66cc66;">/</span>Basic<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#93;</span>
  breadcrumb     <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span></pre></div></div>


<p>As the node is edited, each revision is saved in a similar format, <strong>000002</strong>, etc.  In this way, edit history is managed in a simple way, easily readable by humans, as opposed to being stored in some relational database. However, using a database for storage is also supported by the Sputnik content manager, which is called <a href="http://sputnik.freewisdom.org/en/Saci">Saci</a>.</p>

<h2>Custom Output</h2>

<p>Before actually starting with code, it&#8217;s useful to have a handy shortcut to the Lua executable used by Sputnik.  I suggest creating a little executable script like this on your path:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  $<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">cat</span> ~<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>slua
  ~<span style="color: #000000; font-weight: bold;">/</span>sputnik<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>lua -lluarocks.require <span style="color: #007800;">$*</span></pre></div></div>


<p>Before we actually get round to generating dynamic content, here is a quick review of <a href="http://cosmo.luaforge.net/">Cosmo</a>,  which is a powerful template engine used by Sputnik.</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  ~$ slua</pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  Lua 5.1.4  Copyright <span style="color: #66cc66;">&#40;</span>C<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">1994</span>-<span style="color: #cc66cc;">2008</span> Lua.org, PUC-Rio
  <span style="color: #66cc66;">&gt;</span> <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">&quot;cosmo&quot;</span>
  <span style="color: #66cc66;">&gt;</span> template <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;$rank of $suit&quot;</span>
  <span style="color: #66cc66;">&gt;</span> values <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>rank<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Ace&quot;</span>,suit<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Spades&quot;</span><span style="color: #66cc66;">&#125;</span>
  <span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> cosmo.fill<span style="color: #66cc66;">&#40;</span>template,values<span style="color: #66cc66;">&#41;</span>
  Ace of Spades</pre></div></div>


<p>That&#8217;s useful, although only a little more friendly than Lua&#8217;s <strong>string.format</strong> function.  However, Cosmo goes way beyond simple <a href="http://lua-users.org/wiki/StringInterpolation">string interpolation</a>.</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  <span style="color: #808080; font-style: italic;">-- testcosmo.lua</span>
  <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">&quot;cosmo&quot;</span>
  template <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">==</span><span style="color: #66cc66;">&#91;</span>
  <span style="color: #66cc66;">&lt;</span>h1<span style="color: #66cc66;">&gt;</span>$list_name<span style="color: #66cc66;">&lt;/</span>h1<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>ul<span style="color: #66cc66;">&gt;</span>
   $do_items<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&lt;</span>li<span style="color: #66cc66;">&gt;</span>$item<span style="color: #66cc66;">&lt;/</span>li<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&lt;/</span>ul<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">==</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
  <span style="color: #b1b100;">print</span><span style="color: #66cc66;">&#40;</span>cosmo.fill<span style="color: #66cc66;">&#40;</span>template, <span style="color: #66cc66;">&#123;</span>
      list_name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;My List&quot;</span>,
      do_items  <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #b1b100;">for</span> i<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">5</span> <span style="color: #b1b100;">do</span>
             cosmo.yield <span style="color: #66cc66;">&#123;</span> item <span style="color: #66cc66;">=</span> i <span style="color: #66cc66;">&#125;</span>
          <span style="color: #b1b100;">end</span>
      <span style="color: #b1b100;">end</span>
  <span style="color: #66cc66;">&#125;</span>
  <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  ~$ slua testcosmo.lua</pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;h1&gt;My List&lt;/h1&gt;
  &lt;ul&gt;
   &lt;li&gt;1&lt;/li&gt;&lt;li&gt;2&lt;/li&gt;&lt;li&gt;3&lt;/li&gt;&lt;li&gt;4&lt;/li&gt;&lt;li&gt;5&lt;/li&gt;
  &lt;/ul&gt;</pre></div></div>


<p><em>Subtemplates</em> are a powerful feature which makes generating HTML straightforward.</p>

<p>Now, we create a node which creates custom HTML output.  First, put <strong>Memory.lua</strong> in your  <strong>node_defaults</strong> directory:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  NODE <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
      title <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Lua Memory&quot;</span>,
      content <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
      actions <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          show<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Memory.show_memory&quot;</span>
      <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>Create a directory <strong>actions</strong> (that is, <strong>~/sputnik/examples/sputnik/actions</strong>) and put this <strong>Memory.lua</strong> in it:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  actions <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">local</span> template <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span>
     <span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Memory used by Lua is $mem kb<span style="color: #66cc66;">&lt;/</span>h2<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
  <span style="color: #b1b100;">function</span> actions.show_memory <span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
      node.inner_html <span style="color: #66cc66;">=</span> cosmo.f<span style="color: #66cc66;">&#40;</span>template<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
          mem <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'%6.0f'</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">collectgarbage</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'count'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>,
      <span style="color: #66cc66;">&#125;</span>
      <span style="color: #b1b100;">return</span> node.wrappers.default<span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span></pre></div></div>


<p>The convention is that any <em>action</em> functions are in the <strong>actions</strong> directory; these functions must be in a nested <strong>actions</strong> table.  Visiting the node <strong>Memory</strong> will show the memory managed by Lua (as returned by the <strong>collectgarbage(&#8216;count&#8217;)</strong> call).</p>

<p>The node&#8217;s <strong>inner_html</strong> is the source for the node&#8217;s display area, that is, not including the menu and all other frame decorations.  <strong>node.wrappers.default</strong> is the actual function which generates the source for the <em>whole</em> page.</p>

<p>So, we now have a customized node with generated output.  Please note that it does not appear in <strong>wiki-data</strong>; the node is fully &#8216;virtual&#8217; and has no storage associated with it.</p>

<p>To take this example further, let us wrap the output of the <strong>ps</strong> command:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  ~$ <span style="color: #c20cb9; font-weight: bold;">ps</span> aux <span style="color: #660033;">--cols</span> <span style="color: #000000;">256</span>
  USER       PID <span style="color: #000000; font-weight: bold;">%</span>CPU <span style="color: #000000; font-weight: bold;">%</span>MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  ...
  sdonovan  <span style="color: #000000;">2867</span>  <span style="color: #000000;">0.8</span>  <span style="color: #000000;">2.3</span>  <span style="color: #000000;">41972</span> <span style="color: #000000;">15932</span> pts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1</span>    Sl   <span style="color: #000000;">10</span>:<span style="color: #000000;">47</span>   <span style="color: #000000;">3</span>:<span style="color: #000000;">57</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>sdonovan<span style="color: #000000; font-weight: bold;">/</span>lua<span style="color: #000000; font-weight: bold;">/</span>scite<span style="color: #000000; font-weight: bold;">/</span>SciTE
  sdonovan  <span style="color: #000000;">2902</span>  <span style="color: #000000;">1.2</span> <span style="color: #000000;">12.4</span> <span style="color: #000000;">179152</span> <span style="color: #000000;">83160</span> ?        Sl   <span style="color: #000000;">10</span>:<span style="color: #000000;">48</span>   <span style="color: #000000;">5</span>:<span style="color: #000000;">19</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>iceweasel<span style="color: #000000; font-weight: bold;">/</span>firefox-bin <span style="color: #660033;">-a</span> firefox
  sdonovan  <span style="color: #000000;">5993</span>  <span style="color: #000000;">0.0</span>  <span style="color: #000000;">0.4</span>   <span style="color: #000000;">5360</span>  <span style="color: #000000;">2844</span> pts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>    Ss   <span style="color: #000000;">16</span>:<span style="color: #000000;">13</span>   <span style="color: #000000;">0</span>:00 <span style="color: #c20cb9; font-weight: bold;">bash</span>
  sdonovan  <span style="color: #000000;">7118</span>  <span style="color: #000000;">0.0</span>  <span style="color: #000000;">0.3</span>   <span style="color: #000000;">5360</span>  <span style="color: #000000;">2024</span> pts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0</span>    S+   <span style="color: #000000;">18</span>:03   <span style="color: #000000;">0</span>:00 <span style="color: #c20cb9; font-weight: bold;">bash</span>
  sdonovan  <span style="color: #000000;">7119</span>  <span style="color: #000000;">0.4</span>  <span style="color: #000000;">1.1</span>   <span style="color: #000000;">8384</span>  <span style="color: #000000;">7380</span> pts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0</span>    S+   <span style="color: #000000;">18</span>:03   <span style="color: #000000;">0</span>:01 <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>sdonovan<span style="color: #000000; font-weight: bold;">/</span>sputnik<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>lua -lluarocks.require <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>sdonovan<span style="color: #000000; font-weight: bold;">/</span>sputnik<span style="color: #000000; font-weight: bold;">/</span>rocks<span style="color: #000000; font-weight: bold;">/</span>sputnik<span style="color: #000000; font-weight: bold;">/</span>9.03.16-<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>sputnik.lua start-xavante sputnik.ws</pre></div></div>


<p>(The <strong>&#8211;cols</strong> flag is necessary to prevent <strong>ps</strong> from thoughtfully truncating the line length to fit the terminal screen)</p>

<p>Chopping lines up is easy using <strong>sputnik.util.split</strong> &#8211; notice that it returns multiple values, not a table:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  ~$ slua</pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  Lua 5.1.4  Copyright <span style="color: #66cc66;">&#40;</span>C<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">1994</span>-<span style="color: #cc66cc;">2008</span> Lua.org, PUC-Rio
  <span style="color: #66cc66;">&gt;</span> util <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">'sputnik.util'</span>
  <span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">=</span> util.split<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'one two three'</span>,<span style="color: #ff0000;">'%s+'</span><span style="color: #66cc66;">&#41;</span>
  one     two     three</pre></div></div>


<p>With this, a more exciting version of <strong>actions/Memory.lua</strong> can be written:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">local</span> util <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">require</span> <span style="color: #ff0000;">'sputnik.util'</span>
  actions <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">local</span> template <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span>
     <span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Memory used by Lua is $mem kb<span style="color: #66cc66;">&lt;/</span>h2<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Processes<span style="color: #66cc66;">&lt;/</span>h2<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;</span>table<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;</span>tr<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>th<span style="color: #66cc66;">&gt;</span>User<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;&lt;</span>th<span style="color: #66cc66;">&gt;</span>CPU<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;&lt;</span>th<span style="color: #66cc66;">&gt;</span>Mem<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;&lt;</span>th<span style="color: #66cc66;">&gt;</span>Command<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;/</span>tr<span style="color: #66cc66;">&gt;</span>
     $do_processes<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          <span style="color: #66cc66;">&lt;</span>tr<span style="color: #66cc66;">&gt;</span>
          <span style="color: #66cc66;">&lt;</span>td<span style="color: #66cc66;">&gt;</span>$user<span style="color: #66cc66;">&lt;/</span>td<span style="color: #66cc66;">&gt;&lt;</span>td<span style="color: #66cc66;">&gt;</span>$cpu<span style="color: #66cc66;">&lt;/</span>td<span style="color: #66cc66;">&gt;&lt;</span>td<span style="color: #66cc66;">&gt;</span>$mem<span style="color: #66cc66;">&lt;/</span>td<span style="color: #66cc66;">&gt;&lt;</span>td<span style="color: #66cc66;">&gt;</span>$cmd<span style="color: #66cc66;">&lt;/</span>td<span style="color: #66cc66;">&gt;</span>
          <span style="color: #66cc66;">&lt;/</span>tr<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
     <span style="color: #66cc66;">&lt;/</span>table<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
  <span style="color: #b1b100;">function</span> actions.show_memory <span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
      node.inner_html <span style="color: #66cc66;">=</span> cosmo.f<span style="color: #66cc66;">&#40;</span>template<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
          mem <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'%6.0f'</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #b1b100;">format</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">collectgarbage</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'count'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>,
          do_processes <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">local</span> user <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">os.getenv</span> <span style="color: #ff0000;">'USER'</span>
              <span style="color: #808080; font-style: italic;">-- this works on LInux, may need some mods for BSD/OS X.</span>
              <span style="color: #b1b100;">local</span> f <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">io</span>.popen<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ps --cols 256 aux'</span>,<span style="color: #ff0000;">'r'</span><span style="color: #66cc66;">&#41;</span>
              f:<span style="color: #b1b100;">read</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">-- not interested in column headers</span>
              <span style="color: #b1b100;">for</span> line <span style="color: #b1b100;">in</span> f:lines<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
                  <span style="color: #b1b100;">local</span> fields <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>util.split<span style="color: #66cc66;">&#40;</span>line,<span style="color: #ff0000;">'%s+'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span>
                  <span style="color: #b1b100;">if</span> fields<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">==</span> user <span style="color: #b1b100;">then</span>
                      cosmo.yield <span style="color: #66cc66;">&#123;</span>
                          user <span style="color: #66cc66;">=</span> fields<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#93;</span>, cpu <span style="color: #66cc66;">=</span> fields<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#93;</span>, mem <span style="color: #66cc66;">=</span> fields<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#93;</span>, cmd <span style="color: #66cc66;">=</span> fields<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#93;</span>,
                      <span style="color: #66cc66;">&#125;</span>
                  <span style="color: #b1b100;">end</span>
              <span style="color: #b1b100;">end</span>
          <span style="color: #b1b100;">end</span>
      <span style="color: #66cc66;">&#125;</span>
      <span style="color: #b1b100;">return</span> node.wrappers.default<span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span></pre></div></div>


<p>Now the node <strong>Memory</strong> is actually useful for the administrator of the website &#8211; but probably not a good idea to expose to the world!</p>

<h2>Permissions</h2>

<p>The node <strong>Memory</strong> should be restricted; only the Admin user should be able to view it. Also, it does not make sense to edit it, even as an administrator.  <strong>actions/Memory.lua</strong> needs to have a <em>permissions</em> field:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  NODE <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
      title <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Lua Memory&quot;</span>,
      content <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
      actions <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          show<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Memory.show_memory&quot;</span>
      <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
      permissions <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          deny<span style="color: #66cc66;">&#40;</span>all_users,all_actions<span style="color: #66cc66;">&#41;</span>
          allow<span style="color: #66cc66;">&#40;</span>Admin,show<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>We start by prohibiting <em>everything</em>, and then only let Admin view the page.  Notice that all of the usual little action icons on the right-hand side have disappeared.</p>

<p>To get back to the <strong>pages</strong> example; we may insist that only authenticated users can edit the pages.  There are two kinds of solution to this, make it site-wide policy or only for children of <strong>pages</strong>.  The first solution requires no code; as Admin, go to the <strong>@Root</strong> node, and choose the &#8216;configure&#8217; action (which is usually the little gear icon next to &#8216;edit&#8217; on the actions toolbar)  Now open the &#8216;Advanced Fields&#8217; section, and you can then edit the &#8216;Permissions&#8217; field.  By default, Sputnik comments out this line:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  <span style="color: #808080; font-style: italic;">-- deny(Anonymous, edit_and_save)</span></pre></div></div>


<p>Remove the comment and save.  Now anonymous users have lost their power to make edits anywhere on the site.</p>

<p>We&#8217;ve already seen with <strong>Memory</strong> how to enforce permissions for a single node. But how to do this for a group of nodes?  Sputnik <em>prototypes</em> provide the solution.  A prototype acts as the &#8216;type&#8217; of a node. When a node is retrieved from storage, Sputnik copies default values from its prototype node.  The basic prototype of all nodes is <strong>@Root</strong>.</p>

<p>Previously, the <strong>pages</strong> node has insisted that its children have an &#8216;empty&#8217; prototype.  The idea is to create an explicit prototype that will apply to the children, which will be called <strong>@pages</strong>. (By convention, all prototypes begin with &#8216;@&#8217;)</p>

<p><strong>node_defaults/pages.lua</strong> becomes:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  NODE <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
     title<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Pages&quot;</span>,
     content <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
     child_defaults <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          any<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'prototype = &quot;@pages&quot;'</span>
      <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>and create a new file <strong>node_defaults/@pages.lua</strong> to define the <strong>@pages</strong> prototype:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  NODE <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
     content <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
     permissions<span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          deny<span style="color: #66cc66;">&#40;</span>Anonymous,edit_and_save<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>It does very little, just explicitly overrides the permissions.</p>

<h2>Hooks</h2>

<p>Continuing with the <strong>pages</strong> example, it would be useful if we could track the author of a particular page, defined simply as the user that first edited it.  Also, we would like to track the creation date.  So the prototype for all pages must include these new_fields and define a <em>save hook</em> which will be called when the node is saved:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  <span style="color: #808080; font-style: italic;">-- node_defaults/@pages.lua</span>
  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  NODE <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
     content <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>,
     permissions<span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          deny<span style="color: #66cc66;">&#40;</span>Anonymous,edit_and_save<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     fields <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
        author <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #cc66cc;">1.1</span><span style="color: #66cc66;">&#125;</span>
        creation_time <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #cc66cc;">1.2</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>,
     save_hook <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;pages.save_page&quot;</span>
  <span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>Create a directory &#8216;sputnik/hooks&#8217; as before, and put <strong>pages.lua</strong> in it:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  <span style="color: #808080; font-style: italic;">-- hooks/pages.lua</span>
  module<span style="color: #66cc66;">&#40;</span>..., package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  <span style="color: #b1b100;">function</span> save_page<span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #b1b100;">not</span> node.creation_time <span style="color: #b1b100;">then</span>
         <span style="color: #b1b100;">local</span> params <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
         params.author <span style="color: #66cc66;">=</span> request.user
         params.creation_time <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">tostring</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">os.time</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         node <span style="color: #66cc66;">=</span> sputnik:update_node_with_params<span style="color: #66cc66;">&#40;</span>node, params<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">end</span>
      <span style="color: #b1b100;">return</span> node
  <span style="color: #b1b100;">end</span></pre></div></div>


<p>When a node&#8217;s <strong>save_hook</strong> field is set to <strong>MODULE.FUNCTION</strong> , then Sputnik will try to load <strong>sputnik.hooks.MODULE</strong> and use the <strong>FUNCTION</strong> defined by that module.  In this case, the save hook is only interested in a new node, where the author and creation time fields have not been assigned yet.  It uses the <strong>update_node_with_params</strong> method to write the new key/value pairs into the node.</p>

<p>Now, after saving <strong>pages/fred</strong>, the revision in the <strong>pages%2Ffred</strong> directory will look like this:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  title          <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;pages/fred&quot;</span>
  category       <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>
  prototype      <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;@pages&quot;</span>
  content        <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>Some content<span style="color: #66cc66;">!</span>
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  breadcrumb     <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>
  author         <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;sdonovan&quot;</span>
  creation_time  <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;1257157113&quot;</span></pre></div></div>


<p>This shows that we are saving the new information, although these fields are not displayed yet.</p>

<h2>Wrapping up</h2>

<p>Currently, <strong>pages</strong> is blank, and like <strong>Memory</strong>  we can output something sensible by defining a &#8216;show&#8217; action that will display a table of the existing pages.</p>

<p>If you are accustomed to regular Web frameworks, you are probably tempted to maintain and use a relational database at this point.  Sputnik does not exclude that, you are free to store things as you wish, but it&#8217;s best to work with the underlying &#8216;document-oriented&#8217; database machinery provided by Saci.</p>

<p>The existing pages can be found by querying Saci, which provides a <strong>get_nodes_by_prefix</strong> method. The prefix identifies the <em>namespace</em> for the nodes, which is <strong>pages</strong> in this case. This method returns a table where the keys are the <em>identifiers</em> (e.g. <strong>pages/fred</strong>) and the values are the node objects. Here is code that creates a list of nodes from this table, and sorts it by creation time.</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">function</span> pages_in_order <span style="color: #66cc66;">&#40;</span>sputnik<span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">local</span> pages <span style="color: #66cc66;">=</span> sputnik.saci:get_nodes_by_prefix <span style="color: #ff0000;">'pages'</span>
      <span style="color: #b1b100;">local</span> res <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
      <span style="color: #b1b100;">for</span> id,page <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span><span style="color: #66cc66;">&#40;</span>pages<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
          res<span style="color: #66cc66;">&#91;</span>#res+<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> page
      <span style="color: #b1b100;">end</span>
      <span style="color: #b1b100;">table.sort</span><span style="color: #66cc66;">&#40;</span>res,<span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>p1,p2<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">return</span> p1.creation_time <span style="color: #66cc66;">&lt;</span> p2.creation_time <span style="color: #b1b100;">end</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">return</span> res
  <span style="color: #b1b100;">end</span></pre></div></div>


<p><strong>node_defaults/pages.lua</strong> gets an actions field, just as with <strong>node_defaults/Memory.lua</strong>:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  actions<span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
      show<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;pages.show_pages&quot;</span>
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>


<p>And <strong>actions/pages.lua</strong> will be:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">  module <span style="color: #66cc66;">&#40;</span>...,package.seeall<span style="color: #66cc66;">&#41;</span>
&nbsp;
  actions <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">local</span> template <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#91;</span>
     <span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Existing Pages<span style="color: #66cc66;">&lt;/</span>h2<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;</span>table<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;</span>tr<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>th<span style="color: #66cc66;">&gt;</span>Page<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;&lt;</span>th<span style="color: #66cc66;">&gt;</span>Author<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;&lt;</span>th<span style="color: #66cc66;">&gt;</span>Created<span style="color: #66cc66;">&lt;/</span>th<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&lt;/</span>tr<span style="color: #66cc66;">&gt;</span>
     $do_pages<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
          <span style="color: #66cc66;">&lt;</span>tr<span style="color: #66cc66;">&gt;</span>
          <span style="color: #66cc66;">&lt;</span>td<span style="color: #66cc66;">&gt;&lt;</span>a href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;?p=$id&quot;</span><span style="color: #66cc66;">&gt;</span>$name<span style="color: #66cc66;">&lt;/</span>a<span style="color: #66cc66;">&gt;&lt;/</span>td<span style="color: #66cc66;">&gt;&lt;</span>td<span style="color: #66cc66;">&gt;</span>$author<span style="color: #66cc66;">&lt;/</span>td<span style="color: #66cc66;">&gt;&lt;</span>td<span style="color: #66cc66;">&gt;</span>$created<span style="color: #66cc66;">&lt;/</span>td<span style="color: #66cc66;">&gt;</span>
          <span style="color: #66cc66;">&lt;/</span>tr<span style="color: #66cc66;">&gt;</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
     <span style="color: #66cc66;">&lt;/</span>table<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
  <span style="color: #b1b100;">local</span> <span style="color: #b1b100;">function</span> pages_in_order<span style="color: #66cc66;">&#40;</span>sputnik<span style="color: #66cc66;">&#41;</span>
  ....
  <span style="color: #b1b100;">end</span>
&nbsp;
  <span style="color: #b1b100;">function</span> actions.show_pages<span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
      node.inner_html <span style="color: #66cc66;">=</span> cosmo.f<span style="color: #66cc66;">&#40;</span>template<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
          do_pages <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">local</span> pages <span style="color: #66cc66;">=</span> pages_in_order<span style="color: #66cc66;">&#40;</span>sputnik<span style="color: #66cc66;">&#41;</span>
              <span style="color: #b1b100;">for</span> _,page <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">ipairs</span><span style="color: #66cc66;">&#40;</span>pages<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
                  cosmo.yield<span style="color: #66cc66;">&#123;</span>
                      id <span style="color: #66cc66;">=</span> page.id,
                      name <span style="color: #66cc66;">=</span> page.id:<span style="color: #b1b100;">gsub</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'pages/'</span>,<span style="color: #ff0000;">''</span><span style="color: #66cc66;">&#41;</span>,
                      author <span style="color: #66cc66;">=</span> page.author,
                      created <span style="color: #66cc66;">=</span> sputnik:format_time<span style="color: #66cc66;">&#40;</span>page.creation_time,<span style="color: #ff0000;">&quot;%d %b %Y&quot;</span><span style="color: #66cc66;">&#41;</span>
                  <span style="color: #66cc66;">&#125;</span>
              <span style="color: #b1b100;">end</span>
          <span style="color: #b1b100;">end</span>
      <span style="color: #66cc66;">&#125;</span>
      <span style="color: #b1b100;">return</span> node.wrappers.default<span style="color: #66cc66;">&#40;</span>node, request, sputnik<span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span></pre></div></div>


<h2>Beyond the Basics</h2>

<p>If you are curious about how Sputnik creates the whole page, note that <strong>node.wrappers.default</strong>
is usually implemented by the <strong>wrappers.default</strong> function in <strong>sputnik/actions/wiki.lua</strong> which does a Cosmo expansion of the <strong>node.html_main</strong> template (see <strong>NODE.html_main</strong> in <strong>sputnik/node_defaults/@Root.lua</strong>)</p>

<p>If you don&#8217;t like a visual feature, then it is often easy to remove it.  For instance, editing <strong>@Root</strong> as Admin (using <strong>@Root.configure</strong> as before) you can open up the &#8216;HTML Fields&#8217; and modify the templates directly. Removing the menu bar is as easy as clearing out the text in the &#8216;Menu&#8217; field.</p>

<p>For a good overview of Sputnik permissions, see this <a href="http://sputnik.freewisdom.org/en/list/Way_to_lockdown_editing_features_">list question</a> and its reply.</p>

<p>The next part of this tutorial will deal with further customizations, like internationalization, providing a custom form for editing a node&#8217;s fields, and using the built-in <strong>@Collection</strong> prototype to simplify the common pattern of groups of content nodes.  And Sputnik&#8217;s ability to create custom actions will change the way you look at file extensions forever.</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/sputnik/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Golden Wombat of Destiny</title>
		<link>http://luanova.org/golden-wombat-destiny/</link>
		<comments>http://luanova.org/golden-wombat-destiny/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 01:58:07 +0000</pubDate>
		<dc:creator>nathany</dc:creator>
				<category><![CDATA[mod_wombat]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[computer programming]]></category>
		<category><![CDATA[GSoC]]></category>
		<category><![CDATA[webserver]]></category>

		<guid isPermaLink="false">http://luanova.wordpress.com/?p=12</guid>
		<description><![CDATA[The Golden Wombat of Destiny was a text adventure game (interactive fiction) written by Huw Collingbourne in early `80s. I honestly never got very far in that game, preferring Colossal Cave and The Hitchhiker&#8217;s Guide to the Galaxy in the days of the Kaypro IV. Today we&#8217;re going to talk about a different wombat, with [...]]]></description>
			<content:encoded><![CDATA[<p><em>The Golden Wombat of Destiny</em> was a text adventure game (interactive fiction) written by Huw Collingbourne in early `80s. I honestly never got very far in that game, preferring Colossal Cave and The Hitchhiker&#8217;s Guide to the Galaxy in the days of the Kaypro IV.</p>

<p>Today we&#8217;re going to talk about a different wombat, with a different <em>destiny.</em></p>

<p>Spear-headed by <a href="http://kasparov.skife.org/blog/src/wombat/">Brian McCallister</a>, <strong>mod_wombat</strong> embeds the <a href="http://www.lua.org">Lua</a> programming language into the <a href="http://httpd.apache.org/">Apache HTTP server</a> in the same fashion as mod_perl, mod_php and mod_python bring their respective languages into the Apache world of web development.</p>

<p>How mod_wombat differs has a lot to do with how Lua differs from other languages. Lua is a very lightweight scripting language originally designed for non-programmers to customize the software it is embedded in. It is simple to pick up, while offering a good amount of flexibility and power. Its popularity in game scripting has pushed its&#8217; interpreter towards being very efficient and multi-thread ready.</p>

<p>Apache is the heavy-weight champion of HTTP servers, responsible for <a href="http://news.netcraft.com/archives/web_server_survey.html">serving up half the Internet</a>. Apache 2.x was a substantial reworking, providing:</p>

<ul>
<li>The Apache Portable Runtime (APR) so Module writers don&#8217;t need to deal with all the OS-specific issues.</li>
<li>Swappable multi-processing modules (MPMs) including Prefork (non-threaded), Worker threads, and an Event MPM that decouples server threads from the HTTP connection (read: very efficient).</li>
</ul>

<p>Lua is designed for embedding in C-based programs, which allows mod_wombat to take advantage of the substantial infrastructure Apache provides. More than any other language module, mod_wombat endeavors to <em>work with</em> Apache.</p>

<p>Matthew Burke is <a href="http://mail-archives.apache.org/mod_mbox/httpd-dev/200803.mbox/%3c47CA13D9.7080900@gwu.edu%3e">looking for students</a> to work on mod_wombat as part of the 2008 <a href="http://code.google.com/soc/2008/">Google Summer of Code</a>. If you are a student who is interested, you should definitely get in touch with Matthew Burke and Brian McCallister to discuss your ideas. Who knows, this could be your <em>destiny?</em> <img src='http://luanova.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<h2>This is gonna be great</h2>

<p>Lua atop Apache could make for a very sweet development platform for web applications, both large and small.</p>

<ul>
<li>Lua is simpler than other scripting languages used for web development, making it easy to pick-up. This is exemplified by the use of <em>tables</em> as a universal data structure (like PHP Arrays, but unlike Python or Ruby). </li>
<li>Lua has several commonalities with JavaScript, like first-class functions, closures, and prototype-based object orientation. Yet it steps beyond most languages with proper tail calls and coroutines.</li>
<li>There is a fairly clean slate to start with, meaning it doesn&#8217;t carry the baggage of hundreds of procedural methods like PHP, or code mixed into HTML templates. APIs can be nicely organized and designed for simplicity (i.e. ColdFusion&#8217;s DateFormat and TimeFormat make it easier to reason about date formatting than Ruby or PHP&#8217;s methods).</li>
<li>Apache&#8217;s efficient threading modules combined with Lua&#8217;s low-overhead and thread-safety make for a very performant platform. That means it is able to handle a load of traffic without a huge hardware investment.</li>
<li>Deploying with an Apache module is often the preferred method, as opposed to more complicated reverse proxy setups or FastCGI. For ease of deployment, this is an advantage over the popular Ruby platform, which <a href="http://www.rubyinside.com/no-true-mod_ruby-is-damaging-rubys-viability-on-the-web-693.html">has no true mod_ruby</a>.</li>
<li>The mod_wombat project was started by Apache Software Foundation members, is hosted with Apache, and has their backing as a supported module for Apache users.</li>
</ul>

<h2>Ideas</h2>

<p>If you are a student joining the GSoC, you will need to come up with your own proposal. I&#8217;m not a student, so I don&#8217;t qualify, but I will post here a few of the basic ideas that I believe are of general consensus.</p>

<h3>Simplify installation</h3>

<p>For mod_wombat to become a platform of choice, it needs to be dead-simple to deploy, whether as a development environment or a production server. This would be served by relying only on <a href="http://httpd.apache.org/docs/2.2/mod/">those modules</a> included with the Apache distribution.</p>

<p>There has been a desire to remove the dependency on <a href="http://httpd.apache.org/apreq/docs/libapreq2/">libapreg2</a>, which is used to parse HTTP cookies, query-strings and POST data. The required functionality would need to be incorporated into mod_wombat directly.</p>

<h3>Tighter integration with Apache HTTP Server 2.2</h3>

<p>There is a lot that can be done to further integrate Lua with Apache, whether using Lua to configure Apache, or to pull Apache functionality into Lua.</p>

<p>Perhaps the most significant and obvious, would be integration with <strong>Apache&#8217;s Database Framework</strong>. With DBD, the database drivers for your web application are bundled with Apache, and Apache manages a pool of database connections in an intelligent way appropriate for the MPM being used. With mod_wombat, Lua could be the first language to really take advantage of this feature, new to Apache 2.2.</p>

<h3>Write something with it</h3>

<p>What mod_wombat provides is an API to higher-level web frameworks and applications. It&#8217;s hard to know how those APIs should be written without using them. Building a small project atop mod_wombat could go a long way in designing a <strong>concise and friendly API.</strong></p>

<p>Preferably using some sort of <a href="http://ajato.titanatlas.com/developer/code-standards">code standards</a>.</p>

<h2>Resources</h2>

<p>If you choose to partake in this endeavor, there a few things you must know.</p>

<ul>
<li>Working knowledge of ANSI C, perhaps <a href="http://www.careferencemanual.com/">C: A Reference Manual</a> will help.</li>
<li><a href="http://www.inf.puc-rio.br/~roberto/pil2/">Programming in Lua</a> is an excellent resource for both the Lua programming language and how to interface it with C.</li>
<li><a href="http://www.informit.com/store/product.aspx?isbn=0132409674">The Apache Modules Book</a> goes over Apache&#8217;s architecture and writing Modules for it, including a chapter on DBD.
<li>A willingness to work with <a href="http://www.gnu.org/software/autoconf/">autoconf</a> and related build tools. There is but one book dedicated to the subject, and the <a href="http://sourceware.org/autobook/">online version</a> is more up-to-date.</li>
<li>Familiarity with existing web development environments and experience with database systems.</li>
<li>An understanding of just how <a href="http://code.google.com/soc/2008/">Google Summer of Code</a> works.</li>
<li>Go through Brian&#8217;s <a href="http://kasparov.skife.org/wombat_ac_us_07.pdf">slides</a> and download the <a href="http://svn.apache.org/repos/asf/httpd/mod_wombat/trunk">source code</a> from Subversion to familiarize yourself with mod_wombat.</li>
</ul>

<p>And that&#8217;s all there&#8217;s to it. Ready to get coding?</p>

<h2>Follow-up</h2>

<p>Maxime Petazzoni has accepted the role of working on mod_wombat for GSoC this year. See the Apache <a href="http://mail-archives.apache.org/mod_mbox/httpd-dev/200804.mbox/%3c20080429195230.GA3397@bulix.org%3e">mailing list</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/golden-wombat-destiny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lua and the web: an overview</title>
		<link>http://luanova.org/lua-web-overview/</link>
		<comments>http://luanova.org/lua-web-overview/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 01:50:03 +0000</pubDate>
		<dc:creator>nathany</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Kepler]]></category>
		<category><![CDATA[webserver]]></category>
		<category><![CDATA[Wiki]]></category>

		<guid isPermaLink="false">http://luanova.wordpress.com/?p=11</guid>
		<description><![CDATA[Lua is among the top 20 most popular programming languages, according to the TIOBE Programming Community index. Lua is also faster and has a smaller memory footprint than other interpreted scripting languages (compare with Ruby, Python, PHP and JavaScript SpiderMonkey). We haven&#8217;t heard a lot about Lua on the web, even though there are a [...]]]></description>
			<content:encoded><![CDATA[<p>Lua is among the top 20 most popular programming languages, according to the <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">TIOBE Programming Community index</a>. Lua is also faster and has a smaller memory footprint than other interpreted scripting languages (compare with <a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;lang=lua&amp;lang2=ruby">Ruby</a>, <a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;lang=lua&amp;lang2=python">Python</a>, <a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;lang=lua&amp;lang2=php">PHP</a> and <a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;lang=lua&amp;lang2=javascript">JavaScript SpiderMonkey</a>).</p>

<p>We haven&#8217;t heard a lot about Lua on the web, even though
there are a number of developers working with Lua on the server-side. Lets take a brief look.</p>

<h2>The Kepler Project</h2>

<p><a href="http://www.keplerproject.org/">Kepler</a> is a &#8220;web development platform&#8221; named after astronomer Johannes Kepler. It looks to be the most ambitious project of the bunch. Kepler is written as a number of modules that fit together, and includes its&#8217; own web server named Xavante.</p>

<p>There is also an endeavor to build <em>WSAPI,</em> in similar fashion to
Python&#8217;s <a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> interface, that support pretty much any web server and configuration (CGI, FastCGI, SCGI, etc, etc.)</p>

<h2>Nanoki</h2>

<p>When I joined to Kepler mailing list, &#8220;Petite Abeille&#8221; was the first person to respond. He has been developing a Wiki called <a href="http://alt.textdrive.com/nanoki/">Nanoki</a>.</p>

<p>However, it is not built on top of Kepler. Instead there is a small built-in web server or will run atop the Unix tcp command. All the source code is released under a MIT license, and is instructive in building a light, focussed web application vs. the broad scope of Kepler.</p>

<h2>mod_wombat</h2>

<p><a href="http://kasparov.skife.org/blog/">Brian McCallister</a> spear-headed a project to embed Lua in an Apache HTTP Server module. Going through Brian&#8217;s <a href="http://kasparov.skife.org/wombat_ac_us_07.pdf">slides</a> is quite inspiring as to just how good a fit this is. Apache does all the heavy-lifting, such as providing a fully multi-threaded &#8220;worker MPM&#8221; (multi-processing module) and a portable runtime (APR) environment. Lua is a thread-safe language, with &#8220;share-nothing&#8221; Lua <em>states</em>, so it fits right in and is super-efficient.</p>

<p>Skimming through <a href="http://www.informit.com/store/product.aspx?isbn=0132409674">The Apache Modules Book</a> is even more inspiring, as you can see the potential of mod_wombat if it took advantage of Apache&#8217;s database connection pooling (DBD) and the various other facilities of Apache HTTP Server.</p>

<p>Wombat is still a little rough around the edges, but you can find the Apache-licensed source code at:
<a href="http://svn.apache.org/repos/asf/httpd/mod_wombat/trunk">http://svn.apache.org/repos/asf/httpd/mod_wombat/trunk</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/lua-web-overview/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Launch: getting Lua installed</title>
		<link>http://luanova.org/launch-getting-lua-installed/</link>
		<comments>http://luanova.org/launch-getting-lua-installed/#comments</comments>
		<pubDate>Sun, 11 Nov 2007 06:47:35 +0000</pubDate>
		<dc:creator>nathany</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://luanova.org/2007/11/10/launch-getting-lua-installed/</guid>
		<description><![CDATA[To play with Lua you need to download the source code and compile it. This isn&#8217;t as scary as it sounds, as Lua is a positively tiny download and doesn&#8217;t depend on anything more than a C compiler. Lua is written in standard ANSI C, so any one should work. I will give instructions for [...]]]></description>
			<content:encoded><![CDATA[<p>To play with Lua you need to download the source code and compile it. This isn&#8217;t as scary as it sounds, as Lua is a positively <em>tiny</em> download and doesn&#8217;t depend on anything more than a C compiler. Lua is written in standard ANSI C, so any one should work. I will give instructions for <strong>Mac OS X</strong>, because that&#8217;s what I use.</p>

<h2>Building</h2>

<p>First, you need to have Apple&#8217;s Developer Tools installed. They should be your Mac OS X disc, under Optional Installs -&gt; Xcode Tools. Run the XcodeTools package to install. You can also <a href="http://developer.apple.com/tools/download/">download Xcode</a> if you sign up for a free ADC account (but note: they are large!).</p>

<p>Next, <a href="http://www.lua.org/download.html">download Lua source code</a> and unpack the archive in Finder. Or you can use <strong>Terminal</strong> to download the current  release (5.1.2) to your Downloads folder (or a suitable location of your choice):</p>

<p><code>cd Downloads
curl -O http://www.lua.org/ftp/lua-5.1.2.tar.gz
tar xzvf lua-5.1.2.tar.gz
cd lua-5.1.2</code></p>

<p>Either way, you need <strong>Terminal</strong> (from Application/Utilities) to do the rest. Make sure you are in the lua-5.1.2/ folder, and type:
<code>make macosx</code></p>

<p>Several lines should scroll by. On Leopard you will see some <em>deprecated</em> warnings in loadlib.c. Don&#8217;t worry about it. To make sure everything is okay, run:
<code>make test</code>
You should see <strong>&#8220;Hello world, from Lua 5.1!&#8221;</strong></p>

<h2>Installing</h2>

<p>It is possible to run the Lua interpreter from right here, but let&#8217;s install it the rest of the way. For this we will need to run &#8220;make install&#8221;. By default Lua installs to /usr. This will work, but it&#8217;s recommended to install under /usr/local.</p>

<p>So from the lua-5.1.2/ folder, run:
<code>sudo make install INSTALL_TOP=/usr/local</code>
and provide your password.</p>

<p>It appears that Leopard ships with /usr/local/bin in your path. You can check by running: (make sure PATH is uppercase)
<code>env | grep PATH</code></p>

<p>If you don&#8217;t see it there, you need to modify your .profile file.
<code>pico ~/.profile</code></p>

<p>and include:</p>

<p><code>export PATH="/usr/local/bin:/usr/local/sbin:$PATH"
export MANPATH="/usr/local/man:$MANPATH"</code></p>

<p>If you are using <a href="http://macromates.com">TextMate</a>, and will be installing the Lua bundle later, you may also want to include:</p>

<p><code>export SVN_EDITOR="mate -w"
export LC_CTYPE=en_US.UTF-8</code></p>

<p>With pico, press Ctrl-X followed by Y to exit and save.</p>

<p>The changes will take affect when you open a new Terminal window.</p>

<h2>Running</h2>

<p>With Lua installed in your path, you can run it in Terminal from any folder. Just type:
<code>lua</code></p>

<p>This brings up the interactive interpreter. You can type in Lua code:
<code>print "Hi"</code>
<code>= 2 + 3</code></p>

<p>Press <strong>Ctrl-C</strong> to exit when you&#8217;re done.</p>

<p>Now that Lua is installed, you <em>could</em> remove the Downloads/lua-5.1.2 folder. But you may want to check out the test/ folder for some example code. You can run these examples from within the lua-5.1.2/test/ folder like this:</p>

<p><code>lua factorial.lua</code></p>

<p>A local copy of the <a href="http://www.lua.org/manual/5.1/">Reference Manual</a> can be found under doc/manual.html.</p>

<h2>TextMate</h2>

<p>If you are using <a href="http://macromates.com/">TextMate</a>, there is a Lua bundle to give it color syntax highlighting and a few snippets. Unfortunately the Lua bundle isn&#8217;t included by default. You can either use <a href="http://projects.validcode.net/getbundle">GetBundle</a>, or you can grab it with the command line as follows.</p>

<p>The bundles are stored in a Subversion repository, which requires Subversion (svn) on your computer. Leopard comes with Subversion, but for Tiger or prior you need to install it. I&#8217;ve had good success with <a href="http://homepage.mac.com/martinott/">Martin Ott&#8217;s Subversion package</a>.</p>

<p>As per the <a href="http://macromates.com/textmate/manual/bundles#getting_more_bundles">TextMate manual</a>:</p>

<p><code>mkdir -p /Library/Application\ Support/TextMate/Bundles</code>
<code>cd /Library/Application\ Support/TextMate/Bundles</code>
<code>svn co http://svn.textmate.org/trunk/Bundles/Lua.tmbundle</code></p>

<p>You need to restart TextMate or navigate to to Bundles -&gt; Bundle Editor -&gt; <strong>Reload Bundles</strong> in the menu.</p>

<p>Files with a .lua extension will be associated with the Lua language bundle. One nice feature is that you can press Command-R to run them.</p>

<p>So that&#8217;s about it for getting setup. Now we just need to write some code!</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/launch-getting-lua-installed/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A computer scientist, a mathematician and an engineer&#8230;</title>
		<link>http://luanova.org/a-computer-scientist-a-mathematician-and-an-engineer/</link>
		<comments>http://luanova.org/a-computer-scientist-a-mathematician-and-an-engineer/#comments</comments>
		<pubDate>Sun, 11 Nov 2007 02:44:33 +0000</pubDate>
		<dc:creator>nathany</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[history of programming languages]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://luanova.org/2007/11/10/a-computer-scientist-a-mathematician-and-an-engineer/</guid>
		<description><![CDATA[The Lua programming language was developed by three members of Tecgraf, the Computer Graphics Technology Group of PUC-Rio, a University in Rio de Janeiro. Not merely an academic pursuit, it was developed primarily as a replacement for SOL (meaning &#8220;sun&#8221;) and DEL (data entry language) for Brazilian oil company Petrobras. Lua was started in 1993, [...]]]></description>
			<content:encoded><![CDATA[<p>The <strong>Lua programming language</strong> was developed by <a href="http://www.lua.org/authors.html">three members</a> of Tecgraf, the Computer Graphics Technology Group of PUC-Rio, a University in Rio de Janeiro. Not merely an academic pursuit, it was developed primarily as a replacement for SOL (meaning &#8220;sun&#8221;) and DEL (data entry language) for Brazilian oil company Petrobras.</p>

<p>Lua was started in 1993, near the same time as Matz began working on Ruby. It was designed to be a small and efficient scripting language that could easily be embedded in C/C++ on practically any platform.</p>

<p>Aiming for <strong>simplicity</strong>, Lua implements a single collection type called &#8220;tables&#8221;. PHP also takes this approach, with Arrays that can act as hashes (associative arrays) and standard arrays. Python uses its dictionaries (hashes) for namespaces and passing named parameters to functions. Lua does this and more, making extensive use of tables.</p>

<p>One of Lua&#8217;s precepts is to <em>&#8220;provide mechanisms instead of policies.&#8221;</em> You won&#8217;t find Ruby&#8217;s emphasis on object-oriented programming in Lua, but it still is easy enough to <em>OOP</em>. In fact, Lua works somewhat like the prototype system in today&#8217;s JavaScript.</p>

<p>First-class functions allow functions to be passed as arguments, stored in tables, and basically treated like any other value. Proper tail calls allow for recursion without stack overflows. Closures are a bit hard to explain without an example. You are free to make use of all these mechanisms, which originated in <strong>functional programming</strong>, a distinct discipline from the typical C-style of programming.</p>

<p>Lua isn&#8217;t alone in mixing programming paradigms, but its overall simplicity as a language makes it a good place to <strong>begin</strong> computer programming.</p>

<p>In 1996, Lua found its way into <em>Dr. Dobb&#8217;s Journal</em> and from there into adventure game Grim Fandango and <a href="http://www.lua.org/uses.html">many other games</a> since the 1999 Game Developers&#8217; Conference, including the ever-popular World of Warcraft.</p>

<p>Lua has grown in response to the demands of game programmers. It now posesses an <strong>incremental</strong> garbage collector to avoid long pauses. Coroutines provide programmers with <strong>co-operative multitasking</strong>. Lua&#8217;s virtual machine is register-based, making it one of the fastest interpreted languages available.</p>

<p>Due to a rather strict adherence to ANSI C, Lua doesn&#8217;t run multi-core out of the box. But Lua can take advantage of your OS-dependent threading code, having a fully reentrant API. <strong>Lua states</strong> isolate each thread, so scripters don&#8217;t need to concern themselves with the typical locking complexities of concurrency. <ins datetime="2007-11-11T04:32:08+00:00">Perhaps a future version of</ins> Lua <del datetime="2007-11-11T04:45:14+00:00">5.2</del> could see an <em>optional</em> library with OS-specific threading support.</p>

<p>If you want to dig deep into Lua&#8217;s history, take a look at <a href='http://luanova.files.wordpress.com/2007/11/hopl.pdf' title='hopl.pdf'>The Evolution of Lua</a> paper (26 pages), as was presented at the 2007 History of Programming Languages (HOPL) Conference. I will conclude with a quote from the paper:</p>

<blockquote>&#8220;<em>It is much easier to add features later than to remove them.</em> This development process has been essential to keep the language simple, and <strong>simplicity is our most important asset</strong>. Most other qualities of Lua &#8212; speed, small size, portability &#8212; derive from its simplicity.&#8221;</blockquote>

<p>And contrast it with a quote from Yukihiro &#8220;Matz&#8221; Matsumoto from <em>Beautiful Code</em>:</p>

<blockquote>&#8220;When simpler tools are used to solve a complex problem, complexity is merely shifted to the programmer, which is really putting the cart before the horse.&#8221;</blockquote>

<p>While there is validity to his statement, <strong>the beauty of Lua</strong> is how it manages to be a quite powerful language, despite its simplicity.</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/a-computer-scientist-a-mathematician-and-an-engineer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Lua: how we first met</title>
		<link>http://luanova.org/3/</link>
		<comments>http://luanova.org/3/#comments</comments>
		<pubDate>Sun, 04 Nov 2007 14:08:09 +0000</pubDate>
		<dc:creator>nathany</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[Adobe Lightroom]]></category>
		<category><![CDATA[coroutines]]></category>

		<guid isPermaLink="false">http://luanova.wordpress.com/2007/11/09/3/</guid>
		<description><![CDATA[This past summer I evaluated both Apple Aperture and Adobe Lightroom for managing my digital photographs. You see, iPhoto 6 was getting a bit sluggish, Photoshop Elements even more so (not yet having Intel support). To top it off, I was considering a Digital SLR, so I&#8217;d need something that could read RAW. Adobe Lightroom [...]]]></description>
			<content:encoded><![CDATA[<p><img src='http://luanova.files.wordpress.com/2007/11/moonlove.png' alt='moonlove.png' align='right' alt='Minnie and Mickey mouse in love on the moon' />
This past summer I evaluated both Apple Aperture and Adobe Lightroom for managing my digital photographs. You see, iPhoto 6 was getting a bit sluggish, Photoshop Elements even more so (not yet having Intel support). To top it off, I was considering a Digital SLR, so I&#8217;d need something that could read RAW.</p>

<p>Adobe Lightroom won out for me. It provided enough of the Photoshop functionality (curves, etc.) that I often wouldn&#8217;t need to launch Elements. Just as important, the reviews proclaimed Lightroom to be more responsive and less of a resource hog. <em>So what does all this have to do with <strong>Lua?</strong></em></p>

<p>Adobe Lightroom is programmed with C/C++/Objective-C and&#8230; <strong>40% Lua</strong>. An interpreted scripting language making up 40% of the code, and it feels more responsive and uses less resources?! That deserves a second look&#8230;</p>

<p>Adobe Lightroom puts Lua&#8217;s coroutines to good use, keeping the user interface responsive while images visually rotate or exports process. Coroutines are a form of &#8220;cooperative multitasking,&#8221; where the programmer controls task-switching rather then being preempted as with &#8220;real&#8221; threads.</p>

<p>I&#8217;ve taken a great interest in the Lua language. The more I learn, the more intrigued I am. This blog exists in order to share these findings with you. <strong>Lua</strong> is Portuguese for moon, and &#8220;lua nova&#8221; means <em><strong>new moon</strong></em>.</p>

<p>Welcome to Lua, welcome to the moon&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://luanova.org/3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
