<?xml version="1.0" encoding="UTF-8"?>
<rss 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/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Personal devlog</title>
	<atom:link href="http://tobiasz123.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tobiasz123.wordpress.com</link>
	<description>Personal dev-related weblog</description>
	<lastBuildDate>Wed, 22 Jul 2009 09:31:49 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain="tobiasz123.wordpress.com" port="80" path="/?rsscloud=notify" registerProcedure="" protocol="http-post" />
<image>
		<url>http://www.gravatar.com/blavatar/f466cdde634d69723758a2a905f7a537?s=96&amp;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Personal devlog</title>
		<link>http://tobiasz123.wordpress.com</link>
	</image>
			<creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Get Gmail search queries as terminal output or RSS feeds</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/aFfQsddDqx8/</link>
		<comments>http://tobiasz123.wordpress.com/2009/03/19/get-gmail-search-queries-as-terminal-output-or-rss-feeds/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 00:53:40 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Workflow]]></category>
		<category><![CDATA[feeds]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gtd]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[kde]]></category>
		<category><![CDATA[kwallet]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=379</guid>
		<description><![CDATA[Since i&#8217;ve implemented GTD in my Gmail account i always find myself in need to see a specific query result, outside gmail interface. Such functionality was one of the main reasons of using Remember The Milk, where queries was really powerful.  IMAP wasn&#8217;t an answer, since it was able to export only one label.
Meanwhile i&#8217;ve [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=379&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Since i&#8217;ve implemented GTD in my Gmail account i always find myself in <strong>need to see a specific query result, outside gmail interface</strong>. Such functionality was one of the main reasons of using <a href="http://rememberthemilk.com">Remember The Milk</a>, where queries was really powerful.  IMAP wasn&#8217;t an answer, since it was able to export only one label.</p>
<p><strong>Meanwhile i&#8217;ve found out about <a href="http://libgmail.sourceforge.net">libgmail</a>, a Gmail API for Python.</strong> After couple of minutes i&#8217;ve got a custom search results inside my terminal :) This could allow to embend it almost everywhere and mainly in <a href="http://conky.sourceforge.net">conky</a>. After that i&#8217;ve decided to build an RSS feeds, scheduled in cron which send them to external server. Problem was that i didn&#8217;t want to store the password inside the script nor type it in each time.</p>
<p>As i&#8217;m (un)happy user of KDE4 and i know that it comes with quite wide range of language binding so why not try them out. <strong>That was <a href="http://techbase.kde.org/Development/Languages/Python">PyKDE4</a> and PyQt4 modules.</strong> This one took some more time, since for example <strong>every app communicating with KWallet needs to have a window instance</strong>, even if it&#8217;s windowless. But there were also good sides. I&#8217;ve already had my username and password inside KWallet &#8211; i&#8217;ve configured kopete before. So basically, script doesn&#8217;t need any account information. After some struggling i&#8217;ve ended up with something like this (<em><strong>gmail-search.py</strong></em>):</p>
<p><span id="more-379"></span></p>
<pre class="brush: python;">
#!/usr/bin/python
import sys
import getopt
from time import gmtime, strftime, strptime, time

opts, args = getopt.gnu_getopt(sys.argv[1:], 'j')

from PyKDE4.kdeui import *
from PyQt4 import *
import libgmail
from platform import python_version
import re
if (python_version() &gt;= '2.6'):
	import json
else:
	import simplejson as json

class App(QtGui.QApplication):
	def __init__(self):
		QtGui.QApplication.__init__(self, [])
		self.ui = QtGui.QMainWindow()

def remove_html_tags(data):
	p = re.compile(r'')
	return p.sub('', data)

# KWALLET
app = App()
mywallet = KWallet.Wallet(0, 'kdewallet')
mywallet = mywallet.openWallet('kdewallet', app.ui.winId())
#print mywallet.folderList()
mywallet.setFolder('Kopete')
mypass = QtCore.QString()
account = '';
for entry in mywallet.entryList():
	match = re.search('^Account_[^_]+_(.+?)@gmail.com$', unicode(entry))
	if (match):
		account = match.group(1)
		mywallet.readPassword(entry, mypass)
		break
if (not account):
	print &quot;No kopete gmail account found!n&quot;
	exit(1);

# TERMINAL
#account = 'username@gmail.com';
#from getpass import getpass
#mypass = getpass(&quot;Password please: &quot;)

# PLAIN FILE
#account = 'username@gmail.com';
#mypass = open('/file/path').readline();

ga = libgmail.GmailAccount(account, mypass)
try:
	ga.login()
except libgmail.GmailLoginFailure:
	print &quot;nLogin failed. (Wrong username/password?)&quot;
else:
	#print &quot;nLog in successful.&quot;
	result = ga.getMessagesByQuery(args[0])
	rss = {
		'channel': {
			'title': 'GMAIL: '+args[0],
			'description': args[0],
			'pubDate': strftime(&quot;%a, %d %b %Y %H:%M:%S&quot;, gmtime(time()))
		},
		'items': []
	};
	for t in result:
		# COMMEND LINE OUTPUT
		if (not ('-j', '') in opts):
			print ' * '+remove_html_tags(t.subject)
		else:
			# JSON OUTPUT
			date = remove_html_tags(t.date)
			# 11:45
			if (re.search('d?d:dd', date)):
				date = strftime(&quot;%a, %d %b %Y ${time}:%S&quot;, gmtime(time())).replace('${time}', date)
			# Mar 7
			elif (re.search('w{3} d+', date)):
				date = strptime(date+strftime(&quot; %Y&quot;, gmtime(time())), &quot;%b %d %Y&quot;)
				date = strftime(&quot;%a, %d %b %Y %H:%M:%S&quot;, date)
			# 31/12/2008
			else:
				date = strptime(date, &quot;%d/%B/%Y&quot;)
				date = strftime(&quot;%a, %d %b %Y %H:%M:%S&quot;, date)
			# TODO more date formats
	#		rawMsg = ga.getRawMessage(t.matching_msgid)
			rss['items'].append({
				'title': remove_html_tags(t.subject),
				'description': t.snippet,
				'pubDate': date,
	#			'guid': re.search(&quot;Message-ID: ]+)&gt;&quot;, 	rawMsg).group(1)
				'guid': t.matching_msgid
			});
	if (('-j', '') in opts):
		print json.dumps(rss);
</pre>
<p><strong>You can switch KWallet authentification off to typed into terminal if you want.</strong> Script above doesn&#8217;t create feed yet, by default it print wiki-like list of message subjects. <strong>When you add -j switch it will return JSON data, which i use as input for RSS template</strong> compiled with <a href="http://code.google.com/p/querytemplates">QueryTemplates</a>. Source is of course simple (<em><strong>generate-template.php</strong></em>):</p>
<pre class="brush: php;">
parse(&quot;rss.xml&quot;)-&gt;
	find('channel')-&gt;
		varsToSelector('data.channel', array('title', 'description', 'pubDate'), '%k')-&gt;
	end()-&gt;
	find('item')-&gt;
		varsToLoop('data.items', 'item')-&gt;
		varsToSelector('item', array('title', 'description', 'pubDate', 'guid'), '%k')-&gt;
	end()-&gt;
	prependPHP('
$data = &quot;&quot;;
while (($l = fgets(STDIN)) !== false)
	$data .= $l;
$data = json_decode($data);
	')-&gt;
	save()
;
</pre>
<p>But you don&#8217;t need the source, just the final template (<strong><em>rss-template.php</em>)</strong>:</p>
<pre class="brush: php;">

    {'channel'}-&gt;{'title'})) print $data-&gt;{'channel'}-&gt;{'title'};  ?&gt;
    {'channel'}-&gt;{'description'})) print $data-&gt;{'channel'}-&gt;{'description'};  ?&gt;
{'channel'}-&gt;{'pubDate'})) print $data-&gt;{'channel'}-&gt;{'pubDate'};  ?&gt;
		{'items'})) $__a630a = $data-&gt;{'items'}; if (isset($__a630a) &amp;&amp; (is_array($__a630a) || is_object($__a630a))) { foreach($__a630a as $item):  ?&gt;
			{'title'})) print $item-&gt;{'title'};  ?&gt;
{'pubDate'})) print $item-&gt;{'pubDate'};  ?&gt;
			{'guid'})) print $item-&gt;{'guid'};  ?&gt;
</pre>
<p>But if you like to use the source, here is markup for it taken from wikipedia (<em><strong>rss.xml</strong></em>):</p>
<pre class="brush: xml;">

    Lift Off News
    Liftoff to Space Exploration.
Tue, 10 Jun 2003 04:00:00 GMT

			Star City
Tue, 03 Jun 2003 09:39:21 GMT
			http://liftoff.ma.gov/2003/06/03.html#item573
</pre>
<p>To create the feed simply combine output via pipe:</p>
<blockquote><p><strong>gmail-search.py -j &#8220;label:S-Next-Action -label:S-finished&#8221; | php rss-template.php </strong></p></blockquote>
<p>Whole process takes about 2-3 seconds, depending on traffic load. As for dependencies, on debian system you can install the packages like so:</p>
<blockquote><p><strong>apt-get install python-kde4 python-simplejson python-libgmail</strong></p></blockquote>
<p>Besides creating feeds libgmail can be used as powerful message filter, what could be very usefull in automating GTD processes.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/379/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/379/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/379/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/379/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/379/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/379/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/379/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/379/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/379/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/379/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=379&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/aFfQsddDqx8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/03/19/get-gmail-search-queries-as-terminal-output-or-rss-feeds/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/03/19/get-gmail-search-queries-as-terminal-output-or-rss-feeds/</feedburner:origLink></item>
		<item>
		<title>Personal torrent stream (part 1)</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/6OzjSdrnfXc/</link>
		<comments>http://tobiasz123.wordpress.com/2009/03/19/personal-torrent-stream-part-1/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 00:52:51 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Web Scraping]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[mashup]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[torrent]]></category>
		<category><![CDATA[webbrowser]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=383</guid>
		<description><![CDATA[I really don&#8217;t like reading movie reviews before actually seeing them. For this reason, i found a new nanocrowd.com service quite useful. It claims to provide very specific movie recommendations based on opinions of anonymous masses. Although it&#8217;s accounts are unfortunately still in private beta, we can test recommendations based on one movie.
Long time i&#8217;ve [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=383&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I really don&#8217;t like reading movie reviews before actually seeing them. For this reason, i found a new <a href="http://nanocrowd.com/">nanocrowd.com</a> service quite useful. It claims to provide very specific movie recommendations based on opinions of anonymous masses. Although it&#8217;s accounts are unfortunately still in private beta, we can test recommendations based on one movie.</p>
<p>Long time i&#8217;ve been thinking about downloading movies, without actually downloading them. Finding out nanocrowd convinced me to do this. Of course i&#8217;ve used <a href="http://code.google.com/p/phpquery/">phpQuery</a>&#8217;s <a href="http://code.google.com/p/phpquery/wiki/WebBrowser">WebBrowser</a> plugin. Scenario is as follows:</p>
<ol>
<li>Connect to torrentz.net</li>
<li>Fill search box and submit</li>
<li>Filter results</li>
<li>Print results and ask which to download</li>
<li>Get result sites and find supported one</li>
<li>Download to local filesystem</li>
<li>Optionally, send via SSH to another machine</li>
</ol>
<p>To be practically usefull, script supports following filters:</p>
<blockquote><p><strong>&#8211;min-size<br />
&#8211;max-size<br />
&#8211;min-peers</strong></p></blockquote>
<p>So to get a 1st matching movie in most common cases would be</p>
<blockquote><p><strong>echo 1 | torrent-download.php &#8220;Movie Name&#8221; &#8211;min-peers=50 &#8211;max-size=1500 &#8211;min-size=500</strong></p></blockquote>
<p>Now almost every decent torrent downloading app supports autoloding torrent files found in specified directory. <strong>As for today, only thing you need to do is to type movie name.</strong> Like i&#8217;ve mentioned before, nanocrowd is still not open to registration. When it will be, i will post an update (or maybe someone have a free invitation ?). <strong>Anyway, don&#8217;t use this code to download illegal movies&#8230;</strong></p>
<p><span id="more-383"></span></p>
<h3>torrent-download.php</h3>
<pre class="brush: php;">
#!~/Sources/linux/php-5.3.0alpha3/sapi/cli/php
&amp;lt;?php
$defaultDownloadDir = '/dir/path';
$defaultSshHost = &quot;user@host:/dir/path&quot;;

$args = arguments($argv);

if (! isset($args['arguments'][0]) || ! $args['arguments'][0])
	die(&quot;Usage: torrent-download.php QUERY
Options:
  --target=DIR
  --min-size=MB
  --max-size=MB
  --min-peers=COUNT
    Seeds are counted as 2 peers
  --ssh-target=HOST
    Ex user@host:/target/dir
&quot;);
if (! isset($args['options']['target']))
	$args['options']['target'] = $defaultDownloadDir;
if (! isset($args['options']['ssh-target']))
	$args['options']['ssh-target'] = $defaultSshHost;
require('/home/bob/workspace/phpQuery/phpQuery/phpQuery.php');
phpQuery::plugin('WebBrowser');
#phpQuery::$debug = 1;
$url = 'http://torrentz.com';
$sites = array(
	'mininova.org' =&amp;gt; 'h2 a',
	'thepiratebay.org' =&amp;gt; '.download a:first',
	'btjunkie.org' =&amp;gt; 'h1 a',
);
$scope = array(
	'args' =&amp;gt; $args,
	'sites' =&amp;gt; $sites,
);
$browser = phpQuery::browserGet($url, function($browser) use ($scope) {
	extract($scope);
	//var_dump($browser);
	//die();
	$browser['#thesearchbox']-&amp;gt;
		val($args['arguments'][0])-&amp;gt;
		parents('form')-&amp;gt;
			trigger('submit', array(function($browser) use ($scope) {
				extract($scope);
				//ver_dump($browser);
				$matches = $browser['dt a'];
				if (isset($args['options']['min-peers']))
					$matches = $matches-&amp;gt;filter(function($i, $node) use ($scope) {
						extract($scope);
						$spans = pq($node)-&amp;gt;parent()-&amp;gt;next()-&amp;gt;find('span');
						$peers = 2*$spans-&amp;gt;eq(2)-&amp;gt;text()+$spans-&amp;gt;eq(3)-&amp;gt;text();
						if ($peers &amp;lt; $args['options']['min-peers'])
							return false;
					});
				if (isset($args['options']['min-size']))
					$matches = $matches-&amp;gt;filter(function($i, $node) use ($scope) {
						extract($scope);
						$size = pq($node)-&amp;gt;parent()-&amp;gt;next()-&amp;gt;find('span:eq(1)')-&amp;gt;text();
						list($size, ) = explode(' ', $size);
						if ($size &amp;lt; $args['options']['min-size'])
							return false;
					});
				if (isset($args['options']['max-size']))
					$matches = $matches-&amp;gt;filter(function($i, $node) use ($scope) {
						extract($scope);
						$size = pq($node)-&amp;gt;parent()-&amp;gt;next()-&amp;gt;find('span:eq(1)')-&amp;gt;text();
						list($size, ) = explode(' ', $size);
						if ($size &amp;gt; $args['options']['max-size'])
							return false;
					});
				print &quot;Available results:n&quot;;
				$i = 1;
				foreach($matches as $node) {
					$spans = pq($node)-&amp;gt;parent()-&amp;gt;next()-&amp;gt;find('span');
					print ($i++).'. '.pq($node)-&amp;gt;text().&quot;t&quot;
						.$spans-&amp;gt;eq(1)-&amp;gt;text().&quot; (&quot;
							.$spans-&amp;gt;eq(2)-&amp;gt;text().&quot;/&quot;.$spans-&amp;gt;eq(3)-&amp;gt;text()
						.&quot;)n&quot;;
				}
				print &quot;Choose result number: &quot;;
				$choice = trim(fgets(STDIN));
				if (! $choice)
					return;
				$result = $matches-&amp;gt;eq($choice-1);
				$scope['name'] = trim(str_replace('/', '-', $result-&amp;gt;text()));
				$result-&amp;gt;WebBrowser()-&amp;gt;trigger('click', array(function($browser) use ($scope) {
					extract($scope);
					$siteFound = false;
					foreach($browser['.download .u'] as $node) {
						$site = trim(pq($node)-&amp;gt;text());
						if (isset($sites[$site])) {
							$scope['site'] = $site;
							print &quot;Requesting $site...n&quot;;
							phpQuery::ajaxAllowHost($site, &quot;www.$site&quot;);
							pq($node)-&amp;gt;parent()-&amp;gt;
								WebBrowser()-&amp;gt;
								//dump()-&amp;gt;
								trigger('click', array(function($browser) use ($scope) {
									extract($scope);
									// TODO torrent filename
									$browser[$sites[$site]]-&amp;gt;downloadTo(
										$args['options']['target'], &quot;$name.torrent&quot;
									);
									$path = $args['options']['target'].&quot;/$name.torrent&quot;;
									if (file_exists($path) &amp;amp;&amp;amp; filesize($path))
										print &quot;Got itn&quot;;
									if ($args['options']['ssh-target']) {
										print &quot;Sending via ssh...n&quot;;
										exec(&quot;scp &quot;$path&quot; {$args['options']['ssh-target']}&quot;);
									}
								}));
							$siteFound = true;
							break;
						}
					}
					if (! $siteFound)
						print &quot;No supported site availablen&quot;;
				}));
			}));
});

/**
 * @link http://pl.php.net/features.commandline
 *         'exec'      =&amp;gt; '',
 *         'options'   =&amp;gt; array(),
 *         'flags'     =&amp;gt; array(),
 *         'arguments' =&amp;gt; array(),
 */
function arguments($args ) {
    $ret = array(
        'exec'      =&amp;gt; '',
        'options'   =&amp;gt; array(),
        'flags'     =&amp;gt; array(),
        'arguments' =&amp;gt; array(),
    );

    $ret['exec'] = array_shift( $args );

    while (($arg = array_shift($args)) != NULL) {
        // Is it a option? (prefixed with --)
        if ( substr($arg, 0, 2) === '--' ) {
            $option = substr($arg, 2);

            // is it the syntax '--option=argument'?
            if (strpos($option,'=') !== FALSE) {
            	$t = explode('=', $option, 2);
            	$ret['options'][$t[0]] = $t[1];
//                array_push( $ret['options'], explode('=', $option, 2) );
            } else
            	$ret['options'][$option] = true;
//                array_push( $ret['options'], $option );

            continue;
        }

        // Is it a flag or a serial of flags? (prefixed with -)
        if ( substr( $arg, 0, 1 ) === '-' ) {
            for ($i = 1; isset($arg[$i]) ; $i++)
                $ret['flags'][] = $arg[$i];

            continue;
        }

        // finally, it is not option, nor flag
        $ret['arguments'][] = $arg;
        continue;
    }
    return $ret;
}//function arguments
</pre>
<p><strong>It uses PHP 5.3 closures, so be sure to be using this version.</strong> This was a real test for their&#8217;s (closures) functionality and in my opinion without using extract($scope) they couldn&#8217;t't be so usefull. Writing the selectors i&#8217;ve used quite handy tool <a href="http://selectorgadget.com">SelectorGadget bookmarklet</a>, althought it wasn&#8217;t perfect.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/383/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/383/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/383/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/383/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/383/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/383/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/383/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/383/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/383/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/383/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=383&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/6OzjSdrnfXc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/03/19/personal-torrent-stream-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/03/19/personal-torrent-stream-part-1/</feedburner:origLink></item>
		<item>
		<title>QueryTemplates development progress</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/rixQMsjY7EA/</link>
		<comments>http://tobiasz123.wordpress.com/2009/03/01/querytemplates-development-progress/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 23:06:07 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=371</guid>
		<description><![CDATA[QueryTemplates 1.0 Beta3 is out since a week or so and next release is around the corner, so i decided to do some wrap-up of latest facts in library development:

Extended data targets are no supported by all methods. This means each method can be re-targeted with jQuery insert methods like for example varsToSelectorBefore or even [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=371&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://querytemplates.wordpress.com/2009/02/22/quertytemplates-10-beta3-released/">QueryTemplates 1.0 Beta3 is out</a> since a week or so and next release is around the corner, so i decided to do some wrap-up of latest facts in library development:</p>
<ul>
<li><a href="http://code.google.com/p/querytemplates/issues/detail?id=1&amp;can=1"><strong>Extended data targets</strong></a> are no supported by all methods. This means each method can be re-targeted with jQuery insert methods like for example <a href="http://code.google.com/p/querytemplates/wiki/varsToSelectorBeforeMethodPHP">varsToSelectorBefore</a> or even <a href="http://code.google.com/p/querytemplates/wiki/varsToSelectorAfterMethodPHP">varsToSelectorAttr</a>.</li>
<li><strong>New <a href="http://code.google.com/p/querytemplates/wiki/codeToSyntax">codeTo</a> method type.</strong> It simply injects code groups. Idea evolved from methodTo approach, which would inject method calls. I find codeTo amuch more flexible and useful, but it can be less readable.</li>
<li><strong>New <a href="http://code.google.com/p/querytemplates/wiki/valuesToLoopMethodPHP">valuesToLoop</a> method.</strong> In opposite to <a href="http://code.google.com/p/querytemplates/wiki/varsToLoopMethodPHP">varsToLoop</a> aka loop(), it will iterate existing data over DOM structure and commit it right away. This has less purpose on server side (but can be useful), but it&#8217;s essential on the client-side when you don&#8217;t want to make a server request.</li>
<li><strong>New conditional chains methods</strong> &#8211; onlyJS() and onlyPHP(). They allow to highly customize template for certain language. For example, everything between onlyPHP() and endOnly() will be applied only to PHP template, even when the same chain is used to create JS template.</li>
<li><strong>Light version for JavaScript is available.</strong> It contains all <a href="http://code.google.com/p/querytemplates/wiki/valuesToSyntax">valuesTo</a> methods which includes valuesToSelector, valuesToStack and valuesToLoop. Form methods and mutation events support will be next. It&#8217;s a <a href="http://plugins.jquery.com/project/querytemplates-js">jQuery plugin</a> and <a href="http://sandbox.meta20.net/querytemplates-js/demo.html">demo is available</a>.</li>
<li><strong><a href="http://code.google.com/p/querytemplates/wiki/formFromVarsMethodPHP">formFromVars</a> will generate full form</strong> templates from structure and variable informations. Such form supports error messages and default values. Of course input-wrapper template is customizable. As for today there are couple of things to be done in this area and formFromValues will also be available soon.</li>
<li><strong><a href="http://code.google.com/p/querytemplates/wiki/Syntax">Syntax reference</a> is complete.</strong> Each method has it&#8217;s own wiki page with 6-part example: markup, data, formula aka code, template, tree dump before and tree dump after. Also, new JavaScript Light version is included in this reference. User comment are allowed. Personally i think it&#8217;s the best part of project&#8217;s page ;)</li>
<li><strong>Some API refactorings </strong>had taken place<strong>. </strong>Old names are still accessible, but marked as deprecated.
<ul>
<li><a href="http://code.google.com/p/querytemplates/wiki/varsFromSyntax"><strong>varsFrom</strong></a> type was created from such methods as saveTextAsVar, saveAsVar, valuesToVars.</li>
<li><strong>loop</strong>, loopOne and loopSeparate now becomes varsToLoop, varsToLoopFirst and varsToLoopSeparate and are grouped in <a href="http://code.google.com/p/querytemplates/wiki/ToLoopSyntax">ToLoop</a> type.</li>
</ul>
</li>
<li><strong>dumpTree</strong> is now more verbose and can be used both via HTML and plain text. Just do -&gt;dumpTree() anywhere in the chain to see readable representation of selected structure. It&#8217;s used for syntax reference examples.</li>
</ul>
<p><strong>As you can see project is quite close to 1.0 final.</strong> Code seems stable and each method has pseudo-unit-test in form of example available in <a href="http://code.google.com/p/querytemplates/wiki/Syntax">Syntax reference</a>, which is generated as a real template. I just can&#8217;t wait to start implementing CSS interface <a href="http://tobiasz123.wordpress.com/2009/01/27/can-css-stylesheets-be-applied-on-the-server-side/">i wrote before</a>. Additionaly, as JavaScript version is out, there can be some use for <a href="http://code.google.com/p/phpquery/wiki/jQueryServer">jQueryServer</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/371/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=371&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/rixQMsjY7EA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/03/01/querytemplates-development-progress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/03/01/querytemplates-development-progress/</feedburner:origLink></item>
		<item>
		<title>Can CSS stylesheets be applied on the server-side ?</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/VRWmUQM9XLs/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/27/can-css-stylesheets-be-applied-on-the-server-side/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 01:23:51 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[Workflow]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[designer]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[stylesheets]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=330</guid>
		<description><![CDATA[The question is: can CSS stylesheet be applied in the server-side ? And if yes, would would be the purpose ? I should say yes, they can and i would explain how and why. So what for are stylesheets ? &#8220;Applying cascading styles onto the DOM&#8221; may be the answer. But i would focus more [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=330&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>The question is:</strong> <em>can CSS stylesheet be applied in the server-side ?</em> And if yes, would would be the purpose ? I should say <strong>yes, they can</strong> and i would explain how and why. So what for are stylesheets ? &#8220;<em>Applying cascading <strong>styles onto the DOM</strong></em>&#8221; may be the answer. But i would focus more on that<strong> why actually stylesheets are used for such purpose?</strong></p>
<ul>
<li>Because they are clean ?</li>
<li><strong>Because </strong><strong>CSS selectors do so much job</strong>, that besides them only really needed things are simple properties with obligatory number of arguments ?</li>
<li><strong>Because cascading inheritance is just right for the DOM ?</strong></li>
<li>CSS selector are simply benefiting from DOM structure&#8217;s nature</li>
</ul>
<p>So first thing which needs to be implemented on the server is the DOM. When we already got it, so we can query it thou selector, that&#8217;s the first half. Now the properties. <strong>What could be the property on the server ? </strong>border-color ? Rather not. Do we need to style the DOM on the server ? Is it shown anywhere ? Not right now. <strong>On the server, page&#8217;s DOM is being build.</strong> Typically by various ways of string concatenation.</p>
<p>So if <strong>we need to build a DOM</strong> and same time we can query it with selectors, then the <strong>style&#8217;s properties should build / modify it&#8217;s structure</strong>. For example, show some articles or blog posts on the page. So here is pure <strong>CSS parser-validable code with</strong><strong> some</strong><strong> proposed server properties.</strong></p>
<pre class="brush: css;">
.section.articles ul &gt; li {
  /* loop &quot;articles&quot; variable as &quot;article&quot; using &quot;num&quot; as index
  after that remove all other-than-first LIs */
  loop-one: articles num article;

  /* apply filter method on next variable output */
  vars-filter: htmlentities;

  /* use &quot;article&quot; fields and populate them inside nodes
  matched by &quot;.a-%k&quot; where %k is field name, eg .a-title */
  vars-to-selector: articles var(articleFields) null &quot;.a-%k&quot;;

  /* example custom method to adding class for 1st loop node using index &quot;num&quot; */
  add-class-to-first: num custom-class;
}
/* show .comments node if variable articleComments is true */
.comments {
  if-var: articleComments;
}
/* bubbled event */
.section.articles:inserted {
  /* another custom method */
  /* null means 0 arguments */
  strip-tables: null;
}
</pre>
<p>So what have we done here ?</p>
<ol>
<li><strong>We simply build </strong><strong>articles loop which prints it&#8217;s contents into proper child nodes automagically.</strong> It could have 3 fields or 345, but line in CSS is only one.</li>
<li>We&#8217;ve also used a custom method do add class basing on the loop position.</li>
<li>Comments presentance is conditional.</li>
<li>One Mutation Event is used. Hidden in :insert pseudoclass, really named DOMNodeInserted will apply on all new nodes which matches prior selector and were just inserted into the DOM structure.</li>
<li><strong>Each unspecified event defaults</strong><strong> to :load.</strong></li>
</ol>
<p>All properties should be simply methods which applies something on all matched nodes. Sound familiar ? <strong>That&#8217;s exactly what many of jQuery methods are doing.</strong> Take a look:</p>
<pre class="brush: css;">
.section.articles {
  remove-class: section;
  attr: rel section;
  /* all css properties can be used
  but will result in inline &quot;style&quot; attributes */
  css: padding 2px;
}
/* this rule applies to all load-time nodes
and the new one too */
.change-me,
.change-me:inserted {
  text: &quot;changed innerText&quot;;
  prepend: &quot;
&lt;div&gt;changed&lt;/div&gt;
&quot;;
  remove-class: change-me;
  /* reallocation, interesting... */
  insert-into: &quot;.content&quot;;
  /* passing some data to forward ? */
  data: some-flag &quot;some value for developer&quot;;
}
</pre>
<p>All from above properties are jQuery methods. Possibilities are huge. But let&#8217;s stick with simple things right now. <strong>How would it benefit ? Who will write those server-css-sheets ? </strong>I should say&#8230;</p>
<p><span id="more-330"></span></p>
<h3>Designers</h3>
<p>In opinion of someone, <a href="http://compoundthinking.com/blog/index.php/2008/01/23/two-views-what-are-designer-friendly-templates/">Designers doesn&#8217;t care about anything other than CSS stylesheets</a>. I could agree with such statement. Now i would like to show you a simple but quite complete example of (again) simple webpage made almost entirely using Designer-friendly style.</p>
<p><strong>That means much CSS, much HTML and small amounts of copy-and-paste code :)</strong></p>
<p>Let&#8217;s start with the index.php file. I&#8217;m basing this example on QueryTemplates, a templating engine i&#8217;m currently working on. More on that later, now let&#8217;s see our files map:</p>
<p><strong>our-site/<br />
- templates/</strong><br />
- &#8211; page1.html<br />
- &#8211; page2.html<br />
- &#8211; page3.html<br />
- index.php</p>
<h3>index.php</h3>
<pre class="brush: php;">
include &quot;data.php&quot;;
$dir = dirname(__FILE__).'/';
try {
  require template()-&gt;parse($dir.$_REQUEST['page']);
catch (Exception $e) {
  require template()-&gt;parse($dir.'404.html');
}
</pre>
<p>Simple and catch&#8217;y ;) Who would not know what is this doing ?</p>
<h3>page1.html</h3>
<pre class="brush: xml;">
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
	&lt;link type=&quot;text/css&quot; href=&quot;server.css&quot; rel=&quot;server-stylesheet&quot;&gt;
	&lt;link type=&quot;text/css&quot; href=&quot;document.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;title&gt;Insert title here&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;My Articles&lt;/h1&gt;
&lt;div class=&quot;section articles&quot;&gt;
&lt;ul&gt;
	&lt;li&gt;
&lt;div class=&quot;a-title&quot;&gt;Lorem Ipsum Title&lt;/div&gt;
&lt;div class=&quot;a-body&quot;&gt;Lorem ipsum body&lt;/div&gt;&lt;/li&gt;
	&lt;li&gt;
&lt;div class=&quot;a-title&quot;&gt;Second row title&lt;/div&gt;
&lt;div class=&quot;a-body&quot;&gt;Second row body&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Code above has a completely destroyed indentation coz of wordpress, but it should be clear. Only purpose of second row is <strong>better preview of the page1.html file directly in the browser. </strong> Noticed this <em>server.css</em> link ? Remember about that. Now the last piece.</p>
<h3>data.php</h3>
<pre class="brush: php;">
$articles = array(
  array(
    'title' =&gt; 'My first article',
    'body' =&gt; 'Some body contents'
  ),
  array(
    'title' =&gt; 'My second article',
    'body' =&gt; 'Some body contents'
  ),
);
$articleFields = array_keys($article[0]);
</pre>
<p>Some simple data. Could be also a JSON as more user-friendly and less platform-related format.</p>
<h3>server.css</h3>
<pre class="brush: css;">
.section.articles ul &gt; li {
  loop-one: articles num article;
  vars-to-selector: articles var(articleFields);
  add-class-to-first: num custom-class;
}
</pre>
<p>Stylesheet above, which simply loops our articles over UL list, will be parsed on the server and then removed from the DOM.</p>
<p>Let&#8217;s back to benefits. So:</p>
<ul>
<li> <strong>designers will write more CSS</strong></li>
<li>will have more control over templates</li>
<li>will be able to realize simple tasks by themselves</li>
<li>this also applies to all tasks implemented as custom methods</li>
<li>there will be preview ready template sources to show to the client (in all stages of developement)</li>
<li><strong>to add more stylesheets, only needed thing is to add them as normal documents CSS stylesheets</strong>, no code-level changes would be needed.</li>
</ul>
<p>But would it be sufficient for all app&#8217;s templates ? Or would it mean that all templates <span style="text-decoration:underline;">have to be</span> implemented as CSS stylesheets ? <strong>I think this would be a disaster if we could not use real code for the templates.</strong> Remember this &#8220;<em>template()-&gt;parse()</em>&#8221; line ? Now after the parse() we can continue the chain in jQuery manner. We can query to multiple level and revert stack by the end() methods. We can also, same as CSS stylesheets, bind to an events, <a href="http://tobiasz123.wordpress.com/wp-admin/post.php?action=edit&amp;post=269">which i covered in previous post</a>. <strong>Also those custom methods used in stylesheets</strong> (like eg add-class-to-first) <strong>have to be written by developers</strong>. There is definitely more possible things to do using code, than a stylesheet. Most important is, <strong>those two ways doesn&#8217;t preclude themselves</strong>. Everything finally ends on the DOM. And i think that&#8217;s the way it should be when it comes to dynamically created webpages.</p>
<h3>What about AJAX ?</h3>
<p>So we&#8217;ve got simple chains which can be written as CSS properties. <strong>Now why not to applie them on the same DOM, using same code ?</strong> But instead of compiling template to server-side language, let&#8217;s make it a JavaScript one. That&#8217;s perfectly possible and QueryTemplates is doing this today. But the data is still platform-dependant. <strong>Let&#8217;s make it a JSON.</strong> From a database for example.</p>
<h3>articles.json.php</h3>
<pre class="brush: php;">
// DB fetch
$json = array(
  'articles' = $DB-&gt;articles(),
  'articleFields' =&gt; $DB-&gt;article-&gt;fields(),
);
QueryTemplates::jsonToScope(
  QueryTemplates::toJSON($json);
);
</pre>
<p>To use such template inside a browser we can utilize even old-school script includes, like this:</p>
<pre class="brush: xml;">
&lt;head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;articles.json.php&quot;&gt;&lt;/script&gt;&lt;/head&gt;
&lt;body&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;index.php?page=page1.html&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
</pre>
<p>This way of dealing with templates would be <strong>much better suiting team work and outsourcing companies</strong>. Also preparing <strong>many products on similar code/markup base become much more robust</strong>.</p>
<p>Another question is: <strong>can we use some of this on the browser ? AJAX, again ? </strong>Below i&#8217;m presenting something not so deeply thought. but it seems to be accomplishable and maybe even usable.</p>
<h3>Loosy mockup: browser.css</h3>
<pre class="brush: css;">
/*
#ajax pseudo-id will limit scope of rules to apply only for AJAX responses.
*/
#ajax[url^=&quot;/forms/singup&quot;] .change-me {
	border-color: 2px;
}
#ajax &gt; .sidebar &gt; * {
	insert-into: &quot;.sidebar&quot;;
}
#ajax &gt; .sidebar {
	remove: null;
}
/* there is no .sidebar in the #ajax anymore */
#ajax &gt; * {
	insert-into: &quot;.content&quot;;
}
/*
All below will also work for AJAX reponses.
*/
.article button:click {
	handler: alert &quot;sometext as arg&quot;;
	/* all css will be converted into inline styles */
	border-color: 2px;
}
.article .title:inserted {
	/* attach method to mousein event */
	handler: mousein GUI.showLayer &quot;layer name&quot;;
	/* trigger onclick event */
	trigger: click;
	/* wont trigger handler below, because it's not attached yet */
}
/* attach method to onclick event */
.article .title:click {
	map: GUI.findAnimatedParts;
	each: GUI.animate;
}
.article a.show-me-more:click {
	/* new method */
	load-append: &quot;/articles/more .articles&quot;;
	border-color: 2px;
}
/* context switching */
.article a.show-me-more:click {
	/* null means 0 arguments */
	/* this is actual stack */
	parent: null;
		/* possible delegation root ? */
		delegate-to: this;
		append: &quot;
&lt;div&gt;New element inside parent&lt;/div&gt;
&quot;;
	end: null;
}
.article a {
	filter: method(GUI.filterArticleAnchors);
		add-class: my-filter-result;
	end: null;
	/* this is quite crazy! */
	parent:;
		next:;
			add-class: 'nextone';
		end:;
	end:;
}
</pre>
<p>Stylesheet above behaviorizes the DOM. It realizes such functions as:</p>
<ul>
<li>AJAX handling</li>
<li>Events Delegation</li>
<li>jQuery interface in CSS</li>
</ul>
<p>Let&#8217;s tidy this idea. Look at this diagram. It shows how various CSS stylesheets could be applied into</p>
<h3>Document&#8217;s Lifecycle</h3>
<div id="attachment_340" class="wp-caption alignnone" style="width: 633px"><a href="http://meta20.net/images/querytemplates-css.png"><img class="size-full wp-image-340" title="querytemplates-css" src="http://meta20.net/images/querytemplates-css.png" alt="DOM Document's Lifecycle" width="623" height="597" /></a><p class="wp-caption-text">Document&#39;s Lifecycle</p></div>
<p>Looks complicated but it really isn&#8217;t. It simply means this things:</p>
<ol>
<li><strong>Server level CSS stylesheets</strong>
<ol>
<li>Are applied as many-to-many on templates sources thou template&#8217;s DOM</li>
<li>Are used to transform and prepare markup</li>
<li>Can also be used for easy patching some small bugs</li>
</ol>
</li>
<li><strong>Document level stylesheets</strong>
<ol>
<li>Used to style content visually</li>
</ol>
</li>
<li><strong>Brower level stylesheets</strong>
<ol>
<li>Used to add behaviors to document</li>
<li>Handles also AJAX requests</li>
<li>Can also easily transform DOM</li>
</ol>
</li>
</ol>
<p>That would be all folks. <strong>I know it can look crazy, but i think worth checking out.</strong> Hope you understood the idea, if not &#8211; please post some questions. If yes, feedback is also appreciated :)</p>
<p><strong>Important notice:</strong> most of the code in this post is just a mockup, it&#8217;s not yet implemented. You can follow server-side implementation <a href="http://code.google.com/p/querytemplates/issues/detail?id=15">in this ticket</a>. Meantime if you would like to play with DOM and CSS driven templates on the server download <a href="http://code.google.com/p/querytemplates/">QueryTemplates</a> for PHP.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/330/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=330&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/VRWmUQM9XLs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/27/can-css-stylesheets-be-applied-on-the-server-side/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>

		<media:content url="http://meta20.net/images/querytemplates-css.png" medium="image">
			<media:title type="html">querytemplates-css</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/27/can-css-stylesheets-be-applied-on-the-server-side/</feedburner:origLink></item>
		<item>
		<title>Events in CSS selector-driven markup templates make them highly reusable</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/6kzvzRpMHmk/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/25/events-in-css-selector-driven-markup-templates-make-them-highly-reusable/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 14:36:32 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=269</guid>
		<description><![CDATA[One of the biggest adventage of DOM oriented template engines such as QueryTemplates is events support. Using Event Delegation and some Mutation Events you can set global handlers for all templates. Purpose of such handlers may be varient. I&#8217;m presenting 6 of them as examples.
Let&#8217;s start from events table
Each event can easily have many handlers. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=269&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>One of the biggest adventage of DOM oriented template engines</strong> such as <a href="http://code.google.com/p/querytemplates/">QueryTemplates</a> <strong>is events support</strong>. Using Event Delegation and some Mutation Events you can set global handlers for all templates. Purpose of such handlers may be varient. I&#8217;m presenting 6 of them as examples.</p>
<h3>Let&#8217;s start from events table</h3>
<p>Each event can easily have many handlers. One of them is a mutation event &#8211; <em>DOMNodeInserted</em>.</p>
<pre class="brush: php;">
$globalHandlers = array(
  array('unload', 'everyTableHaveTbody'),
  array('load', 'insertNavigation'),
  array('DOMNodeInserted', 'newListsAlwaysOrdered'),
  array('unload', 'noAds'),
  array('unload', 'clearEmptyClasses'),
  array('load', 'stripTables'),
);
</pre>
<h3>Here&#8217;s our global handlers</h3>
<pre class="brush: php;">
// global handlers
// can be functions, methods, create_function and closures (in PHP 5.3)

function everyTableHaveTbody($e) {
  pq($e-&gt;target-&gt;ownerDocument)
    -&gt;find('table')
      // nested closure should be here
      -&gt;each('everyTableHaveTbodyCallback');
}
function everyTableHaveTbodyCallback($table) {
  if (pq('&gt; tbody', $table)-&gt;length == 0)
    pq($table)-&gt;contents()-&gt;wrapAll('
&lt;tbody&gt;');
}
function noAds($e) {
  pq($e-&gt;target-&gt;ownerDocument)
    -&gt;find('.ads')-&gt;remove();
}
function newListsAlwaysOrdered($e) {
  if (pq($e-&gt;target)-&gt;is('ul'))
    pq($e-&gt;target)-&gt;replaceWith(
      pq('
&lt;ol&gt;')-&gt;append(
        pq($e-&gt;target)-&gt;contents()
      )
    );
}
function insertNavigation($e) {
  $nav = pq($e-&gt;target-&gt;ownerDocument)
    -&gt;find('.navigation')
      -&gt;empty()
      // nested closure should be here
      -&gt;each('insertNavigationCallback');
}
function insertNavigationCallback($nav) {
  pq($nav)-&gt;append(file_get_contents('navigation.html'));
}
function stripTables($e) {
  pq($e-&gt;target)-&gt;find('table.strip-me')
    -&gt;removeClass('strip-me')
    -&gt;find('&gt; tr:odd, &gt; tbody &gt; tr:odd')
      -&gt;addClass('odd');
}
function clearEmptyClasses($e) {
  $nav = pq($e-&gt;target-&gt;ownerDocument)
    -&gt;find('*[class=&quot;&quot;]')
      -&gt;removeAttr('class');
}
</pre>
<p><span id="more-269"></span></p>
<p>Now let&#8217;s quickly extend phpQuery with method for batch event attaching.</p>
<pre class="brush: php;">
function bindMulti($self, $handlers) {
  foreach($handlers as $handler)
    $self-&gt;bind($handler[0], $handler[1]);
  return $self;
}
phpQuery::extend('phpQueryObject', array(
  'bindMulti' =&gt; 'bindMulti',
));
</pre>
<h3>The testing code</h3>
<p>This is out testing code with some data and template that will be modified by global event handlers.</p>
<pre class="brush: php;">
// this is out data
$rows = array(
  array(
    'field-1' =&gt; 'foo1',
    'field-2' =&gt; 'foo2',
  ),
  array(
    'field-1' =&gt; 'bar1',
    'field-2' =&gt; 'bar2',
  ),
);
// this is out file (page fragment)
$source = dirname(__FILE__).'/table.html';
require template('table')-&gt;parse($source)
  // bind all delegation events
  -&gt;bindMulti($globalHandlers)
  // fire up manually
  -&gt;trigger('load')
  // here some template processing takes place
  -&gt;find('table:first &gt; tr, table:first &gt; * &gt; tr')
    -&gt;loopOne('rows', 'i', 'row')
      -&gt;varsToSelector('row', $rows[0])
    -&gt;end()
  -&gt;end()
  // we're testing newListsAlwaysOrdered
  -&gt;append('
&lt;ul&gt;
	&lt;li&gt;1&lt;/li&gt;
	&lt;li&gt;2&lt;/li&gt;
	&lt;li&gt;3&lt;/li&gt;
&lt;/ul&gt;
')
  // fire up manually again
  -&gt;trigger('unload')
;
</pre>
<h3>Result</h3>
<p>The result is as expected. The template logic is shorter than 10 lines but many rules are applied during those lines.</p>
<pre class="brush: xml;">
&lt;table&gt;
&lt;tbody&gt;
&lt;?php  foreach($rows as $i =&gt; $row):  ?&gt;
&lt;tr&gt;
&lt;td class=&quot;field-1&quot;&gt;&lt;?php  print is_object($row) ? $row-&gt;{'field-1'} : $row['field-1']  ?&gt;&lt;/td&gt;
&lt;td class=&quot;field-2&quot;&gt;&lt;?php  print is_object($row) ? $row-&gt;{'field-2'} : $row['field-2']  ?&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;?php  endforeach;  ?&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;row1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td&gt;row2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;row3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;ol&gt;
	&lt;li&gt;1&lt;/li&gt;
	&lt;li&gt;2&lt;/li&gt;
	&lt;li&gt;3&lt;/li&gt;
&lt;/ol&gt;
</pre>
<p>If your concerned about speed in which this will execute and how long it delay your page request &#8211; don&#8217;t worry anymore. <strong>Not counting file inclusions and with template&#8217;s caching turned on it&#8217;s about&#8230; <span style="text-decoration:underline;">~0.0005</span> of the second</strong> :) Why ? Because it just includes plain PHP file, which is generated one time, that&#8217;s why.</p>
<p>To get this code working just grab newest revisions of <a href="http://code.google.com/p/querytemplates/source/checkout">QueryTemplates</a> and <a href="http://code.google.com/p/phpquery/wiki/SVNCheckout?tm=4">phpQuery</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/269/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=269&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/6kzvzRpMHmk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/25/events-in-css-selector-driven-markup-templates-make-them-highly-reusable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/25/events-in-css-selector-driven-markup-templates-make-them-highly-reusable/</feedburner:origLink></item>
		<item>
		<title>QueryTemplates – template’s logic and markup in one file</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/jw6NcwENyYo/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/25/querytemplates-templates-logic-and-markup-in-one-file/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 13:41:47 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=277</guid>
		<description><![CDATA[Using latest phpQuery revisions you can easily keep template&#8217;s markup and logic in one place with 2 extra lines of code. This heavily breaks the general concept, but it may be useful in some cases. Idea is based on support for callbacks as template sources. First you start dumping markup with 1 line.

&#60;?php ob_start(); ?&#62;

After [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=277&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Using <a href="http://code.google.com/p/phpquery/source/list">latest phpQuery</a> revisions <strong>you can easily keep template&#8217;s markup and logic in one place with 2 extra lines of code</strong>. This heavily breaks the general concept, but it may be useful in some cases. Idea is based on support for callbacks as template sources. First you start dumping markup with 1 line.</p>
<pre class="brush: php;">
&lt;?php ob_start(); ?&gt;
</pre>
<p>After that the markup goes</p>
<pre class="brush: xml;">
&lt;html&gt;
  &lt;body&gt;
&lt;div&gt;Hello world&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>And at the end there is whole logic. $markup is dumped using new CallbackReturnValue, which takes a variable as parameter. When callback is called it just returns it.</p>
<pre class="brush: php;">
&lt;?php
require('../src/QueryTemplates.php');
$markup = new CallbackReturnValue(ob_get_clean());
require template('test')-&gt;parse($markup)
	-&gt;find('div')
		-&gt;text('Hello template!')
;
</pre>
<p>This approach could also be used for <a href="http://code.google.com/p/querytemplates/source/browse/qt-blog/views/posts/admin_edit.ctp#6">getting markup with requestAction</a> in CakePHP views.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/277/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=277&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/jw6NcwENyYo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/25/querytemplates-templates-logic-and-markup-in-one-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/25/querytemplates-templates-logic-and-markup-in-one-file/</feedburner:origLink></item>
		<item>
		<title>toReference() inside chains</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/gYLEGvuqNOc/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/25/toreference-inside-chains/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 13:26:03 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[Chainable]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=275</guid>
		<description><![CDATA[There is one extremely useful and not-so widely known toReference() method. It saves actually matched elements inside variable, by reference (as the name says). It can be used to target such cases as:
1. Preserving chain

// declare our variables (this is VERY important)
$deepClass = $section = null;
$template['div.main div.otherclass .deep-class:first']
  -&#62;toReference($deepClass)
//  -&#62;...  // do [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=275&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>There is one extremely useful and not-so widely known <a href="http://meta20.net/querytemplates-api/phpQuery/phpQueryObject.html#methodtoReference">toReference</a>() method. It saves actually matched elements inside variable, by reference (as the name says). It can be used to target such cases as:</p>
<h3>1. Preserving chain</h3>
<pre class="brush: php;">
// declare our variables (this is VERY important)
$deepClass = $section = null;
$template['div.main div.otherclass .deep-class:first']
  -&gt;toReference($deepClass)
//  -&gt;...  // do something
  -&gt;find('.section')
    -&gt;toReference($section)
//  -&gt;...  // do something
  -&gt;end()
  -&gt;next()
    // highlighter but; only one empty()
    -&gt;empty()
    -&gt;append($deepClass-&gt;contents())
    -&gt;eq(0)-&gt;add($section)-&gt;eq(1)
//      -&gt;...  // do something, stack is [$section]
    -&gt;end()-&gt;end()-&gt;end()
//      -&gt;...  // stack is same as after -&gt;next()
;
</pre>
<h3>2. Splitting chains</h3>
<pre class="brush: php;">
// declare our variables (this is VERY important)
$row = $titleBody = null;
$template
  -&gt;find('ul:first &gt; li')
    -&gt;loopOne('posts', 'postNum', 'r')
      // add dynamic class
      -&gt;addClassPHP('if (! $postNum) print &quot;first&quot;')
      -&gt;find('&gt; .title, &gt; .body')
        -&gt;varsToStack('r[&quot;Post&quot;]', $postFields)
        // save our $titleBody variable
        -&gt;toReference($titleBody)
      -&gt;end()
      // save our $row variable
      -&gt;toReference($row)
//    -&gt;...  // lots of code ;)
;
// just continue your work
$row-&gt;find('h3:first, .comments')
// -&gt;...
;
// anywhere...
doSomethingOnFields($titleBody);
</pre>
<p>In <a href="http://code.google.com/p/querytemplates/source/checkout">SVN version</a> of QueryTemplates there is a fix for cache issue. The workaround for beta2 is to do &#8220;if ($ref)&#8221; before, or turning off the cache with &#8220;$cacheTimeout = -1&#8243;.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/275/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=275&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/gYLEGvuqNOc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/25/toreference-inside-chains/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/25/toreference-inside-chains/</feedburner:origLink></item>
		<item>
		<title>Extending QueryTemplates with closures</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/tvSagGu2WF0/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/25/extending-querytemplates-with-closures/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 12:24:19 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[closures]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=255</guid>
		<description><![CDATA[Lastest changes in phpQuery allows us to extend it much more easily. One of the ways to do this is directly same as in jQuery, using phpQuery::extend() method. When you combine this with upcoming closures in PHP 5.3, you will feel like-almost-in-browser. Take a look at this:

$source = dirname(__FILE__).'/table.html';
$rows = array(
	array(
		'field-1' =&#62; 'foo1',
		'field-2' =&#62; 'foo2',
	),
	array(
		'field-1' [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=255&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://code.google.com/p/phpquery/source/list">Lastest changes</a> in <a href="http://code.google.com/p/phpquery/">phpQuery</a> allows us to extend it much more easily. <strong>One of the ways to do this is directly same as in jQuery, using </strong><strong>phpQuery::extend() method</strong>. When you combine this with upcoming closures in PHP 5.3, you will feel <em>like-almost-in-browser</em>. Take a look at this:</p>
<pre class="brush: php;">
$source = dirname(__FILE__).'/table.html';
$rows = array(
	array(
		'field-1' =&gt; 'foo1',
		'field-2' =&gt; 'foo2',
	),
	array(
		'field-1' =&gt; 'bar1',
		'field-2' =&gt; 'bar2',
	),
);
// this will work in PHP 5.3
// this code will evaluate on onLoad event, thus is cache firendly
$onload = function() {
  $tableFirstRowClass = function($self, $var, $classname = 'first') {
    return $self-&gt;addClassPHP(&quot;
      if ($$var == 0)
        print '$classname';
    &quot;);
  };
  // here we pass new closure into extend method, just like in jQuery
  // compact() creates array for us
  phpQuery::extend('phpQueryObject', compact('tableFirstRowClass'));
};
require template('table')-&gt;parse($source)
  // just bind it
  -&gt;bind('onload', $onload)
  // just fire it up ;)
  -&gt;trigger('onload')
  -&gt;find('table &gt; tr, table &gt; * &gt; tr')
    -&gt;loopOne('rows', 'i', 'row')
      -&gt;varsToSelector('row', $rows[0])
      // now you can use this just-like-this
      -&gt;tableFirstRowClass('i')
;
</pre>
<p>But for now to extend phpQuery on-the-fly we have to use create_function or delegate existing one.</p>
<p><strong>We can also use new </strong><strong>Scripts plugin feature</strong>, which does <em>almost</em> the same. Just like all Scripts&#8217; plugin script files, newly attached function will have all available variables. Example below works in PHP &lt; 5.3:</p>
<pre class="brush: php;">
function onload() {
  // in PHP 5.3, this can be done simply like this
//  phpQuery::script(...
  // but for now we have to use fake phpQuery::$plugins namespace
  phpQuery::$plugins-&gt;script('tableFirstRowClass', create_function(
    '$self, $params, &amp;$return, $config', '
    $className = ! $params[1] ? &quot;first&quot; : $params[1];
    $self-&gt;addClassPHP(&quot;
      if ($$params[0] == 0) print '$className';
    &quot;);
  '));
};
$onload = 'onload';
</pre>
<p>One major difference between extending Scripts and phpQuery itself is way of using new functions. With our new script, we have to small change to main code.</p>
<pre class="brush: php;">
// using phpQuery::extend()
//-&gt;tableFirstRowClass('i')
// using Scripts extend
-&gt;script('tableFirstRowClass', 'i')</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/255/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=255&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/tvSagGu2WF0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/25/extending-querytemplates-with-closures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/25/extending-querytemplates-with-closures/</feedburner:origLink></item>
		<item>
		<title>Utilizing Mutation Events for automatic and persistent event attaching</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/JbBhpM4PpPQ/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/19/utilizing-mutation-events-for-automatic-and-persistent-event-attaching/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 17:43:38 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[reglib]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=161</guid>
		<description><![CDATA[Most of you probably heard about Event Delegation, a technique where you bind to event of interest on parent node and when triggered event bubbles from child node, action in taken inside the parent. This pattern is widely popularized by reglib and Live Query (plugin for jQuery). Newly released jQuery 1.3 has it&#8217;s own implementation [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=161&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Most of you probably heard about <strong>Event Delegation</strong>, a technique where you bind to event of interest on parent node and when triggered event bubbles from child node, action in taken inside the parent. This pattern is widely popularized by <a href="http://code.google.com/p/reglib/">reglib</a> and <a href="http://code.google.com/p/jquery-utils/wiki/LiveQuery">Live Query</a> (plugin for jQuery). Newly released jQuery 1.3 has it&#8217;s own implementation thou $.live() method.</p>
<p>This patten has couple of advantages over classic attaching model. First, it&#8217;s faster for BIG number of (same) nodes. Secondly, which is most important i think, it allows easy content exchange via AJAX. But with all that it has also disadvantages and main is that you doesn&#8217;t really attach to a node, only to it&#8217;s parent. That means when you relocate node in the DOM it looses it&#8217;s behavior.</p>
<p>That&#8217;s why i&#8217;ve came with the idea of using <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents">Mutation Events</a> to take best parts from both patterns. Mutation Events aren&#8217;t supported in IE, but i&#8217;ve rolled out some <strong>compatibility layer</strong> to target this problem. Works also with document fragment appends introduced in jQuery 1.3.</p>
<p>You can go straight to the <a href="http://meta20.net/sandbox/mutation-events-attaching/comparsion.html"><strong>demo</strong></a>, which was tested and works with:</p>
<ul>
<li>Firefox 3 and 2 linux</li>
<li>IE6 SP2 win32</li>
<li>Opera 9.63 linux</li>
<li>Safari 3.6 win32</li>
<li>Chrome 1.0 win32</li>
</ul>
<p>First lets see main code:</p>
<pre class="brush: php;">
function attachEvents(node) {
	// node is an optional callback for filter()
	// that applies rules only for new nodes
	node = node || '*';
	$('.container1 .trigger1').filter(node).click(function(e) {
		alert('mutation events work');
		e.preventDefault();
	});
}
</pre>
<p>This is simple, common function that applies behaviors to the document. The only major difference from other such functions is <strong>node</strong> parameter, used as callback for <strong>filter()</strong> method, which limits found nodes to interesting ones. Now the actual event bindings:</p>
<pre class="brush: php;">
// node inserted into DOM
$(document).bind('DOMNodeInserted', function(e) {
	attachEvents(function(node){
		return !e.target.skipEventAttaching &amp;&amp;
			this == e.target
	});
});
// node removed from DOM
$(document).bind('DOMNodeRemoved', function(e) {
	// add information property, that node has been detached
	e.target.skipEventAttaching = true;
});
</pre>
<p>Here the magic happens ;) First handler fires up our event attaching function with callback for filter as a parameter. Callback will check if found node is target of the mutation event or is it reinserted. Second handler adds flag about reinserting.</p>
<p>You can see <a href="http://meta20.net/sandbox/mutation-events-attaching/comparsion.html"><strong>demo</strong></a> which compares this technique with jQuery 1.3 and reglib. It consists of 3 different implementation:</p>
<ul>
<li>jQuery 1.3 using Mutation Events</li>
<li>jQuery 1.3 using $.live</li>
<li>reglib</li>
</ul>
<p><strong>Test it like this</strong>: click <strong>add node</strong> (couple of times), click <strong>.trigger</strong> (first one, last one) then do <strong>move node</strong> and again click moved node. Each time when clicking on <strong>.trigger</strong>, one (and only one) alert should pop out saying that certain technique works.<strong><br />
</strong></p>
<p>Additionally there&#8217;s a <a href="http://meta20.net/sandbox/mutation-events-attaching/ie-mutation-events.js">IE compatibility</a> for mutation events in conditional comment. Great help writing it was from <a href="http://delete.me.uk/2004/09/ieproto.html">ieproto</a> example.</p>
<p>Of course this is proof-of-concept and souldn&#8217;t be used in production until fully tested and fixed.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/161/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=161&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/JbBhpM4PpPQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/19/utilizing-mutation-events-for-automatic-and-persistent-event-attaching/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/19/utilizing-mutation-events-for-automatic-and-persistent-event-attaching/</feedburner:origLink></item>
		<item>
		<title>Test cases for websites using phpQuery and SimpleTest</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/g7HHVgPE-EI/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/13/test-cases-for-websites-using-phpquery-and-simpletest/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 21:09:43 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scraping]]></category>
		<category><![CDATA[test cases]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=177</guid>
		<description><![CDATA[Using phpQuery and some UnitTest framework (SimpleTest in this example) you can automatically test web page for presentence of specific part and it&#8217;s position. Set of such tests can save a lot of time during website development and after that even more.
Not only you can do simple tests like &#8220;are articles visible&#8221; but using WebBrowser [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=177&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Using <strong>phpQuery</strong> and some <strong>UnitTest</strong> framework (<a href="http://simpletest.org/index.html">SimpleTest</a> in this example) you can automatically test web page for presentence of specific part and it&#8217;s position. Set of such tests can save a lot of time during website development and after that even more.</p>
<p>Not only you can do simple tests like &#8220;are articles visible&#8221; but using <strong>WebBrowser plugin</strong> you can test whole process, let&#8217;s say a <strong>user registration</strong>. Example of such test i would like to present. This test will include following steps:</p>
<ol>
<li>Enter main page and follow the registration link</li>
<li>Fill registration form and submit it</li>
<li>Check if result is expected</li>
</ol>
<p>Like i sad before, SimpleTest is framework of choice, but it doesn&#8217;t matter so much. What&#8217;s important:</p>
<ul>
<li>WebBrowser needs callbacks</li>
<li>Callbacks should be declared as functions (for PHP &lt; 5.3)</li>
<li>Inside callbacks, $this variable is unavailable</li>
<li>First step of the test should check if last step has succeeded</li>
</ul>
<p>Full code below:</p>
<pre class="brush: php;">
require('simpletest/autorun.php');
require('phpQuery/phpQuery.php');

class CustomerTest extends UnitTestCase {
	public static $_this;
	public static $registration = array(
		'username' =&gt; null,
		'success' =&gt; false
	);
	function testRegistration() {
		self::$_this = $this;
		phpQuery::browserGet('http://localhost/tested-site/',
			array('CustomerTest', '_testRegistrationLink')
		);
		$this-&gt;assertTrue(
			self::$registration['success'], &quot;Registration unsuccessful&quot;
		);
	}
	function _testRegistrationLink($browser) {
		$registrationLink = null;
		$browser-&gt;find('a:contains(rejestracja)')
			-&gt;WebBrowser(array('CustomerTest', '_testRegistrationForm'))
			-&gt;toReference($registrationLink)
				// jump to _testRegistrationForm
				-&gt;click();
		self::$_this-&gt;assertTrue(
			$registrationLink-&gt;length, &quot;Registration link missing&quot;
		);
	}
	function _testRegistrationForm($browser) {
		$registrationForm = null;
		$username = md5(microtime());
		$browser['.customers.form form']
			-&gt;toReference($registrationForm)
			-&gt;WebBrowser(array('CustomerTest', '_testRegistrationResult'))
			-&gt;find('input[name*=login]')-&gt;val($username)-&gt;end()
			-&gt;find('input[name*=email]')-&gt;val($username.'@test.com')-&gt;end()
			// jump to _testRegistrationResult
			-&gt;submit();
		self::$_this-&gt;assertTrue(
			$registrationForm-&gt;length, &quot;Registration form missing&quot;
		);
		self::$registration['username'] = $username;
	}
	function _testRegistrationResult($browser) {
		$loginForm = $browser-&gt;find('h2:text(Logowanie)');
		self::$_this-&gt;assertTrue($loginForm-&gt;length, &quot;Login form missing&quot;);
		if ($loginForm-&gt;length)
			self::$registration['success'] = true;
	}
}
</pre>
<p>WebBrowser doesn&#8217;t support AJAX, so not all sites can be tested like this (although you can do it with AHAH after some work), but <strong>cookies</strong> and <strong>HTTP authentication</strong> should satisfy most needs.</p>
<p>Of course that&#8217;s noting new, projects accomplishing similar goal exist quite time now, eg <a href="http://jwebunit.sourceforge.net/">jWebUnit</a>, but neither of them have <strong>jQuery </strong>under the hood  ;)</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/177/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/177/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/177/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/177/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/177/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/177/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/177/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/177/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/177/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/177/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=177&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/g7HHVgPE-EI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/13/test-cases-for-websites-using-phpquery-and-simpletest/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/13/test-cases-for-websites-using-phpquery-and-simpletest/</feedburner:origLink></item>
		<item>
		<title>Having fun using PHP 5.3 closures with phpQuery</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/csYbomh0fak/</link>
		<comments>http://tobiasz123.wordpress.com/2009/01/08/having-fun-using-php-53-closures-with-phpquery/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 14:34:08 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[closures]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=159</guid>
		<description><![CDATA[Some time ago i&#8217;ve wrote about new PHP 5.3 closures feature. Today i would like to show you it in action with phpQuery. If you&#8217;re using jQuery you will feel like in home :)
First example illustrates classic inline function, which is used to iterate over li nodes, incrementing each one&#8217;s content.

$markup = '
&#60;ul&#62;
	&#60;li&#62;1&#60;/li&#62;
	&#60;li&#62;2&#60;/li&#62;
	&#60;li&#62;3&#60;/li&#62;
&#60;/ul&#62;
';
$doc = phpQuery::newDocument($markup);
$doc['li']-&#62;each(function($node){
	pq($node)-&#62;text(
		pq($node)-&#62;text()+1
	);
});
print [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=159&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Some time ago <a href="http://tobiasz123.wordpress.com/2008/11/25/php-53-introduces-closures-and-inline-functions/">i&#8217;ve wrote</a> about new <strong>PHP 5.3 closures</strong> feature. Today i would like to show you it in action with phpQuery. If you&#8217;re using jQuery you will feel like in home :)</p>
<p>First example illustrates <strong>classic inline function</strong>, which is used to iterate over <strong>li</strong> nodes, incrementing each one&#8217;s content.</p>
<pre class="brush: php;">
$markup = '
&lt;ul&gt;
	&lt;li&gt;1&lt;/li&gt;
	&lt;li&gt;2&lt;/li&gt;
	&lt;li&gt;3&lt;/li&gt;
&lt;/ul&gt;
';
$doc = phpQuery::newDocument($markup);
$doc['li']-&gt;each(function($node){
	pq($node)-&gt;text(
		pq($node)-&gt;text()+1
	);
});
print $doc;
</pre>
<p>Result will be someting like this (something because i&#8217;ve corrected indentation manually).</p>
<pre class="brush: xml;">
&lt;ul&gt;
	&lt;li&gt;2&lt;/li&gt;
	&lt;li&gt;3&lt;/li&gt;
	&lt;li&gt;4&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Now more complicated stuff &#8211; <strong>scope inheritance</strong>. Scope inheritance means nothing else than ability to use variables declared outside code block (inline function in this case) inside this particular block. In JavaScript we have full inheritance right away. In PHP 5.3 we have to explicitly declare which variable we would like to inherit. It&#8217;s done by <strong>use</strong> keyword.</p>
<pre class="brush: php;">
$markup = '
&lt;div&gt;
	&lt;span&gt;1&lt;/span&gt;
	&lt;span&gt;2&lt;/span&gt;
	&lt;span&gt;3&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
	&lt;span&gt;1&lt;/span&gt;
	&lt;span&gt;2&lt;/span&gt;
	&lt;span&gt;3&lt;/span&gt;&lt;/div&gt;
';
$doc = phpQuery::newDocument($markup);
$doc['div']-&gt;each(function($div){
	$div = pq($div);
	$div['span']-&gt;each(function($span) use ($div){
		pq($span)-&gt;insertBefore($div);
	});
});
print $doc;
</pre>
<p>We&#8217;ve nested one closure inside another. The inner one inherits <strong>$div</strong> variable from the outer. Lack of such feature for <strong>create_function</strong> was <span style="text-decoration:underline;">really</span> problematic. Below you can see the result. Both divs are now empty.</p>
<pre class="brush: xml;">
&lt;span&gt;1&lt;/span&gt;
&lt;span&gt;2&lt;/span&gt;
&lt;span&gt;3&lt;/span&gt;
&lt;div&gt;&lt;/div&gt;
&lt;span&gt;1&lt;/span&gt;
&lt;span&gt;2&lt;/span&gt;
&lt;span&gt;3&lt;/span&gt;
&lt;div&gt;&lt;/div&gt;
</pre>
<p>Third example i want to show is about assigning inline function to a variable. It&#8217;s handful technique to avoid namespace collisions and of course allow easily pass closure thou the parts of code.</p>
<pre class="brush: php;">
$markup = '
&lt;div&gt;1&lt;/div&gt;
&lt;div&gt;2&lt;/div&gt;
&lt;div&gt;3&lt;/div&gt;
';
$callback = function($node){
	$node = pq($node);
	$node-&gt;text(
		'Callbacked: '.$node-&gt;text()
	);
};
print phpQuery::newDocument($markup)
	-&gt;find('div')-&gt;each($callback)-&gt;end();
</pre>
<p>Just how you suspect, every node&#8217;s content will be prefixed with &#8220;Callbacked: &#8220;.</p>
<pre class="brush: xml;">
&lt;div&gt;Callbacked: 1&lt;/div&gt;
&lt;div&gt;Callbacked: 2&lt;/div&gt;
&lt;div&gt;Callbacked: 3&lt;/div&gt;
</pre>
<p>I think that this post clearly illustrates how closures work and that they are important for PHP as web development language.</p>
<p>If you would like to test code from this post and PHP 5.3 in general, download <a href="http://windows.php.net/qa/">windows build</a> from php.net or compile <a href="http://downloads.php.net/johannes/php-5.3.0alpha3.tar.bz2">source</a> yourself for other platform. <strong>CLI</strong> version will be enough, that means <strong>no apache</strong> module struggling.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/159/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=159&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/csYbomh0fak" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2009/01/08/having-fun-using-php-53-closures-with-phpquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2009/01/08/having-fun-using-php-53-closures-with-phpquery/</feedburner:origLink></item>
		<item>
		<title>Modify arrays easily using BAM – BulkArrayModifier</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/mKBT46mVj1g/</link>
		<comments>http://tobiasz123.wordpress.com/2008/12/30/modify-arrays-easily-using-bam-bulkarraymodifier/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 20:46:47 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Chainable]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[arrays]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=144</guid>
		<description><![CDATA[Have you ever needed to modify certain fields in deeply nested array structure ? I&#8217;ve had such tasks writing CakePHP views quite often. Tried to use Set, but it only extracts data. When you modify it, you can use it standalone, but not with rest of the data it was stick to before extracting. That&#8217;s [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=144&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Have you ever needed to modify certain fields in deeply nested array structure ? I&#8217;ve had such tasks writing CakePHP views quite often. Tried to use <a href="http://debuggable.com/posts/xpath-on-php-arrays-set-extract:48ca6265-258c-4032-b3ff-55b84834cda3">Set</a>, but it only extracts data. When you modify it, you can use it standalone, but not with rest of the data it was stick to before extracting. That&#8217;s why i&#8217;ve always wanted to write something what will make this process cleaner and more natural, removing the need to write redundant code.</p>
<p>That&#8217;s why one evening i sat down and here it is &#8211; <strong>BulkArrayModifier</strong>. Standalone, chainable, ~120 lines class which extracts array&#8217;s content via references. It utilizes callbacks as much as possible. Consider this example:</p>
<pre class="brush: php;">
// get all comments from all posts
bam($posts)-&gt;all()-&gt;key('Comment')-&gt;all()-&gt;each('modifyTitle');
// and use this callback to modify each one
function modifyTitle($comment) {
  $comment['title'] = &quot;&lt;a&gt;{$comment['title']}&lt;/a&gt;&quot;;
  return $comment;
}
</pre>
<p>There is also one-method query, like this:</p>
<pre class="brush: php;">
bam($posts)-&gt;path('*.Comment.*')-&gt;each('modifyTitle');
</pre>
<p>You can also apply several callbacks to one bam() object</p>
<pre class="brush: php;">
bam($posts)-&gt;path('*.Comment.*')-&gt;each('modifyTitle')-&gt;reset()
  -&gt;path('*.Post.author')-&gt;each('modifyAuthor');
</pre>
<p><span id="more-144"></span></p>
<p>bam() modifies $posts variable via reference, so no re-assignment is needed. create_function also can be used. It&#8217;s a bit jQuery like and i&#8217;m considering support for end() method.</p>
<p>I&#8217;m placing full sourcecode here, because it&#8217;s too small to be a project. In future, i think it will be merged into Chainable library.</p>
<pre class="brush: php;">
&lt;?php
class BulkArrayModifier {
	protected $source;
	protected $stack;
	function __construct(&amp;$array) {
		$this-&gt;source =&amp; $array;
	}
	/**
	 *
	 * @param $strMatch
	 * @return BulkArrayModifier
	 */
	function all($strMatch = null) {
		if (is_null($this-&gt;stack)) {
			$this-&gt;stack = array();
			foreach($this-&gt;source as $k =&gt; &amp;$v) {
				if (isset($strMatch) &amp;&amp; strpos($k, $strMatch) === false)
					continue;
				$this-&gt;stack[] =&amp; $v;
			}
		} else {
			$result = array();
			foreach($this-&gt;stack as &amp;$array) {
				foreach($array as $k =&gt; &amp;$v) {
					if (isset($strMatch) &amp;&amp; strpos($k, $strMatch) === false)
						continue;
					$result[] =&amp; $v;
				}
			}
			$this-&gt;stack = $result;
		}
		return $this;
	}
	/**
	 *
	 * @param $key
	 * @return BulkArrayModifier
	 */
	function key($key) {
		if (is_null($this-&gt;stack)) {
			$this-&gt;stack = array();
			if (isset($this-&gt;source[$key]))
				$this-&gt;stack[] = &amp;$this-&gt;source[$key];
		} else {
			$result = array();
			foreach($this-&gt;stack as &amp;$array) {
				if (! isset($array[$key]))
					continue;
				$result[] =&amp; $array[$key];
			}
			$this-&gt;stack = $result;
		}
		return $this;
	}
	/**
	 *
	 * @param $path
	 * @return BulkArrayModifier
	 */
	function path($path) {
		// TODO preg split, allow backslashing
		$path = explode('.', $path);
		while(!empty($path)) {
			$part = array_shift($path);
			switch($part) {
				case '*':
					$this-&gt;all();
					break;
				default:
					$this-&gt;key($part);
			}
		}
		return $this;
	}
	/**
	 *
	 * @return Array
	 */
	function &amp;get() {
		return $this-&gt;stack;
	}
	/**
	 *
	 * @param $callback
	 * @return BulkArrayModifier
	 */
	function each($callback) {
		if (is_null($this-&gt;stack)) {
			foreach($this-&gt;source as &amp;$v) {
				$v = call_user_func_array($callback, $v);
			}
		} else {
			foreach($this-&gt;stack as $k =&gt; &amp;$v) {
				$v = call_user_func_array($callback, array($v));
			}
		}
		return $this;
	}
	/**
	 *
	 * @param $callback
	 * @return BulkArrayModifier
	 */
	function filter($callback) {
		if (!is_null($this-&gt;stack)) {
			foreach($this-&gt;stack as $k =&gt; &amp;$v) {
				$result = call_user_func_array($callback, array($v));
				if ($result === false)
					unset($this-&gt;stack[$k]);
			}
		}
		return $this;
	}
	/**
	 *
	 * @param $callback
	 * @return BulkArrayModifier
	 */
	function reset() {
		$this-&gt;stack = null;
		return $this;
	}
}
function bam(&amp;$array) {
	return new BulkArrayModifier($array);
}
</pre>
<p>Have fun ;)</p>
<p>PS. If you&#8217;re playing with arrays check out <a href="http://www.codeplex.com/PHPLinq/Wiki/View.aspx?title=Examples&amp;referringTitle=Home">PHPLinq</a>, a port of .NET&#8217;s <span>Language Integrated Query. However i couldn&#8217;t make it to work like i would want to.<br />
</span></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/144/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/144/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=144&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/mKBT46mVj1g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/12/30/modify-arrays-easily-using-bam-bulkarraymodifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/12/30/modify-arrays-easily-using-bam-bulkarraymodifier/</feedburner:origLink></item>
		<item>
		<title>QueryTemplates finally released</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/cK6q1NCB0Oo/</link>
		<comments>http://tobiasz123.wordpress.com/2008/12/03/querytemplates-finally-released/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 14:47:02 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[QueryTemplates]]></category>
		<category><![CDATA[plainTemplates]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=131</guid>
		<description><![CDATA[I&#8217;ve finally managed to release QueryTemplates, a pure HTML templating engine i&#8217;ve been working past months. There&#8217;re extensive examples which should allow anyone to easily understand the idea. Previously posted Pure HTML templates theory sums up some thoughts about this templating pattern. You can read more about new library on the wiki and there&#8217;s also [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=131&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;ve finally managed to release <a href="http://code.google.com/p/querytemplates/">QueryTemplates</a>, a pure HTML templating engine i&#8217;ve been working past months. There&#8217;re <a href="http://code.google.com/p/querytemplates/wiki/Examples">extensive examples</a> which should allow anyone to easily understand the idea. Previously posted <a href="http://tobiasz123.wordpress.com/2008/11/19/pure-html-templates-theory/">Pure HTML templates theory</a> sums up some thoughts about this templating pattern. You can read more about new library on the <a href="http://code.google.com/p/querytemplates/w/list">wiki</a> and there&#8217;s also an <a href="http://querytemplates.wordpress.com/">official blog</a>. Feel free to post feedback.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/131/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=131&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/cK6q1NCB0Oo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/12/03/querytemplates-finally-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/12/03/querytemplates-finally-released/</feedburner:origLink></item>
		<item>
		<title>PHP 5.3 introduces closures and inline functions</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/LhRRcuZNVtk/</link>
		<comments>http://tobiasz123.wordpress.com/2008/11/25/php-53-introduces-closures-and-inline-functions/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 22:31:07 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[The Net]]></category>
		<category><![CDATA[closures]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=111</guid>
		<description><![CDATA[I couldn&#8217;t believe it in first place, but there are ongoing works to bring closures power to PHP in upcoming 5.3 version! No more create_function() and backslashing backslashed quotes.
There are also some scope inheritance tries (using &#8220;use&#8221; keyword). Below you have some teasing snippet, after which head to wiki.php.net/rfc/closures for more&#8230;

function replace_in_array ($search, $replacement, $array) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=111&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I couldn&#8217;t believe it in first place, but there are <a href="http://wiki.php.net/rfc/closures">ongoing works</a> to bring closures power to PHP in upcoming <strong>5.3</strong> version! No more create_function() and backslashing backslashed quotes.</p>
<p>There are also some scope inheritance tries (using &#8220;use&#8221; keyword). Below you have some teasing snippet, after which head to <a href="http://wiki.php.net/rfc/closures">wiki.php.net/rfc/closures</a> for more&#8230;</p>
<pre class="brush: php;">
function replace_in_array ($search, $replacement, $array) {
  $map = function ($text) use ($search, $replacement) {
    if (strpos ($text, $search) &gt; 50) {
      return str_replace ($search, $replacement, $text);
    } else {
      return $text;
    }
  };
  return array_map ($map, $array);
}</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/111/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=111&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/LhRRcuZNVtk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/11/25/php-53-introduces-closures-and-inline-functions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/11/25/php-53-introduces-closures-and-inline-functions/</feedburner:origLink></item>
		<item>
		<title>Pure HTML templates theory</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/9w3K5fc49rw/</link>
		<comments>http://tobiasz123.wordpress.com/2008/11/19/pure-html-templates-theory/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 21:51:07 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[templates]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=13</guid>
		<description><![CDATA[In this post i would like to sum up my thought about using pure HTML files as fully functional templates. I&#8217;ve examined this pattern for about a year and i have to say it creates real order in application structure and lifecycle.
What means &#8220;pure&#8221; ?

Pure like plain, nothing else than HTML
Fully validable
Readable in any browser
Editable [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=13&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In this post i would like to sum up my thought about using pure HTML files as fully functional templates. I&#8217;ve examined this pattern for about a year and i have to say it creates real order in application structure and lifecycle.</p>
<h3>What means &#8220;pure&#8221; ?</h3>
<ul>
<li>Pure like plain, nothing else than HTML</li>
<li>Fully <span><span>validable</span></span></li>
<li>Readable in any browser</li>
<li>Editable in any HTML editor</li>
</ul>
<h3><span id="more-13"></span>How it works ?</h3>
<p>HTML files are read as Document Object Models (DOM), then queried against selectors (like CSS1-2-3, <span><span>XPath</span></span>, X4E, even SQL ?). Selected elements are joined and/or (cross)manipulated, then full final DOM is exposed as HTML result to the browser.</p>
<h3>Pros</h3>
<ul>
<li>Preview-ready templates (filled with <span><span>ipsum</span></span> content)</li>
<li>Separation of template&#8217;s logic and template&#8217;s markup</li>
<li>Based on commonly known technologies (HTML, <span><span>CSS</span></span>, DOM), no additional languages or grammars introduced</li>
<li>Use one HTML file for holding elements used in any number of functions (1:n relation)</li>
<li><span>Use many HTML files for holding different elements but <span>queryable</span></span> by same selector and used in one function (n:1 relation)</li>
<li>Fill data from DB straight into specific place in template as easy as applying a <span><span>CSS</span></span> style</li>
<li>Shouldn&#8217;t decrease performance when saving parsed template in native syntax of server-side language (<span><span>eg</span></span> <span><span>PHP</span></span>). In some cases it can even increase rendering speed.</li>
</ul>
<h3>Cons</h3>
<ul>
<li>DOM Parser needed</li>
<li>Selector provider needed (<span><span>XPath</span></span> is most common, <span><span>CSS</span></span> implementations are growing)</li>
</ul>
<h3>Possibilities</h3>
<ul>
<li>Reusability of selectors between client-side and server-side templating engines</li>
<li>Event-driven template communication</li>
</ul>
<h3>Use cases</h3>
<ul>
<li>Websites that needs to allow easy layout changing</li>
<li>Preview changes to the Client without server-side logic modification</li>
<li><span>Transparent simultaneous work between </span>HTML and server-side developers</li>
</ul>
<h3>Implementations</h3>
<ul>
<li><a href="http://code.google.com/p/phpquery/">phpQuery</a> &#8211; DOM Parser</li>
<li><a href="http://code.google.com/p/plaintemplates/">plainTemplates</a> &#8211; structured array injector (depracated)</li>
<li><a href="http://code.google.com/p/querytemplates/">QueryTemplates</a></li>
</ul>
<h3>References</h3>
<ul>
<li>
<p class="Post-title"><a href="http://tobiasz123.wordpress.com/2007/07/30/plaintemplates-css-driven-templating-engine/">plainTemplates &#8211; CSS driven templating engine</a></p>
</li>
</ul>
<p><strong>Update 06.12.08:<br />
</strong><a href="http://code.google.com/p/querytemplates/">QueryTemplates</a> has been released to the public.<strong></strong></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/13/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=13&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/9w3K5fc49rw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/11/19/pure-html-templates-theory/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/11/19/pure-html-templates-theory/</feedburner:origLink></item>
		<item>
		<title>Keep things from web up-to-date easily</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/R9n0E4Qx3G0/</link>
		<comments>http://tobiasz123.wordpress.com/2008/11/05/keep-things-from-web-up-to-date-easily/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 15:11:32 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Web Scraping]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[scraping]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=105</guid>
		<description><![CDATA[When some project doesn&#8217;t use SVN or any other version-control system (or you can&#8217;t use it) you have to download things manually. I don&#8217;t have to say that nobody wants to do this, so what can you do to not do it ? You can simulate yourself doing it&#8230;
Example below downloads latest release of madwifi [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=105&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>When some project doesn&#8217;t use SVN or any other version-control system (or you can&#8217;t use it) you have to download things manually. I don&#8217;t have to say that nobody wants to do this, so what can you do to not do it ? You can simulate yourself doing it&#8230;</p>
<p>Example below downloads latest release of madwifi branch with new HAL (which i need for my WiFi adapter).</p>
<pre class="brush: php;">
#!/usr/bin/php
find('table tr')-&gt;slice(-2, -1)-&gt;downloadTo('/target/local/path');
}
?&gt;
</pre>
<p>Now, to get latest release all i need is to run above script from command line. One missing thing is checking if anything has changed but i leave it to you to resolve ;)</p>
<p>For files which names doesn&#8217;t change you can just use <strong>wget</strong>, like so:</p>
<pre class="brush: php;">wget 'http://host.net/somefile.zip' -O new-name.zip</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/105/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=105&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/R9n0E4Qx3G0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/11/05/keep-things-from-web-up-to-date-easily/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/11/05/keep-things-from-web-up-to-date-easily/</feedburner:origLink></item>
		<item>
		<title>jQuery Server Side ports</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/Ak5j0aPS10o/</link>
		<comments>http://tobiasz123.wordpress.com/2008/11/01/jquery-server-side-ports/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 09:03:34 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[The Net]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=99</guid>
		<description><![CDATA[jQuery besides achieving such successes as being used by Google or Micro$soft also has ports to other major languages. Most of them are designed to be server-side what opens doors for new uses to the library.
jQuery ports to other languages:

PHP &#8211; phpQuery
Ruby &#8211; hpricot
Perl &#8211; pQuery
ActionScript &#8211; as3query
Python &#8211; PyQuery

Below some snippets showing each implementation [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=99&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://jquery.com">jQuery</a> besides achieving such successes as being used by Google or Micro$soft also has ports to other major languages. Most of them are designed to be server-side what opens doors for new uses to the library.</p>
<p>jQuery ports to other languages:</p>
<ul>
<li><strong>PHP</strong> &#8211; <a href="http://code.google.com/p/phpquery/">phpQuery</a></li>
<li><strong>Ruby</strong> &#8211; <a href="http://code.whytheluckystiff.net/hpricot/">hpricot</a></li>
<li><strong>Perl &#8211; </strong><a href="http://search.cpan.org/~ingy/pQuery/lib/pQuery.pm">pQuery</a></li>
<li><strong>ActionScript</strong> &#8211; <a href="http://tech.nitoyon.com/blog/2008/01/as3query_alpha.html">as3query</a></li>
<li><strong>Python</strong> &#8211; <a href="http://pypi.python.org/pypi/pyquery">PyQuery</a></li>
</ul>
<p>Below some snippets showing each implementation in few lines.</p>
<h3>PHP</h3>
<pre class="brush: jscript;">
foreach($doc['ul &gt; li'] as $li) {
  pq($li)-&gt;addClass('my-new-class');
      -&gt;filter(':last')
        -&gt;addClass('last-li');
}
$doc['ul &gt; li:last']
  -&gt;addClass('last-li');
</pre>
<h3>Ruby</h3>
<pre class="brush: ruby;">
# load the RedHanded home page
doc = Hpricot(open(&quot;http://redhanded.hobix.com/index.html&quot;))
# change the CSS class on links
(doc/&quot;span.entryPermalink&quot;).set(&quot;class&quot;, &quot;newLinks&quot;)
</pre>
<h3>Perl</h3>
<pre class="brush: jscript;">
pQuery(&quot;http://google.com/search?q=pquery&quot;)
  -&gt;find(&quot;h2&quot;)
    -&gt;each(sub {
      my $i = shift;
        print $i + 1, &quot;) &quot;, pQuery($_)-&gt;text, &quot;n&quot;;
      });
</pre>
<h3>ActionScript</h3>
<pre class="brush: jscript;">
// add enterFrame event handler
$(stage).enterFrame(function(event:Event):void {
  $(&quot;RoundRect&quot;).attr(&quot;color&quot;, function(...args):uint {
    return Math.random() * 0xffffff;
  });
});
</pre>
<p>List comes from <a href="http://code.google.com/p/phpquery/wiki/jQueryServerSidePorts">phpQuery wiki page</a>. Do you know any other ports ? Share it in comments.</p>
<p><strong>Update 09.12.08</strong><br />
New jQuery port has been released. This time it&#8217;s powered by <strong>Python</strong> and named <strong><a href="http://pypi.python.org/pypi/pyquery">PyQuery</a></strong>. Here&#8217;s the code:</p>
<h3>Python</h3>
<pre class="literal-block">
<pre class="brush: python;">
p = d(&quot;#hello&quot;)
p.addClass(&quot;toto&quot;)
p.attr.id = &quot;plop&quot;
p.prependTo(d('#test'))
</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/99/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=99&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/Ak5j0aPS10o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/11/01/jquery-server-side-ports/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/11/01/jquery-server-side-ports/</feedburner:origLink></item>
		<item>
		<title>Songbird – Firefox for your music</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/JO3jOSchvgE/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/22/songbird-firefox-for-your-music/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 08:27:59 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[xul]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=89</guid>
		<description><![CDATA[Since leaving windows behind (yey!) I couldn&#8217;t find decent music player (which won&#8217;t frustrate me). Foobar was my choice for a years. Tried many after that like Rhythmbox, Amarok (3 and 4), Listen, Sonata (MPD client), Banshee (&#60;1.0 and 1.0) and others&#8230; Finally yesterday I found advertised-as-itunes-alternative Songbird &#8211; XUL/Mozilla powered music player! Main features [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=89&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Since leaving windows behind (yey!) I couldn&#8217;t find decent music player (which won&#8217;t frustrate me). <a href="http://www.foobar2000.org/">Foobar</a> was my choice for a years. Tried many after that like Rhythmbox, Amarok (3 and 4), Listen, Sonata (MPD client), Banshee (&lt;1.0 and 1.0) and others&#8230; Finally yesterday I found advertised-as-itunes-alternative <a href="http://getsongbird.com/features/">Songbird</a> &#8211; <strong>XUL/Mozilla</strong> powered music player! Main features are:</p>
<ul>
<li><strong>Addons</strong><br />
Just like in Firefox. There is <a href="http://addons.songbirdnest.com/addons">almost 300 of them</a> right now.</li>
<li><strong>Shoutcast client</strong><br />
This is most important feature for me as I listen to radio most of the time (<a href="http://somafm.com/play/secretagent">Secret Agent</a> is my fav pick)</li>
<li><strong>Webrowser with tabs</strong><br />
Web is everywhere in this player.</li>
</ul>
<p>I feel so foobar-like when using it. For those of you who like iTunes, there is (of course) <a href="http://addons.songbirdnest.com/addon/233">iTunes theme</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=89&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/JO3jOSchvgE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/22/songbird-firefox-for-your-music/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/22/songbird-firefox-for-your-music/</feedburner:origLink></item>
		<item>
		<title>Eclipse PDT 1.0.5 – Zend’s hidden release</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/C3o_NGrchDI/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/22/eclipse-pdt-105-zends-hidden-release/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 08:04:55 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=91</guid>
		<description><![CDATA[When PDT 2.0 is still slow and DLTK 1.0 hasn&#8217;t reached final milestone, Zend guys are using unreleased PDT 1.0.5 in their Zend Studio 6.1. Most important thing is ZS is based on Eclipse 3.4 (Ganymade) and prior PDT 1.0.x builds worked only with 3.3 (Europa).
You can get it in 2 ways &#8211; first is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=91&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>When PDT 2.0 is still slow and DLTK 1.0 hasn&#8217;t reached final milestone, Zend guys are using unreleased PDT 1.0.5 in their <a href="http://www.zend.com/en/products/studio/">Zend Studio 6.1</a>. Most important thing is ZS is based on Eclipse 3.4 (Ganymade) and prior PDT 1.0.x builds worked only with 3.3 (Europa).</p>
<p>You can get it in 2 ways &#8211; first is to compile it from CVS according to <a href="http://dev.eclipse.org/mhonarc/newsLists/news.eclipse.tools.pdt/msg02653.html">these instructions</a> and the second is just to download Zend Studio 6.1 and copy <strong>/features/org.eclipse.php*</strong> and <strong>/plugins/org.eclipse.php*</strong> to Eclipse 3.4 installation.</p>
<p><strong>Update</strong> (17.11.2008):<br />
PDT team have officially released 1.0.5 build for Eclipse 3.4. You can get it directly from <a href="http://www.eclipse.org/pdt/downloads/?project=pdt&amp;hlbuild=M200811162133#M200811162133">download page</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/91/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=91&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/C3o_NGrchDI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/22/eclipse-pdt-105-zends-hidden-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/22/eclipse-pdt-105-zends-hidden-release/</feedburner:origLink></item>
		<item>
		<title>Rails’ ActiveSupport ported to PHP</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/v8Lt1z-wRCk/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/05/rails-activesupport-ported-to-php/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 15:16:33 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[The Net]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=82</guid>
		<description><![CDATA[It&#8217;s year old but found it today on benlog.org. I&#8217;m verry happy since i&#8217;ve been working on project providing similar chains and now i can use well-thought Rails equivalent. Yet i will still write my own implementation as it differs in many ways.
require_once('ActiveSupport.php');
// Outputs &#34;14th&#34;
_(14)-&#62;ordinalize();
// Returns number of bytes in 7.3 megabytes
_(7.3)-&#62;megabytes();
// Returns true
_(&#34;an example [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=82&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>It&#8217;s year old but found it today on <a href="http://www.benlog.org/2007/8/13/activesupport-for-php-ruby-style">benlog.org</a>. I&#8217;m verry happy since i&#8217;ve been working on project providing similar chains and now i can use well-thought Rails equivalent. Yet i will still write my own implementation as it differs in many ways.</p>
<pre class="brush: php;">require_once('ActiveSupport.php');
// Outputs &quot;14th&quot;
_(14)-&gt;ordinalize();
// Returns number of bytes in 7.3 megabytes
_(7.3)-&gt;megabytes();
// Returns true
_(&quot;an example sentence&quot;)-&gt;endsWith(&quot;sentence&quot;);</pre>
<p>I really liked the idea of &#8216;<strong>_</strong>&#8216; suffix to change returned type. See lots of <strong>great examples</strong> in <a href="http://errtheblog.com/post/44">Rails Rubyisms Advent</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/82/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=82&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/v8Lt1z-wRCk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/05/rails-activesupport-ported-to-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/05/rails-activesupport-ported-to-php/</feedburner:origLink></item>
		<item>
		<title>phpQuery edits it’s own wiki</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/fY2NJI0ChF4/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/05/phpquery-edits-its-own-wiki/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 01:05:10 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scraping]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=34</guid>
		<description><![CDATA[phpQuery can connect to Google Code&#8217;s wiki editing form, authorize itself, replace page contents and finally submit the form.
// declare main variable
$pq = null;
// create dummy document as start point
phpQuery::newDocument('
&#60;div&#62;')
// authorize your google account
	-&#62;script('google_login')
// redirect authorized XHR component to googlecode's wiki form
	-&#62;location('http://code.google.com/p/phpquery/w/edit/test')
// save result as $pq, althought we could continue the chain
// but it would [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=34&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>phpQuery</strong> can connect to Google Code&#8217;s wiki editing form, authorize itself, replace page contents and finally submit the form.</p>
<pre class="brush: php;">// declare main variable
$pq = null;
// create dummy document as start point
phpQuery::newDocument('
&lt;div&gt;')
// authorize your google account
	-&gt;script('google_login')
// redirect authorized XHR component to googlecode's wiki form
	-&gt;location('http://code.google.com/p/phpquery/w/edit/test')
// save result as $pq, althought we could continue the chain
// but it would break in case of error...
		-&gt;toReference($pq);
if ($pq) {
// read about CallbackReference later in this post...
	$pq-&gt;WebBrowser(new CallbackReference($pq))
		-&gt;find('textarea:first')
			-&gt;val('lorem ipsum')
			-&gt;parents('form')
// first submit is Preview, so fire up second
				-&gt;find(':submit:eq(1)')
// triggering submit event thought input[type=submit]:click
// is a way to choose which submit is send
					-&gt;click();
	if ($pq) {
// print without  tags
		print $pq-&gt;script('safe_print');
	}
}</pre>
<p>You can notice hot new feature &#8211; <em><strong>new CallbackReference($pq)</strong>. </em>Such callback sets <strong>first callback parameter</strong> to <strong>passed variable</strong>, by reference.<strong> </strong>Such pattern works with all methods accepting callbacks. Thanks to that, we can use <strong>if statements</strong> instead of <strong>function callbacks</strong>. In above example, <strong>CallbackReference</strong> object is called when <strong>click event</strong> is triggered.<em> </em></p>
<p>Presented code snippet makes use of new <a href="/2008/10/04/scripts-plugin-for-phpqueryscripts-plugin-for-phpquery/ Edit">Script plugin</a>, particularly <strong>google_login</strong>.</p>
<p>Now it can be combined with automated <a href="http://phpquery-library.blogspot.com/2008/09/wiki-has-documentation.html">XML documentation to wiki script</a>, but this maybe for<strong> jQuery 1.3</strong>&#8230;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/34/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=34&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/fY2NJI0ChF4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/05/phpquery-edits-its-own-wiki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/05/phpquery-edits-its-own-wiki/</feedburner:origLink></item>
		<item>
		<title>Scripts plugin for phpQuery</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/EkaYLN-ovas/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/05/scripts-plugin-for-phpquery/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 01:05:08 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=31</guid>
		<description><![CDATA[Scripts plugin is an easy file includer. Each script file have 4 variables in scope:

$self Represents $this
$params Represents parameters passed to script() method (without script name)
$return If not null, will be used as method result
$config Content of __config.php file

Possible use cases

Authorizations
Custom Chains
Simple phpQuery plugins
Sort functions
Website APIs
Event binding groups

Example
$return = $self-&#62;find($params[0]);
Actually there is only one script [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=31&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Scripts plugin is an easy <strong>file includer</strong>. Each <strong>script file</strong> have 4 variables in scope:</p>
<ul>
<li><strong>$self</strong> Represents $this</li>
<li><strong>$params</strong> Represents parameters passed to script() method (without script name)</li>
<li><strong>$return</strong> If not null, will be used as method result</li>
<li><strong>$config</strong> Content of __config.php file</li>
</ul>
<h2>Possible use cases</h2>
<ul>
<li>Authorizations</li>
<li>Custom Chains</li>
<li>Simple phpQuery plugins</li>
<li>Sort functions</li>
<li>Website APIs</li>
<li>Event binding groups</li>
</ul>
<h2>Example</h2>
<pre class="brush: php;">$return = $self-&gt;find($params[0]);</pre>
<p>Actually there is only one script which is <strong>Google Login</strong>. It doesn&#8217;t support GMail yet, unfortunately.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=31&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/EkaYLN-ovas" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/05/scripts-plugin-for-phpquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/05/scripts-plugin-for-phpquery/</feedburner:origLink></item>
		<item>
		<title>Web Scraping with cli version of phpquery piped with sed</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/AewjxzjRzIA/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/05/web-scraping-with-cli-version-of-phpquery-piped-with-sed/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 01:05:06 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Web Scraping]]></category>
		<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scraping]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=23</guid>
		<description><![CDATA[I&#8217;ve done what i was thinking about for some time. Terminal-firendly phpQuery CLI interface. Took about 10 minutes of coding&#8230; Works like this:


phpquery http://code.google.com/p/phpquery/downloads/list --find '.vt.col_4 a:first' --contents
This will return number of downloads latest phpQuery release file. Notice there is no need to quote url in any way. I was very happy with this so [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=23&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;ve done what i was thinking about for some time. Terminal-firendly phpQuery <strong>CLI</strong> interface. Took about 10 minutes of coding&#8230; Works like this:<strong><br />
</strong></p>
<pre class="brush: php;">
phpquery http://code.google.com/p/phpquery/downloads/list --find '.vt.col_4 a:first' --contents</pre>
<p>This will return number of downloads latest phpQuery release file. Notice there is no need to quote url in any way. I was very happy with this so i&#8217;ve added callback support in text() and htmlOuter() methods, like so:<strong><br />
</strong></p>
<pre class="brush: php;">
phpquery http://code.google.com/p/phpquery/downloads/list --find '.vt.col_4 a:first' --text strip_tags trim</pre>
<p>When i had all stuff working, i&#8217;ve used it straight away to scrap forums and categories lists from old IPB v1.x. I&#8217;ve piped phpQuery result with <strong>sed</strong>, filtering final output.</p>
<pre class="brush: php;">// Fetch categories
./phpquery http://forum.wiadomosc.info/ --find '.maintitle a' | sed -r 's/^.*?c=([0-9]+).+?&gt;(.+?)]*&gt;([^&lt;]*)&lt;.*$/1: // 2/g'</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=23&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/AewjxzjRzIA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/05/web-scraping-with-cli-version-of-phpquery-piped-with-sed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/05/web-scraping-with-cli-version-of-phpquery-piped-with-sed/</feedburner:origLink></item>
		<item>
		<title>PHP in CLI using $argv</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/FxXduoofgKo/</link>
		<comments>http://tobiasz123.wordpress.com/2008/10/05/php-in-cli-using-argv/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 01:05:04 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Snippets]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=22</guid>
		<description><![CDATA[Just an example showing how easy it is to implement CLI in PHP scripts.  Sandbox.php file:
#!/usr/bin/php
&#60;?php
var_dump($argv);
?&#62;
./sandbox.php param1 &#8211;param2 param3 param4 &#8211;param5 -p 6 -fbi
array(9) {
[0]=&#62;
string(13) &#34;./sandbox.php&#34;
[1]=&#62;
string(6) &#34;param1&#34;
[2]=&#62;
string(8) &#34;--param2&#34;
[3]=&#62;
string(6) &#34;param3&#34;
[4]=&#62;
string(6) &#34;param4&#34;
[5]=&#62;
string(8) &#34;--param5&#34;
[6]=&#62;
string(2) &#34;-p&#34;
[7]=&#62;
string(1) &#34;6&#34;
[8]=&#62;
string(4) &#34;-fbi&#34;
}
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=22&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Just an example showing how easy it is to implement CLI in PHP scripts.  Sandbox.php file:</p>
<pre class="brush: php;">#!/usr/bin/php
&lt;?php
var_dump($argv);
?&gt;</pre>
<p><strong>./sandbox.php param1 &#8211;param2 param3 param4 &#8211;param5 -p 6 -fbi</strong></p>
<pre class="brush: php;">array(9) {
[0]=&gt;
string(13) &quot;./sandbox.php&quot;
[1]=&gt;
string(6) &quot;param1&quot;
[2]=&gt;
string(8) &quot;--param2&quot;
[3]=&gt;
string(6) &quot;param3&quot;
[4]=&gt;
string(6) &quot;param4&quot;
[5]=&gt;
string(8) &quot;--param5&quot;
[6]=&gt;
string(2) &quot;-p&quot;
[7]=&gt;
string(1) &quot;6&quot;
[8]=&gt;
string(4) &quot;-fbi&quot;
}</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=22&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/FxXduoofgKo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/10/05/php-in-cli-using-argv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/10/05/php-in-cli-using-argv/</feedburner:origLink></item>
		<item>
		<title>Meta20.net is here</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/w6NsTIjsSGk/</link>
		<comments>http://tobiasz123.wordpress.com/2008/09/25/meta20net-is-here/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 19:58:16 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[This blog]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=4</guid>
		<description><![CDATA[Hello again, after a year or so :)
Old meta20.net is now deprecated to be used as real development area for some projects and will be available to download as working example of various patterns.
Personally I feel great in this wordpress environment, but big shame is payable CSS editing feature. Will play with it and than [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=4&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>Hello again</strong>, after a year or so :)</p>
<p>Old <a href="http://meta20.net">meta20.net</a> is now deprecated to be used as <strong>real</strong> development area for some projects and will be available to download as working example of various patterns.</p>
<p>Personally I feel great in this <strong>wordpress</strong> environment, but big shame is payable CSS editing feature. Will play with it and than decide to take it home. <a href="http://code.google.com/p/syntaxhighlighter/">SyntaxHighlighter</a> integration is a plus, but doesn&#8217;t cooperate with dark themes and such I&#8217;m using here. I choose fantastic <a href="http://en.blog.wordpress.com/2007/11/05/theme-tuesday-chaostheory/">ChaosTheory</a> which suits me more that i could think of.</p>
<p><a href="http://meta20.net">http://meta20.net</a> will now point to <a href="http://tobiasz123.wordpress.com">http://tobiasz123.wordpress.com</a> and <a href="http://feeds.feedburner.com/meta20">feedburner</a> feed will still work. I will import old posts somewhere in future.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=4&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/w6NsTIjsSGk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2008/09/25/meta20net-is-here/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2008/09/25/meta20net-is-here/</feedburner:origLink></item>
		<item>
		<title>$.include() – script inclusion jQuery plugin</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/d7cgF3Rd4cM/</link>
		<comments>http://tobiasz123.wordpress.com/2007/08/01/include-script-inclusion-jquery-plugin/#comments</comments>
		<pubDate>Wed, 01 Aug 2007 09:11:28 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Snippets]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=226</guid>
		<description><![CDATA[Don&#8217;t like writing &#60;script&#62; tag for every new JS You need ? Nobody likes. Thats why i wrote $.include.
Use it like this:

$.include('js/my-script.js');

It&#8217;s similar plugin to that one written by Petko D. Petkov, but with couple of enhancements :

Properly delayes onDomReady event
Gives You control over order of loading scripts

Here is extended example:

$.include(
	// URL
	'js/my-script.js',
	// will be loaded [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=226&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Don&#8217;t like writing &lt;script&gt; tag for every new JS You need ? Nobody likes. Thats why i wrote $.include.</p>
<p>Use it like this:</p>
<pre class="brush: jscript;">
$.include('js/my-script.js');
</pre>
<p>It&#8217;s similar plugin to that one <a href="http://www.gnucitizen.org/projects/jquery-include/">written by Petko D. Petkov</a>, but with couple of enhancements :</p>
<ul>
<li>Properly delayes <em>onDomReady</em> event</li>
<li>Gives You control over order of loading scripts</li>
</ul>
<p>Here is extended example:</p>
<pre class="brush: jscript;">
$.include(
	// URL
	'js/my-script.js',
	// will be loaded after this script
	$.include(baseURL+'js/my-other-script.js')
);
$.include('js/src/behaviors.js',
	// dependencies can also be an array
	[
		$.include('js/src/jquery-metadata.js'),
		$.include('js/src/jquery.form.js')
	]
);
</pre>
<p><span id="more-226"></span></p>
<h3>Source Code</h3>
<pre class="brush: jscript;">
/**
 * $.include - script inclusion jQuery plugin
 * Based on idea from http://www.gnucitizen.org/projects/jquery-include/
 * @author Tobiasz Cudnik
 * @link http://meta20.net/.include_script_inclusion_jQuery_plugin
 * @license MIT
 */
// overload jquery's onDomReady
if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
	document.removeEventListener( &quot;DOMContentLoaded&quot;, jQuery.ready, false );
	document.addEventListener( &quot;DOMContentLoaded&quot;, function(){ jQuery.ready(); }, false );
}
jQuery.event.remove( window, &quot;load&quot;, jQuery.ready );
jQuery.event.add( window, &quot;load&quot;, function(){ jQuery.ready(); } );
jQuery.extend({
	includeStates: {},
	include: function(url, callback, dependency){
		if ( typeof callback != 'function' &amp;&amp; ! dependency ) {
			dependency = callback;
			callback = null;
		}
		url = url.replace('\n', '');
		jQuery.includeStates[url] = false;
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.onload = function () {
			jQuery.includeStates[url] = true;
			if ( callback )
				callback.call(script);
		};
		script.onreadystatechange = function () {
			if ( this.readyState != &quot;complete&quot; &amp;&amp; this.readyState != &quot;loaded&quot; ) return;
			jQuery.includeStates[url] = true;
			if ( callback )
				callback.call(script);
		};
		script.src = url;
		if ( dependency ) {
			if ( dependency.constructor != Array )
				dependency = [dependency];
			setTimeout(function(){
				var valid = true;
				$.each(dependency, function(k, v){
					if (! v() ) {
						valid = false;
						return false;
					}
				})
				if ( valid )
					document.getElementsByTagName('head')[0].appendChild(script);
				else
					setTimeout(arguments.callee, 10);
			}, 10);
		}
		else
			document.getElementsByTagName('head')[0].appendChild(script);
		return function(){
			return jQuery.includeStates[url];
		}
	},
	readyOld: jQuery.ready,
	ready: function () {
		if (jQuery.isReady) return;
		imReady = true;
		$.each(jQuery.includeStates, function(url, state) {
			if (! state)
				return imReady = false;
		});
		if (imReady) {
			jQuery.readyOld.apply(jQuery, arguments);
		} else {
			setTimeout(arguments.callee, 10);
		}
	}
});
</pre>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/tobiasz123.wordpress.com/226/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/tobiasz123.wordpress.com/226/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/226/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/226/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/226/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/226/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/226/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/226/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/226/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/226/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/226/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/226/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=226&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/d7cgF3Rd4cM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2007/08/01/include-script-inclusion-jquery-plugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2007/08/01/include-script-inclusion-jquery-plugin/</feedburner:origLink></item>
		<item>
		<title>Smooth Menu widget for jQuery</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/XIhl8x-9py4/</link>
		<comments>http://tobiasz123.wordpress.com/2007/07/31/smooth-menu-widget-for-jquery/#comments</comments>
		<pubDate>Tue, 31 Jul 2007 09:08:42 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Snippets]]></category>
		<category><![CDATA[effects]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=224</guid>
		<description><![CDATA[
If You liked Fancy Menu, but not necessarily feel the same to moo.tools (no offence) here You have similar widget for jQuery &#8211; Smooth Menu. It works for vertical lists too.
Examples are bare so it&#8217;s easier to understand whats needed to implement it to your site. Love to see it in combination with rounder corners [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=224&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><div class="true}}">
<p>If You liked <a href="http://devthought.com/cssjavascript-true-power-fancy-menu/">Fancy Menu</a>, but not necessarily feel the same to moo.tools (no offence) here You have similar widget for jQuery &#8211; <a href="http://meta20.net/demos/Smooth_menu_widget_for_jQuery/">Smooth Menu</a>. It works for vertical lists too.</p>
<p>Examples are bare so it&#8217;s easier to understand whats needed to implement it to your site. Love to see it in combination with rounder corners (imageless).</p></div>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/tobiasz123.wordpress.com/224/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/tobiasz123.wordpress.com/224/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/224/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=224&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/XIhl8x-9py4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2007/07/31/smooth-menu-widget-for-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2007/07/31/smooth-menu-widget-for-jquery/</feedburner:origLink></item>
		<item>
		<title>plainTemplates – CSS driven templating engine</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/y559elexVdg/</link>
		<comments>http://tobiasz123.wordpress.com/2007/07/30/plaintemplates-css-driven-templating-engine/#comments</comments>
		<pubDate>Mon, 30 Jul 2007 09:22:43 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[plainTemplates]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=231</guid>
		<description><![CDATA[This post is deprecated and informations below are outdated. Please follow up to QueryTemplates and Pure HTML templates theory.
Introduction
plainTemplates is a PHP and JS library that aims to divide template into 2 separate layers:

CSS selectors driven data attaching mechanism
Plain HTML

It&#8217;s simply creates your templates from plain HTML files on-the-fly, filling it with data and fetching parts [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=231&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:center;">This post is <strong>deprecated</strong> and informations below are <strong>outdated</strong>. Please follow up to <a href="http://tobiasz123.wordpress.com/2008/12/03/querytemplates-finally-released/">QueryTemplates</a> and <a class="url" rel="external nofollow" href="../2008/11/19/pure-html-templates-theory/">Pure HTML templates theory</a>.</p>
<h3>Introduction</h3>
<p><strong>plainTemplates</strong> is a PHP and JS library that aims to divide template into 2 separate layers:</p>
<ol>
<li>CSS selectors driven data attaching mechanism</li>
<li>Plain HTML</li>
</ol>
<p>It&#8217;s simply creates your templates from plain HTML files on-the-fly, filling it with data and fetching parts you like.</p>
<p>It&#8217;s basen on <strong><a href="http://meta20.net/phpQuery">phpQuery</a></strong> &#8211; a <strong><a href="http://jquery.com/">jQuery</a></strong> port to PHP.</p>
<p><strong>Pros</strong></p>
<ul>
<li>True separation of data and visual layer</li>
<li>HTML can be filled with example data</li>
<li>High reusability (several templates from one HTML, one template from several HTMLs)</li>
<li>Framework independed template organisation</li>
<li>Transparent refreshes (including PHP code changes!)</li>
<li><a href="http://meta20.net/phpQuery">phpQuery</a> integration</li>
<li>No need to lear new, template-only language</li>
<li>Saves a lot of time ;)</li>
</ul>
<p><strong>Cons</strong></p>
<ul>
<li>You have to know CSS selectors (XPath will also help)</li>
<li>In most cases you have to know jQuery/phpQuery</li>
<li>You have to format data outside template (eg date).</li>
</ul>
<p>Here is simple example, which inserts data from $data array into template in template.htm:</p>
<pre class="brush: php;">
// get the class
require_once('../../plainTemplates/plainTemplates.php');
// always end dir with a slash
plainTemplates::$cacheDir = '../../plainTemplates/cache/';
$data = array(
	array(
		'title' =&gt; 'News 1 title',
		'body'	=&gt; 'News 1 body',
	),
	array(
		'title' =&gt; 'News 2 title',
		'body'	=&gt; 'News 2 body',
	),
	array(
		'title' =&gt; 'News 3',
		'body'	=&gt; 'News 3 body',
	),
);
// include to fully preserve scope
include(
	plainTemplates::createTemplate(
		// first the template source
		'template.htm',
		// second the var info
		array(
			// var name in scope
			'$data',
			// and var value
			$data,
			// finally the selectors (of course there are defaults, that is UL and LI)
			array(
				'container' =&gt; '.someclass ul',
				'row'		=&gt; 'li'
			)
		)
	)
);
</pre>
<p>Here is <strong>template.htm</strong> itself:</p>
<pre><code class="html">&lt;div class='someclass'&gt;
	&lt;p&gt;UL below will be container, and every LI will be searched agains classes with field names.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;

			&lt;p&gt;Only tags with field classes are replaced.&lt;/p&gt;
			&lt;p class='title'&gt;This will be replaces by the title&lt;/p&gt;
			&lt;p class='body'&gt;And this by the body...&lt;/p&gt;
		&lt;/li&gt;

		&lt;li&gt;
			Only first row will be in the result and this wont be considered by any chance... so You can use as many row examples as You want.
		&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;</code></pre>
<p>Now the result&#8217;s source:</p>
<pre><code class="html">&lt;ul&gt;&lt;?php foreach( $data as $dataRow ): ?&gt;

			&lt;li&gt;
			&lt;p&gt;Only tags with field classes are replaced.&lt;/p&gt;
			&lt;p class="title"&gt;&lt;?php print $dataRow['title']; ?&gt;&lt;/p&gt;
			&lt;p class="body"&gt;&lt;?php print $dataRow['body']; ?&gt;&lt;/p&gt;

		&lt;/li&gt;&lt;?php endforeach; ?&gt;&lt;/ul&gt;
</code></pre>
<p>Those are the basics, it can do a lot more, but i think its good that it can do simple things in a simple way&#8230;<span id="more-231"></span></p>
<h3>Intermediate examples</h3>
<h4>EXAMPLE: Nested data</h4>
<p>In this example you will learn about nested data, which is very common thing in eg CakePHP. So let&#8217;s get started!</p>
<p><strong>Code</strong> (examples/nested-data/code.php)</p>
<pre class="brush: php;">
$data = array(
	array(
		'Post' =&gt; array(
			'title' =&gt; 'Im the title',
			'body' =&gt; 'Im the body',
		),
		'Comment' =&gt; array(
			array(
				'author' =&gt; 'Im the 1st comment of 1st post',
				'body' =&gt; &quot;This field has same name as post's one&quot;,
			),
			array(
				'author' =&gt; 'Im the 2nd comment of 1st post',
				'body' =&gt; 'So am i',
			),
		),
	),
	array(
		'Post' =&gt; array(
			'title' =&gt; 'Im the post without comments',
			'body' =&gt; 'His right',
		),
		'Comment' =&gt; array(),
	),
);
// include to fully preserve scope
include(
	plainTemplates::createTemplate(
		// first the template source
		'template.htm',
		// second the var info
		array(
			// var name in scope
			'$data',
			// and var value
			$data,
			// finally the selectors (of course there are defaults, that is UL and LI)
			array(
				// selectors for 'Post' row
				'container' =&gt; '.someclass &gt; ul',
				'row'		=&gt; '&gt; li',
				// selectors for 'Comment'. we have to group them inside 'Comment' index because it's another data (list), not row
				'Comment' =&gt; array(
					'container' =&gt; '.someclass &gt; ul',
				),
			)
		)
	)
);
</pre>
<p><strong>Template</strong> (examples/nested-data/template.htm)</p>
<pre><code class="html">&lt;div class='someclass'&gt;
	&lt;p&gt;UL below will be container, and every LI will be searched agains classes with field names.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;

			&lt;p&gt;In nested row, class names must have parent index prepended.&lt;/p&gt;
			&lt;p class='Post-title'&gt;This will be replaces by the title&lt;/p&gt;
			&lt;p class='Post-body'&gt;And this by the body...&lt;/p&gt;
			&lt;div&gt;

				&lt;ul&gt;
					&lt;li&gt;
						&lt;p&gt;Here is different situation - we have nested data (list), with container etc, so we DONT prepend index to class name.&lt;/p&gt;
						&lt;p class='author'&gt;Comment's author field&lt;/p&gt;
						&lt;p class='body'&gt;And the body&lt;/p&gt;

					&lt;/li&gt;
				&lt;/ul&gt;
			&lt;/div&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Only first row will be in the result and this wont be considered by any chance... so You can use as many row examples as You want.
		&lt;/li&gt;

	&lt;/ul&gt;
&lt;/div&gt;</code></pre>
<p><strong>Result:</strong></p>
<pre><code class="html">&lt;ul&gt;&lt;?php foreach( $data as $dataRow ): ?&gt;
			&lt;li&gt;
			&lt;p&gt;In nested data class names must have parent index prepended.&lt;/p&gt;

			&lt;p class="Post-title"&gt;&lt;?php print $dataRow['Post']['title']; ?&gt;&lt;/p&gt;
			&lt;p class="Post-body"&gt;&lt;?php print $dataRow['Post']['body']; ?&gt;&lt;/p&gt;
			&lt;div&gt;
				&lt;ul&gt;&lt;?php foreach( $dataRow['Comment'] as $dataRowComment ): ?&gt;

				&lt;li&gt;
						&lt;p class="author"&gt;&lt;?php print $dataRowComment['author']; ?&gt;&lt;/p&gt;
						&lt;p class="body"&gt;&lt;?php print $dataRowComment['body']; ?&gt;&lt;/p&gt;
					&lt;/li&gt;&lt;?php endforeach; ?&gt;&lt;/ul&gt;&lt;/div&gt;

		&lt;/li&gt;&lt;?php endforeach; ?&gt;&lt;/ul&gt;
</code></pre>
<h4>EXAMPLE: Row insertion</h4>
<p>Previous examples was about inserting a list of data. Now you will learn about inserting only one row, eg to show this post.</p>
<p><strong>Code</strong> (examples/row/code.php)</p>
<pre class="brush: php;">
$data = array(
	'Post' =&gt; array(
		'title' =&gt; 'Im the title',
		'body' =&gt; 'Im the body',
	),
	'Comment' =&gt; array(
		array(
			'author' =&gt; 'Im the 1st comment of 1st post',
			'body' =&gt; &quot;This field has same name as post's one&quot;,
		),
		array(
			'author' =&gt; 'Im the 2nd comment of 1st post',
			'body' =&gt; 'So am i',
		),
	)
);
// include to fully preserve scope
include(
	plainTemplates::createTemplate(
		// first the template source
		'template.htm',
		// second the var info
		array(
			// var name in scope
			'$data',
			// and var value
			$data,
			// finally the selectors (of course there are defaults, that is UL and LI)
			array(
				// empty container means that we dont want a loop
				'container' =&gt; '',
				// you can't use plain 'li', because all elements selected by this seletor except first one will be removed
				// in this case LI for comment row
				// there are other ways to write this selector, but this is the simplest
				'row'		=&gt; '.someclass &gt; ul &gt; li',
				// this hasn't changed
				'Comment' =&gt; array(
					'container' =&gt; '.someclass &gt; ul ul',
				),
			)
		)
	)
);
</pre>
<pre><code class="php">
</code></pre>
<p><strong>Template</strong> (examples/row/template.htm) is the same as <strong>previous one</strong>.</p>
<p><strong>Result</strong></p>
<pre><code class="html">&lt;p&gt;In nested row, class names must have parent index prepended.&lt;/p&gt;
&lt;p class="Post-title"&gt;&lt;?php print $data['Post']['title']; ?&gt;&lt;/p&gt;
&lt;p class="Post-body"&gt;&lt;?php print $data['Post']['body']; ?&gt;&lt;/p&gt;

&lt;div&gt;
				&lt;ul&gt;&lt;?php foreach( $data['Comment'] as $dataComment ): ?&gt;
				&lt;li&gt;
						&lt;p&gt;Here is different situation - we have nested data (list), with container etc, so we DONT prepend index to class name.&lt;/p&gt;
						&lt;p class="author"&gt;&lt;?php print $dataComment['author']; ?&gt;&lt;/p&gt;

						&lt;p class="body"&gt;&lt;?php print $dataComment['body']; ?&gt;&lt;/p&gt;
					&lt;/li&gt;&lt;?php endforeach; ?&gt;&lt;/ul&gt;&lt;/div&gt;
</code></pre>
<h4>EXAMPLE: Callback</h4>
<p>In this example i will introduce callback function and it&#8217;s often use to hidding uneeded content (comments listing wrapper in this case).</p>
<p>Callback is a function/method which gets phpQuery object at the end of template creation, but before saving file, so it can affect result.</p>
<p><strong>Code</strong> (examples/callback/code.php), $data is same as in <strong>Nested data</strong> example</p>
<pre class="brush: php;">
function callbackName($_) {
	// find the only div in template
	$_-&gt;find('div')
		// insert condition before div
		-&gt;beforePHP('if ( $dataRow[\'Comment\'] ):')
		// close condition after div
		-&gt;afterPHP('endif;');
}
// include to fully preserve scope
include(
	plainTemplates::createTemplate(
		// first the template source
		'template.htm',
		// second the var info
		array(
			// var name in scope
			'$data',
			// and var value
			$data,
			// finally the selectors (of course there are defaults, that is UL and LI)
			array(
				'container' =&gt; 'ul:first',
				'row'		=&gt; '&gt; li',
				'Comment' =&gt; array(
					'container' =&gt; 'ul ul',
				),
			)
		),
		// now the new thing - callback
		// callback function will have phpQuery object as only arg
		'callbackName'
	)
);
</pre>
<p><strong>Template</strong> (examples/callback/template.htm)</p>
<pre><code class="html">&lt;p&gt;UL below will be container, and every LI will be searched agains classes with field names.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;p&gt;In nested row, class names must have parent index prepended.&lt;/p&gt;

		&lt;p class='Post-title'&gt;This will be replaces by the title&lt;/p&gt;
		&lt;p class='Post-body'&gt;And this by the body...&lt;/p&gt;
		&lt;div&gt;
			&lt;h1&gt;Comments&lt;/h1&gt;

			&lt;ul&gt;
				&lt;li&gt;
					&lt;p&gt;Here is different situation - we have nested data (list), with container etc, so we DONT prepend index to class name.&lt;/p&gt;
					&lt;p class='author'&gt;Comment's author field&lt;/p&gt;
					&lt;p class='body'&gt;And the body&lt;/p&gt;

				&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
		Only first row will be in the result and this wont be considered by any chance... so You can use as many row examples as You want.
	&lt;/li&gt;

&lt;/ul&gt;</code></pre>
<p><strong>Result</strong></p>
<pre><code class="html">&lt;ul&gt;&lt;?php foreach( $data as $dataRow ): ?&gt;
	&lt;li&gt;
		&lt;p&gt;In nested row, class names must have parent index prepended.&lt;/p&gt;
		&lt;p class="Post-title"&gt;&lt;?php print $dataRow['Post']['title']; ?&gt;&lt;/p&gt;

		&lt;p class="Post-body"&gt;&lt;?php print $dataRow['Post']['body']; ?&gt;&lt;/p&gt;
		&lt;?php if ( $dataRow['Comment'] ): ?&gt;&lt;div&gt;
			&lt;h1&gt;Comments&lt;/h1&gt;
			&lt;ul&gt;&lt;?php foreach( $dataRow['Comment'] as $dataRowComment ): ?&gt;

			&lt;li&gt;
					&lt;p&gt;Here is different situation - we have nested data (list), with container etc, so we DONT prepend index to class name.&lt;/p&gt;
					&lt;p class="author"&gt;&lt;?php print $dataRowComment['author']; ?&gt;&lt;/p&gt;
					&lt;p class="body"&gt;&lt;?php print $dataRowComment['body']; ?&gt;&lt;/p&gt;

				&lt;/li&gt;&lt;?php endforeach; ?&gt;&lt;/ul&gt;&lt;/div&gt;&lt;?php endif; ?&gt;
	&lt;/li&gt;&lt;?php endforeach; ?&gt;&lt;/ul&gt;
</code></pre>
<h3>Advanced examples</h3>
<p>I will post some advanced examples here near future, so stay tuned and for now you can read <a href="http://meta20.net/docs/plainTemplates/default/plainTemplates.html">generated phpdocs</a> or those in the source code.</p>
<h3>Download and links</h3>
<ul>
<li><a href="http://code.google.com/p/plaintemplates/downloads/list">Download latest version</a></li>
<li><a href="http://meta20.net/phpQuery">phpQuery</a></li>
<li><a href="http://meta20.net/docs/plainTemplates/default/plainTemplates.html">Generated phpDoc</a></li>
<li><a href="http://meta20.net/tags/plainTemplates-release">Get latest news</a> / <a href="/tags/plainTemplates-release.rss">RSS</a></li>
<li><a href="http://code.google.com/p/plaintemplates/">Google Code Project</a></li>
<li>SVN:
<ul>
<li><a href="http://plaintemplates.googlecode.com/svn/">Browser</a></li>
<li><a href="//plaintemplates.googlecode.com/svn/trunk/">Checkout</a></li>
</ul>
</li>
</ul>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/tobiasz123.wordpress.com/231/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/tobiasz123.wordpress.com/231/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/231/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=231&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/y559elexVdg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2007/07/30/plaintemplates-css-driven-templating-engine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2007/07/30/plaintemplates-css-driven-templating-engine/</feedburner:origLink></item>
		<item>
		<title>phpQuery – a jQuery port to PHP</title>
		<link>http://feedproxy.google.com/~r/tobiasz_cudnik/~3/iG8PxgAsF5w/</link>
		<comments>http://tobiasz123.wordpress.com/2007/07/07/phpquery-a-jquery-port-to-php/#comments</comments>
		<pubDate>Sat, 07 Jul 2007 08:56:54 +0000</pubDate>
		<dc:creator>Tobiasz Cudnik</dc:creator>
				<category><![CDATA[phpQuery]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tobiasz123.wordpress.com/?p=220</guid>
		<description><![CDATA[This post is deprecated and some informations below are outdated.
phpQuery is PHP-port of jQuery &#8211; well known and great web2.0 JS library
It&#8217;s something different than jQPie, which is form of JS code generator and server-client layer.
For example You can do something like this:

print _('file.htm')
    -&#62;find('body div.cls1.cls2 ul &#62; li:first')
    [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=220&subd=tobiasz123&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:center;"><strong>This post is </strong><strong><span style="text-decoration:underline;">deprecated</span> and some informations below are </strong><strong><span style="text-decoration:underline;">outdated</span>.</strong></p>
<p><strong>phpQuery</strong> is PHP-port of <a href="http://jquery.com/">jQuery</a> &#8211; well known and great web2.0 JS library</p>
<p>It&#8217;s something different than <a href="http://projects.cyberlot.net/trac/jqpie/wiki">jQPie</a>, which is form of JS code generator and server-client layer.</p>
<p>For example You can do something like this:</p>
<pre class="brush: php;">
print _('file.htm')
    -&gt;find('body div.cls1.cls2 ul &gt; li:first')
        -&gt;parent()
            -&gt;prepend('
	&lt;li&gt;my new first LI&lt;/li&gt;
')
            -&gt;parents('.myClass')
                -&gt;remove()
                -&gt;end()
            -&gt;appendTo('body')
            -&gt;parents('html')
                -&gt;html();
</pre>
<p>Code above will find first LI inside specific UL, then move pointer into it&#8217;s parent (UL),<br />
then prepend (add at the beginning) new LI, then pointer will move to parent element with class .myClass,<br />
which will be removed, and pointer will go back to UL (with end() method), and then UL will be appended to BODY (moved, not copied).<br />
Atfer all this operations parent with tag HTML will be searched and it&#8217;s content will be returned to print statement.</p>
<p><strong>phpQuery</strong> acts almost like <strong>jQuery</strong> &#8211; it returns new instance on <a href="http://docs.jquery.com/How_jQuery_Works#Chainability_.28The_Magic_of_jQuery.29">certain methods</a> and allows to revert stack.</p>
<p>It works on DOM Extension and is designed for PHP5 only.</p>
<p>There is almost no docs yet, so please refer to <a href="http://docs.jquery.com/Main_Page">jQuery&#8217;s one</a> (DOM section).</p>
<h3>Difference against jQuery</h3>
<p><strong>phpQuery</strong> differs in some cases from <strong>jQuery</strong>:</p>
<ol>
<li>Iteration</li>
<li>Callbacks</li>
<li>No DOM nodes</li>
<li>In some method names (PHP reserved words)</li>
<li>PHP specific addons</li>
<li>Other addons</li>
</ol>
<h4>Iteration</h4>
<p><strong>phpQuery</strong> makes use of PHP&#8217;s SPL <a href="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html">Iterator interface</a>, so You can do:</p>
<pre class="brush: php;">
foreach(_('ul&gt;*') as $_li) {
	$_li-&gt;prepend('new beginning of every LI');
}
</pre>
<h4>Callbacks</h4>
<p>PHP doesn&#8217;t have closures, but You can still use callbacks &#8211; direct or created with create_function() like so:</p>
<pre class="brush: php;">
function imTheCallback($_node){
	$_node-&gt;html(&quot;i'm changed content&quot;);
}
class imTheClass {
	static function imTheStaticCallback($_node){
		$_node-&gt;html(&quot;i'm changed content v2&quot;);
	}
	function imTheCallbackToo($_node){
		$_node-&gt;html(&quot;i'm changed content v3&quot;);
	}
}
$class = new imTheClass;
_('ul&gt;*')
	.each('imTheCallback')
	.each(array('imTheClass', 'imTheStaticCallback'))
	.each(array($class, 'imTheCallbackToo'))
	.each(create_function('$_node', '
		$_node-&gt;html(&quot;i\'m changed content v4&quot;);'
	));
}
</pre>
<h4>No DOM nodes</h4>
<p>Every node passed to callback or inside iteration is <strong>phpQuery</strong> object, not a DOM node. Also there isn&#8217;t a get() method.</p>
<h4>Method names</h4>
<p>There are several methods in <strong>jQuery</strong>&#8217;s interface with names which couldn&#8217;t be used as PHP class method or was changed to preserve consistent naming convention.</p>
<p>All those methods have been prefixed with _underscore and here&#8217;s the list:</p>
<ul>
<li>_clone</li>
<li>_next</li>
<li>_prev</li>
<li>_empty</li>
</ul>
<h4>PHP specific addons</h4>
<p>There are couple of PHP specific addons in <strong>phpQuery</strong> for easier developement:</p>
<ul>
<li>appendPHP($code) &#8211; equals to append(&lt;?php $code ?&gt;)</li>
<li>prependPHP($code) &#8211; equals to prepend(&lt;?php $code ?&gt;)</li>
<li>beforePHP($code) &#8211; equals to before(&lt;?php $code ?&gt;)</li>
<li>afterPHP($code) &#8211; equals to after(&lt;?php $code ?&gt;)</li>
<li>attrPHP($attr, $code) &#8211; equals to attr($attr, &lt;?php $code ?&gt;)</li>
<li>php($code) &#8211; equals to html(&lt;?php $code ?&gt;)</li>
<li>phpPrint($code) &#8211; equals to html(&lt;?php print $code ?&gt;)</li>
<li>phpMeta($selector, $code) &#8211; equals to find($selector)-&gt;php($code)-&gt;end()</li>
<li>__toString() &#8211; equals to htmlWithTag()</li>
</ul>
<h4>Other addons</h4>
<p>There is/will be several methods not present in standard jQuery, which i use (with jQuery) in my projects. More about this later.</p>
<h3>Development status</h3>
<p>Actually <strong>phpQuery</strong> seems to be quite stable and is main part of <strong>plainTemplates</strong> lib, which powers this blog.</p>
<p>Although there are couple of things to be done:</p>
<ul>
<li>Dedicated docs (copy jQuery&#8217;s one, add PHP specific, generate phpdoc)</li>
<li>Missing methods (css, val)</li>
</ul>
<h3>Download and links</h3>
<p>Here are the link which could be helpfull when dealing with <strong>phpQuery</strong>:</p>
<ul>
<li><a href="http://code.google.com/p/phpquery/downloads/list">Download latest version</a></li>
<li>Docs:
<ul>
<li><a href="http://docs.jquery.com/Main_Page">jQuery web</a></li>
<li><a href="http://corky.net/dotan/programming/hacks/jquerydocs/jquery-docs.pdf">jQuery PDF</a></li>
</ul>
</li>
<li><a href="http://meta20.net/tags/phpQuery-release">Get latest news</a> / <a href="http://meta20.net/tags/phpQuery-release.rss">RSS</a></li>
<li><a href="http://code.google.com/p/phpquery/">Google Code Project</a></li>
<li>SVN:
<ul>
<li><a href="http://phpquery.googlecode.com/svn/">Browser</a></li>
<li><a href="//phpquery.googlecode.com/svn/trunk/">Checkout</a></li>
</ul>
</li>
</ul>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/tobiasz123.wordpress.com/220/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/tobiasz123.wordpress.com/220/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tobiasz123.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tobiasz123.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tobiasz123.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tobiasz123.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tobiasz123.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tobiasz123.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tobiasz123.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tobiasz123.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tobiasz123.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tobiasz123.wordpress.com/220/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tobiasz123.wordpress.com&blog=4979845&post=220&subd=tobiasz123&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/tobiasz_cudnik/~4/iG8PxgAsF5w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tobiasz123.wordpress.com/2007/07/07/phpquery-a-jquery-port-to-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ee52f832cc820572f0a097d0b88dafe7?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G" medium="image">
			<media:title type="html">Tobiasz Cudnik</media:title>
		</media:content>
	<feedburner:origLink>http://tobiasz123.wordpress.com/2007/07/07/phpquery-a-jquery-port-to-php/</feedburner:origLink></item>
	</channel>
</rss>
