]> git.sesse.net Git - xml-template/commitdiff
Add a simple introduction document.
authorsgunderson@bigfoot.com <>
Sat, 12 Aug 2006 15:05:22 +0000 (17:05 +0200)
committersgunderson@bigfoot.com <>
Sat, 12 Aug 2006 15:05:22 +0000 (17:05 +0200)
doc/intro.txt [new file with mode: 0644]

diff --git a/doc/intro.txt b/doc/intro.txt
new file mode 100644 (file)
index 0000000..a5d1ded
--- /dev/null
@@ -0,0 +1,281 @@
+Introduction to XML::Template (name suggestions welcome)
+
+[In plain text; HTML coming soon. Note that this is mainly a rough brain
+dump, even though the code is out there and working; nothing is finished
+yet, especially as I haven't used it in a bigger project yet.]
+
+XML::Template is a templating system; there are already many others, so if
+you do not like it, look into a different one (its design is inspired by
+at least Template Toolkit and Kid, probably also including elements from
+others). XML::Template is (like Kid or TAL) designed to guarantee that your
+output is well-formed XML, which is a good step on the road to give you
+valid XHTML.
+
+You can get the latest version of XML::Template with bzr; get bzr from your
+favourite distribution and do "bzr get http://bzr.sesse.net/xml-template/"
+to check out the code and this documentation.
+
+There is a lot to be said about design philosophy, but let's first give a
+simple example to give you the feel of how it works. (The example is in
+Perl, but there's also a functionally equivalent PHP version, and more
+languages should probably come soon.)
+
+Template (simple.xml):
+
+  <!DOCTYPE
+    html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:t="http://template.sesse.net/" xml:lang="en">
+    <head>
+      <title />
+    </head>
+    <body>
+      <p t:id="hello">This will be replaced.</p>
+    </body>
+  </html>
+
+Code (simple.pl):
+
+  #! /usr/bin/perl
+  use XML::Template;
+  
+  my $doc = XML::Template::process_file('../xml/simple.xml', {
+       'title' => 'A very basic example',
+       '#hello' => 'Hello world!'
+  });
+  print $doc->toString;
+
+Result:
+
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+    <head>
+      <title>A very basic example</title>
+    </head>
+    <body>
+      <p>Hello world!</p>
+    </body>
+  </html>
+
+This is about as simple as it gets, but we've already touched on most of the
+functionality we want or need. A few points are worth commenting on:
+
+ - We template by first _selecting_ certain elements (either by tag name, or
+   by ID -- the syntax is borrowed from CSS since you probably already know
+   it), then _replace_ their contents. (Soon, we'll also _clone_ elements.)
+ - We get a DOM tree out, which we can either print out or do other things
+   with (say, style further if XML::Template should not prove enough).
+   (Actually, we start with a DOM tree as well, but process_file is a
+   shortcut to read in an XML file and parse it into a DOM tree first, since
+   that's usually what we want.)
+ - All traces of our templating system have been removed -- there is a flag
+   you can give to prohibit this "cleaning" in case you don't want that.
+
+Note how little syntax we need to do simple things -- XML::Template is
+designed to _keep simple things simple_, since you want to do simple things
+most of the time. (I don't believe in "lines of code" as the primary metric
+for API usability in general, though.)
+
+We move on to another useful operation, cloning.
+
+Template (clone.xml):
+
+  <!DOCTYPE
+    html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:tmpl="http://template.sesse.net/" xml:lang="en">
+    <head>
+      <title>Cloning test</title>
+    </head>
+    <body>
+       <p>My favourite color is <tmpl:color />; I like that very much.
+         All my favourite things:</p>
+      <ul tmpl:id="things">
+        <li />
+      </ul>
+    </body>
+  </html>
+
+Code (clone.pl):
+
+  #! /usr/bin/perl
+  use XML::Template;
+  
+  my $doc = XML::Template::process_file('../xml/clone.xml', {
+       'color' => 'blue',
+       '#things' => [
+               { 'li' => 'Raindrops on roses' },
+               { 'li' => 'Whiskers on kittens' },
+               { 'li' => 'Bright copper kettles' },
+               { 'li' => 'Warm, woolen mittens'} 
+       ]
+  });
+  print $doc->toString;
+
+Result:
+
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+    <head>
+      <title>Cloning test</title>
+    </head>
+    <body>
+       <p>My favourite color is blue; I like that very much.
+         All my favourite things:</p>
+      <ul>
+        <li>Raindrops on roses</li>
+      
+        <li>Whiskers on kittens</li>
+      
+        <li>Bright copper kettles</li>
+      
+        <li>Warm, woolen mittens</li>
+      </ul>
+    </body>
+  </html>
+
+This isn't much harder than the example above; we've done a simple replacement
+of the contents of <tmpl:color> to "blue" (and after that just removed the tag;
+any tag you use in the templating namespace will automatically get stripped
+away), and then cloned the contents of our "things" bullet list. Note that
+XML::Template automatically recurses after the cloning, since you probably
+don't want four identical elements. You can recurse as many times as you'd like,
+in case you'd need lists of lists or multiple tables and rows and columns --
+you don't even have to understand what's happening to get it to work.
+
+Note that we did all of this without any logic in the template at all. This
+is completely intentional -- it's a bit of an experiment, really, but hopefully
+it will all turn out well. There is no logic in the templating system at all;
+if-s are handled with replacements (or DOM deletions), for-s are handled with
+cloning and expressions are handled by the language you're using.
+
+This means we have introduced all three operations we need (replacement,
+substitution/selection and repeating/cloning), and only need two more features
+before we're all done.
+
+The first one is just a variation on replacement; instead of replacing with
+a string, you can replace with a DOM tree or document. This facilitates simple
+inclusion, since you probably want some header and footer to be the same
+across all your pages. (No example here, you can probably work it out by
+yourself; just send a DOM object instead of a string. There's an example in
+the source code distribution if you need it.)
+
+The second one is also a variation on replacement; sometimes, you want to
+set attributes on elements instead of replacing their contents, and for that,
+we have a small hack:
+
+Template (clone.xml), repeated for your convenience:
+
+  <!DOCTYPE
+    html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:tmpl="http://template.sesse.net/" xml:lang="en">
+    <head>
+      <title>Cloning test</title>
+    </head>
+    <body>
+       <p>My favourite color is <tmpl:color />; I like that very much.
+         All my favourite things:</p>
+      <ul tmpl:id="things">
+        <li />
+      </ul>
+    </body>
+  </html>
+
+Code (attribute.pl):
+
+  #! /usr/bin/perl
+  use XML::Template;
+
+  my $doc = XML::Template::process_file('../xml/clone.xml', {
+       'color' => 'red',
+       '#things' => [
+               { 'li' => 'Raindrops on roses',    'li.class' => 'odd' },
+               { 'li' => 'Whiskers on kittens',   'li.class' => 'even' },
+               { 'li' => 'Bright copper kettles', 'li.class' => 'odd' },
+               { 'li' => 'Warm, woolen mittens',  'li.class' => 'even' }
+       ]
+  });
+  print $doc->toString;
+
+Result:
+
+  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+    <head>
+      <title>Cloning test</title>
+    </head>
+    <body>
+       <p>My favourite color is red; I like that very much.
+         All my favourite things:</p>
+      <ul>
+        <li class="odd">Raindrops on roses</li>
+      
+        <li class="even">Whiskers on kittens</li>
+      
+        <li class="odd">Bright copper kettles</li>
+      
+        <li class="even">Warm, woolen mittens</li>
+      </ul>
+    </body>
+  </html>
+
+Naturally, you can't put anything else than a simple string into an attribute,
+but it's not like this is a big limitation. (There's also a shortcut for doing
+stuff like odd/even automatically, but I'll leave that for yourself to find out;
+see the attribute2 example.)
+
+That's it for the examples; now let's turn to the boring design philosophy.
+
+The main thoughts behind XML::Template have been, in no particular order:
+
+ - Make the simple things simple. (A template should not be much more cumbersome
+   to write than if you wrote the page statically.) More complex things can be
+   harder if it makes the simple things simpler; that's OK.
+ - Make it easy for the user to do the right thing. (Guarantee well-formed XML,
+   and make a design that makes it easy to separate back-end logic, viewing logic
+   and HTML templating. Incidentially, I've only seen one library ever that does
+   the same properly for database logic and other back-end logic, and that is the
+   excellent libpqxx library.)
+ - Premature optimization is the root of all evil; most web systems are not
+   performance limited by their output anyway.
+ - Don't try to be everything for everyone. (XML::Template can not output to
+   plain text or PostScript, even though that would clearly be useful for some
+   people in some cases.)
+ - Be language agnostic. (DOM is rather universal, and there's a useful
+   implementation for most web-relevant languages out there.) Maintaining
+   several implementations in several languages is suboptimal, but it's better
+   than only supporting one language or having someting that needs to reimplement
+   the entire DOM with wrappers for each language. (Thankfully, by relying on
+   the DOM support in each language, the code so far is under 200 lines per
+   implementation, so maintaining this hopefully shouldn't be much work.)
+   As proof-of-concept, I've got Perl and PHP implementations that work and
+   feel largely the same -- Python, Ruby and other implementations are welcome.
+
+As a side note to the second point, I've spent some time wondering exactly
+_why_ you want to separate the back-end logic from your HTML, and why people
+don't seem to do it. After some thought, I've decided that what I really want
+is to get the HTML away from my code -- not the other way round. (In other
+words, HTML uglifies code more then code uglifies HTML -- someone using a
+WYSIWYG editor to generate their HTML might disagree, though.)
+
+However, this also means that you want the _entire_ viewing logic away from
+your back-end logic if you can. When you process your data, you really don't
+want to care if you're on an odd or even row to get those styled differently
+in the HTML; that's for another part. XML::Template, incidentially, by
+moving the entire output logic to the end of your script, makes this easy
+for you; you _can_ do the viewing logic "underway" if you really want to,
+but there's no incentive to, and the natural modus operandi is to split
+viewing and other logic into two distinct parts.
+
+An open question is how to do internationalization on web pages; I haven't
+yet seen a good system for handling this. To be honest, this might be something
+handled in another layer (cf. "don't try to be everything to everyone" above),
+but I'd be interesting to hear others' thoughts on this, especially how
+you could achieve clean text/markup separation (stuff like gettext doesn't
+really work well with markup in general).
+
+More to come here at some point, probably. Now, go out and just _use_ the
+thing -- I hope it will make your life on the web simpler. :-)
+
+  - Steinar H. Gunderson <sgunderson@bigfoot.com>, http://www.sesse.net/