<?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>web(cslai) &#187; Web Development</title>
	<atom:link href="http://cslai.coolsilon.com/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://cslai.coolsilon.com</link>
	<description>Findings and Notes in Web Development</description>
	<lastBuildDate>Tue, 06 Sep 2011 08:15:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Redland for RDF Work</title>
		<link>http://cslai.coolsilon.com/2011/05/13/redland-for-rdf-work/</link>
		<comments>http://cslai.coolsilon.com/2011/05/13/redland-for-rdf-work/#comments</comments>
		<pubDate>Fri, 13 May 2011 06:47:20 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Semantic Web]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=226</guid>
		<description><![CDATA[Although my supervisor strongly recommend using JENA for RDF related work, but as I really don&#8217;t like Java (just personal preference), and wouldn&#8217;t want to install JRE/JVM (whatever it is called) at my shared server account, so I went to look for an alternative. After spending some time searching, I found this library called Redland [...]]]></description>
			<content:encoded><![CDATA[<p>Although my supervisor strongly recommend using JENA for RDF related work, but as I really don&#8217;t like Java (just personal preference), and wouldn&#8217;t want to install JRE/JVM (whatever it is called) at my shared server account, so I went to look for an alternative. After spending some time searching, I found this library called <a href="http://librdf.org/">Redland</a> and it provides binding for my current favorite language &#8212; PHP, so I decided to use this for my RDF work.</p>
<p><span id="more-226"></span></p>
<p>I used pure relational database approach (postgresql to be exact) to store information collected via flickr initially, but it wouldn&#8217;t really scale (or I just simply suck at designing/maintaining database tables) and my queries got killed numerously by the web host. Besides that, as the table grow larger, the amount of resource consumed to serve a query also grow, hence I needed to find another way to store the data. At first I thought of using some popular noSQL solutions, but my supervisor told me to turn the data into RDF format instead. So I went on with Redland and use postgresql (again) as storage.</p>
<p>However, for some reason, postgresql doesn&#8217;t seem to work efficiently and a simple query can take tens of minutes to run when it holds more than 100k RDF statements. For some reason, the <a href="http://stackoverflow.com/questions/5882707/getting-statements-from-redland-hash-storage">hash storage doesn&#8217;t work</a> on my Ubuntu development VM, so I switched the storage engine to MySQL after <a href="https://twitter.com/#!/dajobe/status/67969726550253568">@dajobe&#8217;s suggestion</a>.</p>
<p>However, as PHP binding apparently not that popular, so there aren&#8217;t much information / tutorial posted. I actually wanted to write a collection of scripts to collect data from <a href="http://flickr.com/">flickr</a> for my research project, so I began with finding an existing script for that task. However, I didn&#8217;t find good ones in PHP, so I ported <a href="https://github.com/straup/p5-Net-Flickr-RDF">this from Perl</a> to PHP and use Redland. Then after knowing how it really works, I rewrote everything again from scratch (will put them up to bitbucket when I have time to clean up). I even wrapped the library with class methods, which I hope to release later (I only knew about another <a href="http://blog.literarymachine.net/?p=5">OO wrapper in PHP</a> for Redland after almost done writing my scripts).</p>
<p>To use Redland&#8217;s PHP functions without OO wrapper, we always start with a statement to build a world. I am not very sure what this means (yes, I didn&#8217;t really read the <a href="http://librdf.org/docs/api/index.html">documentation</a> that thoroughly), but it seems that almost all constructor functions depend on it to create new object (yes, Redland has this OO feel although all the function calls are in procedural style). So, in PHP, the statement would look like:</p>
<pre class="php"><code>$world = librdf_new_world();</code></pre>
<p>Then you would want to decide <a href="http://librdf.org/docs/api/redland-storage-modules.html">where to store your RDF statements</a>. For this piece of note, I will just use non-persistent memory store. So the function call to build a storage object is</p>
<pre class="php"><code>$storage = librdf_new_storage($world, 'memory', $name, $options);</code></pre>
<p>where <code>$name</code> stores the name of the storage object, and <code>$options</code> often carries the <abbr title="Database Source Name">DSN</abbr>, but in our case it is NULL. Now that we have storage defined, then we proceed with building a model to actually store RDF statements into the storage (it would be easy to think model as a database library, and storage as an abstraction layer).</p>
<pre class="php"><code>$model = librdf_new_model($world, $storage, NULL);</code></pre>
<p>Statements are consists of nodes, so let&#8217;s create some. To create a URI node, it is just as easy as</p>
<pre class="php"><code>$foo = librdf_new_node_from_uri_string($world, 'urn:foo');
$bar = librdf_new_node_from_uri_string($world, 'urn:bar');</code></pre>
<p>Creating a literal node would be just as simple as</p>
<pre class="php"><code>$baz = librdf_new_node_from_literal($world, 'baz', NULL, FALSE);</code></pre>
<p>Putting them into a statement</p>
<pre class="php"><code>$statement = librdf_new_statement_from_nodes($world, $foo, $bar, $baz);</code></pre>
<p>which is the equivalent to this</p>
<pre><code>&lt;urn:foo&gt; &lt;urn:bar&gt; 'baz' .</code></pre>
<p>To run a query to the model, just simply send a SPARQL statement as follows</p>
<pre><code>
$query = librdf_new_query(
    $world,
    'sparql',
    NULL,
<<<SPARQL
SELECT  ?subject, ?object
WHERE   {
            ?subject <urn:bar> ?object .
        }
SPARQL
);
</code></pre>
<p>Running the query and get result</p>
<pre><code>$result = librdf_model_query_execute($model, $query);
var_dump(librdf_query_results_to_string2($result, 'json', 'application/json', NULL, NULL));</code></pre>
<p>Enjoy!</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2011/05/13/redland-for-rdf-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Collaborative Tagging &amp; Folksonomy</title>
		<link>http://cslai.coolsilon.com/2011/02/17/collaborative-tagging-folksonomy/</link>
		<comments>http://cslai.coolsilon.com/2011/02/17/collaborative-tagging-folksonomy/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 03:28:20 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=207</guid>
		<description><![CDATA[Folksonomy is a neologism of two words, ’folk’ and ’taxonomy’ which describes conceptual structures created by users [4, 5]. A folksonomy is a set of unstructured collaborative usage of tags for content classification and knowledge representation that is popularized by Web 2.0 and social applications [1, 5]. Unlike taxonomy that is commonly used to organize [...]]]></description>
			<content:encoded><![CDATA[<p>Folksonomy is a neologism of two words, ’folk’ and ’taxonomy’ which describes conceptual structures created by users <sup>[<a href="#cite-4">4</a>, <a href="#cite-5">5</a>]</sup>. A folksonomy is a set of unstructured collaborative usage of tags for content classification and knowledge representation that is popularized by Web 2.0 and social applications <sup>[<a href="#cite-1">1</a>, <a href="#cite-5">5</a>]</sup>. Unlike taxonomy that is commonly used to organize resources to form a category hierarchy, folksonomy is non-hierarchical and non-exclusive <sup>[<a href="#cite-3">3</a>]</sup>. Both content hierarchy and folksonomy can be used together to better content classification.</p>
<p><span id="more-207"></span></p>
<p>Users of Web 2.0 applications typically organize their created content with a set of terms or keywords, also commonly known as tags <sup>[<a href="#cite-3">3</a>, <a href="#cite-4">4</a>, <a href="#cite-6">6</a>, <a href="#cite-7">7</a>]</sup>. Spending additional time and effort to provide annotation such as tags to a resource usually implicitly implies the relevance and/or importance of the resource to a user <sup>[<a href="#cite-1">1</a>]</sup>. Therefore, besides being used for content classification, tags assignment can also be analyze to find the implicit relationship between users and the tagged content.</p>
<p>It is also observed that the frequency of term usage is proportional to the level of importance or connection to user, i.e. the more a tag is used, the more it is important to the user <sup>[<a href="#cite-1">1</a>, <a href="#cite-8">8</a>]</sup>. The choice of tags when annotating a resource often express the user interest and perceptions <sup>[<a href="#cite-8">8</a>]</sup>. Users usually have different ideas and interests when tagging a resource especially when the application allow the same resource tagged by multiple users <sup>[<a href="#cite-2">2</a>]</sup>. Therefore tagging activity pattern can be studied to find a user’s domain of interest.<br />
Users with common interests tend to use similar set of tags in tagging re- sources of interest <sup>[<a href="#cite-2">2</a>]</sup>. The similarity of users can then be calculated through the tagging pattern for recommending purpose as it provides social relationships between users <sup>[<a href="#cite-4">4</a>, <a href="#cite-7">7</a>]</sup>. This may allow more collaboration between users sharing similar interest.</p>
<p>Although the variety selection of tag helps in better representation of the resource, but this may cause some problems as users don’t tend to agree to each other <sup>[<a href="#cite-2">2</a>]</sup>. Observations also shows tagging behaviour follows power law distribution where tags are mostly assigned to a small subset of more<br />
popular resources <sup>[<a href="#cite-2">2</a>, <a href="#cite-7">7</a>]</sup>. Hence, when a resource gets popular, users having different interests will attempt to assign tags with keywords from all different domains. However, when different tags that are semantically related from each other are assigned to related resources (vocabulary mismatch problem), it may drastically decrease the level of relevance although the tags may actually share similar meaning <sup>[<a href="#cite-3">3</a>, <a href="#cite-7">7</a>]</sup>.</p>
<p>Correlation between resources is often established when they are assigned with common tags <sup>[<a href="#cite-8">8</a>]</sup>. The level of relevance can then be observed by studying the similarity in their set of assigned tags <sup>[<a href="#cite-8">8</a>]</sup>. The correlation and similarity between the tags assigned to resources may also help users to find unseen resources by browsing the tags.</p>
<p>The assigned tags can be used as a tool to enable discovery, sharing and collaboration of web resources <sup>[<a href="#cite-1">1</a>, <a href="#cite-2">2</a>, <a href="#cite-3">3</a>, <a href="#cite-8">8</a>]</sup>. Some applications even allow sharing of tagging information <sup>[<a href="#cite-2">2</a>, <a href="#cite-8">8</a>]</sup>. Hence, besides using tags as a tool for content classification and user interest study, they can be used to make collaboration easier.</p>
<p>A resource may be described by its assigned tags depending on the tagging behaviour <sup>[<a href="#cite-1">1</a>]</sup>. When an tagging system follows the bag-model, i.e. system that allows multiple users to tag a resource, the frequency of a tag is assigned also indirectly shows the increased relevance between the tag and the resource <sup>[<a href="#cite-1">1</a>, <a href="#cite-2">2</a>, <a href="#cite-8">8</a>]</sup>. Weights can be also calculated for each tag to rank the relevance with the resource.<br />
On the other hand, systems that implements the set-model do not provide enough data to deduce the level of importance or popularity of an assigned tag to the resource <sup>[<a href="#cite-8">8</a>]</sup>. Due to the unstructured nature of collabo- rative tagging, the system can be easily abused if users assign tags that do not describe the content <sup>[<a href="#cite-1">1</a>, <a href="#cite-8">8</a>]</sup>. The problem is more apparent for system implementing the set-model as there is no way to rank the assigned tags.</p>
<h2>References</h2>
<ol>
<li id="cite-1">I. Cantador, A. Bellog ́ın, and D. Vallet. Content-based Recommendation in Social Tagging Systems. Methodology, pages 237–240, 2010.</li>
<li id="cite-2">Y. Guo and J. B. Joshi. Topic-based personalized recommendation for collaborative tagging system. Number 10. ACM Press, New York, New York, USA, 2010.</li>
<li id="cite-3">R. Lambiotte and M. Ausloos. Collaborative tagging as a tripartite network, 2005.</li>
<li id="cite-4">P. Mika. Ontologies are us: A unified model of social networks and semantics. Web Semantics Science Services and Agents on the World Wide Web, 5(1):5–15, 2007.</li>
<li id="cite-5">C. Schmitz, A. Hotho, R. J ̈aschke, and G. Stumme. Mining Association Rules in Folksonomies, pages 261–270. Studies in Classification, Data Analysis, and Knowledge Organization. Springer, 2006.</li>
<li id="cite-6">N. Shadbolt, T. Berners-Lee, and W. Hall. The Semantic Web Revisited. IEEE Intelligent Systems, 21(3):96–101, May 2006.</li>
<li id="cite-7">S. Siersdorfer and S. Sizov. Social recommender systems for web 2.0 folksonomies. ACM Press, New York, New York, USA, 2009.</li>
<li id="cite-8">M. Szomszor, C. Cattuto, H. Alani, K. OHara, A. Baldassarri, V. Loreto, and V. D. P. Servedio. Folksonomies, the Semantic Web, and Movie Recommendation. eprintsecssotonacuk, pages 71–84, 2007.</li>
</ol>
<div class="postscript">
I initially wrote this for my report, but thought this may make a good blog post, hence posting it over.
</div>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2011/02/17/collaborative-tagging-folksonomy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing jQuery Plugin 101</title>
		<link>http://cslai.coolsilon.com/2010/03/04/writing-jquery-plugin-101/</link>
		<comments>http://cslai.coolsilon.com/2010/03/04/writing-jquery-plugin-101/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 17:25:05 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=145</guid>
		<description><![CDATA[I often struggle to get my Javascript code organized, and have tried numerous ways to do so. I have tried putting relevant code into classes and instantiate as needed, then abuse jQuery&#8217;s data() method to store everything (from scalar values to functions and callbacks). Recently, after knowing (briefly) how a jQuery plugin should be written, [...]]]></description>
			<content:encoded><![CDATA[<p>I often struggle to get my Javascript code organized, and have tried numerous ways to do so. I have tried putting relevant code into <a href="http://cslai.coolsilon.com/2009/04/11/random-javascript-notes/">classes</a> and instantiate as needed, then abuse jQuery&#8217;s <code class="javascript">data()</code> method to store everything (from scalar values to functions and callbacks). Recently, after knowing (briefly) how a jQuery plugin should be written, it does greatly simplify my code.</p>
<p><span id="more-145"></span></p>
<p>While there are still a lot to learn about plugin authoring, I would only jot down what I know right now. As the code may not conform to the best practice, please let me know if there is a better way.</p>
<p>To begin, we start with an empty html page</p>
<p><code class="html"><br />
&lt;html&gt;<br />
&lt;head&gt;<br />
       &lt;title&gt;Title&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
       &lt;input type="text" id="a" /&gt;&lt;br /&gt;<br />
       &lt;input type="text" id="b" /&gt;&lt;br /&gt;<br />
       &lt;input type="text" id="c" /&gt;<br />
       &lt;script type="text/javascript" src="./jquery-1.4.1.min.js"&gt;&lt;/script&gt;<br />
       &lt;script type="text/javascript" src="./script.js"&gt;&lt;/script&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
</code></p>
<p>The first included Javascript script is obviously jQuery, the second file (script.js) is my code, which is not named properly. The basic structure of the file should look like follows:</p>
<p><code class="javascript"><br />
(function($) {<br />
    var module_init = function(plugin, module) {<br />
            return function(action) {<br />
                var arg = trim_argument(arguments);<br />
                return this.each(function() {<br />
                    if($.fn[plugin][module][action]) {<br />
                        $.fn[plugin][module][action]<br />
                            .apply(this, arg);<br />
                    } else {<br />
                        throw(action + '() does not exist');<br />
                    }<br />
                })<br />
            }<br />
        },<br />
&nbsp;<br />
        module_exists = function(plugin, module) {<br />
            return $.fn[plugin][module];<br />
        },<br />
&nbsp;<br />
        shift_argument = function(item, arg) {<br />
            result = [item];<br />
&nbsp;<br />
            for(i = 0; i < arg.length; i++) {<br />
                result.push(arg[i]);<br />
            }<br />
&nbsp;<br />
            return result;<br />
        },<br />
&nbsp;<br />
        trim_argument = function(arg) {<br />
            result = [];<br />
&nbsp;<br />
            if(arg.length > 1) {<br />
                for(i = 1; i < arg.length; i++) {<br />
                    result.push(arg[i]);<br />
                }<br />
            }<br />
&nbsp;<br />
            return result;<br />
        };<br />
&nbsp;<br />
        // further code below this line<br />
})(jQuery);<br />
</code></p>
<p>Let us just ignore the functions above for now and proceed to the actual plugin code first. What we're trying to achieve here is to post whatever written to #a is posted to #b, and #b post it to #c. The function call should be as follows:</p>
<p><code class="javascript"><br />
$(selector).foo(sub_module, options);<br />
// or<br />
$(selector).foo(sub_module, action, [parameter_if_any]);<br />
</code></p>
<p><code class="javscript">foo</code> is the name of the example plugin, and <code class="javascript">sub_module</code> determines which sub-module is responsible to carry out the actual action specified by <code class="javascript">action</code>. If <code class="javascript">options</code> is passed in instead, then it would trigger <code class="javascript">init()</code> for the respective sub-module.</p>
<p>In short, <code class="javascript">foo()</code> is there just to notify the sub-module to call the right action, hence the code should be simple, as follows (add after the last comment in the basic structure code shown above):</p>
<p><code class="javascript"><br />
    (function foo() {<br />
        $.fn.foo = function(module, param) {<br />
            var arg = trim_argument(arguments);<br />
&nbsp;<br />
            return this.each(function() {<br />
                if(module_exists('foo', module)) {<br />
                    if(typeof param != 'string') {<br />
                        $.fn.foo[module]<br />
                            .apply($(this), shift_argument('init', arg));<br />
                    } else {<br />
                        $.fn.foo[module]<br />
                            .apply($(this), arg);<br />
                    }<br />
                } else {<br />
                    throw(module + ' module does not exists');<br />
                }<br />
            });<br />
        }<br />
    })();<br />
</code></p>
<p>I have a habit to group all the relevant bits together, hence the code is enclosed in an immediately executed function block. It does what it is designed to do -- to delegate the function call to the respective sub-module. <code class="javascript">trim_argument();</code> is there to remove the first argument (in this case <code class="javascript">module</code>), and <code class="javascript">shift_argument();</code> is used to insert an argument into the existing argument list. These two function functions are written to enable us to manipulate the arguments to be used in <code class="javascript">Function.apply()</code> method. Of course, if the specified sub-module does not exist, the code will throw an exception.</p>
<p>Now that we have the main plugin code written, next is to start developing the submodules. Firstly, is a plugin for the text box #a. The textbox is supposed to show textbox #b and passes the input text to #b whenever the value is not null. The code is to be added right after the main plugin, as mentioned above.</p>
<p><code class="javascript"><br />
    (function alpha() {<br />
        $.fn.foo.alpha = module_init('foo', 'alpha');<br />
&nbsp;<br />
        var alpha = $.fn.foo.alpha;<br />
&nbsp;<br />
        alpha.init = function(options) {<br />
            $(this)<br />
                .data('options', $.extend({}, options))<br />
                .keyup(alpha.alpha_update);<br />
        };<br />
&nbsp;<br />
        alpha.alpha_update = function() {<br />
            $(this)<br />
                .data('options').b<br />
                    .foo('bravo', 'alpha_update', $(this).val());<br />
        };<br />
    })();<br />
</code></p>
<p><code class="javascript">module_init</code> is there to do the actual delegation of action. Again, it will check with the remaining arguments after removing the first, which is the <code class="javascript">action</code>. The function will then attempt to call the action if available, otherwise a new exception is thrown.</p>
<p><code class="javascript"><abbr title="$.fn.foo.alpha">alpha</abbr>.init</code> is a compulsory method that initializes the sub-module. On the other hand, <code class="javascript">alpha.alpha_update</code> is the actual code that updates another textbox via another sub-module, which is named 'bravo', and coded as follows:</p>
<p><code class="javascript"><br />
    (function bravo() {<br />
        $.fn.foo.bravo = module_init('foo', 'bravo');<br />
&nbsp;<br />
        var bravo = $.fn.foo.bravo;<br />
&nbsp;<br />
        bravo.init = function(options) {<br />
            $(this)<br />
                .data('options', $.extend({}, options))<br />
                .hide();<br />
        };<br />
&nbsp;<br />
        bravo.hide = function() {<br />
            $(this).fadeOut('fast');<br />
        };<br />
&nbsp;<br />
        bravo.show = function() {<br />
            $(this).fadeIn('fast');<br />
        };<br />
&nbsp;<br />
        bravo.toggle = function(value) {<br />
            if($(this).is(':hidden') &#038;&#038; value.length > 0) {<br />
                bravo.show.call(this);<br />
            } else if($(this).is(':visible') &#038;&#038; value.length == 0) {<br />
                bravo.hide.call(this);<br />
            }<br />
        };<br />
&nbsp;<br />
        bravo.alpha_update = function(value) {<br />
            $(this)<br />
                .val('bravo: ' + value)<br />
                .data('options').c<br />
                    .foo('charlie', 'alpha_update', value);<br />
&nbsp;<br />
            bravo.toggle.call(this, value);<br />
        };<br />
    })();<br />
</code></p>
<p>The bravo code basically does what it is intended to, which is to receive update from alpha, and then toggle the display of the text box depending on the length of passed in value. After that, bravo is going to post the received update to charlie, as follows:</p>
<p><code class="javascript"><br />
    (function charlie() {<br />
        $.fn.foo.charlie = module_init('foo', 'charlie');<br />
&nbsp;<br />
        var charlie = $.fn.foo.charlie;<br />
&nbsp;<br />
        charlie.init = function(options) {<br />
            $(this)<br />
                .data('options', $.extend({}, options))<br />
                .hide();<br />
        };<br />
&nbsp;<br />
        charlie.hide = function() {<br />
            $(this).fadeOut('slow');<br />
        };<br />
&nbsp;<br />
        charlie.show = function() {<br />
            $(this).fadeIn('slow');<br />
        };<br />
&nbsp;<br />
        charlie.toggle = function(value) {<br />
            if($(this).is(':hidden') &#038;&#038; value.length > 0) {<br />
                charlie.show.call(this);<br />
            } else if($(this).is(':visible') &#038;&#038; value.length == 0) {<br />
                charlie.hide.call(this);<br />
            }<br />
        };<br />
&nbsp;<br />
        charlie.alpha_update = function(value) {<br />
            $(this).val('charlie: ' + value);<br />
&nbsp;<br />
            charlie.toggle.call(this, value);<br />
        };<br />
</code></p>
<p>After receiving data from bravo, likewise, it updates the textbox, then display or hide the textbook accordingly. For every action method call, <code class="javascript">this</code> keyword is usually similar to the jQuery callback functions, which refers to the respective html element (not wrapped with jQuery functions), hence the function call within the sub-module is often via <code class="javascript">Function.call() /* or */ Function.apply()</code>.</p>
<p>To run the code, one only need the following code:</p>
<p><code class="javascript"><br />
    $(function() {<br />
        var a = $('#a'),<br />
            b = $('#b'),<br />
            c = $('#c');<br />
&nbsp;<br />
        a.foo('alpha', { b: b, c: c }).focus();<br />
        b.foo('bravo', { a: a, c: c });<br />
        c.foo('charlie', { a: a, b: b });<br />
    });<br />
</code></p>
<p>That's all, we have done a very simple, and pointless plugin.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2010/03/04/writing-jquery-plugin-101/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mixing Non-array and Array in array_map()</title>
		<link>http://cslai.coolsilon.com/2010/01/28/mixing-non-array-and-array-in-array_map/</link>
		<comments>http://cslai.coolsilon.com/2010/01/28/mixing-non-array-and-array-in-array_map/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 03:34:07 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array_map]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=141</guid>
		<description><![CDATA[array_map function is a function that I use the most in my php scripts recently. However, there are times where I want to pass some non-array into it, therefore often times I have code like the snippet shown below: $result = array_map( 'some_callback', array_fill(0, count($some_array), 'some_string'), array_fill(0, count($some_array), 'some_other_string'), $some_array ) It doesn&#8217;t look good [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.php.net/manual/en/function.array-map.php">array_map</a> function is a function that I use the most in my php scripts recently. However, there are times where I want to pass some non-array into it, therefore often times I have code like the snippet shown below:</p>
<p><code class="php">$result = array_map(<br />
    'some_callback',<br />
    array_fill(0, count($some_array), 'some_string'),<br />
    array_fill(0, count($some_array), 'some_other_string'),<br />
    $some_array<br />
)</code></p>
<p>It doesn&#8217;t look good IMO, as it makes the code looks complicated. Hence, after seeing how the code may vary in all different scenarios, I created some functions to clean up the array_map call as seen above. Code snippet after the jump</p>
<p><span id="more-141"></span></p>
<p><code class="php">function array_map_mix($callback, $param) {<br />
    $main = array();</p>
<p>    $args = func_get_args();</p>
<p>    if((is_numeric($param) &#038;&#038; count($args) < 3)<br />
        || (is_array($param) &#038;&#038; count($args) < 2)) {<br />
        throw new Exception('No input available.');<br />
    } elseif(is_array($param)) {<br />
        list($main, $param) = array($param, count($param));<br />
    } elseif(is_numeric($param) === FALSE) {<br />
        throw new Exception('Invalid parameter');<br />
    }</p>
<p>    return call_user_func_array(<br />
        'array_map',<br />
        array_merge(<br />
            array($callback),<br />
            count($main) > 0 ? array($main) : array(),<br />
            count($args) - 2 > 0 ?<br />
                array_map(<br />
                    'array_create',<br />
                    array_create(count($args) - 2, $param),<br />
                    array_slice($args, 2)<br />
                )<br />
                : array()<br />
        )<br />
    );<br />
}</p>
<p>function array_create($count, $input) {<br />
    $result = array_fill(0, $count, NULL);</p>
<p>    if(is_array($input) &#038;&#038; count($input) == 1 &#038;&#038; is_array($input[0])) {<br />
        $result = array_fill(0, $count, $input[0]);<br />
    } else if(is_array($input) &#038;&#038; count($input) == $count) {<br />
        $result = $input;<br />
    } else {<br />
        $result = array_fill(0, $count, $input);<br />
    }</p>
<p>    return $result;<br />
}</code></p>
<h2>array_create</h2>
<p>Before stepping into the main array_map_mix function, we first look at the array_create function. It is basically a variant of <a href="http://www.php.net/manual/en/function.array-fill.php">array_fill</a> function, but without the initial index argument.</p>
<p>The important argument here is the <code class="php">$input</code> argument, depending on what is passed into the function, the end result can be different. If anything but array is passed in, then it will behave exactly like the array_fill call as follows:</p>
<p><code class="php">$foo = array_create(5, 'bar');<br />
// is equivalent to<br />
$foo = array_fill(0, 5, 'bar');</code></p>
<p>However, if an array is passed in, and the array element count is equivalent to the <code class="php">$count</code> argument, then array_create will return <code class="php">$input</code> without any modification.</p>
<p><code class="php">array('bar', 'baz') == array_create(2, array('bar', 'baz'));</code></p>
<p>If the array passed in has one and only one element, and the element happens to be another array, then the child array is passed into the array_fill function, as follows</p>
<p><code class="php">$foo = array_create(3, array(array('bar', 'baz')));<br />
// is equivalent to<br />
$foo = array_fill(0, 3, array('bar', 'baz'))</code></p>
<p>If the array passed in doesn&#8217;t fulfill the above two conditions, then the end result is similar like passing in a non-array argument.</p>
<p><code class="php">$foo = array_create(3, array('bar'));<br />
// is equivalent to<br />
$foo = array_fill(0, 3, array('bar'));</code></p>
<p>The weird behavior caused by the array argument is actually intended, as this function is initially created for the following function, which is the array_map_mix function.</p>
<h2>array_map_mix</h2>
<p>The first 2 mandatory arguments for array_map_mix are the <code class="php">$callback</code> as well as <code class="php">$param</code>. The <code class="php">$callback</code> is the callback function, and <code class="php">$param</code> is the parameter. The parameter can be either a number, or an array.</p>
<p>When a number is passed in as the parameter, then the code is throwing all the following arguments into array_create function as described above, with the number is sent in as <code class="php">$count</code>. This is an example showing the equivalent array_map function call.</p>
<p><code class="php">$foo = array_map_mix(<br />
    'some_callback',<br />
    2,<br />
    array('foo', 'bar'),<br />
    'baz'<br />
);<br />
// is equivalent to<br />
$foo = array_map(<br />
    'some_callback',<br />
    array('foo', 'bar'),<br />
    array_fill(0, 2, 'baz')<br />
);</code></p>
<p>What if the number passed in does not equal to the count of array elements?</p>
<p><code class="php">$foo = array_map_mix(<br />
    'some_callback',<br />
    2,<br />
    array('foo', 'bar', 'baz')<br />
);<br />
// is equivalent to<br />
$foo = array_map(<br />
    'some_callback',<br />
    array_fill(0, 2, array('foo', 'bar', 'baz'))<br />
);</code></p>
<p>What if I have 2 array, <code class="php">$foo</code> and <code class="php">$bar</code>, even both has the same amount of array elements, but I want the callback to receive <code class="php">$bar</code> as a whole, instead of just an element?</p>
<p><code class="php">// given<br />
count($foo) == count($bar);<br />
// wants this<br />
$foo = array_map(<br />
    'some_callback',<br />
    $foo,<br />
    array_fill(0, count($foo), $bar)<br />
);<br />
// equivalent array_map_mix call<br />
$foo = array_map_mix(<br />
    'some_callback',<br />
    count($foo),<br />
    $foo,<br />
    array($bar)<br />
);</code></p>
<p>Hopefully this explains why array_create is coded like above. As mentioned above, <code class="php">$param</code> can be an array as well. This is helpful when the count of array to be passed to array_map is dynamic and a fixed number is not always available.</p>
<p><code class="php">// suppose function foo() returns an array of variable size<br />
$foo = array_map_mix(<br />
    'some_callback',<br />
    foo(),<br />
    'baz'<br />
);<br />
// the equivalent code<br />
$bar = foo();<br />
$foo = array_map(<br />
    'some_callback',<br />
    $bar,<br />
    array_fill(0, count($bar), 'baz')<br />
);</code></p>
<p>Nevertheless, array_map_mix can also be used as a direct array_map alternative, although this is not advisible as the function call should take much longer time to complete because of the call_user_func_array call within array_map_mix.</p>
<p><code class="php">array_map('some_callback', array('foo', 'bar')) == array_map_mix('some_callback', array('foo', 'bar'));</code></p>
<p>The total number of arguments required is 2 when <code class="php">$param</code> is an array (means using array_map_mix as array_map) and 3 when <code class="php">$param</code> is a non-array. An exception will be thrown if expected argument is missing. Also, if anything but an array or a number is passed into array_map_mix as <code class="php">$param</code>, then another exception is thrown.</p>
<p>Hopefully these two short code snippet helps for people who uses array_map as much as I do.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2010/01/28/mixing-non-array-and-array-in-array_map/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Selecting Node with XPath</title>
		<link>http://cslai.coolsilon.com/2009/10/27/selecting-node-with-xpath/</link>
		<comments>http://cslai.coolsilon.com/2009/10/27/selecting-node-with-xpath/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 14:19:50 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=133</guid>
		<description><![CDATA[To do node selection for DOM operations, one typically uses CSS selectors as (probably) popularized by jQuery. However, there is another alternative that is as powerful if not better known as XPath. XPath may be able to do a lot more than just selecting node (which I have no time to find out for now) [...]]]></description>
			<content:encoded><![CDATA[<p>To do node selection for DOM operations, one typically uses CSS selectors as (probably) popularized by <a href="http://www.jquery.org/">jQuery</a>. However, there is another alternative that is as powerful if not better known as XPath. XPath may be able to do a lot more than just selecting node (which I have no time to find out for now) but I will just focus on how to do node selection in this blog post. </p>
<p><span id="more-133"></span> </p>
<p>The main source of inspiration of this post is from John Resig&#8217;s <a href="http://ejohn.org/blog/xpath-css-selectors/">blog post</a> comparing CSS selectors to XPath selectors. Recently I am involved in a project where I need to scrap information from a bunch of <del datetime="2009-10-27T07:02:46+00:00">badly marked up</del> HTML files. Although I am advised to use regular expression to scrap information out from the file, but I decided to give XPath a try. </p>
<p>The initial version was coded with PHP but it wouldn&#8217;t work efficiently, as the files are not correctly marked up (and also not marked up semantically) and I had to fix it by throwing the markup to Tidy before processing it. Then the markup is passed to the DOM library classes for data extraction. To sum up on the performance, it was terribly slow (mainly caused by the Tidy process).</p>
<p>Then I headed to <a href="http://www.stackoverflow.com/">stackoverflow</a> to <a href="http://stackoverflow.com/questions/1553511/extracting-info-from-html-using-phpxpath-php-pythonregexp-or-pythonxpath">look for alternatives</a>. As recommended, I use lxml and beautiful soup together to scrap information out from the source HTML file (details to be discussed in the other post).</p>
<p>Back to the topic, supposedly a HTML file is given that is marked up as follows:</p>
<p><code class="html"><br />
&lt;html&gt;<br />
    &lt;head&gt;<br />
        &lt;title&gt;Foo&lt;/title&gt;<br />
    &lt;/head&gt;<br />
    &lt;body&gt;<br />
        &lt;table&gt;<br />
            &lt;tr&gt;<br />
                &lt;td&gt;<br />
                    &lt;table&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;th&gt;&lt;h1&gt;Main Content&lt;/h1&gt;&lt;/th&gt;<br />
                        &lt;/tr&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;td&gt;&lt;span&gt;I am a terribly marked up HTML file&lt;/span&gt;&lt;/td&gt;<br />
                        &lt;/tr&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;td&gt;&lt;span id=&quot;horrible_text&quot;&gt;Just too horrible&lt;/span&gt;&lt;/td&gt;<br />
                        &lt;/tr&gt;<br />
                    &lt;/table&gt;<br />
                &lt;/td&gt;<br />
                &lt;td&gt;<br />
                    &lt;table class=&quot;sidebar&quot;&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;th colspan=&quot;2&quot;&gt;&lt;font&gt;Fancy Sidebar&lt;/font&gt;&lt;/th&gt;<br />
                        &lt;/tr&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;td&gt;&lt;font&gt;Fizz&lt;/font&gt;&lt;/td&gt;<br />
                            &lt;td&gt;&lt;a href=&quot;another_broken_link.html&quot;&gt;Fancy menu 1&lt;/a&gt;&lt;/td&gt;<br />
                        &lt;/tr&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;td&gt;&lt;font&gt;Buzz&lt;/font&gt;&lt;/td&gt;<br />
                            &lt;td&gt;&lt;a href=&quot;i_am_also_broken.html&quot;&gt;Fancy menu 2&lt;/a&gt;&lt;/td&gt;<br />
                        &lt;/tr&gt;<br />
                        &lt;tr&gt;<br />
                            &lt;td&gt;&lt;font&gt;Bar&lt;/font&gt;&lt;/td&gt;<br />
                            &lt;td&gt;&lt;a href=&quot;some_fancy_broken_link.html&quot;&gt;Fancy menu 3&lt;/a&gt;&lt;/td&gt;<br />
                        &lt;/tr&gt;<br />
                    &lt;/table&gt;<br />
                &lt;/td&gt;<br />
            &lt;/tr&gt;<br />
        &lt;/table&gt;<br />
        &lt;div id=&quot;footer&quot;&gt;<br />
            &lt;p&gt;Some meaningless copyright text&lt;/p&gt;<br />
        &lt;/div&gt;<br />
    &lt;/body&gt;<br />
&lt;/html&gt;<br />
</code></p>
<p>As seen in the above HTML, it is not as badly marked up but it basically shows what kind of HTML files I am dealing with (except there is no single element ID defined). To quickly get started in working with XPath, I went to <a href="http://www.w3schools.com/XPath/default.asp">w3schools</a> to dig the tutorials as I am working with the file.</p>
<p>Starting from the simplest and most obvious case, which is looking for the copyright text node.</p>
<p><code>//*[@id='footer']/p</code></p>
<p>In CSS, one would probably get this done via</p>
<p><code>#footer > p</code></p>
<p>However, as I am doing this to get text information, hence in order to get the text content, I would need to do</p>
<p><code>//*[@id='footer']/p/text()</code></p>
<p>To summarize what those symbols mean, let me translate the last XPath selector into a layman friendly statement &#8212; select any node (empty tag followed by a wild card, <code>//*</code>) that has (<code>[...]</code>) an attribute named id (<code>@id</code>) which is valued &#8216;footer&#8217; (<code>@id='footer'</code>), from there, select a paragraph node (<code>/p</code>) and extract the text contained within the node (<code>/text()</code>).</p>
<p>Now that you get some idea, we shall proceed do a slightly more complicated selector. Suppose I want to extract content from the third row in the main content table, I would need to do this (as I&#8217;m new in this, this may not be the most efficient way of selecting)</p>
<p><code>//tr[*/descendant-or-self::*[contains(text(), 'Main') and contains(text(), 'Content')]]<br />
    /following-sibling::tr[2]<br />
    /td<br />
    /descendant-or-self::text()</code></p>
<p>Well, from the markup above, there is no id, no class and basically there is nothing to uniquely identify the node that I want. (I don&#8217;t know how to select the node using CSS, so assume there is none for now) Therefore, in order to select the text that I want, I select the any tr node from the document (<code>//tr</code>) that contains (<code>[...]</code>) any node (<code>*/descendant-or-self::*</code>) which in turns contains (the nested <code>[...]</code>) text &#8216;Main&#8217; and &#8216;Content&#8217; (<code>contains(text(), 'Main') and contains(text(), 'Content')</code>). From there, find the second sibling after the selected tr(s) (<code>/following-sibling::tr[2]</code>) and get the descendant which is the table data node (<code>/td</code>). Then regardless what node is wrapping the text content, just return any text-content found within the selected table data node (<code>/descendant-or-self::text()</code>).</p>
<p>You may be curious why I don&#8217;t just test <code>contains(text(), 'Main Content')</code> but to split them into two different tests. This is due to the fact that in HTML, although browsers treat all whitespace and newline characters as a space, but they do make a difference in the markup. So if it happens that my table header node is marked up as follows</p>
<p><code>&lt;th&gt;&lt;h1&gt;Main<br />
Content&lt;/h1&gt;&lt;/th&gt;</code></p>
<p>Although it is displayed identically within the browser, but if my selector tests using <code>contains(text(), 'Main Content')</code> it will fail as the correct way of doing it should be inserting a newline character instead of a space, maybe something like <code>contains(text(), "Main\nContent")</code>. There is a weakness in my approach though as the order is ignored in my test. So if there is a table within the document as follows</p>
<p><code class="html">&lt;table&gt;<br />
    &lt;tr&gt;<br />
        &lt;th&gt;&lt;h1&gt;Content not in the Main&lt;/h1&gt;&lt;/th&gt;<br />
    &lt;/tr&gt;<br />
    &lt;tr&gt;<br />
        &lt;td&gt;&lt;span&gt;I am a terribly marked up HTML file&lt;/span&gt;&lt;/td&gt;<br />
    &lt;/tr&gt;<br />
    &lt;tr&gt;<br />
        &lt;td&gt;&lt;span id=&quot;horrible_text&quot;&gt;Not supposed to be selected&lt;/span&gt;&lt;/td&gt;<br />
    &lt;/tr&gt;<br />
&lt;/table&gt;</code></p>
<p>Then the text &#8216;Not supposed to be selected&#8217; will also be selected.</p>
<p>Last example of the day, suppose I want to select all the second column of table data nodes within &#8216;Fancy Sidebar&#8217; if the first column has text content either &#8216;Fizz&#8217; or &#8216;Buzz&#8217;</p>
<p><code>//td[*/descendant-or-self::*[contains(text(), 'Fizz') or contains(text(), 'Buzz')]]<br />
    /following-sibling::td[position() = 1]</code></p>
<p>The selector basically says select any table data node (<code>//td</code>) that contains (<code>[..]</code>) regardless node type (<code>*/descendant-or-self::*</code>) as long as it contains (<code>[...]</code>) text either &#8216;Fizz&#8217; or &#8216;Buzz&#8217; (<code>contains(text(), 'Fizz') or contains(text(), 'Buzz')</code>). From there select its sibling table data nodes (<code>/following-sibling::td</code>) and pick the first among them (<code>[position() = 1]</code>).</p>
<p>If you are observant enough, you should find out that the selector may actually be simplified as follows</p>
<p><code>//td[*/descendant-or-self::*[contains(text(), 'Fizz') or contains(text(), 'Buzz')]]<br />
    /following-sibling::td</code></p>
<p>The previous selector was used because I wanted to show the <code>position()</code> function XD.</p>
<p>Lastly, if firebug is used, then <a href="https://addons.mozilla.org/en-US/firefox/addon/11900">FireXPath</a> is a great addition to the firebug that allows web developer to test XPath selectors. </p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/10/27/selecting-node-with-xpath/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hello World from Zend MVC</title>
		<link>http://cslai.coolsilon.com/2009/09/08/hello-world-from-zend-mvc/</link>
		<comments>http://cslai.coolsilon.com/2009/09/08/hello-world-from-zend-mvc/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 14:00:22 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=125</guid>
		<description><![CDATA[This post continued from this post. Finally I have found some time to start developing my pet project using Zend Framework. After getting the controller to work the way I am more familiar (comparing to Kohana which I used at work) with, the next step is to get it to output some data. Base Action [...]]]></description>
			<content:encoded><![CDATA[<p>This post continued from this <a href="http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/">post</a>. Finally I have found some time to start developing my pet project using <a href="http://framework.zend.com/">Zend Framework</a>. After getting the controller to work the way I am more familiar (comparing to <a href="http://www.kohanaphp.com/">Kohana</a> which I used at work) with, the next step is to get it to output some data.</p>
<p><span id="more-125"></span></p>
<h3>Base Action Controller</h3>
<p>When I used other frameworks like Kohana or <a href="http://codeigniter.com/">CodeIgniter</a>, without extra modules installed, I would have to define view scripts specifically. However, in Zend_Controller, a view is likely to be defined properly and is waiting for data to be populated in. However, I still don&#8217;t get any output after a few attempts so I went to compare my dispatch method in the derived action controller with Zend_Controller_Action. The following code shows the updated dispatch method:</p>
<p><code class="php"><br />
    public function dispatch($actionName) {<br />
        $this->_helper->notifyPreDispatch();<br />
        $this->preDispatch();<br />
        $parameters = array();<br />
        foreach($this->_parametersMeta($actionName) as $paramMeta) {<br />
            $parameters = array_merge(<br />
                $parameters,<br />
                $this->_parameter($paramMeta, $this->_getAllParams())<br />
            );<br />
        }<br />
        call_user_func_array(array(&#038;$this, $actionName), $parameters);<br />
        $this->postDispatch();<br />
        $this->_helper->notifyPostDispatch();<br />
    }<br />
</code></p>
<p>Apparently there are some &#8216;hooks&#8217; that needs to be called throughout the dispatching process. Besides that, I want my view scripts to be loaded from another folder instead of the default ones, so I added a init method in the base action controller, as follows:</p>
<p><code class="php"><br />
    public function init() {<br />
        $this->view->addScriptPath(sprintf('%s/View', APP_PATH));<br />
    }<br />
</code></p>
<p>The script path should be defined during bootstrap phase, and I will post up a better solution once I find the exact place to configure it. Now that we have our base action controller fixed, let&#8217;s move to the actual action controller.</p>
<h3>Action Controller</h3>
<p>I am not sure whether action stack is <a href="http://en.wikipedia.org/wiki/Presentation-abstraction-control">HMVC</a>, however, I like the way it works (although it is <a href="http://www.rmauger.co.uk/2009/03/why-the-zend-framework-actionstack-is-evil/">evil</a>). I will probably stick to action stack for the time being while finding out how partial view can help in widgetizing my page. Besides having a view defined automatically, to put them into a layout I made a call in my bootstrap script, as follows:</p>
<p><code class="php"><br />
        Zend_Layout::startMvc(array(<br />
            'layoutPath' => APP_PATH . '/View/_layout'<br />
        ));<br />
</code></p>
<p>Then I did the action stack thingy as follows:</p>
<p><code class="php"><br />
class Controller_Index<br />
    extends Coolsilon_Controller_Base {<br />
    public function index() {<br />
        $this->_helper->actionStack('menu', 'index');<br />
    }<br />
    public function menu() {<br />
        $this->_helper->viewRenderer->setResponseSegment('menu');<br />
    }<br />
}<br />
</code></p>
<p>Then, in my View/_layout/layout.phtml, </p>
<p><code class="php"><br />
< ?php echo $this->layout()->menu; ?><br />
< ?php echo $this->layout()->content; ?><br />
</code></p>
<p>View/index/index.phtml</p>
<p><code>This is the main content.</code></p>
<p>View/index/menu.phtml</p>
<p><code>This is the menu.</code></p>
<p>Then by visiting the project site, then I get the following output</p>
<p><code><br />
This is the menu.<br />
This is the main content.<br />
</code></p>
<p>Phew, I can&#8217;t believe I spent so much time on this easy stuff, XD. Now I am one step closer in writting the actual website, now what kind of website should I make?</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/09/08/hello-world-from-zend-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Collection of Common Javascript Functions &#8211; Part 1</title>
		<link>http://cslai.coolsilon.com/2009/06/04/my-collection-of-common-javascript-functions-part-1/</link>
		<comments>http://cslai.coolsilon.com/2009/06/04/my-collection-of-common-javascript-functions-part-1/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 13:19:14 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=121</guid>
		<description><![CDATA[After coded enough Javascript few months back, I found that there are a couple of functions that I kept re-using in different projects. Therefore I took some time to refactor them and re-arrange them into a single file. The common code that I keep reusing even today consists of functions that does prototypical inheritance, scope [...]]]></description>
			<content:encoded><![CDATA[<p>After coded enough Javascript few months back, I found that there are a couple of functions that I kept re-using in different projects. Therefore I took some time to refactor them and re-arrange them into a single file. The common code that I keep reusing even today consists of functions that does prototypical inheritance, <a href="http://cslai.coolsilon.com/2009/04/11/random-javascript-notes/">scope maintenance</a>, some <a href="http://www.jquery.com/">jquery</a> stuff, <a href="http://code.google.com/apis/maps/">google maps api</a> stuff and some general ajax application related code.</p>
<p><span id="more-121"></span></p>
<h3><del datetime="2010-02-18T06:44:55+00:00">Prototypical</del>Prototypal Inheritance</h3>
<p>Basically after reading through some articles across the internet, especially <a href="http://javascript.crockford.com/prototypal.html">this article</a>, then I have this piece of code in my collection.</p>
<pre class="ln-"><code class="javascript">if(typeof Object.create !== 'function') {
    Object.create = function(_o) {
        var F = function () {}
        F.prototype = _o;
        return new F();
    };
}</code></pre>
<p>It is basically the same piece of code because I find it cleaner and more efficient than my initial draft.</p>
<h3>Namespacing</h3>
<p>Everyone agrees that global variables are evil, therefore I group all my common functions and classes into one single object, as follows,</p>
<pre class="ln-"><code class="javascript">var cs = Object.create(new function() {
    // some other code
}</code></pre>
<p>And I find the way <a href="http://developer.yahoo.com/yui">YUI</a> manages the modules good enough for me, then I emulated YAHOO.namespace function by having this in my object.</p>
<pre class="ln-"><code class="javascript">    this.namespace = function(_namespace) {
        if(!this[_namespace]) {
            this[_namespace] = Object.create(new function() {});
        }

        return this[_namespace];
    }</code></pre>
<p>The code may not be clever/clean, but as long as it does the job I have no complaint.</p>
<h3>Preserving State</h3>
<p>I didn&#8217;t quite like the delegate function as I can&#8217;t pass in extra arguments, therefore I have this after some refactoring</p>
<pre class="ln-"><code class="javascript">    var __delegate = function(_method, _scope) {
        var _arguments = arguments;
        return function() {
            return _method.apply(
                _scope, compile_arguments.call(
                    this, _arguments, [], 2
            ));
        }
    };

    var compile_arguments = function(_arguments, _result, _start) {
        for(var i = _start; _arguments.length > _start &#038;&#038; i < _arguments.length; i++) {
            _result.push(_arguments[i]);
        }

        return _result;
    };

    this.delegate = __delegate;
</code></code></pre>
<h3>Emulate Functional Programming</h3>
<p>I have recently decided to learn a little bit on functional programming recently but I haven&#8217;t decide which language I am picking. I have some experience in SWI-Prolog but prolog is just a declarative functional programming and does not seem to offer closure, higher order functions and currying. Anyway, back to the topic, after spending some time in this <a href="http://eloquentjavascript.net/chapter6.html">book</a>, I modified some code in the book and result in&#8230;</p>
<pre class="ln-"><code class="javascript">    this.functional = Object.create(new function() {
        this.map = function(_function, _arguments) {
            var result = [];

            for(var i = 0; i < _arguments.length; i++) {
                result.push(_function(_arguments[i]));
            }

            return result;
        };

        this.reduce = function(_combine, _base, _arguments) {
            return _arguments.length > 0 ?
                this.reduce(
                    _combine, _combine(_base, _arguments.shift()),
                    _arguments
                ) : _base;
        };
    });</code></pre>
<p>I am not sure if I can do the similar recursion in cs.functional.map compared to cs.functional.reduce because I am rather weak in recursion.</p>
<p><del datetime="2009-08-15T14:20:38+00:00">That&#8217;s all for now, and in the second part of this article I will post some helper functions for use with some third party libraries like jQuery and Google Maps API.</del></p>
<p>EDIT 15/8/2009 There are some changes to this set of functions, will post an update soon and there will probably no part 2 any time soon.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/06/04/my-collection-of-common-javascript-functions-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maintaining State with jQuery Event</title>
		<link>http://cslai.coolsilon.com/2009/05/04/maintaining-state-with-jquery-event/</link>
		<comments>http://cslai.coolsilon.com/2009/05/04/maintaining-state-with-jquery-event/#comments</comments>
		<pubDate>Mon, 04 May 2009 13:17:24 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=118</guid>
		<description><![CDATA[Maintaining state in Javascript is not too difficult once you catch the idea. However, as I am not a super brilliant programmer, it takes me some time to find a way to maintain state as YUI Event does in jQuery. I like grouping relevant functions into a class as it makes code easier to manage [...]]]></description>
			<content:encoded><![CDATA[<p>Maintaining state in Javascript is not too difficult once you catch the idea. However, as I am not a super brilliant programmer, it takes me some time to find a way to maintain state as <a href="http://developer.yahoo.com/yui/event/">YUI Event</a> does in <a href="http://jquery.com/">jQuery</a>.</p>
<p><span id="more-118"></span></p>
<p>I like grouping relevant functions into a class as it makes code easier to manage (for me, as there may be better ways. As I just recently found out how prototyping inheritance works, it is possible that the discovery may change the way I code in future), therefore the scope of event handler functions is very important. Making the scope (value/reference of <code class="javascript">this</code>) to the DOM element listened to the event does not help in accessing the shared data so I needed a way to change that behavior.</p>
<p>To solve the problem, a small derivation of the <a href="http://cslai.coolsilon.com/2009/04/11/random-javascript-notes/">previously discussed</a> delegate function will come in useful.</p>
<pre class="ln-">
<code class="javascript">
/**
 * Simulating YUI Event with jQuery
 */
(function($) {
EventHandler = function(_method, _scope) {
    var _argument = {};

    if(arguments.length > 2) {
        _argument = arguments[2];
    }

    // jquery default event callback format
    return function(_event) {
        // this = DOM element
        return _method.call(_scope, _event, this, _argument);
    };
};
})(jQuery);

var Foo = function() {

    var bar_handler = function(_event, _element) {
        alert('bar');
    }

    var foo_handler = function(_event, _element, _extra_argument) {
        alert(_extra_argument);
    }

    (function() {
        $('#foo').click(EventHandler(foo_handler, this, 'foo'));
        $('#bar').click(EventHandler(bar_handler, this));
    }).call(this);
};
var foo = new Foo();
</code>
</pre>
<p>That basically wraps up what I found these couple of days, if I manage to dig some time, the next post should be focused on prototypical inheritance.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/05/04/maintaining-state-with-jquery-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proof of Concept: YQuery</title>
		<link>http://cslai.coolsilon.com/2009/05/04/proof-of-concept-yquery/</link>
		<comments>http://cslai.coolsilon.com/2009/05/04/proof-of-concept-yquery/#comments</comments>
		<pubDate>Mon, 04 May 2009 13:01:24 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=114</guid>
		<description><![CDATA[After the last post, I found that it may be fun to write a wrapper for YUI in order to make it behave like jQuery. Therefore, the code below is clearly mainly for self-amusement and is not intended to be used in production projects. However, through coding this, I found that although the difference in [...]]]></description>
			<content:encoded><![CDATA[<p>After the <a href="http://cslai.coolsilon.com/2009/04/11/maintaining-state-with-yui-event/">last post</a>, I found that it may be fun to write a wrapper for YUI in order to make it behave like <a href="http://jquery.com/">jQuery</a>. Therefore, the code below is clearly mainly for self-amusement and is not intended to be used in production projects. However, through coding this, I found that although the difference in design, but <a href="http://developer.yahoo.com/yui/">YUI</a> is obviously capable to do what jQuery offers (if not more). I will not continue working on this so whoever interested may just copy and paste the code to further developing it. </p>
<p><span id="more-114"></span></p>
<pre class="ln-">
<code class="javascript">/**
 * Proof of concept : jQuery-like syntax in YUI
 */
(function() {

var yui_builder = (function(Selector, Element, DOM, Event) {
    return function(_selector) {
        var Result = function() {};

        var init = function(_selector) {
            var result = [];

            if(typeof _selector == 'object') {
                result = [ new Element(_selector) ];
            } else {
                result = query_elements.call(this, _selector);
            }

            return result;
        };

        var delegate = function(_scope, _function) {
            return function() {
                return _function.apply(_scope, arguments);
            };
        };

        var query_elements = function(_selector) {
            var result = new Result;
            var elements = wrap_elements(Selector.query(_selector));

            for(var i in elements) {
                result[i] = elements[i];
            }

            return result;
        };

        var unwrap_elements = function(_elements) {
            var result = [];

            for(var i in _elements) {
                result[i] = _elements[i].get('element');
            }

            return result;
        };

        var wrap_elements = function(_elements) {
            var result = [];

            for(var i in _elements) {
                result[i] = new Element(_elements[i]);
            }

            return result;
        };

        return (function(_elements) {
            _this = new Result;

            _this.addClass = function(_class) {
                for(var i in _elements) {
                    _elements[i].addClass(_class);
                }

                return this;
            };

            _this.append = function(_content) {
                if(typeof _content == 'string') {
                    for(var i in _elements) {
                        _elements[i].set(
                            'innerHTML',
                            _elements[i].get('innerHTML') + _content
                        );
                    }
                } else if(typeof _content == 'object') {
                    _elements[0].appendChild(_content);
                }

                return this;
            };

            _this.appendTo = function(_selector) {
                var _parent = yui_builder(_selector);

                for(var i in _elements) {
                    _elements[i].appendTo(_parent.get(0));
                }

                return this;
            }

            _this.attr = function() {
                var result = this;

                if(arguments.length == 1 &#038;&#038; typeof arguments[0] == 'string') {
                    result = _elements[0].get(arguments[0]);

                    if(!result) {
                        result = undefined;
                    }
                } else if(arguments.length == 1 &#038;&#038; typeof arguments[0] == 'object') {
                    for(var i in _elements) {
                        for(var attribute in arguments[0]) {
                            _elements[i].set(attribute, arguments[0][attribute]);
                        }
                    }
                } else if(typeof arguments[1] == 'function') {
                    for(var i in _elements) {
                        _elements[i].set(arguments[0], arguments[1].call(_elements[i].get('element'), i));
                    }
                } else {
                    for(var i in _elements) {
                        _elements[i].set(arguments[0], arguments[1]);
                    }
                }

                return result;
            };

            _this.each = function(_callback) {
                for(var i in _elements) {
                    _callback.call(_elements[i].get('element'), i, _elements[i].get('element'));
                }

                return this;
            };

            _this.eq = function(_index) {
                return yui_builder(_elements[_index]);
            };

            _this.get = function() {
                var result = [];

                if(arguments.length == 0) {
                    result = unwrap_elements.call(this, _elements);
                } else {
                    result = _elements[arguments[0]].get('element');
                }

                return result;
            };

            _this.hasClass = function(_class) {
                var result = false;

                for(var i in _elements) {
                    if(_elements[i].hasClass(_class)) {
                        result = true;
                        break;
                    }
                }

                return result;
            };

            _this.html = function() {
                var result = this;

                if(arguments.length == 0) {
                    result = _elements[0].get('innerHTML');
                } else {
                    _elements[0].set('innerHTML', arguments[0]);
                }

                return result;
            }

            _this.index = function(_subject) {
                var result = -1;

                for(var i in _elements) {
                    if(_elements[i].get('element') === _subject) {
                        result = i;
                    }
                }

                return result;
            };

            _this.removeClass = function(_class) {
                for(var i in _elements) {
                    _elements[i].removeClass(_class);
                }

                return this;
            }

            _this.size = function() {
                return _elements.length;
            };

            _this.toggleClass = function() {
                if(arguments.length == 0) {
                    for(var i in _elements) {
                        if(_elements[i].hasClass) {
                            _elements[i].removeClass(arguments[0]);
                        } else {
                            _elements[i].addClass(arguments[0]);
                        }
                    }
                } else {
                    for(var i in _elements) {
                        if(arguments[1]) {
                            _elements[i].addClass(arguments[0]);
                        } else {
                            _elements[i].removeClass(arguments[0]);
                        }
                    }
                }

                return this;
            };

            _this.val = function() {
                var result = this;

                if(arguments.length == 0) {
                    result = this.attr('value');
                } else {
                    for(var i in _elements) {
                        this.attr('value', arguments[0]);
                    }
                }

                return result;
            };

            (function() {
                for(var i in _elements) {
                    _this[i] = _elements[i];
                }
            }).call(_this)

            return _this;
        }).call(this, init.apply(this, arguments));
    }
})(YAHOO.util.Selector, YAHOO.util.Element, YAHOO.util.Dom, YAHOO.util.Event);

})();
</code>
</pre>
<p>Most of the implemented functions are similar to what jQuery offers, therefore to use the yui_builder:</p>
<pre class="ln-">
<code class="javascript">
(function($) {
    // everyone loves $ function
    $(document.createElement('a'));
        .attr('href', 'test')
        .html('test')
        .appendTo(document.body);
})(yui_builder);
</code>
</pre>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/05/04/proof-of-concept-yquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maintaining State with YUI Event</title>
		<link>http://cslai.coolsilon.com/2009/04/11/maintaining-state-with-yui-event/</link>
		<comments>http://cslai.coolsilon.com/2009/04/11/maintaining-state-with-yui-event/#comments</comments>
		<pubDate>Sat, 11 Apr 2009 04:39:30 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=107</guid>
		<description><![CDATA[When one start writting Javascript in patterns like the module pattern, then sooner or later he would want to maintain the state when an event handler is called. The reason I am still using YUI to handle my event handling code is because I like how state can be maintained. There are some other interesting [...]]]></description>
			<content:encoded><![CDATA[<p>When one start writting Javascript in patterns like the <a href="http://yuiblog.com/blog/2007/06/12/module-pattern/">module pattern</a>, then sooner or later he would want to maintain the state when an event handler is called. The reason I am still using YUI to handle my event handling code is because I like how state can be maintained.</p>
<p><span id="more-107"></span></p>
<p>There are some other interesting things in the <a href="http://developer.yahoo.com/yui/event/">Event utility</a> like <code class="javascript">YAHOO.util.Event.onDOMReady</code>, <code class="javascript">YAHOO.util.Event.onContentReady</code> as well as <code class="javascript">YAHOO.util.Event.onAvailable</code> methods. Most of the time, the developer may want certain code to start running as soon as the DOM tree is loaded completely without having to wait for all the elements (image, flash etc.) to finish loading. Then <code class="javascript">YAHOO.util.Event.onDOMReady</code> may come in handy. For example </p>
<p><code class="javascript">YAHOO.util.Event.onDOMReady(function() {<br />
    alert('Good day!');<br />
});</code></p>
<p>After loading the DOM tree, then the browser will prompt &#8216;Good day!&#8217; to the user.</p>
<p>Back to the topic, if the developer wishes to listen to some event and perform action as soon as the event is fired, then he may register the event as follows.</p>
<p><code class="javascript">YAHOO.util.Event.on(some_element, 'change', some_callback_function, extra_parameter);</code></p>
<p>Everything looks fine, but when the developer has structure his code into patterns like the module patttern as follows:</p>
<p><code class="javascript"><br />
(function(Event) {<br />
&nbsp;<br />
var Some_Module = function() {<br />
    return {<br />
        foo: 'bar',<br />
        execute: function() {<br />
            alert(this.foo);<br />
        },<br />
&nbsp;<br />
        listen: function() {<br />
            Event.on(element, 'change', this.execute, null, this);<br />
        }<br />
    };<br />
}();<br />
&nbsp;<br />
})(YAHOO.util.Event);<br />
</code></p>
<p>Notice in the forth and fifth arguments passed into the <code class="javascript">YAHOO.util.Event.on</code> function, I am passing in no extra parameters and the fifth argument defines the scope of <code class="javascript">this</code> keyword in the <code class="javascript">Some_Module.execute</code> method.</p>
<p>If the developer uses <code class="javascript">YAHOO.util.Element</code> to wrap certain elements, then he can also use another way to listen to the event</p>
<p><code class="javascript">var element = YAHOO.util.Element('div');<br />
element.on(some_event, some_callback_function, some_extra_parameter, some_scope);<br />
</code></p>
<p>Speaking of YUI Element, I just recently found a way to &#8216;emulate&#8217; jQuery&#8217;s <code>$()</code> function with YUI components.</p>
<p><code class="javascript"><br />
(function($) {<br />
    $(document.body); // returns the body element wrapped in YAHOO.util.Element class<br />
})(function(_selector) {<br />
    var result = YAHOO.util.Selector.query(_selector);<br />
&nbsp;<br />
    if(result.length > 0) {<br />
        if(result.length == 1) {<br />
            result = new YAHOO.util.Element(result[0]);<br />
        } else {<br />
            for(i in result) {<br />
                result[i] = new YAHOO.util.Element(result[i]);<br />
            }<br />
        }<br />
    } else {<br />
        result = false;<br />
    }<br />
&nbsp;<br />
    return result;<br />
});<br />
</code></p>
<p>Although not as powerful as jQuery&#8217;s $() function, but It can be useful in many situations where YUI is the only choice.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/04/11/maintaining-state-with-yui-event/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

