<?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>Three of Coins &#187; Maciej</title>
	<atom:link href="http://www.3ofcoins.net/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.3ofcoins.net</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 21 Jan 2010 14:01:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Yaclml in pictures, part II: Templating</title>
		<link>http://www.3ofcoins.net/2010/01/21/yaclml-in-pictures-part-ii-templating/</link>
		<comments>http://www.3ofcoins.net/2010/01/21/yaclml-in-pictures-part-ii-templating/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 14:00:47 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bese]]></category>
		<category><![CDATA[common lisp]]></category>
		<category><![CDATA[ediware]]></category>
		<category><![CDATA[html-template]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[yaclml]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=94</guid>
		<description><![CDATA[After a short intermission and explanation/excuse, let&#8217;s go on interesting stuff, Yaclml; and if you still didn&#8217;t read the first part, where I wrote about HTML generation and compared Yaclml to CL-WHO, do so now!
Continuing first part&#8217;s focus on comparing Yaclml to Ediware, let&#8217;s start by mentioning that CL-WHO doesn&#8217;t do templating at all; Edi [...]]]></description>
			<content:encoded><![CDATA[<p>After a short intermission and explanation/excuse, let&#8217;s go on interesting stuff, <a href="http://common-lisp.net/project/bese/yaclml.html">Yaclml</a>; and if you still didn&#8217;t read <a href="http://www.3ofcoins.net/2009/02/07/yaclml-in-pictures-part-i-html-generation/">the first part</a>, where I wrote about HTML generation and compared Yaclml to <a href="http://www.weitz.de/cl-who/">CL-WHO</a>, do so now!</p>
<p>Continuing <a href="http://www.3ofcoins.net/2009/02/07/yaclml-in-pictures-part-i-html-generation">first part</a>&#8217;s focus on comparing Yaclml to <a href="http://www.weitz.de/">Edi</a>ware, let&#8217;s start by mentioning that CL-WHO doesn&#8217;t do templating at all; Edi Weitz wrote a separate library for this: <a href="http://www.weitz.de/html-template/">HTML-Template</a>.  It provides simple templating support, which turns template of a HTML file (or actually any text file, not limited to HTML) to a closure which, when called, can fill the template with supplied values and output result to a stream.  Simple enough, based on Perl&#8217;s <a href="http://search.cpan.org/dist/HTML-Template/">HTML::Template</a>—which shows in the templating language syntax.  The template directives of HTML-Template are embedded in HTML comments.</p>
<p>Yaclml includes the templating feature, and it chose a different path.  For me, with a tiny bit of <a href="http://www.zope.org/">Zope</a> background, their path is a little nicer: they decided to support a Lisp variant of Zope&#8217;s <a href="http://wiki.zope.org/ZPT/TAL">Template Attribute Language</a>.  TAL is strictly an XHTML and XML templating language, whose directives are special XML tags and attributes, living in a separate XML namespace.  I find this approach much more elegant than magic directives embedded in comments.  This also makes it possible to use XML/XHTML editing tools (such as Emacs&#8217; <a href="http://www.thaiopensource.com/nxml-mode/">nxml-mode</a> and excellent <a href="http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html">nxhtml-mode</a> built on top of it) to aid in authoring and validation of the code.  Supposedly it also plays fine with visual design tools, such as Adobe Dreamweaver, but I can&#8217;t confirm that, since I don&#8217;t use those.</p>
<p>In this section, I won&#8217;t go on comparing Yaclml to HTML-Template, because I didn&#8217;t use much of the latter, those two are not as similar as CL-WHO and Yaclml&#8217;s HTML generation, and would require non-trivial examples to really see meaningful differences; besides, Yaclml&#8217;s TAL is obviously better, and anyone will see it from TAL alone. ;)  Seriously, HTML-Template&#8217;s documentation is great, it&#8217;s a simple package, and you can compare it for yourself.  These two packages are similar, main difference being TAL&#8217;s focus on XML and XHTML, and syntactic differences are much more of a matter of taste than it is with HTML generation.  However, Yaclml, and especially its TAL support, is underdocumented (there was some <a href="http://trac.common-lisp.net/ucw/wiki/IntroHtmlTemplating">tutorial</a> over at UCW Wiki, but at the moment it&#8217;s inaccessible, and only option to read it is Google&#8217;s cache) and it&#8217;s really hard to figure out how to use it, especially outside of UCW framework; that&#8217;s the hole I&#8217;m trying to fill here.</p>
<p>During writing this article, I&#8217;ve found that Yaclml is actually <em>somewhat</em> documented, in the <a href="http://common-lisp.net/project/bese/qbook">qbook</a> format, but the generated, readable docs are nowhere to be found.  I&#8217;ve rebuilt the HTML files and uploaded them at <a href="http://common-lisp.net/~mpasternacki/yaclml-qbook/">http://common-lisp.net/~mpasternacki/yaclml-qbook/</a>.  These are auto-generated API docs, so it&#8217;s not an easy-to-read tutorial, but rather a reference, and some descriptions in there might be dated; however, it may come in handy when you explore Yaclml&#8217;s APIs on your own.</p>
<h2>Using templates</h2>
<p>Let&#8217;s start from the basic <em>Hello, World</em> template and see how to render it from Lisp. I will write more about the template language in the next section, but I want to write about the Lisp part first, so that you&#8217;re able to run and test more complex examples as you read.  Here&#8217;s the template:</p>
<p><!-- htmlize tmpl1.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
&lt;<span style="color: #00008b;">html</span> <span style="color: #ff6347;">lang</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">en</span><span style="color: #4d4d4d;">"</span>
      <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span><span style="color: #8b0000; font-weight: bold;">&gt;</span>
  &lt;<span style="color: #00008b;">head</span>&gt;
  &lt;<span style="color: #00008b;">title</span>&gt;Hello, world!&lt;/<span style="color: #00008b;">title</span>&gt;
  &lt;/<span style="color: #00008b;">head</span>&gt;
  &lt;<span style="color: #00008b;">body</span>&gt;
    &lt;<span style="color: #00008b;">h1</span>&gt;Hello, World!&lt;/<span style="color: #00008b;">h1</span>&gt;
    &lt;<span style="color: #00008b;">p</span> <span style="color: #8b0000; font-weight: bold;">tal:content</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$param</span><span style="color: #4d4d4d;">"</span>&gt;Parameter will go here.&lt;/<span style="color: #00008b;">p</span>&gt;
  &lt;/<span style="color: #00008b;">body</span>&gt;
&lt;/<span style="color: #00008b;">html</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p>We can see it&#8217;s an XHTML document, which makes it also proper XML, and uses <a href="http://www.w3.org/TR/REC-xml-names/">XML namespaces</a>.  The namespace <code>tal</code> will refer to the templating language tags and attributes; the <code>tal:content</code> attribute&#8217;s meaning is to replace tag&#8217;s interior with value of a variable.  We&#8217;ll get to this later, now we just want to display this.</p>
<p>To render a template from Lisp, we need cooperation of three parts: the <strong>generator</strong>, the <strong>template</strong> itself, and the <strong>environment</strong>. Generator is an object that finds templates by name, and compiles them to efficient closures.  Yaclml provides a <em>filesystem generator</em>, which finds templates as files in specified directories (‘roots’), but it&#8217;s possible to get templates e.g. from SQL database or from network, by creating a class that would inherit from <code>TAL-GENERATOR</code> or <code>FILE-SYSTEM-GENERATOR</code>. A loaded template is a closure which, when called (with an environment and a generator for finding included templates as arguments) renders the template to <code>*YACLML-OUTPUT*</code>. Environment is mapping from variables used in templates to values.</p>
<p>So, let&#8217;s render our template in the simplest way possible:</p>
<p><!-- htmlize yaclml-test.lisp --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
(<span style="color: #551a8b;">defpackage</span> <span style="color: #458b74;">:yaclml-test</span>
  (<span style="color: #b03060;">:use</span> <span style="color: #b03060;">:common-lisp</span> <span style="color: #b03060;">:yaclml</span>))
(<span style="color: #551a8b;">in-package</span> <span style="color: #b03060;">:yaclml-test</span>)

(<span style="color: #551a8b;">defvar</span> <span style="color: #ff6347;">*generator*</span>
  (make-instance 'file-system-generator
                 <span style="color: #b03060;">:root-directories</span> (list *default-pathname-defaults*))
  <span style="color: #4d4d4d;">"A filesystem-based TAL generator that looks for templates only in
  current directory."</span>)

(<span style="color: #551a8b;">defvar</span> <span style="color: #ff6347;">*environment*</span>
  (tal-env 'param <span style="color: #4d4d4d;">"foo"</span>)
  <span style="color: #4d4d4d;">"Simple environment with a single variable."</span>)

(<span style="color: #551a8b;">defvar</span> <span style="color: #ff6347;">*template*</span>
  (load-tal *generator* <span style="color: #4d4d4d;">"test.tal"</span>)
  <span style="color: #4d4d4d;">"Template read from generator."</span>)

<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">Render the template:
</span>(funcall *template* *environment* *generator*)
<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">This yields:
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;html lang="en"&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;head&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;title&gt;Hello, world!&lt;/title&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;/head&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;body&gt;
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">&lt;h1&gt;Hello, World!&lt;/h1&gt;
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">&lt;p&gt;foo&lt;/p&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;/body&gt;
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;/html&gt;
</span></pre>
<p><!-- end htmlize --></p>
<p>Here, we define a filesystem generator, a simple environment, then we load the template using generator, and we call it. Simple. Result is rendered into stream defined in <code>YACLML:*YACLML-STREAM*</code> variable (default is <code>T</code>, which makes output go to <code>*STANDARD-OUTPUT*</code>; macros <code>(YACLML:WITH-YACLML-STREAM STREAM &amp;BODY BODY)</code> and <code>(YACLML:WITH-YACLML-OUTPUT-TO-STRING &amp;BODY BODY)</code> can be used to redirect the output elegantly).</p>
<p>There is not much more to say about generators: the only generator type actually provided by Yaclml is <code>FILE-SYSTEM-GENERATOR</code>, which accepts a list of pathnames naming directories that will be searched for templates, and an optional initarg <code>:CACHEP</code> which tells whether to cache already parsed templates.</p>
<p>To get the template closure, we use the generator and <code>LOAD-TAL</code> function. Alternatively, we can compile template directly from file or string, using <code>COMPILE-TAL-FILE</code> or <code>COMPILE-TAL-STRING</code>. To render a template, we simply call resulting closure, passing it an environment and a generator (which is used for finding templates included by a template being called) as arguments.</p>
<p>Finally, we get to environments. These are used to fill in templates; they map variable names used in TAL expressions to values. Environments are lists of binding sets; binding set may be a hash table, an association list, a CLOS object (in this case, key would be a slot name), or anything on which a method for <code>FETCH-TAL-VALUE</code> generic is defined. A new environment can be constructed from key-value pairs using <code>TAL-ENV</code> function, from list of binding sets using <code>MAKE-STANDARD-TAL-ENVIRONMENT</code>, or from two existing environments with <code>EXTEND-ENVIRONMENT</code>.  The last of these functions effectively allows to create binding stacks in Lisp code.</p>
<h2>Template syntax</h2>
<p>As I already wrote, template is plain XML (usually XHTML), and whole logic is done by active tags and attributes.  Yaclml maps XML namespaces to Lisp packages (see <code>YACLML:*URI-TO-PACKAGE*</code> variable), so you can easily look up definition of any tag with <a href="http://common-lisp.net/project/slime/">SLIME</a> (or—if you&#8217;re one of <em>those people</em>—using your Lisp vendor&#8217;s IDE).</p>
<p>Only package/namespace which actually contains active tags/attributes provided by Yaclml is <code>:IT.BESE.YACLML.TAL</code>, <abbr title="Also Known As">AKA</abbr> <code>:TAL</code>, attributed to namespace <code>http://common-lisp.net/project/bese/tal/core</code>.</p>
<h3>Tags</h3>
<p>There is only a handful of tags, so let&#8217;s start from them.</p>
<h4><code>tal:tal</code></h4>
<p>This tag is semantically neutral—meaningless, and this is why it&#8217;s useful.  It is used whenever we want to do something with templates, but don&#8217;t want to introduce HTML/XML-level elements.  I usually use it to group together a sequence of tags.</p>
<p>For example: if we <a href="#tal_include">include a sub-template</a>, and the included template consists of more than one tag, we need a top-level tag to be well-formed XML, and to e.g. set XML namespace:</p>
<p><!-- htmlize tmpl2.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #00008b;">h1</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">content</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$title</span><span style="color: #4d4d4d;">"</span>&gt;Tytu&#322;&lt;/<span style="color: #00008b;">h1</span>&gt;
  &lt;<span style="color: #00008b;">div</span> <span style="color: #ff6347;">class</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">container</span><span style="color: #4d4d4d;">"</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">content</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$body</span><span style="color: #4d4d4d;">"</span> /&gt;
&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p>Other example: I need to <a href="#tal_when_unless">conditionalize</a> a sequence of list elements in menu:</p>
<p><!-- htmlize tmpl3.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
&lt;<span style="color: #00008b;">ul</span> <span style="color: #ff6347;">id</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">menu</span><span style="color: #4d4d4d;">"</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #00008b;">li</span>&gt;&lt;<span style="color: #00008b;">a</span> <span style="color: #ff6347;">href</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">/</span><span style="color: #4d4d4d;">"</span>&gt;Main page&lt;/<span style="color: #00008b;">a</span>&gt;&lt;/<span style="color: #00008b;">li</span>&gt;
  &lt;<span style="color: #00008b;">li</span>&gt;&lt;<span style="color: #00008b;">a</span> <span style="color: #ff6347;">href</span><span style="color: #8b0000; font-weight: bold;">=</span>/sub"&gt;Subpage&lt;/<span style="color: #00008b;">a</span>&gt;&lt;/<span style="color: #00008b;">li</span>&gt;
  &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">when</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$logged_in</span><span style="color: #4d4d4d;">"</span>&gt;
    &lt;<span style="color: #00008b;">li</span>&gt;&lt;<span style="color: #00008b;">a</span> <span style="color: #ff6347;">href</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">/profile</span><span style="color: #4d4d4d;">"</span>&gt;My profile&lt;/<span style="color: #00008b;">a</span>&gt;&lt;/<span style="color: #00008b;">li</span>&gt;
    &lt;<span style="color: #00008b;">li</span>&gt;&lt;<span style="color: #00008b;">a</span> <span style="color: #ff6347;">href</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">/logout</span><span style="color: #4d4d4d;">"</span>&gt;Logout&lt;/<span style="color: #00008b;">a</span>&gt;&lt;/<span style="color: #00008b;">li</span>&gt;
  &lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
  &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">unless</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$logged_in</span><span style="color: #4d4d4d;">"</span>&gt;
    &lt;<span style="color: #00008b;">li</span>&gt;&lt;<span style="color: #00008b;">a</span> <span style="color: #ff6347;">href</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">/sign-up</span><span style="color: #4d4d4d;">"</span>&gt;Sign up&lt;/<span style="color: #00008b;">a</span>&gt;&lt;/<span style="color: #00008b;">li</span>&gt;
    &lt;<span style="color: #00008b;">li</span>&gt;&lt;<span style="color: #00008b;">a</span> <span style="color: #ff6347;">href</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">/login</span><span style="color: #4d4d4d;">"</span>&gt;Log in&lt;/<span style="color: #00008b;">a</span>&gt;&lt;/<span style="color: #00008b;">li</span>&gt;
  &lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
&lt;/<span style="color: #00008b;">ul</span>&gt;
</pre>
<p><!-- end htmlize --><br />
<!-- " to bring Emacs back to norm --></p>
<h4 id="tal_lisp"><code>tal:lisp</code></h4>
<p>This is the tag that <em>you should never, ever use</em>.  Seriously.  It is the root of all evil.  Cause of <strong>mixing <abbr title="Model, View, Controler">MVC</abbr> layers</strong> by introducing logic to templates.  However, it was included by Yaclml authors, so I feel obligated to cover it.  And, when you&#8217;re a programmer and create a structure of templates for further use, or library of widgets, it might have some limited use, and might save some keystrokes.  But rule of thumb, when it comes to using this tag, is <strong>don&#8217;t</strong>.</p>
<p>OK, you&#8217;ve been warned.  Now, here&#8217;s how this tag works:  it simply interprets tag&#8217;s content as a <a href="#expressions">TAL expression</a>, which is actually Lisp code sprinkled with a bit of environment magic.  That&#8217;s it.  I don&#8217;t want to spoil you, so no examples for this tag; figure it out yourself (there is not much there to figure out anyway).</p>
<h4 id="tal_include"><code>tal:include</code></h4>
<p>This tag allows one to dynamically include templates within templates.  It requires either <code>tal:name</code> attribute literally specifying name of included template, or <code>tal:name-expression</code> attribute, which is interpreted as a <a href="#expressions">TAL expression</a>, whose result specifies name of included template:</p>
<p><!-- htmlize tmpl4.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
<span style="color: #008b8b;">&lt;!--</span><span style="color: #008b8b;"> inc0.tal </span><span style="color: #008b8b;">--&gt;</span>
&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">include</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">name</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">inc1.tal</span><span style="color: #4d4d4d;">"</span> /&gt;
  &lt;<span style="color: #00008b;">strong</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">content</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$included</span><span style="color: #4d4d4d;">"</span> /&gt;
  &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">include</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">name-expression</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">${$included}.tal</span><span style="color: #4d4d4d;">"</span> /&gt;
&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl4.1.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
<span style="color: #008b8b;">&lt;!--</span><span style="color: #008b8b;"> inc1.tal </span><span style="color: #008b8b;">--&gt;</span>
&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;FOO&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p>Let&#8217;s render these two templates:</p>
<p><!-- htmlize tmpl4.lisp --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
(funcall (load-tal *generator* <span style="color: #4d4d4d;">"inc0.tal"</span>)
         (tal-env 'included <span style="color: #4d4d4d;">"inc1"</span>)
         *generator*)
<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">Yields:
</span><span style="color: #008b8b;">;;</span><span style="color: #008b8b;">
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">FOO
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">&lt;strong&gt;inc1&lt;/strong&gt;
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">FOO
</span><span style="color: #008b8b;">;;</span><span style="color: #008b8b;">
</span></pre>
<p><!-- end htmlize --></p>
<p>But hey!  There&#8217;s more!</p>
<p>I didn&#8217;t yet mention one special XML namespace, <code>xmlns:param=&quot;http://common-lisp.net/project/bese/tal/params&quot;</code>.  It allows you to <em>pass arguments</em> (environment parameters) to included template, which effectively gives you not only parametrized subtemplates, but also <a href="http://docs.djangoproject.com/en/dev/topics/templates/#template-inheritance">template inheritance</a>, a <strong>very</strong> powerful tool for organizing your templates.  Let&#8217;s look into Yaclml&#8217;s own test suite and see how it works:</p>
<p><!-- htmlize tmpl5.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
<span style="color: #008b8b;">&lt;!--</span><span style="color: #008b8b;"> inc3.tal </span><span style="color: #008b8b;">--&gt;</span>
&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">include</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>
             <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">param</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/params</span><span style="color: #4d4d4d;">"</span>
             <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">name</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">inc4.tal</span><span style="color: #4d4d4d;">"</span>
             <span style="color: #b03060;">param</span>:<span style="color: #ff6347;">baz</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$foo</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #b03060;">param</span>:<span style="color: #00008b;">bar</span>&gt;&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">include</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">name</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">inc5.tal</span><span style="color: #4d4d4d;">"</span>/&gt;&lt;/<span style="color: #b03060;">param</span>:<span style="color: #00008b;">bar</span>&gt;
  &lt;<span style="color: #b03060;">param</span>:<span style="color: #00008b;">quux</span>&gt;&lt;<span style="color: #00008b;">p</span>&gt;xyzzy&lt;/<span style="color: #00008b;">p</span>&gt;&lt;/<span style="color: #b03060;">param</span>:<span style="color: #00008b;">quux</span>&gt;
&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">include</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl5.1.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
<span style="color: #008b8b;">&lt;!--</span><span style="color: #008b8b;"> inc4.tal </span><span style="color: #008b8b;">--&gt;</span>
&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;
  foo is &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$foo</span><span style="color: #4d4d4d;">"</span>&gt;bad bad bad&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;,
  bar is &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$bar</span><span style="color: #4d4d4d;">"</span>/&gt;,
  baz is &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$baz</span><span style="color: #4d4d4d;">"</span> /&gt;, and
  quux is &lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">content-as-is</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$quux</span><span style="color: #4d4d4d;">"</span> /&gt;.
&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl5.2.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
<span style="color: #008b8b;">&lt;!--</span><span style="color: #008b8b;"> inc5.tal </span><span style="color: #008b8b;">--&gt;</span>
&lt;<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;BARINCLUDED&lt;/<span style="color: #b03060;">tal</span>:<span style="color: #00008b;">tal</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl5.lisp --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
(funcall (load-tal *generator* <span style="color: #4d4d4d;">"inc3.tal"</span>)
         (tal-env 'foo <span style="color: #4d4d4d;">"FOOPARAM"</span>)
         *generator*)
<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">Yields:
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">foo is FOOPARAM,
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">bar is BARINCLUDED,
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">baz is FOOPARAM, and
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">quux is &lt;p&gt;xyzzy&lt;/p&gt;.
</span></pre>
<p><!-- end htmlize --></p>
<p>We can pass to subtemplates not only plain parameters, we can pass <em>whole HTML subtrees</em>.</p>
<h3>Attributes</h3>
<p>More interesting work, and actual logic, lives in TAL&#8217;s attributes.  Let&#8217;s look at those.</p>
<h4 id="tal_content"><code>tal:content</code>, <code>tal:content-as-is</code>, and <code>tal:replace</code></h4>
<p>These attributes insert into their tag (<code>content</code>) or replace their tag entirely with (<code>replace</code>) with a <a href="#expressions">TAL expression</a>.  Plain <code>content</code> and <code>replace</code> escape HTML special chars (&lt;&quot;&gt;); <code>content-as-is</code> does not escape anything.  We&#8217;ve already seen those in action.</p>
<h4 id="tal_when_unless"><code>tal:when</code> and <code>tal:unless</code></h4>
<p>These tags are <em>conditionals</em>.  They render the tag they belong to (and its content, of course) when a <a href="#expressions">TAL expression</a> is true (<code>tal:when</code>) or false (<code>tal:unless</code>).  We&#8217;ve seen those too.  Unfortunately, there is no if-then-else construct; this would be hard to encode <em>elegantly</em> in XML.</p>
<h4 id="tal_dolist"><code>tal:dolist</code></h4>
<p>Looping construct.  Its <a href="#expressions">TAL expression</a> should return a <em>list of environments</em>.  Its tag will be executed with current environment extended by each of environments on the list.  Let&#8217;s see it:</p>
<p><!-- htmlize tmpl6.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
<span style="color: #008b8b;">&lt;!--</span><span style="color: #008b8b;"> dolist.tal </span><span style="color: #008b8b;">--&gt;</span>
&lt;<span style="color: #00008b;">ul</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #00008b;">li</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">dolist</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$envlist</span><span style="color: #4d4d4d;">"</span>&gt;
    &lt;<span style="color: #00008b;">span</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$foo</span><span style="color: #4d4d4d;">"</span> /&gt;
    &lt;<span style="color: #00008b;">em</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">content</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$bar</span><span style="color: #4d4d4d;">"</span>&gt;default&lt;/<span style="color: #00008b;">em</span>&gt;
  &lt;/<span style="color: #00008b;">li</span>&gt;
&lt;/<span style="color: #00008b;">ul</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl6.lisp --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
(funcall (load-tal *generator* <span style="color: #4d4d4d;">"dolist.tal"</span>)
         (tal-env 'envlist (list (tal-env 'foo 1 'bar 2)
                                 (tal-env 'foo 3 'bar 4)
                                 (tal-env 'foo 5)))
         *generator*)
<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">Yields:
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;ul&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;li&gt;
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">1
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">&lt;em&gt;2&lt;/em&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;/li&gt;&lt;li&gt;
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">3
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">&lt;em&gt;4&lt;/em&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;/li&gt;&lt;li&gt;
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">5
</span><span style="color: #008b8b;">;;     </span><span style="color: #008b8b;">&lt;em&gt;&lt;/em&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;/li&gt;
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;/ul&gt;
</span></pre>
<p><!-- end htmlize --></p>
<p>Not most readable or elegant, but expressive and gets the work done.  A bit like next attribute…</p>
<h4 id="tal_let"><code>tal:let</code></h4>
<p>This one, added to Yaclml by yours truly (of which yours truly should be slightly ashamed), extends environment for tag content with variables specified as for <code>LET</code> command.  This breaks layer separation almost as badly as <code>TAL:LISP</code>, could be implemented way better (e.g. by using <code>xmlns:param=&quot;http://common-lisp.net/project/bese/tal/params&quot;</code> namespace and allowing user to use it in all tags, not only <code>tal:include</code>), and is generally evil.  Nevertheless, it&#8217;s already commited to Yaclml, and should be documented.  Please, don&#8217;t look at the following example:</p>
<p><!-- htmlize tmpl7.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
&lt;<span style="color: #00008b;">div</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>
     <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">let</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">((foo 1) (bar 2) (baz 3))</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #00008b;">div</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$foo</span><span style="color: #4d4d4d;">"</span>/&gt; &lt;<span style="color: #00008b;">div</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$bar</span><span style="color: #4d4d4d;">"</span>/&gt; &lt;<span style="color: #00008b;">div</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">replace</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">$baz</span><span style="color: #4d4d4d;">"</span>/&gt;
&lt;/<span style="color: #00008b;">div</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl7.lisp --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
(funcall (load-tal *generator* <span style="color: #4d4d4d;">"let.tal"</span>)
         nil
         *generator**)
<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">Yields:
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;div&gt;
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">1 2 3
</span><span style="color: #008b8b;">;;</span><span style="color: #008b8b;">&lt;/div&gt;
</span></pre>
<p><!-- end htmlize --></p>
<h4 id="tal_in_package"><code>tal:in-package</code></h4>
<p>This attribute sets current package for <a href="#expressions">TAL expressions</a> within its tag.  We&#8217;ll talk about expressions in a moment, now—a silly example:</p>
<p><!-- htmlize tmpl8.xml --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
&lt;<span style="color: #00008b;">div</span> <span style="color: #b03060;">xmlns</span>:<span style="color: #ff6347;">tal</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">http://common-lisp.net/project/bese/tal/core</span><span style="color: #4d4d4d;">"</span>
     <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">in-package</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">:yaclml</span><span style="color: #4d4d4d;">"</span>&gt;
  &lt;<span style="color: #00008b;">pre</span> <span style="color: #b03060;">tal</span>:<span style="color: #ff6347;">content</span>=<span style="color: #4d4d4d;">"</span><span style="color: #4d4d4d;">*uri-to-package*</span><span style="color: #4d4d4d;">"</span>/&gt;
&lt;/<span style="color: #00008b;">div</span>&gt;
</pre>
<p><!-- end htmlize --></p>
<p><!-- htmlize tmpl8.lisp --></p>
<pre style="color: #000000; background-color: #EAF0F0;">
(funcall (load-tal *generator* <span style="color: #4d4d4d;">"inpackage.tal"</span>) nil *generator*)
<span style="color: #008b8b;">;;; </span><span style="color: #008b8b;">Yields:
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;div&gt;
</span><span style="color: #008b8b;">;;   </span><span style="color: #008b8b;">&lt;pre&gt;(http://common-lisp.net/project/bese/tal/core . #&amp;lt;PACKAGE &amp;quot;IT.BESE.YACLML.TAL&amp;quot;&amp;gt;) (http://common-lisp.net/project/bese/tal/params
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">. #&amp;lt;PACKAGE &amp;quot;IT.BESE.YACLML.TAL.INCLUDE-PARAMS&amp;quot;&amp;gt;) (http://common-lisp.net/project/bese/yaclml/core
</span><span style="color: #008b8b;">;;  </span><span style="color: #008b8b;">. #&amp;lt;PACKAGE &amp;quot;IT.BESE.YACLML.TAGS&amp;quot;&amp;gt;) (http://www.w3.org/XML/1998/namespace . #&amp;lt;PACKAGE &amp;quot;IT.BESE.YACLML.XML&amp;quot;&amp;gt;) (http://www.w3.org/1999/xlink/ . #&amp;lt;PACKAGE &amp;quot;IT.BESE.YACLML.XLINK&amp;quot;&amp;gt;)&lt;/pre&gt;
</span><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">&lt;/div&gt;
</span></pre>
<p><!-- end htmlize --></p>
<h3 id="expressions">Expressions</h3>
<p>Yaclml&#8217;s TAL expressions are <em>simply Lisp expressions</em>, with all their upsides and downsides.  Current package is one set with <a href="#tal_in_package"><code>tal:in-package</code></a> or, when none was set, <em>package that was active when template was called</em>.  There is one difference, though: readtable is modified.  Symbols following the <code>$</code> prefix are looked up in current environment.  That&#8217;s all.  You can (and should <em>not</em>) use all the power of Lisp in the expressions; remember to quote the double quotation marks (the &quot; sign) as <code>&amp;quot;</code> entities.  Yes, this gets <em>unreadable</em> and <em>ugly</em>.  Simply, don&#8217;t overuse it.  When in doubt, move logic to Lisp code.</p>
<p>These rules apply for most Yaclml attributes; unfortunately, not for all of them.  The ugly exception is the <code>tal:name-expression</code> attribute of the <a href="#tal_include"><code>tal:include</code></a> tag.  This tag, and all plain HTML tags, <strong>can</strong> include TAL expressions, by surrounding it with <code>${<i>tal-expression</i>}</code>.  That&#8217;s where the ugly <code>${$included}.tal</code> syntax in <code>tal:include</code> example came from.</p>
<p>The second form, <code>@{<i>tal-expression</i>}</code>, expects <code><i>tal-expression</i></code> to return a <em>list</em>, and resulting string is concatenation of this list&#8217;s elements.</p>
<h2>Caveats</h2>
<p>Yaclml has some issues to be aware of.  Here are those that I know; this is probably not an exhaustive list, but it should be useful anyway.  So…</p>
<p>Input TAL templates are read and interpreted as XML files.  This means that XML comments are discarded <em>before the interpreter even sees them</em>.  This usually is a good thing; however, if someone tries to use <a href="http://www.quirksmode.org/css/condcom.html">conditional comments</a>, there&#8217;s a nasty surprise: conditionals are eaten by template engine.  In the next part, which will be about extending Yaclml, we&#8217;ll learn, how to work around this.</p>
<p>Attributes aren&#8217;t interpreted consistently: most TAL attributes accept TAL expressions, except the <code>tal:name-expression</code> attribute of the <a href="#tal_include"><code>tal:include</code></a> tag, which is interpreted as plain HTML attribute and needs escaping expressions with <code>${…}</code> syntax; and <code>tal:name</code> attribute of the same tag ignores every attempt to use any syntax at all.</p>
<p>TAL expressions need to be valid XML attributes, so Lisp has to be quoted.  This is especially annoying when you try to use string literals within expressions. However, this has a simple workaround: don&#8217;t pack logic into your expressions.  If this is annoying, make sure you&#8217;re not cramming controller logic into your view layer inside templates.</p>
<h2>Summary</h2>
<p>TAL is not perfect, but it is a solid, usable and quite optimized code base.  For generating HTML and XML documents, it is way more convenient (for me) than text based approaches, as it enforces well-formedness and (to some extent) validity of generated HTML.  It is also extensible, about which I&#8217;ll write in the next part—stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2010/01/21/yaclml-in-pictures-part-ii-templating/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Revive the blog—Project 52</title>
		<link>http://www.3ofcoins.net/2010/01/08/revive-the-blog-project-52/</link>
		<comments>http://www.3ofcoins.net/2010/01/08/revive-the-blog-project-52/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 21:02:10 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3ofcoins]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[project52]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=90</guid>
		<description><![CDATA[I know, I know… long time, no blog.  Since last article, I was busy graduating my MSc, setting up a freelance programming business, moving, and so on.  Busy time.  But since some time, I have no such excuse—quite the contrary, blogging should serve my freelancing by making me more googlable.  And [...]]]></description>
			<content:encoded><![CDATA[<p>I know, I know… long time, no blog.  Since last article, I was busy graduating my MSc, setting up a freelance programming business, moving, and so on.  Busy time.  But since some time, I have no such excuse—quite the contrary, blogging should serve my freelancing by making me more googlable.  And during this time I gathered a LOT of experience, and quite a lot of things that I can blog about.  Mostly non-Lisp, as I turned out to be concentrating on <a href="http://www.python.org/">Python</a>/<a href="http://www.djangoproject.com/">Django</a> programming and infrastructure/deployment work, but I do some Lispy stuff on the side to keep sane.  And, of course, to finish the templating article, about which I&#8217;ve been already nagged—sorry, everyone, for keeping you waiting!</p>
<p>Anyway, I am not a big fan of new year resolutions—but this time, resolutions of other people turned out to be useful.  I stumbled upon <a href="http://project52.info/">Project 52</a>, and it seems to be a nice version of the <a href="http://www.stevepavlina.com/blog/2005/04/30-days-to-success/">30-day trial</a> (which, by the way, are *very* effective way to pick up or change a daily habit) for habits that doesn&#8217;t make sense as daily ones.  Why not?</p>
<p>And I promise—this is the last meta-post on this topic.  I hate meta-blogging, but this time I allowed myself to do so to commit in public, and to get excuses for lack of posts during last… oh, man, it was almost a year… to get those excuses out of the way.  Stay tuned for real posts!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2010/01/08/revive-the-blog-project-52/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Yaclml in pictures, part I: HTML generation</title>
		<link>http://www.3ofcoins.net/2009/02/07/yaclml-in-pictures-part-i-html-generation/</link>
		<comments>http://www.3ofcoins.net/2009/02/07/yaclml-in-pictures-part-i-html-generation/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 20:41:04 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bese]]></category>
		<category><![CDATA[cl-who]]></category>
		<category><![CDATA[ediware]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html-template]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[ucw]]></category>
		<category><![CDATA[yaclml]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=49</guid>
		<description><![CDATA[Everyone and their dog loves Edi Weitz&#8217;s Lisp software (unless they don&#8217;t use Lisp, that is).  Not without reason—Edi&#8217;s libraries are solid, well-designed and robust pieces of software.  CL-PPCRE is unbeatable (it parses Perl&#8217;s regular expressions faster than Perl, when properly compiled, and is more compatible with Perl 5.8 than Perl 5.8 is with Perl [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone and their dog loves <a href="http://www.weitz.de/">Edi Weitz&#8217;s Lisp software</a> (unless they don&#8217;t use Lisp, that is).  Not without reason—Edi&#8217;s libraries are solid, well-designed and robust pieces of software.  <a href="http://www.weitz.de/cl-ppcre/">CL-PPCRE</a> is unbeatable (it parses Perl&#8217;s regular expressions faster than Perl, when properly compiled, and is more compatible with Perl 5.8 than Perl 5.8 is with Perl 5.6), and <a href="http://www.weitz.de/hunchentoot/">Hunchentoot</a> seems to be the best and most hassle-free HTTP server library available for Lisp.  Hunchentoot is also most popular server, and many people using it, automatically use Edi&#8217;s <a href="http://www.weitz.de/cl-who/">CL-WHO</a> for HTML output, and <a href="http://www.weitz.de/html-template/">HTML-Template</a> for templating, which—I think—are not the best libraries available for this, and I will explain now, why.</p>
<p>I worked for about a year on an <a href="http://common-lisp.net/project/ucw/">UnCommon Web</a>-based application.  This was an interesting experience; <abbr title="UnCommon Web">UCW</abbr> provides a great way to express complex behaviour in a Web application, as it is <a href="http://en.wikipedia.org/wiki/Continuation">continuation</a>-based, which enabled me to code app&#8217;s logic as regular control flow, complete with looping, conditions, etc., from time to time presenting user a form and receiving user-supplied values (form presentation was as simple as calling out to a function, which returned values supplied by user).  Cool, huh?  Currently, <abbr title="UnCommon Web">UCW</abbr> seems to be mostly a dead project, and there is an alternative, which may be more interesting—namely, <a href="http://common-lisp.net/project/cl-weblocks/">Weblocks</a>—but I didn&#8217;t check that out yet.  What&#8217;s more, <abbr title="UnCommon Web">UCW</abbr>, with all its complexity, had very little documentation, and what was avalilable, was mostly outdated, as the framework was constantly evolving at that time.  Not so cool, but it forced me to learn to <acronym title="Read The Fine Source">RTFS</acronym> when needed (with <a href="http://common-lisp.net/project/slime/">Slime</a>&#8217;s <code>M-.</code> it was not as hard as it seems).  But I digress; <abbr title="UnCommon Web">UCW</abbr> made use of some other projects of Bese (<abbr title="UnCommon Web">UCW</abbr> developers seemed to have quite a bad case of <abbr title="Not Invented Here">NIH</abbr>), including HTML output and templating library <a href="http://common-lisp.net/project/bese/yaclml.html">Yaclml</a>—Yet Another Common Lisp Markup Language—which I really loved, and which, in my opinion, surpasses CL-WHO + HTML-Template in many ways.  Unfortunately it is almost undocumented, which is what I&#8217;ll try to fix in this article, along with comparing Yaclml to its Ediware counterparts.<span id="more-49"></span></p>
<h2>Formatting HTML output</h2>
<p>Edi, when designing CL-WHO, decided to use keyword symbols to represent HTML tags; Bese guys decided to create separate package for tags—<code>it.bese.yaclml.tags</code>, conveniently nicknamed <code>&lt;</code>.  Let&#8217;s compare a simple example code:</p>
<pre style="color: #000000; background-color: #EAF0F0;"><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">CL-WHO
</span>(<span style="color: #551a8b;">with-html-output-to-string</span> (s)
  (<span style="color: #b03060;">:ul</span> (<span style="color: #b03060;">:li</span> <span style="color: #4d4d4d;">"foo"</span>)
       (<span style="color: #b03060;">:li</span> <span style="color: #4d4d4d;">"bar"</span>)))

<span style="color: #008b8b;">;; </span><span style="color: #008b8b;">Yaclml
</span>(<span style="color: #551a8b;">with-yaclml-output-to-string</span>
  (&lt;:ul (&lt;:li <span style="color: #4d4d4d;">"foo"</span>)
        (&lt;:li <span style="color: #4d4d4d;">"bar"</span>)))</pre>
<p>Looks like a trivial difference, only on visual level (but this level is also important: we see the <code>&lt;</code> sign, which is distinct visually and actually looks like an HTML tag, not a keyword that looks just like any other keyword scattered throughout the code), but it actually has many subtle consequences.  First, keywords can&#8217;t have a function or macro definition, at least not in a practical way without conflicting with anything.  Thus, with CL-WHO syntax, one has to explicitly pass the sexprs through sexp-to-html translation function or macro; escaping to Lisp code from HTML-describing sexprs, and back to HTML is not trivial and requires a separate macro layer to switch back and forth.  Using separate package to describe HTML tags makes it possible to implement tags as macros, which was what Bese guys did.  As an important side effect, this enables basic HTML validation support, and guards users from their own typos, which CL-WHO is simply unable to do.  Yaclml also avoided the stream variable binding (they just use a dynamically bound special variable to hold output stream), so we don&#8217;t see this binding contributing to visual noise.  Now, let&#8217;s see what happens with the code when we wish to use loop to generate list items:</p>
<pre style="color: #000000; background-color: #EAF0F0;"><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">CL-WHO
</span>(<span style="color: #551a8b;">with-html-output-to-string</span> (s)
  (<span style="color: #b03060;">:ul</span> (<span style="color: #551a8b;">dolist</span> (i '(<span style="color: #4d4d4d;">"foo"</span> <span style="color: #4d4d4d;">"bar"</span> <span style="color: #4d4d4d;">"baz"</span> 23))
         (htm (<span style="color: #b03060;">:li</span> (esc (princ-to-string i)))))))

<span style="color: #008b8b;">;; </span><span style="color: #008b8b;">Yaclml
</span>(<span style="color: #551a8b;">with-yaclml-output-to-string</span>
  (&lt;:ul (<span style="color: #551a8b;">dolist</span> (i '(<span style="color: #4d4d4d;">"foo"</span> <span style="color: #4d4d4d;">"bar"</span> <span style="color: #4d4d4d;">"baz"</span> 23))
          (&lt;:li (&lt;:as-html i)))))</pre>
<p>We see now that Yaclml actually includes a whole lot less visual noise.  There is an <code>&lt;:AS-HTML</code> macro, which is necessary because tags are implemented as macros, not as functions, which allows for some optimizations, but requires some more thought from user.  Yaclml authors decided to ignore value returned by forms included in tag macros, and require them to write directly to <code>YACLML:*YACLML-STREAM*</code>.  There are helper macros <!--more-->&lt;:AS-HTML (with shorthand <code>&lt;:AH</code>), which quotes its arguments&#8217; evaluation results to Yaclml output stream, and <code>&lt;:AS-IS</code> (<code>&lt;:AI</code>), which outputs evaluation results directly to the stream, allowing called function to generate its own HTML, but also requiring it to escape anything that needs to be escaped.</p>
<p>Using special variable <code>YACLML:*YACLML-STREAM*</code> instead of a lexical binding (which is what CL-WHO does) has one more benefit, when we want to delegate some parts of HTML generation to separate functions.  Let&#8217;s compare once again:</p>
<pre style="color: #000000; background-color: #EAF0F0;"><span style="color: #008b8b;">;; </span><span style="color: #008b8b;">CL-WHO
</span>(<span style="color: #551a8b;">defun</span> <span style="color: #00008b;">item-html/who</span> (val)
  (<span style="color: #551a8b;">with-html-output-to-string</span> (s)
    (<span style="color: #b03060;">:li</span> <span style="color: #b03060;">:class</span> <span style="color: #4d4d4d;">"item"</span>
         (esc (princ-to-string val)))))
(<span style="color: #551a8b;">with-html-output-to-string</span> (s)
  (<span style="color: #b03060;">:ul</span> (<span style="color: #551a8b;">dolist</span> (i '(<span style="color: #4d4d4d;">"foo"</span> <span style="color: #4d4d4d;">"bar"</span> <span style="color: #4d4d4d;">"baz"</span> 23))
          (str (item-html/who i)))))

<span style="color: #008b8b;">;; </span><span style="color: #008b8b;">Yaclml
</span>(<span style="color: #551a8b;">defun</span> <span style="color: #00008b;">&lt;item</span> (val)
  (&lt;:li <span style="color: #b03060;">:class</span> <span style="color: #4d4d4d;">"item"</span>
    (&lt;:ah val)))
(<span style="color: #551a8b;">with-yaclml-output-to-string</span>
  (&lt;:ul (<span style="color: #551a8b;">dolist</span> (i '(<span style="color: #4d4d4d;">"foo"</span> <span style="color: #4d4d4d;">"bar"</span> <span style="color: #4d4d4d;">"baz"</span> 23))
          (&lt;item i)))</pre>
<p>The CL-WHO functions include very much noise, which Yaclml manages to avoid.  The visual distinction of tags with the <code>&lt;</code> package alias helps with code readability.  We also use a convention to put formatting-only functions and macros in a separate package, with name starting with <code>&lt;</code>, or to start their names with <code>&lt;</code>.  This convention clearly indicates formatting/visual layer; for simplicity, I used function name starting with <code>&lt;</code>, but in a larger project, I&#8217;d use separate package for formatting, nicknamed <code>&lt;project</code>, so I would use <code>&lt;project:item</code> here.</p>
<p>Could Yaclml HTML generation be better?  Sure thing.  It could step away from macros (at a performance penalty, though), and use functions, which would return and consume HTML fragments (or consume strings, or actually any Lisp values—including closures for lazy evaluation).  This would introduce first-class HTML fragment object, giving us sort of DOM and possibility of passing around and manipulating already generated HTML fragments, and wouldn&#8217;t requre the <code>&lt;:AH</code> and <code>&lt;:AI</code> helper macros (or actually would require only one of those).  That seems to be what <a href="http://labs.core.gen.tr/">core-server</a> guys are doing with their <a href="http://labs.core.gen.tr/#domprogramming">DOM programming support</a>.  I don&#8217;t use it yet, partly because I don&#8217;t need this kind of functionality and I&#8217;m more acquainted with Yaclml; partly because I don&#8217;t want to buy into core-server as a whole—core-server is a monolith and ripping DOM support out of it would require substantial amount of work—and partly because I use the second part of Yaclml, which I will describe in the following article: <a href="http://www.3ofcoins.net/2010/01/21/yaclml-in-pictures-part-ii-templating/">HTML and XML templating</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2009/02/07/yaclml-in-pictures-part-i-html-generation/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Common Lisp, Clojure, and seriousness.</title>
		<link>http://www.3ofcoins.net/2009/01/30/common-lisp-clojure-and-seriousness/</link>
		<comments>http://www.3ofcoins.net/2009/01/30/common-lisp-clojure-and-seriousness/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 14:06:16 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[common lisp]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[programming language]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=78</guid>
		<description><![CDATA[Brian Carper described a few days ago, how Clojure is better (for him) than Common Lisp (actually, SBCL).  I managed to dig through ensuing flame war, but it seems like nobody in the flame war realized (or it wasn&#8217;t stressed enough) that original post is actually comparing apples to oranges, a serious language to a toy language.
A [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://briancarper.net/2009/01/19/clojure-1-common-lisp-0/">Brian Carper described</a> a few days ago, how <a href="http://www.clojure.org/">Clojure</a> is better (for him) than <a href="http://www.lispworks.com/documentation/HyperSpec/Front/">Common Lisp</a> (actually, <a href="http://www.sbcl.org/">SBCL</a>).  I managed to dig through ensuing flame war, but it seems like nobody in the flame war realized (or it wasn&#8217;t stressed enough) that original post is actually comparing apples to oranges, a serious language to a toy language.</p>
<p>A language, to be considered serious, needs to be self-sufficient, a serious language can&#8217;t be a mere parasite on some host language or environment, and its <a href="http://en.wikipedia.org/wiki/Bus_factor">bus factor</a> can&#8217;t be finite.  That translates to just a couple of features:</p>
<ul>
<li>A serious language has to have a defining standard, it can&#8217;t be implementation-defined.  A good standard bumps language&#8217;s bus factor to <a href="http://en.wikipedia.org/wiki/Aleph_number">aleph null</a>: after a nuclear catastrophe, archæologists of future generations should be able to re-implement the language on any hardware, including <a href="http://en.wikipedia.org/wiki/Souls_in_the_Great_Machine">the Calculor</a>;</li>
<li>A serious language has to be self-hosting, or at least have some self-hosting implementations.  Only then language stops being dependent on other languages.</li>
</ul>
<p><span id="more-78"></span>Leaving aside other important traits (such as having multiple implementations, having a machine code compiler, extensibility, and so on), these two alone are necessary and sufficient for language to be serious; all programing languages not having these traits are just toys that can&#8217;t be guaranteed to last.</p>
<p>Toy languages may stay this way (as did Tcl and Perl, I think, and TeX is one-of-a-kind toy language which managed to grow enormously, staying implementation-defined and standardless).  On the other hand, starting a toy language may be just a way to bootstrap a serious language without starting from gathering a commitee, and I think that&#8217;s what is currently happening to Python.  I hope that will also happen to Clojure; I looked at it, and I liked what I saw (good concurrency support, decoupling polymorphism from data structures even more than in Common Lisp, a tiny bit more modern syntax, and it feels really well designed), however at the moment it is a toy language, feeding off Java, at very early stage of development.</p>
<p>Toy languages have short-term advantages (they are fast to create, usually simple, they leverage the host environment (libraries, operating system interface), they solve problem at hand quickly), and long-term disadvantages (lack of stability).  Serious languages have short-term disadvantages (multitude of slightly differing implementations to choose from, every single one of which has its own differences and extensions to the standard; implementation/library compatibility matrix; standard features are set in stone and it may be tricky to work around them), and long-term advantages (stability, one can rely on a serious language to be there in one form or another in ten years).</p>
<p>I have nothing against toy languages: they do their job, and do it well.  As a glue language, as a scripting language, as a solution to short-term problems, they&#8217;re good enough, and short-term advantages win over long-term disadvantages.  Brian was trying to solve a short-term problem and, not surprisingly, toy language worked better.  But: will the solution still work in ten, twenty years?  Heck, will it work with next release of Clojure, or next release of JVM, or if Rich Hickey (Clojure author) gets hit by a bus?  Brian didn&#8217;t need to answer these questions; do you?</p>
<p>When you get to choose a programming language, or any other tool, you may have some personal preferences, but don&#8217;t forget to ask yourself the single most important question: <em>What is the problem you&#8217;re trying to solve?</em>  The answer to this question determines all further questions and answers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2009/01/30/common-lisp-clojure-and-seriousness/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Darcs vs Git: mathematician versus engineer</title>
		<link>http://www.3ofcoins.net/2008/12/16/darcs-vs-git-mathematician-versus-engineer/</link>
		<comments>http://www.3ofcoins.net/2008/12/16/darcs-vs-git-mathematician-versus-engineer/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 22:43:24 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[darcs]]></category>
		<category><![CDATA[distributed]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[quote]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=62</guid>
		<description><![CDATA[Nablaone summarizes (in Polish) today&#8217;s presentations at TechAula about distributed version control systems. Precisely, he wrote about main difference between Darcs and Git—being the difference between science and engineering:
Darcs represents what&#8217;s best in the science, beautiful ideas and loooooong waiting for the reply, approaching infinity. Git, on the other hand, represents engineering—down-to-earth, mundane, hairy duct-tape-driven architecture, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nablaone.net/blog/2008/12/16/techaula-darcs-vs-git/">Nablaone summarizes</a> (in Polish) today&#8217;s presentations at <a href="http://www.aulapolska.pl/?p=89">TechAula</a> about distributed version control systems. Precisely, he wrote about main difference between <a href="http://darcs.net/">Darcs</a> and <a href="http://git.or.cz/">Git</a>—being the difference between science and engineering:</p>
<blockquote><p>Darcs represents what&#8217;s best in the science, beautiful ideas and loooooong waiting for the reply, approaching infinity. Git, on the other hand, represents engineering—down-to-earth, mundane, hairy duct-tape-driven architecture, responding within seconds.</p>
<p>Choice between darcs and git is simple.  We study darcs, we use git. :-)</p></blockquote>
<p>Having used both of this system—Darcs extensively, now mostly switched to Git—I can&#8217;t help but agree.</p>
<div id="post-238" class="post"></div>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2008/12/16/darcs-vs-git-mathematician-versus-engineer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Bash .ini file parser</title>
		<link>http://www.3ofcoins.net/2008/11/11/bash-ini-file-parser/</link>
		<comments>http://www.3ofcoins.net/2008/11/11/bash-ini-file-parser/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 13:30:26 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[cl-trane]]></category>
		<category><![CDATA[ini]]></category>
		<category><![CDATA[runtime configuration]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=44</guid>
		<description><![CDATA[Just found on the Net a cute little bash parser for .ini files.  Since I do runtime configuration for CL-Trane based projects in an ini file, parsed with py-configparser, this looks like a really cool way to configure startup scripts (think SBCL&#8217;s --dynamic-space-size).  Now, if there only was a decent .ini parser for [...]]]></description>
			<content:encoded><![CDATA[<p>Just found on the Net a cute little <a href="http://ajdiaz.wordpress.com/2008/02/09/bash-ini-parser/">bash parser for .ini files</a>.  Since I do runtime configuration for <a title="CL-Trane" href="http://common-lisp.net/project/cl-trane/">CL-Trane</a> based projects in an ini file, parsed with <a href="http://common-lisp.net/project/py-configparser/">py-configparser</a>, this looks like a really cool way to configure startup scripts (think <a href="http://sbcl.org/">SBCL</a>&#8217;s <code>--dynamic-space-size</code>).  Now, if there only was a decent .ini parser for Ruby…</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2008/11/11/bash-ini-file-parser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lisp HTML sanitizer</title>
		<link>http://www.3ofcoins.net/2008/10/24/lisp-html-sanitizer/</link>
		<comments>http://www.3ofcoins.net/2008/10/24/lisp-html-sanitizer/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 22:46:44 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[common lisp]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[markup]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=38</guid>
		<description><![CDATA[Lately, I was thinking a lot about enabling webapp users to edit rich text easily while staying secure and injection-free.  Until recently, I would just use trane-bb module of CL-Trane, and make users type BBCode inside a textarea, since many users are familiar with it, and I&#8217;d be able to easily convert their BB to [...]]]></description>
			<content:encoded><![CDATA[<p>Lately, I was thinking a lot about enabling webapp users to edit rich text easily while staying secure and injection-free.  Until recently, I would just use <a href="http://repo.or.cz/w/cl-trane.git?a=blob;f=src/bb.lisp;hb=HEAD">trane-bb</a> module of <a href="http://common-lisp.net/project/cl-trane/">CL-Trane</a>, and make users type BBCode inside a textarea, since many users are familiar with it, and I&#8217;d be able to easily convert their BB to safe HTML.  However, all JavaScript WYSIWYG editors provide HTML code, which is not that surprising.  I googled around and read a bit on all the issues related with <a href="http://www.bbcode.org/">BBCode</a>, <a href="http://textism.com/tools/textile/">Textile</a> and <a href="http://en.wikipedia.org/wiki/Lightweight_markup_language">other markup languages</a>, and came to agree with John Atwood (<a class="title-link" href="http://www.codinghorror.com/blog/archives/001116.html">Is HTML a Humane Markup Language?</a>) on HTML being the actually friendly, single markup language.  I was pleasantly surprised to see <a href="http://common-lisp.net/project/bese/">Bese</a>&#8217;s fork of <a href="http://franz.com/">Franz</a>&#8217;s <a href="http://www.franz.com/support/documentation/current/doc/phtml.htm">phtml</a> actually <a href="http://common-lisp.net/project/bese/repos/parse-html/sanitize.lisp">support HTML sanitizing</a>, and (having contributed quite a bit to Bese a few years ago) not surprised at all that this feature is not actually described or documented anywhere.  So, if you&#8217;re worried about accepting HTML (and if you&#8217;ve decided to accept HTML from users, you should be worried!), check this out:</p>
<p><kbd><a href="http://darcs.net/">darcs</a> get <a href="http://common-lisp.net/project/bese/repos/parse-html/">http://common-lisp.net/project/bese/repos/parse-html/</a></kbd></p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2008/10/24/lisp-html-sanitizer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hello, World!</title>
		<link>http://www.3ofcoins.net/2008/10/20/hello-world/</link>
		<comments>http://www.3ofcoins.net/2008/10/20/hello-world/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 15:14:30 +0000</pubDate>
		<dc:creator>Maciej</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3ofcoins]]></category>

		<guid isPermaLink="false">http://www.3ofcoins.net/?p=24</guid>
		<description><![CDATA[As this site is finally up, it&#8217;s time to introduce myself.  My name is Maciej, and I am a Common Lisp &#38; Python Web/Middleware programmer.  This page is an umbrella for bunch of my Web-related projects, and hopefully will end up as a self-sustaining Web enterprise.  At the moment, my main focus is on infrastructure [...]]]></description>
			<content:encoded><![CDATA[<p>As this site is finally up, it&#8217;s time to introduce myself.  My name is <a href="http://www.pasternacki.net/en/">Maciej</a>, and I am a Common Lisp &amp; Python Web/Middleware programmer.  This page is an umbrella for bunch of my Web-related <a href="/projects">projects</a>, and hopefully will end up as a self-sustaining Web enterprise.  At the moment, my main focus is on infrastructure and gathering the team, but some end projects are also well underway.  I will write here about Common Lisp, Web, projects gathered under Three of Coins umbrella, and probably from time to time about some unrelated things.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3ofcoins.net/2008/10/20/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
