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

<channel>
	<title>blog.kno.at &#187; Tools</title>
	<atom:link href="http://blog.kno.at/folders/tools/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kno.at</link>
	<description>Marketing, Webdesign, Graphics, Drinking, a little WebApp every once in a while, it&#039;s like love. You could live without it, but why the hell should you?</description>
	<lastBuildDate>Wed, 18 Aug 2010 16:40:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Sometimes going on is all about closing doors</title>
		<link>http://blog.kno.at/trash/sometimes-going-on-is-all-about-closing-doors/</link>
		<comments>http://blog.kno.at/trash/sometimes-going-on-is-all-about-closing-doors/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 21:19:02 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[All the Rest]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.kno.at/trash/sometimes-going-on-is-all-about-closing-doors/</guid>
		<description><![CDATA[<p>If you close a door, you open another one &#8211; that&#8217;s common belief. I&#8217;m not so sure, but I&#8217;m quite certain that sometimes it&#8217;s necessary to close a door to get any further. Now it&#8217;s really easy to close most doors (it&#8217;s even easier not to close them, but the ... <a class="more-link" href="http://blog.kno.at/trash/sometimes-going-on-is-all-about-closing-doors/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>If you close a door, you open another one &#8211; that&#8217;s common belief. I&#8217;m not so sure, but I&#8217;m quite certain that sometimes it&#8217;s necessary to close a door to get any further. Now it&#8217;s really easy to close most doors (it&#8217;s even easier not to close them, but the whole open-doors-thingy easily leads to a huge mess and confusion and distracts you from where to go. So many doors to take care of. No good).</p>
<p>But some doors you&#8217;d just rather keep open. Most of the time these aren&#8217;t even the wide-open ones, but the ones about to slowly slam shut by themselves. The doors where there&#8217;s something on the other side you really want. But that damn door won&#8217;t just stay open.</p>
<p>Uh oh ah, I&#8217;m all philosophical and bullshitty.</p>
<p>However, here&#8217;s my end-of-philosophical advice: Close these doors. Maybe, some day, they open from the other side.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/trash/sometimes-going-on-is-all-about-closing-doors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Highlight Source Pro: Sourcecode Highlighting WordPress-Plugin</title>
		<link>http://blog.kno.at/tools/highlight-source-pro/</link>
		<comments>http://blog.kno.at/tools/highlight-source-pro/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 14:26:36 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[automatically]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[colorize]]></category>
		<category><![CDATA[COMPLIANCE]]></category>
		<category><![CDATA[compliant]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[CSS-styles]]></category>
		<category><![CDATA[display]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[geshi]]></category>
		<category><![CDATA[highlight]]></category>
		<category><![CDATA[highlight source pro]]></category>
		<category><![CDATA[highligt]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[HTML-Markup]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[markup]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[salvation]]></category>
		<category><![CDATA[server-side]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[sourcecode]]></category>
		<category><![CDATA[styling]]></category>
		<category><![CDATA[syntax]]></category>
		<category><![CDATA[valid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xhtml]]></category>
		<category><![CDATA[XHTML-Compliant]]></category>

		<guid isPermaLink="false">http://blog.kno.at/?p=178</guid>
		<description><![CDATA[<p>Syntax-Highlighting for WordPress made easy. Utilizing GeSHi and simple, standards-compliant attribute-based controls the possibilites are unlimited. All styling is done with CSS and can easily be personalized. ... <a class="more-link" href="http://blog.kno.at/tools/highlight-source-pro/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Yeah, there&#8217;s that WordPress-Blog we have and there are these tools we develop, and when we blog about our ingeniousity we have to go through all those painful code-markup-problems. I hate that. But fear no more, my furry friends, for this is our path to salvation.</p>
<h2>Highlight Source Pro</h2>
<p>Based upon <a href="http://jpipes.com/index.php?/archives/216-Syntax-Highlighting-and-Allowing-HTML-in-Comments.html">this Posting</a> I found on my research I tweaked and improved things a little and here it is, in it&#8217;s full glory, flexible, automatic, degrading &#8211; amazing.</p>
<h2><a href="http://wordpress.org/extend/plugins/highlight-source-pro/download/" class="download">Download Current Version (from wordpress.org)</a></h2>
<p><a href="http://tinyurl.com/3mjxz2">Donate (PayPal)</a></p>
<h3>Features</h3>
<ul>
<li>Highlight sources of any language</li>
<li>automatically, server-side (no javascripts)</li>
<li>XHTML-Compliant, &lt;div&gt;, &lt;ul&gt; &amp; &lt;span&gt;&#8217;s with class-attributes and a css-file are used for styling</li>
<li>optionally add a heading for every code-block</li>
<li>optionally specify line-number offset (BREAKS XHTML COMPLIANCE)</li>
<li>optionally don&#8217;t display line-numbers</li>
<li>set per-codeblock if the code is html_entity_encoded or not</li>
<li>only parses &lt;pre&gt;-tags with the lang-attribute, thus does not interfere with any regular preformatted contents you might have</li>
<li>degrades beautifully through &lt;pre&gt;-tags (if you keep the sources clean, that is)</li>
<li>all settings through logical, valid arguments for the main container</li>
<li>comes with generic cross-browser (IE5/Mac, IE5.5+, FF, Safari, Opera) default CSS-styles</li>
<li>see <a href="http://kno.at/files/images/highlight-source-pro_screenshot-1.png">screenshot</a> for preview</li>
</ul>
<h3>How to use</h3>
<p>Set your code-blocks as &lt;pre&gt;-tags. If the language is supported by GeSHi (see filelist in the /geshi-directory) use the filename (without extension) as language-attribute. If your code is encoded (html-entities; e.g. &lt; is displayed as &amp;lt; &#8211; most likely the case if you write in the visual editor) add the &#8216;enc__&#8217; &#8211; prefix. For example for a php-codeblock you would start as follows:</p>
<p><code>&lt;pre lang=&quot;php&quot;&gt;</code></p>
<p>You can control various things:</p>
<ul>
<li>Start of Line-Offset, e.g. for #17: <code>&lt;pre class=&quot;17&quot;&gt;</code></li>
<li>define entity-encoded blocks, e.g. for php: <code>lang=&quot;enc__php&quot;</code></li>
<li>Define a title for your code-block that appears inside the block, but above the code lines. Everything in the same line as the opening <code>&lt;pre&gt;</code> tag will be considered the title, including HTML. Example: <code>&lt;pre lang=&quot;php&quot;&gt;&lt;strong&gt;This is&lt;/strong&gt; an &lt;em&gt;example&lt;/em&gt; with a &lt;h3&gt;headline&lt;/h3&gt;</code></li>
<li>disable line numbers by not specifying an offset</li>
</ul>
<h3>Known Issues</h3>
<ul>
<li>While the plugin is basically XHTML 1.0 Strict compliant there&#8217;s just no way of getting the offset-based line-numbering to display without inadequate (ab)use of javascript &#038; css hacks, so be warned that IF you use the line-number offset, your documents will NOT validate because of the forbidden start-attribute for the <code>&lt;ol&gt;</code>!</li>
<li>Watch out for your ampersands (<code>&amp;</code>) for HTML-listings: Those little friends ALWAYS have to be encoded (<code>&amp;amp;</code>), even twice (<code>&amp;amp;amp;</code>) if your source is encoded. This is because GeSHi only checks for HTML 4 Strict.
</ul>
<h3>Example #1: HTML</h3>
<pre>
&lt;pre lang=&quot;html&quot;&gt; Some Demo-HTML-Markup
&lt;body&gt;
&lt;h1 class=&quot;a_class&quot;&gt;What a great afternoon &amp;amp; stuff&lt;/h1&gt;
&lt;p&gt;Isn't &lt;a href=&quot;http://kno.at/&quot;&gt;today&lt;/a&gt; just &quot;beautiful&quot;?&lt;/p&gt;
&lt;/body&gt;
&lt;/pre&gt;
</pre>
<div class="geshi no html4strict">
<div class="head">Some Demo-HTML-Markup</div>
<ol>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;body&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;h1</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;a_class&quot;</span><span class="kw2">&gt;</span></span>What a great afternoon <span class="sc1">&amp;amp;</span> stuff<span class="sc2"><span class="kw2">&lt;/h1&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;p&gt;</span></span>Isn&#39;t <span class="sc2"><span class="kw2">&lt;a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;http://kno.at&quot;</span><span class="kw2">&gt;</span></span>today<span class="sc2"><span class="kw2">&lt;/a&gt;</span></span> just &quot;beautiful&quot;?<span class="sc2"><span class="kw2">&lt;/p&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;/body&gt;</span></span></div>
</li>
</ol>
</div>
<h3>Example #2: PHP</h3>
<pre>
&lt;pre lang=&quot;enc__php&quot; class=&quot;17&quot;&gt; now &lt;strong&gt;with&lt;/strong&gt; headline: &lt;h3&gt;a PHP-Filename&lt;/h3&gt;
&amp;lt;?php
/**
 *  Here is a comment! Weeeeeeeee.
 */
function demonstrate_stuff ( $me_so_horny )
{
    $a = 17;
    print ( &quot;$a: $me_so_horny&quot;. $a * 3 + $this-&amp;gt;testvar );
    return 'excellent!';
}
?&amp;gt;
&lt;/pre&gt;
</pre>
<div class="geshi php">
<div class="head">now <strong>with</strong> headline:<br />
<h3>a PHP-Filename</h3>
</div>
<ol start="17">
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &nbsp;Here is a comment! Weeeeeeeee.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> demonstrate_stuff <span class="br0">&#40;</span> <span class="re1">$me_so_horny</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$a</span> <span class="sy0">=</span> <span class="nu0">17</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">print</span> <span class="br0">&#40;</span> <span class="st0">&quot;$a: $me_so_horny&quot;</span><span class="sy0">.</span> <span class="re1">$a</span> <span class="sy0">*</span> <span class="nu0">3</span> <span class="sy0">+</span> <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">testvar</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&#39;excellent!&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/highlight-source-pro/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		</item>
		<item>
		<title>randomFlickr V0.6</title>
		<link>http://blog.kno.at/tools/randomflickr-v06/</link>
		<comments>http://blog.kno.at/tools/randomflickr-v06/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 12:35:11 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[freeware]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[picture]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blogs.kno.at/personal/2008/04/02/randomflickr-v06/</guid>
		<description><![CDATA[<p>Fetch one photo from a badge and then do stuff. V0.6 now supports choosing the size to fetch, or can even try to automagically detect the best suited one (woo-hoo!) ... <a class="more-link" href="http://blog.kno.at/tools/randomflickr-v06/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I just tweaked <a href="http://blogs.kno.at/doc/2007/12/01/one-random-photo-from-your-flickr-stream/" title="randomFlickr - One random photo from your flickr-stream">randomFlickr</a> a bit and thus am releasing V0.6. Not because it&#8217;s a huge update, I just feel like releasing something and my new blog layout still is quite a bit from &#8220;done&#8221;, so here we go with a few more options on the source-file. See the <a href="http://blogs.kno.at/doc/2007/12/01/one-random-photo-from-your-flickr-stream/#vhis" title="randomFlickr">Release-Notes</a> for details, or just have a look at the <a href="http://dev.kno.at/flickpic/" title="randomFlickr Demo">Demo-Page</a> code-sample.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/randomflickr-v06/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finally: Full Google-Calendar Sync with GCALDaemon</title>
		<link>http://blog.kno.at/tools/finally-full-google-calendar-sync-with-gcaldaemon/</link>
		<comments>http://blog.kno.at/tools/finally-full-google-calendar-sync-with-gcaldaemon/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 18:48:03 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[2-way]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[bidirectional]]></category>
		<category><![CDATA[button]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[freeware]]></category>
		<category><![CDATA[gcaldaemon]]></category>
		<category><![CDATA[google calendar]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[ical]]></category>
		<category><![CDATA[instructions]]></category>
		<category><![CDATA[knoperblog]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[sync now]]></category>
		<category><![CDATA[synching]]></category>
		<category><![CDATA[synchronisation]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[synchronize]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[two-way]]></category>

		<guid isPermaLink="false">http://blogs.kno.at/personal/2007/12/03/finally-full-google-calendar-sync-with-gcaldaemon/</guid>
		<description><![CDATA[<p>Since I use Google Calendar I was looking for an elegant and logical solution to keep it synchronized with my local calendar application (which was to be found) &#8211; biderectional. I guess soon this will become a standard feature, however by now it is not. Today I stumbled upon what I was looking ... <a class="more-link" href="http://blog.kno.at/tools/finally-full-google-calendar-sync-with-gcaldaemon/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Since I use Google Calendar I was looking for an elegant and logical solution to keep it synchronized with my local calendar application (which was to be found) &#8211; biderectional. I guess soon this will become a standard feature, however by now it is not. Today I stumbled upon what I was looking for, and once again this is possible due to the *nix-Core of OSX.</p>
<p><span id="more-101"></span></p>
<h2 style="color:red">Update: Flawless Sync with CalDav</h2>
<p>Sync without any tweaking around is working perfectly with Google&#8217;s CalDav. Check out how to set it up <a href="http://www.google.com/support/calendar/bin/answer.py?answer=99358">here</a> and enjoy flawless syncronization.</p>
<p>Big thanks go out to an anonymous commenter!</p>
<h2>Update for OSX 10.5 Leopard</h2>
<p>As things are by now it seems that Leopard stores iCal&#8217;s files kind of unusual and without extra PERL-Scripts and other humpty-tumpty hacking there&#8217;s <strong>no way of getting GCALDaemon to properly work</strong> with it. Therefore this solution is plain not working and not recommended for Leopard. I&#8217;ve hear that Plaxo Online can do all the syncing, but haven&#8217;t tried myself.</p>
<p>But don&#8217;t mind that, in clear words what this solution does is: Whatever calendar program you&#8217;re using, as long as it is based on .ical-files this handy little tool will run in the background and then, every few minutes, will synchronize this file with your google calendar. That way it&#8217;s totally independent from the calendar application and basically you can use whatever program suits your needs. You install this tool only once and then, forever, can sync any local ical file with any online google calender &#8211; bidirectional. The following instructions are for setting the thing up with Apple&#8217;s iCal, but other programs are pretty much the same.</p>
<h2><a title="GCALDaemon Home" href="http://gcaldaemon.sourceforge.net/">GCALDaemon</a></h2>
<p>A great and simple program, doing one thing: It synchronizes your remote google calendar with your local .ical-sourcefile, and vice versa. That&#8217;s not just great because it simply works, it also brings along two major features: The local calendar file will keep the calendar 100% available offline plus it&#8217;s no problem switching to any other program that&#8217;s using the ical &#8211; format.</p>
<p>However since we&#8217;re talking about an unix-application here the installation requires a little Terminal-fiddling, but not as much as one would expect. The following tutorial will make you a happy synchronized person and I promise things are easy, because I&#8217;ll use the finder instead of the terminal as much as possible. Now for the process:</p>
<ol>
<li>Download GCALDaemon</li>
<li>Unzip to the correct directory</li>
<li>Create your calendars</li>
<li>Configure with the built-in GUI</li>
<li>Install as startup-application</li>
</ol>
<h2><a title="GCALDaemon Downloads" href="http://gcaldaemon.sourceforge.net/downloads.html">1: Downloading GCALDaemon</a></h2>
<p>That one&#8217;s easy. Click the headline. Download the Linux/Mac &#8211; compatible .zip-archive. That&#8217;s it. <strong>don&#8217;t bother with the installation instructions, we&#8217;ll get that done in a second</strong></p>
<h2>2. Unzip to the correct directory</h2>
<p>Unzip the archive to your desktop. In the now new directory you&#8217;ll find another directory: GCALDaemon. We&#8217;ll need this in a second. Now, first time for some Finder trickery. Click on an empty place on your desktop so the finder is the active application. Now either press Command + Shift + G or go to the menu bar and select &#8220;Go To &gt; Folder &#8230;&#8221;. A dialogue box will pop up. Enter, and enter exactly:</p>
<div class="geshi no bash">
<div class="head">/usr/local</pre>
</div>
<ol>
<li class="li1">
<div class="de1">If everything<span class="st0">&#39;s right you now should have a Finder window showing the folders: /lib and /sbin. If the latter doesn&#39;</span>t exist, create it now from within the Finder. You<span class="st0">&#39;ll probably have to identify as administrator, as those directories can be write-protected. That&#39;</span>s ok, enter your password, create the folder and get <span class="kw1">in</span>. Congratulations, you<span class="st0">&#39;re now in /usr/local/sbin. On with the stuff.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="st0">Copy the folder GCALDaemon from your desktop to /usr/local/sbin. Once again it&#39;</span>s possible the system will ask you to identify - <span class="kw1">do</span> that <span class="br0">&#40;</span><span class="kw1">do</span> that whenever it happens during the installation process<span class="br0">&#41;</span>.</div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">&lt;</span>h2<span class="sy0">&gt;</span><span class="nu0">3</span>. Create your calendars<span class="sy0">&lt;/</span>h2<span class="sy0">&gt;</span></div>
</li>
<li class="li1">
<div class="de1">If you haven<span class="st0">&#39;t already done that, go to iCal now and create your calendars &lt;strong&gt;as normal local calendars.&lt;/strong&gt; If you just wanna try this you can also use the default calendar that&#39;</span>s already <span class="kw1">set</span> up, repeating step <span class="nu0">4</span> you can easily add <span class="kw2">more</span> calendars whenever you feel like.</div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">&lt;</span>h2<span class="sy0">&gt;</span><span class="nu0">4</span>. Configure with the built-<span class="kw1">in</span> GUI<span class="sy0">&lt;/</span>h2<span class="sy0">&gt;</span></div>
</li>
<li class="li1">
<div class="de1">This one was listed at <span class="sy0">&lt;</span>strong<span class="sy0">&gt;</span>the end<span class="sy0">&lt;/</span>strong<span class="sy0">&gt;</span> of the manual installation instructions and I kind of hated the GCALDaemon-Guys <span class="kw1">for</span> a few minutes there. But you don<span class="st0">&#39;t have to suffer, but can profit from my findings. Now for the first of two terminal commands (you&#39;</span>ll need no <span class="kw2">more</span> than those two, I promise<span class="br0">&#41;</span>. Open a Terminal window <span class="br0">&#40;</span>Applications <span class="sy0">&amp;</span>gt; Utilities <span class="sy0">&amp;</span>gt; Terminal<span class="br0">&#41;</span>. Now <span class="kw3">type</span>, and once again <span class="kw3">type</span> exactly, the following:</div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">&lt;</span>pre <span class="re2">lang=</span><span class="st0">&quot;bash&quot;</span><span class="sy0">&gt;/</span>usr<span class="sy0">/</span><span class="kw3">local</span><span class="sy0">/</span>sbin<span class="sy0">/</span>GCALDaemon<span class="sy0">/</span>bin<span class="sy0">/</span>config-editor.<span class="kw2">sh</span></div>
</li>
</ol>
</div>
<p>Execute the command by hitting the Enter. After a second or so a window will pop up. Ignore the whole settings-stuff and go to "File synchronizer". Click the first line: "Enable file-based calendar synchronizer" until it's checked green. Do the same with "Enable dial-up connection and/or use PDA synchronizer ['offline-enabled' mode]" (the latter is theoretically unnecessary when you're on a constantly connected workstation, but the sync-mode is more flexible and there's no disadvantages whatsoever, so just check if if you don't have a good reason not to). The "Google Calendar polling interval" is the interval GCALDaemon uses to synchronize your online-calendar. The 15 minutes setting should be fine, so if you're not excessively switching between browser and iCal access you can leave this alone.</p>
<p>Now for the real part. On the bottom right there's a button "Google Accounts". Click it, choose New Account, enter your mail and enter your password twice. Check with verify. If everything's fine click ok. The next interesting button is the "New"-Button, just three steps left from the "Google Accounts"-one. Click it, select the remote calendar you want to synchronize and the local Calendar you want it to be synchronized with. Close the application and if you're asked to save your changes click "Ok". Tada, Magic done. You can repeat this step whenever you need to add or edit a calendar.</p>
<h2>5. Install as startup-application - THANK YOU <a title="Build Chimp" href="http://www.ejlife.net/blogs/buildchimp/2007/03/19/1174357591009.html">BUILD CHIMP</a></h2>
<p>This is a little bit tricky, but if you follow the steps below you should be fine. Credits for that all go to <a title="Build Chimp" href="http://www.ejlife.net/blogs/buildchimp/2007/03/19/1174357591009.html">Build Chimp</a>. Now we need to tell OS X to execute this file on startup. This is being done with a .plist file. Open the editor (Applications &gt; Utilities &gt; Editor). <strong>Don't use TextEdit,</strong> you'll need the Editor! Create a new file, copy the following code - exactly - to the editor:</p>
<div class="geshi no xml">
<div class="head">EnvironmentVariables</div>
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">JAVA_HOME</div>
</li>
<li class="li1">
<div class="de1">/System/Frameworks/JavaVM.framework/Versions/1.5</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">Label</div>
</li>
<li class="li1">
<div class="de1">net.sf.gcald</div>
</li>
<li class="li1">
<div class="de1">OnDemand</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">ProgramArguments</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">/usr/local/sbin/GCALDaemon/bin/standalone-start.sh</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">RunAtLoad</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">ServiceDescription</div>
</li>
<li class="li1">
<div class="de1">GCALDaemon</div>
</li>
<li class="li1">
<div class="de1">StandardErrorPath</div>
</li>
<li class="li1">
<div class="de1">/usr/local/sbin/GCALDaemon/log/launchd.stderr</div>
</li>
<li class="li1">
<div class="de1">StandardOutPath</div>
</li>
<li class="li1">
<div class="de1">/usr/local/sbin/GCALDaemon/log/launchd.stdout</div>
</li>
</ol>
</div>
<p>Easy. Now save the file to your desktop with the name:</p>
<pre>net.sf.gcald.plist</pre>
<p>Watch out that editor doesn't add a file extension. Next we'll have to move it to it's final destination:</p>
<pre>/Library/LaunchDaemons</pre>
<p>Go to your desktop, double-click your harddrive ("Macintosh HD", or "OSX", or whatever yours is called). Select the folder "Library", then select "LaunchDaemons". There's a good chance the folder is empty, but never mind, that's ok. Now move the file net.sf.gcald.plist from the desktop to this folder (Indentification might be needed once more). We're almost done.</p>
<p>Finally open a Terminal window again and type in the following line:</p>
<div class="geshi no bash">
<div class="head">sudo launchctl load -w /Library/LaunchDaemons/net.sf.gcald.plist</pre>
</div>
<ol>
<li class="li1">
<div class="de1">Hit Enter. You<span class="st0">&#39;ll be asked for your password. As you enter it the Terminal will not reflect your input, no stars, no nothing, that&#39;</span>s normal. Just enter your password and finish with Enter.</div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">&lt;</span>h2<span class="sy0">&gt;</span>Congratulations, you successfully installed full iCal <span class="sy0">/</span> Google-Calendar synchronization.<span class="sy0">&lt;/</span>h2<span class="sy0">&gt;</span></div>
</li>
<li class="li1">
<div class="de1">If you<span class="st0">&#39;re fine with the terminal you could now start the tool manually with the line</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">&lt;pre lang=&quot;bash&quot;&gt;/usr/local/sbin/GCALDaemon/bin/standalone-start.sh</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0"</span></div>
</li>
</ol>
</div>
<p>or initialize a first sync with</p>
<pre lang="bash">/usr/local/sbin/GCALDaemon/bin/sync-now.sh</pre>
<p>Otherwise you'll have to logout and back in. Remember that the synchronization-interval is 15 minutes and the data transfer might take some time, but for me it by now works perfectly fine and I really enjoy the synced calendaring.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/finally-full-google-calendar-sync-with-gcaldaemon/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>The holy Grail: Image browser freeware stuff</title>
		<link>http://blog.kno.at/tools/the-holy-grail-image-browser-freeware-stuff/</link>
		<comments>http://blog.kno.at/tools/the-holy-grail-image-browser-freeware-stuff/#comments</comments>
		<pubDate>Sun, 02 Dec 2007 16:47:39 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[cocoaslideshow]]></category>
		<category><![CDATA[cocoviewx]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[ffview]]></category>
		<category><![CDATA[footagehead]]></category>
		<category><![CDATA[freeware]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[image browser x]]></category>
		<category><![CDATA[imagebrowser]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[imagewell]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[multithumbs]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[photopolis]]></category>
		<category><![CDATA[pixelwalker]]></category>
		<category><![CDATA[rapidomap]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[xee]]></category>

		<guid isPermaLink="false">http://blogs.kno.at/personal/2007/12/02/the-holy-grail-image-browser-freeware-stuff/</guid>
		<description><![CDATA[<p>I&#8217;m a heavy Keep-Everything-Even-If-It&#8217;s-Trash kind of person if it comes to digital data. This includes, but is not restricted to, photos. My little crappy snapshot cam is in high use and my flickr-Account already stuffed with a few thousand snapshots. What I really crave for is a little ... <a class="more-link" href="http://blog.kno.at/tools/the-holy-grail-image-browser-freeware-stuff/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a heavy Keep-Everything-Even-If-It&#8217;s-Trash kind of person if it comes to digital data. This includes, but is not restricted to, photos. My little crappy snapshot cam is in high use and my flickr-Account already stuffed with a few thousand snapshots. What I really crave for is a little handy tool that let&#8217;s me manage my photos offline. But I couldn&#8217;t find one yet. Also the discussion on <a href="http://freewareosx.wordpress.com/2007/09/20/kostenlose-bilderverwaltung-ohne-iphoto/" title="Imaging Solutions for Mac">my favourite (german) mac freeware-blog OS X Freeware</a> didn&#8217;t end up all too promising, so on with the search.</p>
<p><span id="more-98"></span></p>
<p>There&#8217;s iPhoto packed with OSX, but since I like to have control over my data and iPhoto does stuff like copying photos if you manipulate them and some other uncontrollable stuff it&#8217;s no choice. Most of the other stuff is too heavyweight or does too much. I want focused stuff &#8211; do what you have to do, and stay slim. Freeware is preferred, of course.</p>
<p>So right now I just downloaded 13 potential candidates to become my favorite photo-assistant and since I&#8217;m currently trying the handy offline-blog-management tool ecto I&#8217;ll just document each single of those 14 guys on-the-fly to share my experience and ease this process for others. I&#8217;m nice, eh?</p>
<h4>Candidate #1: <a href="http://code.google.com/p/cocoaslideshow/" title="Cocoa Slideshow on Google Code">CocoaSlideShow</a></h4>
<p>Hm ok, I guess I didn&#8217;t carefully read the description here. This tool does what it&#8217;s name suggests: It makes slideshows. You add the files, click &#8220;view&#8221; and there you go: Slideshow. But it&#8217;s doing this pretty good, so I&#8217;ll keep it for that purpose. You never know. It&#8217;s only 280kb, non-installing and keeps focus &#8211; the kind of software I like.</p>
<h4>Candidate #2: <a href="http://www.stalkingwolf.net/software/cocoviewx/" title="CocoViewX Homepage">CocoViewX</a></h4>
<p>This is a good thing! First of all it&#8217;s offering a great way of browsing. You have a list just like in the finder. Choose the folder to start, and click your way through your collection. Intuitive. As you explore it you find out about it&#8217;s features. There&#8217;s a drop box: A sidebar on the right, where you can &#8211; surprise &#8211; drop photos you find for quick access later. It creates thumbnails by default, however you can fasten the whole thing by either turning this behaviour off (there&#8217;s a button to do this manually for the folder you&#8217;re in) or at least by disabling anti-aliasing for thumbnails.</p>
<p>Under the graphical surface there&#8217;s a lot of power, like exif viewing / editing, batch processing, thumbnail generation and a lot more. If you customize the toolbar you&#8217;ll find out about the Rotate CW / CCW buttons. Also there&#8217;s a slideshow feature, a fullscreen mode and easy access to favorite folders. Looks like the tool to go. Definitely being kept. Ah, and by dragging a picture from the dropbox back to the browsing window you move it from it&#8217;s original location (or, with the default finder ALT-key-cheat, copy). I like this. Oh, 3.4MB by the way. On to the next.</p>
<h4>Candidate #3: <a href="http://www.feedface.com/software/ffview.html" title="FFView Homepage">FFView</a></h4>
<p>Now that&#8217;s going to be interesting. This is intentionally done to read mangas and comics on-screen. First of all the mac speech control is popping up, so it&#8217;s audio-accessible. However I don&#8217;t use that feature at all, so none of interest for me. Uhm &#8230; strange things happening. The folder browser looks good, however if I click a folder it pops to a fullscreen-window, no file list anymore. Don&#8217;t know why, can&#8217;t seem to prevent this. Clicking the &#8220;list&#8221; &#8211; icon doesn&#8217;t do anything, clicking fullscreen shows the pictures fullscreen, portrait-formats to be scrolled down. I get the idea of that being useful if you read a manga, however I&#8217;d like to stop that fullscreen thing with ESC or at least by accessing a menu with the right mouse button. But nope. Had to quit it and won&#8217;t start it again :) In a field of 14 starters there&#8217;s no 2nd chance.</p>
<h4>Candidate #4: <a href="http://www.zankasoftware.com/footagehead/" title="FootageHead Homepage">FootageHead</a></h4>
<p>Wow, nice. Very fast, very minimalistic: A simple folder-drawer to the left, a viewport to the right. Creates thumbnails and views pictures almost instantly. Perfect for browsing through and deleting the baddies, however doesn&#8217;t offer any form of manipulation (even the rotation only affects the view, I couldn&#8217;t find a way to save that). But it&#8217;s <strong>very</strong> fast, so I&#8217;ll gonna keep it. Funny enough it&#8217;s 2.4MB, that&#8217;s about ten times the size of CocoaSlideShow by offering quite the same features. But hey, 2.4MB in times of terabyte-harddrives &#8230;</p>
<h4>Candidate #5: <a href="http://www.simulacrum.net.nz/imagebrowser.php" title="ImageBrowser Homepage">ImageBrowser</a></h4>
<p>Huh, welcomes me with a donation-dialogue and is asking for a code (you get one if you donate). However, the only disadvantage is that this dialogue pops up on startup. And hey, if the program turns out to be great I&#8217;ll consider a donation anyway. So on with the testing. First of all customize the toolbar and throw in the useful stuff that&#8217;s not there by default: A button for &#8220;fit to window&#8221;, a dropdown to change the sort-by-behaviour, a dropdown with applications to edit the current file (supports view for videos &amp; audo, as well as selecting all kinds of files and define an editor in the preferences). There&#8217;s a button to generate thumbnails for all files in the directory and one to stop, if things get too slow.</p>
<p>The preferences offer a lot of useful customization, like turning off auto-thumbnail-generation, an option to generate thumbnails when the picture is viewed, one-click-file-renaming and so on. However, especially compared to FootageHead, that thing&#8217;s real slow. Loading the same picture takes about one second. Sounds fast, but try for yourself. FootageHead beats that by far. But the cool thing about this is I can specify all kinds of programs to show up in the edit with dropdown, so I&#8217;ll probably keep it as a small browser to edit specific types of files. There&#8217;s potential, but the image-thing doesn&#8217;t work all that well &#8230;</p>
<h4>Candidate #6: <a href="http://kstudio.net/ib.html" title="Image Browser X Homepage">Image Browser X</a></h4>
<p>Similar name, other software. They&#8217;re not related. This one starts up kind of weird, with a huge info dialogue and a strange startup-window &#8230; hmmm. Hm ok, whyever that one was listed as an image-browser, it in fact isn&#8217;t. You have to &#8220;prepare&#8221; single pictures first, with a helper application, and I guess you then can view it or stuff, but that&#8217;s not what I was looking for at all. So on with the tool testing.</p>
<h4>Candidate #7: <a href="http://www.angry-%3Cwbr%3Emongoose.com/blog/images/" title="Images Homepage">Images</a></h4>
<p>Yep, I really think it&#8217;s good for software to have unique name. Makes it easy to find in Google, does it not? Okay, I&#8217;ll not be too sarcastic, due I admire people releasing free software. This thing is neither visually beautiful, nor very functional. It&#8217;s preview is slow, you can&#8217;t edit anything. It&#8217;s basically pretty much the same as the finder, just with less functionality and worse looking. Sorry, but this just is &#8230; uhm &#8230; useless (ah, turns out it&#8217;s a java-app. Those tend to be slow, and are just not the way to go for imaging software).</p>
<h4>Candidate #8: <a href="http://xtralean.com/IWOverview.html" title="ImageWell Homepage">ImageWell</a></h4>
<p>Once more an application that&#8217;s not for browsing. There are some nice features, like flickr-uploading, iDisk uploading and stuff like that. You can add watermarks and do some fancy editing. But once again it&#8217;s slow, especially with bigger pictures, and there&#8217;s no browsing-like-functionality whatsoever. Probably does another job real well, but it&#8217;s no good for what I need. So dismissed.</p>
<h4>Candidate #9: <a href="http://homepage.mac.com/mdewalt/iWeb/Site/Thumb-%3Cwbr%3EApplications.html" title="MultiThumbs Homepage">MultiThumbs</a></h4>
<p>Starts up with a huge dialogue and an easy-to-understand message: Open a folder with the file menu or drag photos here. I&#8217;ll do the file menu thing. Ok, it opens the folder, creates thumbnails and displays them clean on a black background. I didn&#8217;t check out the preferecnes, but you can open a photo fullscreen by clicking it and probably do some more stuff &#8211; however the creation takes it&#8217;s time and isn&#8217;t anything like browsing. So this one also isn&#8217;t what I am looking for, however does another nice job so if you&#8217;re looking for thumbnail-stuff give it a try.</p>
<h4>Candidate #10: <a href="http://homepage.mac.com/dschulius/Photopolis/frame.html" title="Photopolis Home">Photopolis</a></h4>
<p>Ok, this is an exotic thing. It will use photo&#8217;s creation dates and build a virtual town (3D) you then can walk through, for example on the &#8220;December Street&#8221; or the &#8220;2007 Street&#8221; (years = vertical, months = horizontal). No for the startup. Ok, the first thing with an installation dialogue. I don&#8217;t really like this, because I want lightweight stuff I can just delete if I don&#8217;t need it anymore, but I really want to try this. I chose my whole pictures-folder (1.5GB). It&#8217;s 16.18 now. The progress bar looks good, seems to process the pics kind of fast (yeah, Live-Blog-Reporting. I should do this for a NFL-game: &#8220;NOW ALL NEW: LIVE-BLOG-ENTRY-WRITING-AND-AFTERWARDS-READING &#8211; All the excitement, as fast as you like!&#8221; 16.35 &#8211; it&#8217;s done. 17 minutes to export 1.5GB isn&#8217;t all that bad. Now for the city. Wow, that&#8217;s really nice. It&#8217;s damn slow on my PBG4 though (3fps isn&#8217;t that exciting), but on a fast machine this most be great. Give it a try, it&#8217;s a great way to explore your archive! Not of much use, but hey &#8211; life&#8217;s not only about efficiency.</p>
<h4>Candidate #11: <a href="http://software.hartungdesign.net/" title="PixelWalker Home">PixelWalker</a></h4>
<p>Starts up instantly and the first impression is good &#8211; kind of like the column browsing in finder, but all columns accessible. Looks good to me. I&#8217;ll check the toolbar and the preferences. Ok, nothing there. The toolbar includes everything, the preferences are minimalistic: Choose your default editor, add file extensions to exclude and decide if thumbnails shall be loaded in the background. Now for the program. Hm ok, it&#8217;s kind of fast, but uhm &#8230; uncomfortable to operate. There&#8217;s four states of window arrangement, bot none with thumbnails + browsing. You can browse to a folder and then switch to thumbnail view, but you can&#8217;t see thumbnails as you browse. Not so good. Ok, the shortcuts for the views are 1 &#8211; 2 &#8211; 3 &#8211; 4, so switching is as easy as can be. This way you can browse very fast with the keyboard. Strange enough the folder-view doesn&#8217;t show some of the pictures, whereas switching to thumbnail view lists everything. I&#8217;ll keep this one and play around a little more, could be handy to find stuff. The thumbnail creation is pretty fast.</p>
<p>By the way it just turned out that any of the tools tested until now has manipulated some of my files. Renamed them quite strangely, one Thumbnails-subfolder has been created &#8230; damn, that&#8217;s the stuff that just shouldn&#8217;t happen at all. Should have checked that after every tool, shouldn&#8217;t I? Indeed, I should. DAMN.</p>
<h4>Candidate #12: <a href="http://wakaba.c3.cx/s/apps/xee.html" title="Xee Home">Xee</a></h4>
<p>A highspeed starter. The preferences are loaded with keyboard shortcuts. A few highlights: You can define up to 10 destinations and define shortcuts to move or copy pictures there. Basically you can browse through any folder with the keyboard damn fast and &#8220;throw the pictures around&#8221; with ease. Sounds like one hell of a productivity application. Wooohooo! Image display is the fastest yet. I like the keyboard navigation, however the scroll wheel works just as fine. There&#8217;s a crop function and you can save the cropped part to a new file, however can&#8217;t just overwrite the original (what&#8217;s probably a good thing). Also you can mirror and rotate pictures and save that over the original file. Somehow the preview isn&#8217;t updated, so if you move on to the next pic and go back the just rotated image will show up as before the rotation, but the file is updated. Strange. I like Xee.</p>
<p>The statusbar shows a lot of Info, like how many frames (this not only includes animations, but also the default finder-preview is detected as another frame &#8211; neat!), the zoom rate, the total picture count in this folder, date &amp; time, file name, file size in bytes and file dimensions in pixels. There&#8217;s a fullscreen-mode as well. That&#8217;s the closest thing to IrfanView (PC) and it&#8217;s going to have a fix place in my tool collection. Recommended!</p>
<h4>Candidate #13: <a href="http://www.app4mac.com/rapidomap.html" title="RapidoMap Home">RapidoMap</a></h4>
<p>Ah, finally another one with an installation dialogue. But this isn&#8217;t a picture browser, it&#8217;s something special I decided to give a try: It&#8217;s a geotagging-tool, for adding your photos to a map. Based on yahoo-maps it first of all fetches map data from the web. Now I can add locations. The interface is simple and functional, I like this. As I geotag all my flickr-images and this application has a built-in flickr-upload function it&#8217;s just one thing: Perfect. Well, almost. Unfortunately it won&#8217;t let me add locations when I&#8217;m offline. I need a tool like that for travelling. I want to add locations based on addresses wherever I am, add the photos and the next time I connect to the web the app should assign the locations to the map and let me upload the photos. By now the tool just won&#8217;t let me start it up if I&#8217;m not online, but I wrote a feedback mail and am looking forward to the reply. After all it can&#8217;t be that much of an issue to implement this, it&#8217;s just delayed assigning of the info. THEN it would be perfect.</p>
<h4>Preview: <a href="http://www.jetphotosoft.com/web/home/" title="JetPhoto Studio Home">JetPhoto Studio &amp; a view more</a></h4>
<p>Just stumbled upon this handy thing. With 20MB it&#8217;s real heavyweight compared to the rest, but it looks damn promising: Calender view, flickr-integration (tagging, geotagging, uploading, organization by EXIF-data, &#8230;) The downloads almost done, now for the testing. I expect another installation dialogue ;)</p>
<p>Also I found more freeware image stuff, I&#8217;ll continue my report another day &#8211; I&#8217;m tired of this screen and I already unpacked too much stuff for one day by now. A quick summary of today&#8217;s odyssey: Xee, CocoView X, Footagehead are potential candidates for browsing, as is Pixelwalker. CocoaSlideshow will be kept, cause you never know and it&#8217;s just nice, plus ImageBrowser will stay on the disk for browsing other stuff than images.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/the-holy-grail-image-browser-freeware-stuff/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>One random photo from your flickr-stream</title>
		<link>http://blog.kno.at/tools/one-random-photo-from-your-flickr-stream/</link>
		<comments>http://blog.kno.at/tools/one-random-photo-from-your-flickr-stream/#comments</comments>
		<pubDate>Sat, 01 Dec 2007 20:51:16 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[badge]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[crop]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[display]]></category>
		<category><![CDATA[fetch]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[grayscale]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imageUrl]]></category>
		<category><![CDATA[IMG]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[magic]]></category>
		<category><![CDATA[manipulate]]></category>
		<category><![CDATA[modify]]></category>
		<category><![CDATA[one]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[randomFlickr]]></category>
		<category><![CDATA[REQUEST]]></category>
		<category><![CDATA[resize]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[stream]]></category>
		<category><![CDATA[url]]></category>

		<guid isPermaLink="false">http://blogs.kno.at/doc/2007/12/01/one-random-photo-from-your-flickr-stream/</guid>
		<description><![CDATA[<p>Note: Since ANY badge-url will work you can use randomFlickr with whatever photo you feel like, if your badge fetches the most recent photo of a category that&#8217;s what will be used, you&#8217;re only limited by what the badge-url can do
I&#8217;m a heavy flickr-user, trashing it with all my ... <a class="more-link" href="http://blog.kno.at/tools/one-random-photo-from-your-flickr-stream/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>Note:</strong> Since ANY badge-url will work you can use randomFlickr with whatever photo you feel like, if your badge fetches the most recent photo of a category that&#8217;s what will be used, you&#8217;re only limited by what the badge-url can do</p>
<p>I&#8217;m a heavy flickr-user, trashing it with all my snapshots, useless party-pics, all kinds of stuff. And I like to use my flickr photos outside flickr, e.g. on my personal blog. Now there&#8217;s the flickr API and all kinds of wrappers and kits, but all of this is kind of hardcore stuff if the task as simple as: Gimme one random photo from my stream. randomFlickr.class can do this for you.</p>
<ul>
<li><a href="http://dev.kno.at/flickpic/" title="randomFlickr Demo">Demo-Page</a></li>
<li><a href="#vhis">Version History</a></li>
<li><a href="#comment">Feedback</a></li>
</ul>
<h2><a href="http://dev.kno.at/flickpic/dl.php" class="download">Download V 0.6</a></h2>
<p><a href="http://tinyurl.com/3mjxz2">Donate (PayPal)</a></p>
<p>Applying filters requires PHP5+. There&#8217;s a <a href="http://dev.kno.at/flickpic/index4.php" title="PHP4 Version">PHP4 version</a> available, too. GD Library 2 is required for image resizing, that should be included as a standard extension. If you plan to do anything above that I&#8217;d suggest having a look at the various available PHP-tools for flickr:</p>
<ul>
<li><a href="http://sourceforge.net/projects/phlickr/">phlickr</a></li>
<li><a href="http://www.phpflickr.com/">phpFlickr</a></li>
<li><a href="http://code.iamcal.com/php/flickr/readme.htm">PEAR::Flickr_API</a></li>
<li><a href="http://framework.zend.com/manual/en/zend.service.flickr.html">Zend_Service_Flickr</a></li>
</ul>
<p>But if all you want to do is fetch a single photo then have a look at the <a href="http://dev.kno.at/flickpic/" title="randomFlickr Demo">randomFlickr Demo</a>. Now for the documentation.</p>
<p>The initial bright idea was brought to me be an article I can&#8217;t seem to find anymore, but I&#8217;ll try to give proper credit. The class utilizes a flickr-feature: Javascript-badges. There&#8217;s a <a href="http://flickr.com/badge.gne">page to create a badge</a> on flickr, which results in a JavaScript / CSS codeblock. While that works it has a few major downsides:</p>
<ul>
<li>it&#8217;s javascript where javascript definitely isn&#8217;t appropriate</li>
<li>it doesn&#8217;t give control over the images themselves</li>
<li>it only can fetch kind of small images</li>
</ul>
<p>But what it does is it provides the necessary image data we then can process with PHP. For the development I used <a href="http://www.flickr.com/badge_code_v2.gne?count=1&amp;display=random&amp;size=m&amp;layout=x&amp;source=user&amp;user=7353617%40N04">this badge-url</a> I set up to fetch one random medium-sized image from my whole photostream. Click the link to see what the returned HTML/JS-Stuff looks like.</p>
<h2>Focus</h2>
<p>While building the class I always had one thing in mind: This is for <strong>one image, </strong>nothing more, so the class was built to offer a nice variety of things to do with that one picture, however doesn&#8217;t support anything beyond. The final result should achieve three goals:</p>
<ul>
<li>light-weight</li>
<li>easy to use</li>
<li>easy to integrate</li>
</ul>
<h2>Basic usage</h2>
<p>Most of the code is kind of self-explanatory and, as I like it, heavily documented, so best you just browse through the class file you can download from the <a href="http://dev.kno.at/flickpic/">demo-page</a>. Now for the class. It&#8217;s kind of hard to wrap my mind inside-out back to the start now that all is done, so I&#8217;ll do it the other way round and explain what&#8217;s happening from the usage point-of-view, that should work. So let&#8217;s have a look at how the thing is integrated on a webpage:</p>
<div class="geshi php">
<div class="head">/flickpic/index.php</div>
<ol start="30">
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$badge</span> &nbsp;<span class="sy0">=</span> <span class="st0">&#39;http://www.flickr.com/badge_code_v2.gne?count=1&amp;amp;display=random&amp;amp;size=m&amp;amp;layout=x&amp;amp;source=user&amp;amp;user=7353617%40N04&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$width</span> &nbsp;<span class="sy0">=</span> <span class="nu0">400</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$height</span> <span class="sy0">=</span> <span class="nu0">240</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$gray</span> &nbsp; <span class="sy0">=</span> <span class="kw2">true</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">include_once</span><span class="br0">&#40;</span><span class="st0">&#39;flickpic.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>This is the more &#8216;dummy-friendly&#8217; way to integrate, since there&#8217;s hardly anything related to coding. Just replace the badge url with whatever badge you want, modify the size settings and you&#8217;re fine. The $gray-thing converts the image to grayscale, if set to true. Using the whole thing this way will result in an image linked to it&#8217;s flickr-page and doesn&#8217;t require anyone to write any php, or to alter any files. We&#8217;ll shortly reveal the real magic, so hold on for a more programmer-like approach giving you the details you want.</p>
<h2>A few more details: flickpick.php</h2>
<div class="geshi php">
<div class="head">/flickpic/flickpic.php</div>
<ol start="8">
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy0">!</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;imageUrl&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; try</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$x</span> <span class="sy0">=</span> <span class="kw2">new</span> randomFlickr<span class="br0">&#40;</span><span class="re1">$user</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re1">$badge</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">setBadgeUrl</span><span class="br0">&#40;</span><span class="re1">$badge</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">fetch</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Line 08 checks if an image-url has already been submitted. That&#8217;s not the case when including the file, so what&#8217;s about to be done is to display some nice HTML to display the image. try &#8211; catch is needed due the methods throw exceptions. In line 12 the randomFlickr-object is being created using a variable $user. This variable isn&#8217;t specified here, therefore will just be ignored. Then we check if a badge-url has been specified in $badge. If so, we change the object&#8217;s badge url according. Time to fetch some data on line 17.</p>
<p>A few words about the fetch()-method. It will check if there&#8217;s a user id specified (the ugly flickr user-id string, that is, due the badges don&#8217;t seem to work with the usernames). If so, it uses the default badge-url for 1 random image and passes that user-id. Easy. If there&#8217;s no user specified, the badge-url will be used as-is. That way there are four possibilities to get a valid result:</p>
<ol>
<li>specify a user and rely on the default url</li>
<li>specify a full badge-url</li>
<li>specify a user and a badge url</li>
<li>specify nothing and pass the user-id to fetch() (will override a stored username for this one call only)</li>
</ol>
<p>The method doesn&#8217;t really do much, just usual dirty regex-info-fetching, no great inventions there. Most important, it doesn&#8217;t retrieve the actual image, it just sets up meta-information, like dimensions, title and that kind of stuff. So let&#8217;s go on in the code of flickpic.php:</p>
<div class="geshi php">
<div class="head">/flickpic/flickpic.php</div>
<ol start="24">
<li class="li1">
<div class="de1"><span class="re1">$src_post</span> <span class="sy0">=</span> <span class="br0">&#40;</span> <span class="re1">$width</span> ? <span class="st0">&quot;&amp;amp;width=$width&quot;</span> <span class="sy0">:</span> <span class="st0">&#39;&#39;</span> <span class="br0">&#41;</span> <span class="sy0">.</span> <span class="br0">&#40;</span> <span class="re1">$height</span> ? <span class="st0">&quot;&amp;amp;height=$height&quot;</span> <span class="sy0">:</span> <span class="st0">&#39;&#39;</span> <span class="br0">&#41;</span> <span class="sy0">.</span> <span class="br0">&#40;</span> <span class="re1">$gray</span> ? <span class="st0">&#39;&amp;amp;grayscale&#39;</span> <span class="sy0">:</span> <span class="st0">&#39;&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$http</span> <span class="sy0">=</span> <span class="st0">&#39;http://&#39;</span><span class="sy0">.</span> <span class="re1">$_SERVER</span><span class="br0">&#91;</span><span class="st0">&#39;HTTP_HOST&#39;</span><span class="br0">&#93;</span> <span class="sy0">.</span> <span class="kw3">dirname</span><span class="br0">&#40;</span><span class="re1">$_SERVER</span><span class="br0">&#91;</span><span class="st0">&#39;REQUEST_URI&#39;</span><span class="br0">&#93;</span> <span class="sy0">.</span> <span class="st0">&#39;x&#39;</span><span class="br0">&#41;</span> <span class="sy0">.</span><span class="st0">&#39;/&#39;</span><span class="sy0">.</span> <span class="re1">$relpath</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">print</span> <span class="br0">&#40;</span> <span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">getHtml</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#39;src_pre&#39;</span> <span class="sy0">=&gt;</span> <span class="re1">$http</span> <span class="sy0">.</span><span class="st0">&#39;flickpic.php?imageUrl=&#39;</span><span class="sy0">,</span> <span class="st0">&#39;src_post&#39;</span> <span class="sy0">=&gt;</span> <span class="re1">$src_post</span><span class="sy0">,</span> <span class="st0">&#39;fixwidth&#39;</span> <span class="sy0">=&gt;</span> <span class="re1">$width</span><span class="sy0">,</span> <span class="st0">&#39;fixheight&#39;</span> <span class="sy0">=&gt;</span> <span class="re1">$height</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>The first line builds a parameter src_post, the next line uses the current directory (the &#8216;x&#8217; is added to &#8220;simulate&#8221; a file if the home dir is being requested, otherwise we&#8217;s loose one directory here &#8211; just try, it&#8217;s stupid to explain) plus any specified relative path to build the path to this file for the output-generation later. Now the next line does some magic. It prints the result of the getHtml()-method which, obviously, generates HTML code. Let&#8217;s have a look at the method and the parameter, due this is one of the most flexible parts of the whole thing:</p>
<h2>HTML is what we need</h2>
<div class="geshi php">
<div class="head">/flickpic/randomFlickr.class.php</div>
<ol start="352">
<li class="li1">
<div class="de1"><span class="co1">// &nbsp;@param &nbsp;string &nbsp;$sFormat &nbsp; &nbsp;the new format &#8211; anything you want, that is</span></div>
</li>
</ol>
</div>
<p>So there&#8217;s the first parameter $sFormat. This parameter will, if specified, override the object&#8217;s default HTML-template (this can also be done permanently using the setDefaultHtml()-method). HTML-Template? Yessss! The class uses this default HTML to create the output: &lt;a href=&#8221;{url}&#8221; title=&#8221;{title}&#8221; class=&#8221;{class}&#8221;&gt;&lt;img src=&#8221;{src}&#8221; title=&#8221;{title}&#8221; alt=&#8221;{title}&#8221; {html_dim} /&gt;&lt;/a&gt;, so nothing more than a link-wrapped image. BUT note the template-variables enclosed by {}. There&#8217;s a whole bunch of them available, namely:</p>
<ul>
<li>{title} title fetched from flickr</li>
<li>{url} url for the link the image is wrapped with</li>
<li>{src} image&#8217;s src</li>
<li>{html_dim} image&#8217;s dimensions as html attributes (see getHtml() for details)</li>
<li>{width} image&#8217;s width</li>
<li>{height} image&#8217;s height</li>
<li>{hwidth} width value used for the html-attributes (image&#8217;s width or fix width)</li>
<li>{hheight} height value used for the html-attributes (image&#8217;s width or fix width)</li>
<li>{fixwidth} value passed to getHtml() to use for width-attribute</li>
<li>{fixheight} value passed to getHtml() to use for height-attribute</li>
<li>{class}  a string for a css-class</li>
</ul>
<p>All these variables can be used in custom HTML-Templatecode to suite all kinds of possible ajax or whatnot needs, thus making the display as flexible as you like. But back to getHtml(). There&#8217;s a list of special parameters to pass as indices of an associative array (second method parameter $aParams):</p>
<ul>
<li>&#8216;fixwidth&#8217;: for the width=&#8221;" attribute of the &lt;img&gt;</li>
<li>&#8216;fixheight&#8217;: for the height=&#8221;" attribute of the &lt;img&gt;</li>
<li>&#8216;nativedim&#8217;: the image&#8217;s real dimensions will be used for width=&#8221;" &amp; height=&#8221;"</li>
<li>&#8216;class&#8217;: for the &lt;a&gt;, by default</li>
<li>&#8216;src_pre&#8217;: inserted just before the image&#8217;s src</li>
<li>&#8216;src_post&#8217;: inserted right after the image&#8217;s src</li>
<li>&#8216;url_pre&#8217;: inserted right before the url to the image</li>
</ul>
<p>Using those values the image source can be utilized as a parameter for a PHP script (that&#8217;s what flickpic.php does), giving us &lt;strong&gt;much&lt;/strong&gt; more possibilities to control it&#8217;s appearance. All possibilites, that is. Now on to that part that&#8217;s responsible for generating the actual image:</p>
<h2>Now for the image</h2>
<div class="geshi php">
<div class="head">/flickpic/flickpic.php</div>
<ol start="34">
<li class="li1">
<div class="de1"><span class="re1">$x</span> <span class="sy0">=</span> <span class="kw2">new</span> randomFlickr<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">init</span><span class="br0">&#40;</span><span class="st0">&#39;&#39;</span><span class="sy0">,</span> <span class="kw3">urldecode</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;imageUrl&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> <span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;width&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">||</span> <span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;height&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">resize</span><span class="br0">&#40;</span><span class="br0">&#40;</span> <span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;width&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &nbsp; ? <span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;width&#39;</span><span class="br0">&#93;</span> &nbsp;<span class="sy0">:</span> <span class="kw2">false</span> <span class="br0">&#41;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#40;</span> <span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;height&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &nbsp;? <span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;height&#39;</span><span class="br0">&#93;</span> <span class="sy0">:</span> <span class="kw2">false</span> <span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> <span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;grayscale&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">applyFilter</span><span class="br0">&#40;</span>IMG_FILTER_GRAYSCALE<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$x</span><span class="sy0">-&gt;</span><span class="me1">send</span><span class="br0">&#40;</span> <span class="nu0">90</span> <span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>There you go. First of all a new randomFlickr-object is being created (the script is called again, so there&#8217;s no object there). Then the actual image is loaded with the init()-method. This method either uses the data already present within the object or any passed url (the urldecode() is necessary because the script generates XML-validating URLs, thus urlencoding all parameters. By the way the method can also be used to fetch any non-flickr image, if you only want to use it for the image manipulation the class offers). The init()-method accepts two parameters. The first one is for the image size. If not specified, the default size (large) will be used. Then for the probably most important feature the class has to offer: Intelligent image resizing:</p>
<ul>
<li>Only width / height specified: The image will be resized proportionally</li>
<li>width &amp; height specified: The image will be resized proportionally to fill the whole format, then will be cropped to it&#8217;s center</li>
</ul>
<p>This way you can show your pictures in any unusual format, what&#8217;s not only cool but also handy if it comes to fitting them into your design. On with the code. The next thing we&#8217;re doing is we check for the grayscale-variable. If it&#8217;s set we apply the grayscale filter (we&#8217;re clever, aren&#8217;t we?). The applyFilter() method is a full-featured wrapper for the <a href="http://php.net/imagefilter">imagefilter</a>-function, so have fun doing stuff!</p>
<p>Finally the last line sends the appropriate headers and the image data itself. So the endresult is kind of a recursive script (probably not, but sounds sophisticated) that doesn&#8217;t need much of editing to work for anyone, but provides a lot of flexibility if you&#8217;re willing to play around in flickpic.php.</p>
<h2><a title="vhis" name="vhis"></a>Version History</h2>
<ul>
<li>
<h3>2008-04-02: V0.6</h3>
<p>There&#8217;s new options to choose different source-sizes. Specifying $size = &#8220;auto&#8221; will let the script guess which version to use based on the destination dimensions. This, however, may only work for close-to-standard formats, you might want to either leave everything as it is if it&#8217;s working or use one of the new constants to explicitly define which source to use:</p>
<ul>
<li>xxs = 75px by 75px</li>
<li>xs = 100px by X</li>
<li>s = 240px by X</li>
<li>m = 500px by X</li>
<li>l = 1024px by X</li>
<li>xl = your uploaded file</li>
</ul>
<p>Note that flickr always uses the bigger side to scale the sizes, so portrait-format images will be scaled to 1024/500/240/100 Pixels height, while landscape-format images will be scaled to 1024/500/240/100 Pixels width. The three smaller sizes are the ones being used by flickr itself and are fixed-size.<br />
       Oh, and I switched the <a href="http://dev.kno.at/flickpic/">Demo-Page</a> from XHTML 1.1 back to XHTML 1.0, due to the inability of some browsers to handle the application/xml mime-type. Welcome to randomFlickr, Win IE6 Users.</p>
</li>
<li>
<h3>2008-03-19: V0.5</h3>
<p>now falling back on CURL if allow_url_fopen is disabled. As the title says the script now checks if allow_url_fopen is enabled, if not it tries to fall back on the CURL-library. One of both should be available on every hosting plan and I hope compatibility increased.</p>
</li>
<li>
<h3>2007-12-07: V0.4</h3>
<p>PHP4-Version: There now is also a PHP4-Version. Please note that image-filters are only available in PHP5, thus the PHP4 version can&#8217;t convert your images to grayscale, thus resizing + cropping work perfectly fine.</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/one-random-photo-from-your-flickr-stream/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>Das erste offizielle Kno-Plugin</title>
		<link>http://blog.kno.at/tools/das-erste-offizielle-kno-plugin/</link>
		<comments>http://blog.kno.at/tools/das-erste-offizielle-kno-plugin/#comments</comments>
		<pubDate>Sat, 17 Nov 2007 16:15:38 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress mu]]></category>
		<category><![CDATA[wpmu]]></category>

		<guid isPermaLink="false">http://blog.kno.at/2007/11/17/das-erste-offizielle-kno-plugin/</guid>
		<description><![CDATA[<p>Da i seit a kurzem net nur WordPress zum Bloggen verwend, sondern im Zuge eines Umzugs (man beachte den gefinkelten Wortwitz! Ha. Hahaha!) und aufgrund der Tatsache, dass i mehrere Blogs führen werd (und woascheinlich alle davon a weng inkonsequent, oba do foit ma scho no wos ei) auch WordPress MU, ... <a class="more-link" href="http://blog.kno.at/tools/das-erste-offizielle-kno-plugin/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Da i seit a kurzem net nur <a href="http://www.wordpress.org/">WordPress</a> zum Bloggen verwend, sondern im Zuge eines Umzugs (man beachte den gefinkelten Wortwitz! Ha. Hahaha!) und aufgrund der Tatsache, dass i mehrere Blogs führen werd (und woascheinlich alle davon a weng inkonsequent, oba do foit ma scho no wos ei) auch <a href="http://mu.wordpress.org">WordPress MU</a>, mit dem ma mehrere Blogs verwalten kann. (Wer sich für so a Lösung intressiert dem sei mein Vergleich <a href="http://blogs.kno.at/doc/2007/11/04/moveable-type-4/">Moveable Type 4 vs. WordPress MU</a> an&#8217;s Herz gelegt).</p>
<p><span id="more-83"></span></p>
<p>I mag AJAX-Funktionen (des neimodische Zeig, wo ma net Seiten neu laden muss, sondern des alles gaunz toll vollautomatisch tuat) und wollt&#8217; mir ein AJAX-Kommentar-Plugin installieren, hob aba keins gefunden, des funktioniert hat. Also hab&#8217; i selber eins gebastelt.</p>
<ul>
<li style="list-style-type: none; list-style-position: initial; list-style-image: initial;"></li>
<li>WordPress Plugin-Verzeichnis: <a href="http://wordpress.org/extend/plugins/ajax-comments-wpmuified/">Ajax Comments WPMUified</a></li>
<li>SVN Repository: <a href="http://svn.wp-plugins.org/ajax-comments-wpmuified/">svn.wp-plugins.org</a></li>
<li>Plugin-Homepage: <a href="http://blogs.kno.at/doc/ajax-comments-wpmuified">KnoDocBlog</a></li>
<li>Plugin-Entwicklungs-Doku: <a href="http://blogs.kno.at/doc/2007/11/03/wordpress-mu-and-ajax-comments/">KnoDocBlog</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/das-erste-offizielle-kno-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moveable Type 4 vs. WordPres MU</title>
		<link>http://blog.kno.at/tools/mt4-vs-wpmu/</link>
		<comments>http://blog.kno.at/tools/mt4-vs-wpmu/#comments</comments>
		<pubDate>Sun, 04 Nov 2007 17:01:34 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[content management]]></category>
		<category><![CDATA[moveable type 4]]></category>
		<category><![CDATA[mt4]]></category>
		<category><![CDATA[web application design]]></category>
		<category><![CDATA[wordpress mu]]></category>

		<guid isPermaLink="false">http://blogs.kno.at/doc/2007/11/04/moveable-type-4/</guid>
		<description><![CDATA[<p>Since I set up WordPress MU in order to manage a few blogs from one central tool it just so happened that I found out about Moveable Type 4. As I was fine with WordPress I didn&#8217;t think much of looking at other blog-applications, so I just didn&#8217;t care. Today I stumbled upon MT4. And I ... <a class="more-link" href="http://blog.kno.at/tools/mt4-vs-wpmu/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Since I set up <a href="http://mu.wordpress.com" title="WordPress MU">WordPress MU</a> in order to manage a few blogs from one central tool it just so happened that I found out about <a href="http://www.moveabletype.com" title="Movable Type Publishing Platform">Moveable Type 4</a>. As I was fine with WordPress I didn&#8217;t think much of looking at other blog-applications, so I just didn&#8217;t care. Today I stumbled upon <a href="http://www.moveabletype.com" title="Movable Type Publishing Platform">MT4</a>. And I thought I&#8217;d just give it a try. See what the very superior me knows 10 minutes after getting <a href="http://www.moveabletype.com" title="Movable Type Publishing Platform">MT4</a> up and running.<span id="more-160"></span></p>
<h2>Basic Differences</h2>
<p>First things first: <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">MT</a> isn&#8217;t a tool for the casual user. It&#8217;s another approach than WordPress. While the latter is an encapsulated PHP-application aimed to be as simple as possible (upload &#8211; customize &#8211; blog), <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">MT</a> feels much more like a publishing platform. The first difference is the installation. For WordPress (MU is pretty much the same, the differences are minor) that is:</p>
<ol>
<li>Upload to your desired operating and blogging directory.</li>
<li>Call the installation script</li>
<li>Start Blogging</li>
</ol>
<p>Whereas the <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">MT</a> installation looks like this:</p>
<ol>
<li>Upload the Application to your maintenance directory</li>
<li>Adopt the configuration file</li>
<li>Call installation script</li>
<li>Login to the Maintenance Part</li>
<li>Create blogs wherever on the server you feel like having one</li>
<li>Start blogging</li>
</ol>
<p>The difference might not look that big, however I think it is. It&#8217;s another backend approach of publishing content. Let&#8217;s have a look at my <a href="http://mu.wordpress.com/" title="WordPress MU">WordPress MU</a> and my <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">Moveable Type 4</a> installations to compare.</p>
<h2><a href="http://mu.wordpress.com/" title="WordPress MU">WordPress MU</a></h2>
<ul>
<li>Main Site: http://blogs.kno.at/</li>
<li>Maintenance: http://blogs.kno.at/wp-admin/</li>
<li>Automatically sets up a &#8220;godfather-blog&#8221; at the Main site location</li>
<li>Various blogs are here: http://blogs.kno.at/blog-name/</li>
<li>Various blogs administration is there: http://blogs.kno.at/blog-name/wp-admin/</li>
</ul>
<h2><a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">Moveable Type 4</a></h2>
<ul>
<li>Main Site: http://kno.at/apps/mt/</li>
<li>Maintenance: http://kno.at/apps/mt/</li>
<li>From the beginning, there&#8217;s only the basic application</li>
<li>Various blogs are here: Every blog&#8217;s address can freely be assigned</li>
<li>Various blogs administration is there: http://kno.at/apps/mt/</li>
</ul>
<h2>So what&#8217;s that mean?</h2>
<p>For <a href="http://mu.wordpress.com/" title="WordPress MU">WordPress MU</a>, the location where files are stored, the overall handling of what&#8217;s being done where and the paths to the blogs are fixed. If I chose to use subdomains for blogs and my domain is example.com, all my blogs will have an url like blogname.example.com. If I chose dubdirectories all my blogs will have an url like example.com/blogname. Eventually uploaded files will be stored in wpmu/wp-content/blogs.dir/. Period.</p>
<p>For <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">Moveable Type</a> things are more flexible here. Let&#8217;s pick up that example.com &#8211; example (uh, <em>repetition!</em>): My domain is example.com. Now I can set paths and URLs for all Blogs to whatever I feel like. There can be blogs with URLs like blogname1.example.com, example.com/blogname2, example.com/here-be-blogs/blogname3, it just doesn&#8217;t matter. Also I can easily have my blogs spread all over the domain URL-wise, but keep all my data organized by pointing the storage paths like so: /home/www-root/blogdata/blogname1, /home/www-root/blogdata/blogname2, /home/www-root/blogdata/blogname3. Note that as far as I found out by now you&#8217;ll have to care about URL-rewriting yourself!</p>
<h2>More crucial differences</h2>
<p>The name <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">Moveable Type</a> isn&#8217;t just for fun and cosy Web2.0ish feelingness. Actually it&#8217;s what the application does &#8211; creating <em>moveable</em> contents. That is because, by default, <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">MT4</a> creates static files every time something is changed in the specified publishing directory for everything &#8211; images, archives, feeds. So if I want to move my blog from one domain to another, all I have to do is to <em>move</em> those files to their new location. Neat!</p>
<h2>More about moving</h2>
<p>Actually it&#8217;s not <em>that</em> easy because <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">MT4</a> currently builds the files with absolute URLs. I couldn&#8217;t find an option to change this to relative and am not absolutely sure why this is, but I guess it&#8217;s answered somewhere in their FAQs. However it still doesn&#8217;t require any magic to do this, because <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">MT</a> comes packed with two options particularly helpful in this case: Blog Cloning and URL changing. Both do exactly what they are called. You might clone a blog any time, to whatever location you feel like. For that cloned blog you then might change the base URL any time, resulting in a full rebuild with the new absolute URLs. If this new URL is on another server and you plan to keep blogging there you&#8217;ll have to migrate the database and the actual <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">Moveable Type</a> application too, by the way. At least as far as I see by now. However the static-file-thing would make it easy to write a small shell-script (or even MT-plugin) to automatically synchronize any blog with any FTP location wherever you feel like having your blog. There are also options to publish your blogs dynamically, however when I tried I got 404s for all files except the directory itself &#8211; but this might be because of errors in my custom root-.htaccess configuration (I hope not).</p>
<h2>Conclusion</h2>
<p>I guess the choice really depends on your needs and likings. If all you want to do is blogging, <a href="http://mu.wordpress.com/" title="WordPress MU">WordPress MU</a> will do just fine. If you want to implement a content management system you might want to consider Moveable Type, due it seems to be much more flexible and appropriate for those things. My opinion, however, might not be very valuable by now, since I only had a rough glance at <a href="http://www.moveabletype.com/" title="Movable Type Publishing Platform">Moveable Type</a> and don&#8217;t know nothing about how flexible it can be used, extended or modified, whereas I have quite a bit experience on doing those things with WordPress.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/mt4-vs-wpmu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress MU and AJAX comments</title>
		<link>http://blog.kno.at/tools/wordpress-mu-and-ajax-comments/</link>
		<comments>http://blog.kno.at/tools/wordpress-mu-and-ajax-comments/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 15:35:16 +0000</pubDate>
		<dc:creator>Kno</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress mu]]></category>

		<guid isPermaLink="false">http://blogs.kno.at/doc/2007/11/03/wordpress-mu-and-ajax-comments/</guid>
		<description><![CDATA[<p>Discontinued
This plugin has been discontinued. There are better, more compatible ones available by now so there&#8217;s really no reason to further support this one!
How complicated could it be to adopt a WordPress plugin to work with WordPress MU? Pretty complicated, if you&#8217;re the purist and ... <a class="more-link" href="http://blog.kno.at/tools/wordpress-mu-and-ajax-comments/" title="View Post">&#187;</a></p>]]></description>
			<content:encoded><![CDATA[<h2>Discontinued</h2>
<p><strong>This plugin has been discontinued. There are better, more compatible ones available by now so there&#8217;s really no reason to further support this one!</strong></p>
<p>How complicated could it be to adopt a WordPress plugin to work with WordPress MU? Pretty complicated, if you&#8217;re the purist and perfectionist I am. From <em>adoption</em> to <em>rewrite</em>, up to a weird WordPress issue i am currently fighting.<span id="more-171"></span></p>
<h2>Starting</h2>
<p>I already mentioned a while ago that I am looking for an elegant solution of combining multiple blogs. Well, turns out that <a href="http://www.wordpress.org">WordPress</a> can do just this for me, with the superior free thing that <a href="http://mu.wordpress.org">WordPress MU</a> is. During installation I stumbled up a PlugIn that is called <a href="http://wordpress.org/extend/plugins/ajax-comments/">AJAX Comments</a>, and this is something I always wanted to have in WordPress. So i thought I&#8217;ll just grab it, bring it to WordPress MU and enjoy the sexyness of AJAXified commenting.</p>
<h2>I wished.</h2>
<p>Reality turned out to be much more cruel. First of all the plugin didn&#8217;t work. <q>Ok, probably I&#8217;m just missing out on a few adoptions.</q> Probably that would have done the trick, but as I started digging into the code I got enthusastic to bring this thing to a more sophisticated stage of operating. What was bothering me about that PlugIn?</p>
<ul>
<li>It&#8217;s all mixed in one file</li>
<li>The whole comment processing happens independent from WordPress core functionality</li>
<li>Therefore it&#8217;s interfering with other plugins</li>
<li>It needs in-depth adoption for different themes, which especially for use with WordPress MU seemed to be a problem</li>
</ul>
<p>Please note that, by now, there&#8217;s still a problem with fetching the WordPress error message, so the PlugIn will just use a generic, non-localized, uninformative standard error message!</p>
<h2>Organize, baby!</h2>
<p>So I started rewriting <em>(as I thought it might be interesting to others I added precious documentation to everything, so if if you&#8217;re not interested in my rambling and just want to get to the code have a look at the sources)</em>. First of all WordPress MU seems to not like PlugIns inside folders (at least not in the folder /mu-plugins), so I put the main file to /mu-plugins and added the folder for the additional stuff. Then I started separating functionality. The JavaScript was output through that very file, due it needed a few little parameters. I took the whole JS-functionality and put it into one clean, static .js &#8211; file and then hooked in a few variable definitions that would solve the parameter problem. So let&#8217;s have a look how the JavaScript-sections turn out after the little rework.</p>
<div class="geshi php">
<div class="head">@/wpmu/mu-plugins/ajax-comments.php</div>
<ol start="42">
<li class="li1">
<div class="de1"><span class="kw3">global</span> <span class="re1">$ajax_comments_count</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$ajax_comments_count</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">add_action<span class="br0">&#40;</span><span class="st0">&#39;wp_footer&#39;</span><span class="sy0">,</span> &nbsp; &nbsp;<span class="st0">&#39;ajax_comments_getcount&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">add_action<span class="br0">&#40;</span><span class="st0">&#39;comment_text&#39;</span><span class="sy0">,</span> <span class="st0">&#39;ajax_comments_countdisplay&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">add_action<span class="br0">&#40;</span><span class="st0">&#39;wp_head&#39;</span><span class="sy0">,</span> &nbsp; &nbsp; &nbsp;<span class="st0">&#39;ajax_comments_js&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<h2>What for?</h2>
<p>43, 44 and 45 handle with a simple but annoying issue. The problem is that when a page is viewed by anyone who is logged in chances are that there are more comments actually being displayed than are approved. For example if you&#8217;re an admin you&#8217;ll see all unapproved comments, but the variables available in WordPress core functions don&#8217;t tell us anything about how many comments there actually are on the page. So what I did was to hook a function to <var>comment_text</var>, abusing a filter, to increment the global variable <var>$ajax_comments_count</var> by 1 for every actually displayed commment. Neat:</p>
<div class="geshi php">
<ol start="27">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> ajax_comments_countdisplay<span class="br0">&#40;</span><span class="re1">$comment</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw3">global</span> <span class="re1">$ajax_comments_count</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$ajax_comments_count</span><span class="sy0">++;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="re1">$comment</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Line 44 hooks in just before the closing <var>body</var>-tag and hardcodes the JavaScript variable telling the scripting-magic-pixie-stuff if there&#8217;s an even or odd number of comments:</p>
<div class="geshi php">
<ol start="41">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> ajax_comments_getcount<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw3">global</span> <span class="re1">$ajax_comments_count</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw3">echo</span> <span class="st0">&#39;&lt;script type=&quot;text/javascript&quot;&gt;ajax_comments_odd &nbsp;= &#39;</span><span class="sy0">.</span> <span class="br0">&#40;</span><span class="re1">$ajax_comments_count</span> <span class="sy0">%</span> <span class="nu0">2</span> <span class="sy0">==</span> <span class="nu0">0</span> ? <span class="st0">&#39;true&#39;</span> <span class="sy0">:</span> <span class="st0">&#39;false&#39;</span><span class="br0">&#41;</span> <span class="sy0">.</span><span class="st0">&#39;;&lt;/script&gt;&#39;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<h2>Multiple Theme Support</h2>
<p>Line 46 deals with everything else regarding JavaScript, including theme-specific settings. Yep, if you install the original PlugIn it soon turns out that you&#8217;ll have to modify it for various themes. That&#8217;s disturbing, but ok in general. However, when using this for WordPress MU you&#8217;d run into problems if the available themes use different markup. So I added a few settings to make this more flexible:</p>
<div class="geshi php">
<div class="head">@/wpmu/mu-plugins/ajax-comments/functions.php</div>
<ol start="98">
<li class="li1">
<div class="de1"><span class="kw2">function</span> ajax_comments_js<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st0">&#39;themes.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re1">$ajax_comments_themes</span><span class="br0">&#91;</span><span class="st0">&#39;hardcode&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$curTempDir</span> <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw3">substr</span><span class="br0">&#40;</span>TEMPLATEPATH<span class="sy0">,</span> <span class="kw3">strlen</span><span class="br0">&#40;</span><span class="kw3">dirname</span><span class="br0">&#40;</span>TEMPLATEPATH<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$allThemes</span> &nbsp;<span class="sy0">=</span> <span class="kw3">array_keys</span><span class="br0">&#40;</span><span class="re1">$ajax_comments_themes</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span><span class="re1">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="sy0">!</span><span class="kw3">is_array</span><span class="br0">&#40;</span><span class="re1">$theme</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re1">$i</span><span class="sy0">&amp;</span>lt<span class="sy0">;</span>count<span class="br0">&#40;</span><span class="re1">$allThemes</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re1">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re1">$curTempDir</span><span class="sy0">,</span> <span class="re1">$allThemes</span><span class="br0">&#91;</span><span class="re1">$i</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$theme</span> <span class="sy0">=</span> <span class="re1">$ajax_comments_themes</span><span class="br0">&#91;</span><span class="re1">$allThemes</span><span class="br0">&#91;</span><span class="re1">$i</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">is_array</span><span class="br0">&#40;</span><span class="re1">$theme</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="re1">$theme</span> <span class="sy0">=</span> <span class="re1">$ajax_comments_themes</span><span class="br0">&#91;</span><span class="st0">&#39;default&#39;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$theme</span> <span class="sy0">=</span> <span class="re1">$ajax_comments_themes</span><span class="br0">&#91;</span><span class="re1">$ajax_comments_themes</span><span class="br0">&#91;</span><span class="st0">&#39;hardcode&#39;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Okay, so let&#8217;s have a look at this. Line 2 includes the theme-settings script <var>themes.php</var>. In this script you can specify theme-specific settings, like so (this also is the default setting the PlugIn falls back to if it can&#8217;t figure out anything else):</p>
<div class="geshi php">
<ol start="114">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$ajax_comments_themes</span><span class="br0">&#91;</span><span class="st0">&#39;default&#39;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#39;commentform&#39;</span><span class="sy0">,</span> &nbsp; <span class="co1">// [0] = id or classname form</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#39;commentlist&#39;</span><span class="sy0">,</span> &nbsp; <span class="co1">// [1] = id or classname 04: comment-&amp;lt;ol&amp;gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#39;commentform&#39;</span><span class="sy0">,</span> &nbsp; <span class="co1">// [2] = id or classname element comments are inserted before</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#39;&#39;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [3] = comma-separated list of element-id&#39;s to hide</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>Line 3 is easy: If there&#8217;s a hardcoded theme-setting the PlugIn will obey, use it and just go on. The more interesting part happens if there&#8217;s no hardcoded setting. Then the current template path is used to find a matching setting <em>(hint: if you add settings, name them according to the directory they are located at and all the magic will do just fine).</em> If there&#8217;s no matching setting available, the default settings will be used, matching the default kubrick-theme.</p>
<div class="geshi php">
<ol start="120">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$hideMore</span> <span class="sy0">=</span> <span class="re1">$theme</span><span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re1">$hideMore</span><span class="sy0">,</span> <span class="st0">&#39;,&#39;</span><span class="br0">&#41;</span> <span class="sy0">!==</span> <span class="kw2">false</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$all</span> <span class="sy0">=</span> <span class="kw3">explode</span><span class="br0">&#40;</span><span class="st0">&#39;,&#39;</span><span class="sy0">,</span> <span class="re1">$hideMore</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re1">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re1">$i</span><span class="sy0">&amp;</span>lt<span class="sy0">;</span>count<span class="br0">&#40;</span><span class="re1">$all</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re1">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$all</span><span class="br0">&#91;</span><span class="re1">$i</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw3">trim</span><span class="br0">&#40;</span><span class="re1">$all</span><span class="br0">&#91;</span><span class="re1">$i</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$hideMore</span> <span class="sy0">=</span> <span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&quot;&#39;,&#39;&quot;</span><span class="sy0">,</span> <span class="re1">$all</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re1">$hideMore</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="re1">$hideMore</span> <span class="sy0">=</span> <span class="st0">&quot;&#39;&quot;</span><span class="sy0">.</span> <span class="kw3">trim</span><span class="br0">&#40;</span><span class="re1">$hideMore</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&quot;&#39;&quot;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p><var>$hideMore</var> can be one or many Id&#8217;s, so the PlugIn has to act accordingly, creating a nice string that can be used as output to feed the <var>new Array()</var> that soon will follow:</p>
<div class="geshi php">
<ol start="131">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&#39;&lt;script type=&quot;text/javascript&quot; src=&quot;&#39;</span><span class="sy0">.</span> PLUGIN_AJAXCOMMENTS_ROOT<span class="sy0">.</span>PLUGIN_AJAXCOMMENTS_PATH <span class="sy0">.</span><span class="st0">&#39;ajax-comments/scriptaculous/prototype.js&quot;&gt;&lt;/script&gt;&#39;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&#39;&lt;script type=&quot;text/javascript&quot; src=&quot;&#39;</span><span class="sy0">.</span> PLUGIN_AJAXCOMMENTS_ROOT<span class="sy0">.</span>PLUGIN_AJAXCOMMENTS_PATH <span class="sy0">.</span><span class="st0">&#39;ajax-comments/scriptaculous/scriptaculous.js&quot;&gt;&lt;/script&gt;&#39;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&#39;&lt;script type=&quot;text/javascript&quot; src=&quot;&#39;</span><span class="sy0">.</span> PLUGIN_AJAXCOMMENTS_ROOT<span class="sy0">.</span>PLUGIN_AJAXCOMMENTS_PATH <span class="sy0">.</span><span class="st0">&#39;ajax-comments/ajax-comments.js&quot;&gt;&lt;/script&gt;&#39;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&#39;&lt;script type=&quot;text/javascript&quot;&gt;&#39;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span><span class="st0">&#39; &nbsp;ajax_comments_path = &quot;&#39;</span><span class="sy0">.</span> PLUGIN_AJAXCOMMENTS_ROOT<span class="sy0">.</span>PLUGIN_AJAXCOMMENTS_PATH <span class="sy0">.</span><span class="st0">&#39;&quot;;&#39;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span><span class="st0">&quot; &nbsp;ajax_comments_form = &#39;${theme[0]}&#39;;<span class="es0">\n</span>&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span><span class="st0">&quot; &nbsp;ajax_comments_list = &#39;${theme[1]}&#39;;<span class="es0">\n</span>&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span><span class="st0">&quot; &nbsp;ajax_comments_here = &#39;${theme[2]}&#39;;<span class="es0">\n</span>&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span><span class="st0">&quot; &nbsp;ajax_comments_hide = new Array($hideMore);<span class="es0">\n</span>&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span><span class="st0">&quot;&lt;/script&gt;<span class="es0">\n</span>&quot;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<h2>On to sophisticated AJAX-Magic</h2>
<p>There you go. All JavaScript-stuff done, theme-related settings included. So we can head on to the next part our PlugIn will have to do server-sided: Handling the AJAX-request. Here is where to biggest changes happened, because I totally changed the way this worked. The original PlugIn was called instead of WordPress, then imported WordPress-functionality and finally handled the comment-process itself, hardcoded and separated from core WordPress functionality. This is a method I just can&#8217;t get along with. Not only does it intefere with all other PlugIns by just stripping them out, but it also makes the PlugIn very unstable due it totally relies on the current state of WordPress.</p>
<h2>Integrating</h2>
<p>PlugIns should be integrated into, and therefore benefiting of, the core application&#8217;s functionality. WordPress offers a very nice way of doing so: Hooks, that is. I already handled the JavaScript-stuff with hooks, so doing the same with the AJAX-functionality seemed like a good and clean idea. After a little research, however, it turned out that action hooks are a kind of unconsistent implemented thing. There are a lot of hooks, granted, but there are also a lot of hooks missing. Especially if it comes to comments, things get kind of weird. When WordPress encounters an error there&#8217;s a good chance it will simply call <var>wp_die();</var>, thus killing the app immediately, without any notice to PlugIns. That&#8217;s no good. But let&#8217;s get back to this later. First the core AJAX-section:</p>
<div class="geshi php">
<ol start="26">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span><span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_POST</span><span class="br0">&#91;</span><span class="st0">&#39;ajax-comments-submit&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; add_action<span class="br0">&#40;</span><span class="st0">&#39;comment_post&#39;</span><span class="sy0">,</span> <span class="st0">&#39;ajax_comments_send&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p><em>Update: The PlugIn now takes the whole error-page as a response and then strips out the error-message from there. This way no files need to be modified whatsoever.</em></p>
<p>The first hook is a native WordPress-hook and calls <var>ajax_comments_send()</var> after a comment is saved to the database. That&#8217;s exactly when we want to jump in to cut off the regular application, fetch the last comment and send it back as AJAX-response. Nice. However when I started looking for the hook when a comment-error is encountered I soon realized how loose WordPress&#8217; error-handling is. To be honest I was disappointed, that&#8217;s really bad implementation there. Let&#8217;s have a look at <var>wp-comments-post.php</var> and see what&#8217;s happening if there&#8217;s an error:</p>
<div class="geshi php">
<ol start="32">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>wp<span class="sy0">-</span>comments<span class="sy0">-</span>post<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// If the user is logged in</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$user</span> <span class="sy0">=</span> wp_get_current_user<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re1">$user</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>ID <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
</ol>
</div>
<div class="geshi php">
<ol start="44">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>wp<span class="sy0">-</span>comments<span class="sy0">-</span>post<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> get_option<span class="br0">&#40;</span><span class="st0">&#39;comment_registration&#39;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; wp_die<span class="br0">&#40;</span> __<span class="br0">&#40;</span><span class="st0">&#39;Sorry, you must be logged in to post a comment.&#39;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Uhm &#8230; great. No error is being generated, no action is being called, no handling of this issue whatsoever occurs. The developer is being left with a silent application kill, that&#8217;s just a no-go. If <var>wp_die()</var> would call <var>do_action()</var> at least we could react to this in <em>some</em> way, however we can never be sure what happened, because there&#8217;s no error code or anything like this. All we would know is: <q>The application has been terminated. Have fun!</q> However, that seems to be the most we can do without going in for some really crucial changes on WordPress&#8217; core. <strike>So I added one line of code that should keep me busy for about 10 hours or so:</strike></p>
<p><em>Update: The PlugIn now takes the whole error-page as a response and then strips out the error-message from there. This way no files need to be modified whatsoever.</em></p>
<h2>AJAX-Response</h2>
<p><strike>Looks easy and makes sense, due the function <var>ajax_comments_send()</var> is hooked in to <var>wp_</var><var>abort</var> and</strike><strike> the</strike> <var>$message</var> is the most we can get out of WordPress at the time. I&#8217;ll explain the problem with this line at the end, due it&#8217;s still unresolved. Let&#8217;s have a look at the last function:</p>
<div class="geshi php">
<ol start="64">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> ajax_comments_send <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$passed</span> &nbsp;<span class="sy0">=</span> <span class="kw3">func_get_arg</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$comment</span> <span class="sy0">=</span> <span class="sy0">@</span>get_comment<span class="br0">&#40;</span><span class="re1">$passed</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>So far, so easy. We fetch the argument, <strike>check if it was a valid comment-id, and <var>die()</var> with </strike><strike>whatever error-message has been sent by <var>do_action(&#8216;wp_abort&#8217;</var><var>)</var> being identified with a status code 406 header if something went wrong.</strike> get us the saved comment&#8217;s data and go on:</p>
<div class="geshi php">
<ol start="72">
<li class="li1">
<div class="de1"><span class="sy0">@/</span>wpmu<span class="sy0">/</span>mu<span class="sy0">-</span>plugins<span class="sy0">/</span>ajax<span class="sy0">-</span>comments<span class="sy0">/</span>functions<span class="sy0">.</span>php</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">header</span><span class="br0">&#40;</span><span class="st0">&#39;Content-type: text/html; charset=utf-8&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">ob_start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$comments</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="re1">$comment</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">global</span> <span class="re1">$comment</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span><span class="br0">&#40;</span>TEMPLATEPATH<span class="sy0">.</span><span class="st0">&#39;/comments.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$commentout</span> <span class="sy0">=</span> <span class="kw3">ob_get_clean</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">preg_match</span><span class="br0">&#40;</span><span class="st0">&#39;|(&lt;li.*&lt;/li&gt;)|ims&#39;</span><span class="sy0">,</span> <span class="re1">$commentout</span><span class="sy0">,</span> <span class="re1">$matches</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">die</span><span class="br0">&#40;</span><span class="re1">$matches</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>This part is hardly modified from the original. This idea is great and I love the simplicity how the comment can be integrated in the current theme without any problems. What we do is we call the template with a fake list of comments only including the one generated by the AJAX-request. Then we fetch out this one comment from the generated HTML and return it. Lovely! And works perfect. Basically I only changed the regexp to fetch the whole list-item, not to loose any attributes. The alternation will be dealt with via JavaScript.</p>
<p><em>Update: Due the function is only being called if a comment has successfully been saved we don&#8217;t need to implement any kind of error handling here. How useful would the message &#8216;unknown error&#8217; be anyways?!</em></p>
<h2>Finally: DHTML</h2>
<p>This part already was very nice, so I only made a few minor changes. I didn&#8217;t like the alerts so I added a function that would display the message inside a <var>div</var> with the id <var>ajax-comments-message</var>, nested in another <var>div</var> and getting class <var>error</var> attached if status code 500 is being returned (wp&#8217;s header status for wp_die()). Also, if the result is an error, the actual message has to be fetched from the whole page, which is pretty easy due to very simple markup. A lot of words, let&#8217;s just have a look of how this turns out:</p>
<div class="geshi no html">
<ol>
<li class="li1">
<div class="de1">&lt;div id=&quot;ajax-comments-message&quot; class=&quot;error&quot;&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &lt;div&gt;
</div>
</li>
<li class="li1">
<div class="de1">the message
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &lt;/div&gt;
</div>
</li>
<li class="li1">
<div class="de1">&lt;/div&gt;</div>
</li>
</ol>
</div>
<p>The outer <var>div</var> is for easy CSS access and may has the class <var>error</var>, the inner <var>div</var> is for DHTML compatibility (guaranteeing a firstChild-node) and contains whatever WordPress returns in <var>$message</var> (at the time either <var>p</var> or <var>ul</var>). Furthermore in the original plugin there was no check if the form is there. So I added an onload-block:</p>
<div class="geshi javascript">
<ol start="210">
<li class="li1">
<div class="de1"><span class="sy0">@</span><span class="re0">/wpmu/mu-plugins/ajax-comments/</span>ajax-comments-js</div>
</li>
<li class="li1">
<div class="de1">ac_oldLoad = window.<span class="kw3">onload</span>;</div>
</li>
<li class="li1">
<div class="de1">window.<span class="kw3">onload</span> = <span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ac_oldLoad;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; f = ajax_comments_find_element<span class="br0">&#40;</span>ajax_comments_form, <span class="st0">&#39;form&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>f<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; f.<span class="me1">onsubmit</span> = ajax_comments_submit;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> Insertion.<span class="me1">Bottom</span><span class="br0">&#40;</span>f, <span class="st0">&#39;&lt;input id=&quot;ajax-comments-submit&quot; name=&quot;ajax-comments-submit&quot; type=&quot;hidden&quot; value=&quot;1&quot; /&gt;&#39;</span><span class="br0">&#41;</span>; <span class="co1">// toggle ajax-catch</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
</ol>
</div>
<p>This ensures that the AJAX-functionality on the server is only activated when the script can find the comment-form, otherwise the behaviour will fall back to default. The rest of the JavaScript is pretty straight forward, so just browse through the file if you want to know more.</p>
<h2>A pain in the Source</h2>
<p>If you&#8217;re still reading you&#8217;re probably interested in my problem with the <var>do_action()</var> in <var>wp_die()</var>. This is an interesting story and I&#8217;d be glad if you have a look at it in the <a href="http://wordpress.org/support/topic/141798">WordPress Support Forum Thread</a> I opened, hoping for help.</p>
<p><em>Update: The PlugIn now takes the whole error-page as a response and then strips out the error-message from there. This way I don&#8217;t need the do_action() in wp_die() anymore, however it&#8217;s interesting why it didn&#8217;t work &#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kno.at/tools/wordpress-mu-and-ajax-comments/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
