<?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:atom="http://www.w3.org/2005/Atom"
				  >
<channel><atom:link href="http://andreyshubin.com/rss" rel="self" type="application/rss+xml" />
<title>AndreyShubin.com</title>
<link>http://andreyshubin.com</link>
<description><![CDATA[Human-Computer Translator]]></description>
<item>
<title>Hoduli: free markup abstractions</title>
<link>http://andreyshubin.com/updates/Hoduli</link>
<pubDate>Fri, 13 Nov 2009 17:27:56 +0300</pubDate>
<description><![CDATA[<p>
	<em>One of the most valuable part of any good product is it&#39;s user interface.<br />
	</em></p>
<p>
	<img src="/images/updates/hoduli_paint.jpg" style="float: right;" /> But the current state of UI development seems to be ugly. Development of Web UI for large projects is terrifically complex. We are forced to implement our ideas with hardcoded HTML and CSS. Of course there is XML/XSLT family, but it&#39;s redundant and unreadable.</p>
<p>
	Let me show you this small PHP code. It&#39;s called <strong>Hoduli</strong> (<a href="http://en.wikipedia.org/wiki/Stilts">stilts</a> in Russian). I think we should wear something like that while splashing through the mud of web-development :-)</p>
<p>
	<a name="more"></a>The main part of Hoduli is a special tag <code class="inline">&lt;h:define /&gt;</code>.<br />
	We can define any other tag using that one. (All references to tags will have a prefix <code class="inline">h:</code>.)</p>
<p>
	<code>&lt;h:define name=&quot;<strong>page-head</strong>&quot;&gt;<br />
	&nbsp; &lt;head&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;title&gt;The Question&lt;/title&gt;<br />
	&nbsp; &lt;/head&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;h:define name=&quot;<strong>page-body</strong>&quot;&gt;<br />
	&nbsp; &lt;body&gt;To be or not to be?&lt;/body&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;h:define name=&quot;<strong>page-main</strong>&quot;&gt;<br />
	&nbsp; &lt;html&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;<strong>h:page-head</strong> /&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;<strong>h:page-body</strong> /&gt;<br />
	&nbsp; &lt;/html&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;<strong>h:page-main</strong> /&gt;<br />
	</code></p>
<p>
	Here we define three tags. And we <q>execute</q> one of them ( <code class="inline">h:page-main</code> ) at the end. That will output the following:</p>
<p>
	<code>&lt;html&gt;<br />
	&nbsp; &lt;head&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;title&gt;The Question&lt;/title&gt;<br />
	&nbsp; &lt;/head&gt;<br />
	&nbsp; &lt;body&gt;To be or not to be?&lt;/body&gt;<br />
	&lt;/html&gt;<br />
	</code></p>
<p>
	We can use <em>attributes</em> also:</p>
<p>
	<code>&lt;h:define name=&quot;upcase&quot;&gt;<br />
	&nbsp;<strong>&lt;?= strtoupper($attr[&#39;str&#39;]) ?&gt;</strong><br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;h:upcase <strong>str=&quot;hello&quot;</strong> /&gt;</code></p>
<p>
	Note that we just include PHP code where we need it.<br />
	By the way, we can work with the <em>inner contents</em> of tags:</p>
<p>
	<code>&lt;h:define name=&quot;repeat&quot;&gt;<br />
	&nbsp; &lt;?php for ($i = 0; $i &lt; $attr[&#39;count&#39;]; $i++): ?&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;li&gt;<strong>&lt;?= sprintf($inner, $i) ?&gt;</strong>&lt;/li&gt;<br />
	&nbsp; &lt;?php endfor; ?&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;ul&gt;<br />
	&nbsp; &lt;h:repeat count=&quot;3&quot;&gt;<br />
	&nbsp;&nbsp;&nbsp; <strong>Item %u</strong><br />
	&nbsp; &lt;/h:repeat&gt;<br />
	&lt;/ul&gt;<br />
	</code></p>
<p>
	The result will look like this:</p>
<p>
	<code>&lt;ul&gt;<br />
	&nbsp; &lt;li&gt;Item 0&lt;/li&gt;<br />
	&nbsp; &lt;li&gt;Item 1&lt;/li&gt;<br />
	&nbsp; &lt;li&gt;Item 2&lt;/li&gt;<br />
	&lt;/ul&gt;<br />
	</code></p>
<p>
	<code class="inline">$inner</code> is not just a string &mdash; it is XHTML object model, so we can work with it&#39;s different parts as well.<br />
	<br />
	I hope you caught the idea now.<br />
	<em><br />
	We can create a bunch of <q>functions</q> that will have <strong>one main goal &mdash; output something</strong>. And these <q>functions</q> are declared as tags (using PHP if needed).</em></p>
<p>
	Suppose we want to create layout for this design:</p>
<p style="text-align: center;">
	<img src="/images/updates/tabulate.png" /></p>
<p>
	Let&#39;s do that as we wish to:</p>
<p>
	<code>&lt;<strong>h:include</strong> file=&quot;mytags.php&quot; /&gt;<br />
	<br />
	&lt;h:define name=&quot;list-animals&quot;&gt;<br />
	<strong> &nbsp; &lt;?php<br />
	&nbsp; foreach ($animals as $a):<br />
	&nbsp;&nbsp;&nbsp; if ($a[&#39;type&#39;] == $attr[&#39;type&#39;]):<br />
	&nbsp; ?&gt;<br />
	</strong> &nbsp;&nbsp;&nbsp; &lt;h:animal name=&quot;<strong>&lt;?= $a[&#39;name&#39;] ?&gt;</strong>&quot; link=&quot;<strong>&lt;?= $a[&#39;link&#39;] ?&gt;</strong>&quot; /&gt;<br />
	<strong>&nbsp; &lt;?php<br />
	&nbsp;&nbsp;&nbsp; endif;<br />
	&nbsp; endforeach;<br />
	&nbsp; ?&gt;<br />
	</strong> &lt;/h:define&gt;<br />
	<br />
	&lt;<strong>h:tabulate</strong> selected=&quot;&lt;?= $_REQUEST[&#39;tab_id&#39;] ?&gt;&quot;&gt;<br />
	&nbsp; &lt;<strong>tab</strong> id=&quot;1&quot; title=&quot;Dogs&quot;&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;h:list-animals type=&quot;dog&quot; /&gt;<br />
	&nbsp; &lt;<strong>/tab</strong>&gt;<br />
	&nbsp; &lt;<strong>tab</strong> id=&quot;2&quot; title=&quot;Cats&quot;&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;h:list-animals type=&quot;cat&quot; /&gt;<br />
	&nbsp; &lt;<strong>/tab</strong>&gt;<br />
	&nbsp; &lt;<strong>tab</strong> id=&quot;3&quot; title=&quot;Dinosaurs&quot;&gt;<br />
	&nbsp;&nbsp;&nbsp; Rest in peace...<br />
	&nbsp; &lt;<strong>/tab</strong>&gt;<br />
	&lt;<strong>/h:tabulate</strong>&gt;<br />
	</code></p>
<p>
	<code class="inline">h:tabulate</code> and <code class="inline">h:animal</code> is not shown here. But we could have them defined! Libraries of useful functions can be created and included with <code class="inline">h:include</code> tag :-) I have started a sample collection of helpful functions. It&#39;s included within Hoduli <a href="http://code.google.com/p/hoduli/">source code</a>.</p>
<p>
	B O N U S</p>
<p>
	We can define <em><q>macros</q></em> (much like Lisp macros, not as C preprocessor #define).<br />
	<br />
	Just add <code class="inline">macro</code> attribute to the definition and we have a tag that can be used to generate other tag&#39;s body.</p>
<p>
	<code>&lt;h:define <strong>macro</strong> name=&quot;inblock&quot;&gt;<br />
	&nbsp; &lt;<strong>&lt;?= $attr[&#39;tag&#39;] ?&gt;</strong>&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;?= $inner ?&gt;<br />
	&nbsp; &lt;/<strong>&lt;?= $attr[&#39;tag&#39;] ?&gt;</strong>&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;h:define name=&quot;quote&quot;&gt;<br />
	&nbsp; &lt;<strong>h:inblock tag=&quot;q&quot;</strong>&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;?= $inner ?&gt;<br />
	&nbsp; &lt;<strong>/h:inblock</strong>&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;h:define name=&quot;heavy&quot;&gt;<br />
	&nbsp; &lt;<strong>h:inblock tag=&quot;strong&quot;</strong>&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;?= $inner ?&gt;<br />
	&nbsp; &lt;<strong>/h:inblock</strong>&gt;<br />
	&lt;/h:define&gt;<br />
	</code><br />
	Here <code class="inline">h:inblock</code> calls will be expanded, so that <code class="inline">h:quote</code> and <code class="inline">h:heavy</code> will become:</p>
<p>
	<code>&lt;h:define name=&quot;quote&quot;&gt;<br />
	&nbsp; &lt;q&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;?= $inner ?&gt;<br />
	&nbsp; &lt;/q&gt;<br />
	&lt;/h:define&gt;<br />
	<br />
	&lt;h:define name=&quot;heavy&quot;&gt;<br />
	&nbsp; &lt;strong&gt;<br />
	&nbsp;&nbsp;&nbsp; &lt;?= $inner ?&gt;<br />
	&nbsp; &lt;/strong&gt;<br />
	&lt;/h:define&gt;</code></p>
<p>
	The same methods can be used for abstracting other types of contents (e.g. CSS or PHP code itself). I really don&#39;t know all the posibilites yet. But I&#39;m sure there are many interesting things that could be done here.</p>
<p>
	<strong>What do you think about that all?</strong></p>
<p class="secondary">
	The source code of Hoduli and Kostyli (library of tags) is available at <a href="http://code.google.com/p/hoduli/">http://code.google.com/p/hoduli/</a>.</p>
<p class="secondary">
	<em>Implementation:</em> PHP class with several methods. Parsing of XHTML is done by <a href="http://simplehtmldom.sourceforge.net/">SimpleHtmlDom</a> (included).<br />
	<em>Note:</em> this is just an early prototype yet.</p>
]]></description>
</item>
</channel>
</rss>
