<?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>Frederick Giasson's Weblog &#187; Programming</title>
	<atom:link href="http://fgiasson.com/blog/index.php/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://fgiasson.com/blog</link>
	<description></description>
	<lastBuildDate>Fri, 30 Mar 2012 00:56:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>jQuery Cookie Pluging Extended With HTML5 localStorage And Chunked Cookies</title>
		<link>http://fgiasson.com/blog/index.php/2012/01/05/jquery-cookie-pluging-extended-with-html5-localstorage-and-chunked-cookies/</link>
		<comments>http://fgiasson.com/blog/index.php/2012/01/05/jquery-cookie-pluging-extended-with-html5-localstorage-and-chunked-cookies/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 13:30:27 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[#cookies]]></category>
		<category><![CDATA[#developer]]></category>
		<category><![CDATA[#html5]]></category>
		<category><![CDATA[#javascript]]></category>
		<category><![CDATA[#jquery]]></category>
		<category><![CDATA[#localStorage]]></category>
		<category><![CDATA[#plugin]]></category>

		<guid isPermaLink="false">http://fgiasson.com/blog/?p=1861</guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=jQuery Cookie Pluging Extended With HTML5 localStorage And Chunked Cookies&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2012-01-05&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2012/01/05/jquery-cookie-pluging-extended-with-html5-localstorage-and-chunked-cookies/&amp;rft.language=English"></span>
Is there a web developer that never used cookies to save some information in a user&#8217;s browser? There may be, but they should be legion. As you probably know, the problem with cookies is that their implementation in browsers is random: some will limit the size of the cookie to 4096 bytes, others will limit [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=jQuery Cookie Pluging Extended With HTML5 localStorage And Chunked Cookies&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2012-01-05&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2012/01/05/jquery-cookie-pluging-extended-with-html5-localstorage-and-chunked-cookies/&amp;rft.language=English"></span>
<table>
<tbody>
<tr>
<td>Is there a web developer that never used cookies to save some information in a user&#8217;s browser? There may be, but they should be legion. As you probably know, the problem with cookies is that their implementation in browsers is random: some will limit the size of the cookie to 4096 bytes, others will limit the number of cookies from a specific domain to 50, others will have no perceivable limits, etc.</td>
<td><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2pxdWVyeS5jb20="><img class="aligncenter size-thumbnail wp-image-1891" title="jQuery" src="http://fgiasson.com/blog/wp-content/uploads/2012/01/jquery1-150x150.png" alt="" width="150" height="150" /></a></td>
</tr>
</tbody>
</table>
<p><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDEyLzAxL2Rvd25sb2FkLnBuZw=="><br />
</a>In any case, if one of these limits is reached, the cookie is simply not created the browser. This is fine, because web developer expects cookies to fail from time to time, and the system they develop has to cope with this unreliableness. However, this situation can sometimes become frustrating, and it is why I wanted to extend the default behavior of the <a title=\"jQuery Cookie Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2NhcmhhcnRsL2pxdWVyeS1jb29raWU=">jQuery Cookie plugin</a> with a few more capabilities.</p>
<p>This <a title=\"jQuery Extended Cookie Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2ZnaWFzc29uL2pxdWVyeS1lbmhhbmNlZC1jb29raWU=">extension to the jQuery Cookie plugin</a> adds the capability to save content that is bigger than 4096 bytes long using two different mechanism: the usage of HTML5&#8242;s <code>localStorage</code>, or the usage of a series of cookies where the content is chunked and saved. This extension is backward compatible with the jQuery Cookie plugin and its usage should be transparent to the users. Even if existing cookies have been created with the normal Cookie plugin, they will still be usable by this new extension. The usage syntax is the same, but 3 new options have been created.</p>
<p>Now, let&#8217;s see how this plugin works, how developers should use it, what are its limitations, etc.</p>
<p>You can immediately download the jQuery Extended Cookie plugin from here:</p>
<p style="text-align: center;"><a title=\"jQuery Extended Cookie Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2ZnaWFzc29uL2pxdWVyeS1lbmhhbmNlZC1jb29raWU="><img class=" wp-image-1893 aligncenter" style="border-style: initial; border-color: initial;" title="Download the jQuery Extended Cookie Plugin" src="http://fgiasson.com/blog/wp-content/uploads/2012/01/download-300x181.png" alt="" width="180" height="109" /></a></p>
<div>
<h3>Limitations Of Cookies</h3>
<p>First, let&#8217;s see what the <a title=\"RFC 2109\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjEwOS50eHQ=">RFC 2109</a> says about the limitations of cookies in web browsers. Browsers should normally have these implementation limits (see section 6.3):</p>
<blockquote>
<pre>   Practical user agent implementations have limits on the number and
   size of cookies that they can store.  In general, user agents' cookie
   support should have no fixed limits.  They should strive to store as
   many frequently-used cookies as possible.  Furthermore, general-use
   user agents should provide each of the following minimum capabilities
   individually, although not necessarily simultaneously:

      * at least 300 cookies
      * at least 4096 bytes per cookie (as measured by the size of the
        characters that comprise the cookie non-terminal in the syntax
        description of the Set-Cookie header)
      * at least 20 cookies per unique host or domain name

   User agents created for specific purposes or for limited-capacity
   devices should provide at least 20 cookies of 4096 bytes, to ensure
   that the user can interact with a session-based origin server.

   The information in a Set-Cookie response header must be retained in
   its entirety.  If for some reason there is inadequate space to store
   the cookie, it must be discarded, not truncated.

   Applications should use as few and as small cookies as possible, and
   they should cope gracefully with the loss of a cookie.</pre>
</blockquote>
<h3>New Options</h3>
<p>Before I explains how this extension works, let me introduce three new options that have been added to the <a title=\"jQuery Cookie Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2NhcmhhcnRsL2pxdWVyeS1jb29raWU=">Cookie plugin</a>. These new options will be put into context, and properly defined later in this blog post.</p>
<ul>
<li><code>maxChunkSize </code>- This defines the maximum number of bytes that can be saved in a single cookie. <code>(default: 3000)</code></li>
<li><code>maxNumberOfCookies -</code> This is the maximum number of cookies that can be created for a single domain name.<code> (default: 20)</code></li>
<li><code>useLocalStorage </code>- This tells the extended Cookie plugin to use the HTML5&#8242;s<code> localStorage</code> capabilities of the browser instead of a cookie to save that value.<code> (default: true)</code></li>
</ul>
<h3>How Does This Extension Works?</h3>
<p>As I said in the introduction of this blog post, this extension to the jQuery Cookie plugin does two things:</p>
<ol>
<li>It uses the HTML5 <code>localStorage</code> capabilities of the browser if this feature is available instead of relying on the cookies. However, if cookies are needed by the developer, this feature can be turned off with the <code>useLocalStorage = false</code> option</li>
<li>If the <code>localStorage</code> option is disable, or simply not available on a browser, and if the content is bigger than the limit of the size of a cookie, then this extension will chunk the input content, and save it in multiple cookies</li>
</ol>
<p>If the <code>useLocalStorage</code> is <code>true</code>, then the plugin will try to see if the HTML5 <code>localStorage</code> mechanism is available on the browser. If it is, then it will use that local storage to save and retrieve content to the browser. If it is not, then the plugin will act like if <code>useLocalStorage</code> is <code>false </code>and the process will continue by using cookies to save and read that content from the browser.</p>
<p>If <code>useLocalStorage</code> is <code>false</code>, or if the HTML5 <code>localStorage</code> mechanism is not available on the browser, then the plugin will check if the content is bigger than the <code>maxChunkSize</code> option, than all the chunks will be saved in different cookies until it reaches the limit imposed by the <code>maxNumberOfCookies</code> option.</p>
<p>If cookies are used, then two use-cases can happen:</p>
<ol>
<li>The content is smaller than or equal to <code>maxChunkSize</code></li>
<li>The content is bigger than<code> maxChunkSize</code></li>
</ol>
<p>If the content is smaller than or equal to <code>maxChunkSize</code> than only one cookie will be created by the browser. The name of the cookie will be the value provided to the <code>key</code> parameter.</p>
<p>If the content is bigger tha<code>n maxChunkSize</code> than multiple cookies will be created, one per chunk. The convention is that the name of the first cookie is the value provided to the <code>key</code> parameter. The name of the other chunks is the value provided to the <code>key </code>parameter with the chunk indicator <code>---ChunkNum</code> append to it. For example, if we have a cookie with a content of 10000 bytes that has <code>maxChunkSize </code>defined to 4000 bytes, then these three cookies would be created:</p>
<ul>
<li><code>cookie-name</code></li>
<li><code>cookie-name---1</code></li>
<li><code>cookie-name---2</code></li>
</ul>
<h3>Usage</h3>
<p>Now, let&#8217;s see how this extended jQuery Cookie plugin should be used in your code. The usage of the extension is no different from the usage of the normal jQuery Cookie plugin. However, I am showing how to use the new options along with how to use the plugin in general.</p>
<h4>Create a Cookie</h4>
<p>Let&#8217;s create a cookie that expires in 365 days and where the path is the root:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container javascript railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$.<span style="color: #660066;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'my-cookie'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;the-content-of-my-cookie&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> expires<span style="color: #339933;">:</span> <span style="color: #CC0000;">365</span><span style="color: #339933;">,</span> path<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>By default, this value will be persisted in the <code>localStorage</code> if the browser supports it, and not in a cookie. So, let&#8217;s see how to force the plugin to save the content in a cookie by using the <code>useLocalStorage</code> option:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container javascript railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$.<span style="color: #660066;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'my-cookie'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;the-content-of-my-cookie&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>useLocalStorage<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> expires<span style="color: #339933;">:</span> <span style="color: #CC0000;">365</span><span style="color: #339933;">,</span> path<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<h4>Delete a Cookie</h4>
<p>Let&#8217;s see how a cookie can be deleted. The method is simply to put <code>null</code> as the value of the cookie. This will instruct the plugin to remove the cookie.</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container javascript railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$.<span style="color: #660066;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'my-cookie'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>With that call, the plugin will try to remove <code>my-cookie</code> both in the <code>localStorage</code> and in the <code>cookies</code>.</p>
<h4>Read a Cookie</h4>
<p>Let&#8217;s see how we can read the content of a cookie:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container javascript railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #339933;">=</span> $.<span style="color: #660066;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'my-cookie'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>With this call, <code>value</code> will get the content that has been saved in the <code>localStorage</code>, or the <code>cookies</code>. This will depend if the <code>localStorage</code> was available in the browser.</p>
<p>Now, let&#8217;s see how to force reading the cookies by bypassing the <code>localStorage</code> mechanism:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container javascript railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #339933;">=</span> $.<span style="color: #660066;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'my-cookie'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>useLocalStorage<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Note that if the cookie is not existing for a <code>key</code>, then the <code>$.cookie()</code> function will return <code>null</code>.</p>
<h4>Using Limitations</h4>
<p>Let&#8217;s see how to use the<code> maxNumberOfCookies</code> and<code> maxChunkSize</code> options to limit the size and the number of cookies to be created.</p>
<p>With this example, the content will be saved in multiple cookies of 1000 bytes each up to 30 cookies:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container javascript railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #339933;">=</span> $.<span style="color: #660066;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'my-cookie'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;the-content-of-my-cookie-is-10000-bytes-long...&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>useLocalStorage<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> maxChunkSize  <span style="color: #339933;">=</span> <span style="color: #CC0000;">1000</span><span style="color: #339933;">,</span> maxNumberOfCookies <span style="color: #339933;">=</span> <span style="color: #CC0000;">30</span><span style="color: #339933;">,</span> expires<span style="color: #339933;">:</span> <span style="color: #CC0000;">365</span><span style="color: #339933;">,</span> path<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<h3>Limitations</h3>
<p>Users have to be aware of the limitations of this enhanced plugin. Depending on the browser, the values of the <code>maxChunkSize </code>and the <code>maxNumberOfCookies</code> options should be different. In the worse case, some cookies (or cookies chunks) may simply not be created by the browser. As stated in the RFC 2109, the web applications have to take that fact into account, and be able to gracefully cope with this.</p>
<h3>Future Enhancements</h3>
<p>In the future, this extension should detect the browser where it runs, and setup the<code> maxChunkSize</code> and the <code>maxNumberOfCookies</code> parameters automatically depending on the cookies limitation of each browser.</p>
<h3>Conclusion</h3>
<p>I had to create this extension to the jQuery Cookie plugin to be able to store the resultsets returned by some web service endpoints. It is only used to limit the number of queries sent to these endpoints. Since the values returned by the endpoints are nearly static, that they are loaded at each page view and that they are a few kilobytes big, I had to find a way to save that information in the browser, and to overcome the size limitation of the cookies if possible. I also needed to be able to cope with older versions of browsers that only supports cookies. In the worse case scenario, the browser will simply send the request to the endpoints at each page load for the special use-cases where nothing works: not the cookies and not the <code>localStorage</code>. But at least, my application will benefit of this enhancement from the 95% of the users were one of these solutions works.</p>
</div>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1861" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2012/01/05/jquery-cookie-pluging-extended-with-html5-localstorage-and-chunked-cookies/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Moving Projects from Google Code to GitHub</title>
		<link>http://fgiasson.com/blog/index.php/2011/11/21/moving-projects-from-google-code-to-github/</link>
		<comments>http://fgiasson.com/blog/index.php/2011/11/21/moving-projects-from-google-code-to-github/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 21:29:50 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[conStruct]]></category>
		<category><![CDATA[irON]]></category>
		<category><![CDATA[Open Semantic Framework]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Semantic Components]]></category>
		<category><![CDATA[structWSF]]></category>
		<category><![CDATA[#developer]]></category>
		<category><![CDATA[#git]]></category>
		<category><![CDATA[#github]]></category>
		<category><![CDATA[#google code]]></category>
		<category><![CDATA[#source control]]></category>
		<category><![CDATA[#svn]]></category>

		<guid isPermaLink="false">http://fgiasson.com/blog/?p=1677</guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Moving Projects from Google Code to GitHub&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=conStruct&amp;rft.subject=irON&amp;rft.subject=Open Semantic Framework&amp;rft.subject=Programming&amp;rft.subject=Semantic Components&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-11-21&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/11/21/moving-projects-from-google-code-to-github/&amp;rft.language=English"></span>
Last week we slowly migrated Structured Dynamics&#8216; Google Code Projects to GitHub.We have been thinking about moving to GitHub for some time now, but we only wanted to move projects to it if no prior history and commits were dropped in the process. One motivation for the possible change has been the seeming lack of [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Moving Projects from Google Code to GitHub&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=conStruct&amp;rft.subject=irON&amp;rft.subject=Open Semantic Framework&amp;rft.subject=Programming&amp;rft.subject=Semantic Components&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-11-21&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/11/21/moving-projects-from-google-code-to-github/&amp;rft.language=English"></span>
<table>
<tbody>
<tr>
<td>Last week we slowly migrated <a title=\"Structured Dynamics LLC.\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0cnVjdHVyZWRkeW5hbWljcy5jb20=">Structured Dynamics</a>&#8216; Google Code Projects to <a title=\"Structured Dynamics' Open Source Projects\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3N0cnVjdHVyZWRkeW5hbWljcw==">GitHub</a>.We have been thinking about moving to GitHub for some time now, but we only wanted to move projects to it if no prior history and commits were dropped in the process. One motivation for the possible change has been the seeming lack of support by Google for certain long-standing services: we are seeing disturbing trends across a number of existing services. We also needed a migration process that would work with all of our various projects, without losing a trunk, branch, tag or commits (and their related comments).</td>
<td><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3N0cnVjdHVyZWRkeW5hbWljcw=="><img class="aligncenter size-medium wp-image-1713" src="http://fgiasson.com/blog/wp-content/uploads/2011/11/github-profile-200x300.png" alt="" width="120" height="180" /></a></td>
</tr>
</tbody>
</table>
<p>It was not until recently that I found a workable process. Other people have successfully migrated Google Code SVN projects to GitHub, but I had yet to find a consolidated guide to do it. It is for this last reason that I write this blog post: to help people, if they desire, to move projects from Google Code to GitHub.</p>
<h3>Moving from Google Code to GitHub</h3>
<p>The protocol outlined below may appear complex, but it looks more intimidating than it really is. Moving a project takes about two to five minutes once your GitHub account and your migration computer is properly configured.</p>
<p>You need four things to move a Google Code SVN project to GitHub:</p>
<ol>
<li>A Google Code project to move</li>
<li>A GitHub user account</li>
<li>SSH keys, and</li>
<li>A <em>migration computer</em> that is configured to migrate the project from Google Code to GitHub. (in this tutorial, we will use a Ubuntu server; but any other Linux/Windows/Mac computer, properly configured, should do the job)</li>
</ol>
<h3>Create GitHub Account</h3>
<p>If you don&#8217;t already own a GitHub account, the first step is to <a title=\"Create GitHub Account\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3NpZ251cC9mcmVl">create one here</a>.</p>
<h3>Create &amp; Configure SSH Keys</h3>
<p>Once your account has been created, you have to create and setup the SSH keys that you will use to commit the code into the Git Repository on GitHub:</p>
<ol>
<li>Go to the <a title=\"GitHub SSH Keys Registration Page\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2FjY291bnQvc3No">SSH Keys Registration page of your account</a></li>
<li>If you already have a key, then add it to this page, <a title=\"How to create SSH keys on Windows for GitHub\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2hlbHAuZ2l0aHViLmNvbS93aW4tc2V0LXVwLWdpdC8=">otherwise read this manual to learn how to generate one</a></li>
</ol>
<h3>Configure Migration Server</h3>
<p>The next step is to configure the computer that will be used to migrate the project. For this tutorial, I use a <em>Ubuntu server</em> to do the migration, but any Windows, Linux or Mac computer should do the job if properly configured.</p>
<p>The first step is to install Git and Ruby on that computer:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> git-core <span style="color: #c20cb9; font-weight: bold;">git-svn</span> ruby rubygems</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>To perform the migration of a Google Code SVN project to GitHub, we are using a Ruby application called <code><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL25pcnZkcnVtL3N2bjJnaXQ=">svn2git</a></code> that is now developed by <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL25pcnZkcnVt">Kevin Menard</a>. The next step is to install <code>svn2git</code> on that computer:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> svn2git --source http:<span style="color: #000000; font-weight: bold;">//</span>gemcutter.org</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<h3>Migrate Project</h3>
<p>Before migrating your project, you have to link the Google Code committers to GitHub accounts. This is done by populating a simple text file that will be given as input to <code>svn2git</code>.</p>
<p>Open the <code>authors.txt</code> file into a temporary folder:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">vim</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>authors.txt</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Then, for each author, you have to add the mapping between their Google Code and GitHub accounts. If a Google Code committer does not exist on GitHub, then you should map it to your own GitHub account.</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;(no author) = Frederick Giasson &lt;fred@f...com&gt;<br />
&nbsp;fred@f...com = Frederick Giasson &lt;fred@f...com&gt;</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>The format of this <code>authors.txt</code> file is:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;Google-Account-Username = Name-Of-Author-On-GitHub &lt;Email-Of-Author-On-Github</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Take note of the first Google Code committer <code>(no author)</code> mapping. This link is required for every <code>authors.txt</code> file. This placeholder is used to map the initial commit performed by the Google Code system. (When Google Code initializes a new project, it uses that username for creating the first commit of any project.)</p>
<p>When you are done, save the file.</p>
<p>Now that set up is complete, you are ready to migrate your project. First, let&#8217;s create the folder that will be used to checkout the SVN project on the server, and then to push it on GitHub.</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> myproject<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> myproject</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>In this tutorial, we have a normal migration scenario. However, your migration scenario may differ from this one. It is why I would suggest you check out the <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL25pcnZkcnVtL3N2bjJnaXQ=">different scenarios that are supported by <code>svn2git</code> document</a>. Change the following command accordingly. Let&#8217;s migrate the Google Code SVN Project into the local Git repository:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>svn2git http:<span style="color: #000000; font-weight: bold;">//</span>myproject.googlecode.com<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #660033;">--authors</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>authors.txt <span style="color: #660033;">--verbose</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Make sure that no errors have been reported during the process. If it is the case, then refer to the <code>Possible Errors and Fixes</code> section below to troubleshoot your issue.</p>
<p>The next step is to create a new GitHub repository where to migrate the SVN project. <a title=\"Create a new GitHub repository\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3JlcG9zaXRvcmllcy9uZXc=">Go to this GitHub page to create your new repository</a>. Then you have to configure Git to add a remote link, from the local Git repository you created on your migration computer, to this remote GitHub repository:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #c20cb9; font-weight: bold;">git remote</span> add origin <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>github.com:you-github-username<span style="color: #000000; font-weight: bold;">/</span>myproject.git</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Finally, let&#8217;s push the local Git repository master, branches and tags to GitHub. The first thing to push onto GitHub is the SVN&#8217;s trunk. It is done by running that command:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #c20cb9; font-weight: bold;">git push</span> <span style="color: #660033;">-u</span> origin master</div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Then, if your project has multiple branches and tags, you can push them, one by one, using the same command. However, you will have to replace <code>master</code> by the name of that branch or tag. If you don&#8217;t know what is the exact name of these branches or tags, you can easily list all of them using this Git command:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #c20cb9; font-weight: bold;">git show-ref</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Once you have progressed through all branched and tags, you are done. If you take a look at your GitHub project&#8217;s page, you should see that the trunk, branches, tags and commits are now properly imported into that project.</p>
<h3>Possible Errors And Fixes</h3>
<h4>Fatal Error: Not a valid object name</h4>
<p>There are a few things that can go wrong while trying to migrate your project(s).</p>
<p>One of the errors I experienced is a <code>"fatal"</code> error message <code>"Not a valid object name"</code>. <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL25pcnZkcnVtL3N2bjJnaXQvaXNzdWVzLzI2">To fix this</a>, we have to fix a line of code in <code>svn2git</code>. Open the <code>migration.rb</code> file. Check around the <code>line 227</code> for the method <code>fix_branches()</code>. Remove the first line of that method, and replace the second one by:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container ruby railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;svn_branches = <span style="color:#0066ff; font-weight:bold;">@remote</span>.<span style="color:#9900CC;">find_all</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>b<span style="color:#006600; font-weight:bold;">|</span> !@tags.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> b.<span style="color:#9900CC;">strip</span> =~ <span style="color:#006600; font-weight:bold;">%</span>r<span style="color:#006600; font-weight:bold;">&#123;</span>^svn\<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<h4>Error: author not existing</h4>
<p>While running the <code>svn2git</code> application, the process may finish prematurely. If you check the output, you may see that it can&#8217;t find the match for an author. What you will have to do is to add that author to your authors file and re-run <code>svn2git</code>. Otherwise you won&#8217;t be able to fully migrate the project.</p>
<p>I&#8217;m not quite sure why these minor glitches occurred during my initial migrate, but with the simple fixes above you should be good to go.</p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1677" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2011/11/21/moving-projects-from-google-code-to-github/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Open Sources Projects As A Pool Of Resources</title>
		<link>http://fgiasson.com/blog/index.php/2011/10/17/open-sources-projects-as-a-pool-of-resources/</link>
		<comments>http://fgiasson.com/blog/index.php/2011/10/17/open-sources-projects-as-a-pool-of-resources/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 02:17:42 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[conStruct]]></category>
		<category><![CDATA[Open Semantic Framework]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Semantic Components]]></category>
		<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[Structured Dynamics]]></category>
		<category><![CDATA[structWSF]]></category>
		<category><![CDATA[#business]]></category>
		<category><![CDATA[#developer]]></category>
		<category><![CDATA[#enterprise]]></category>
		<category><![CDATA[#open source]]></category>
		<category><![CDATA[#structured dynamics]]></category>
		<category><![CDATA[#structwsf]]></category>

		<guid isPermaLink="false">http://fgiasson.com/blog/?p=1558</guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Open Sources Projects As A Pool Of Resources&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=conStruct&amp;rft.subject=Open Semantic Framework&amp;rft.subject=Programming&amp;rft.subject=Semantic Components&amp;rft.subject=Semantic Web&amp;rft.subject=Structured Dynamics&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-10-17&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/10/17/open-sources-projects-as-a-pool-of-resources/&amp;rft.language=English"></span>
In a previous blog post, I wrote about how Open Source may be unnatural, and even counter intuitive, to many people. However, that really begs some questions evident with my current company's strategy. Why have Mike Bergman and I chosen to develop no less than three major open source projects (structWSF, conStruct and the Semantic [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Open Sources Projects As A Pool Of Resources&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=conStruct&amp;rft.subject=Open Semantic Framework&amp;rft.subject=Programming&amp;rft.subject=Semantic Components&amp;rft.subject=Semantic Web&amp;rft.subject=Structured Dynamics&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-10-17&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/10/17/open-sources-projects-as-a-pool-of-resources/&amp;rft.language=English"></span>
<table>
<tbody>
<tr>
<td>In a previous blog post, I wrote about how <a title=\"Unnatural Open Source\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL2luZGV4LnBocC8yMDExLzEwLzA1L3VubmF0dXJhbC1vcGVuLXNvdXJjZS8=">Open Source may be unnatural, and even counter intuitive, to many people</a>. However, that really begs some questions evident with my current company's strategy.</td>
<td><div style="margin:10px;overflow:hidden;display:table;line-height:0;text-align:center;width:210px;" class="aligncenter"><img class=" size-medium wp-image-1650" style="shadow_curl; padding:0 !important; margin:0 !important; max-width:100% !important;" title="The construction of the Bridge of Quebec. Last step to bridge the North and South side of the Fleuve Saint-Laurent." src="http://fgiasson.com/blog/wp-content/uploads/2011/10/quebec_bridge_construction-300x207.jpg" alt="" width="210" height="145" /><br/><img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="shadow_img" style="margin:0 !important;height:10px;width:100%;"></div></td>
</tr>
</tbody>
</table>
<p>Why have <a title=\"Structured Dynamics - About\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0cnVjdHVyZWRkeW5hbWljcy5jb20vYWJvdXQuaHRtbA==">Mike Bergman</a> and I chosen to develop no less than three major open source projects (<a title=\"structWSF\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL29wZW5zdHJ1Y3RzLm9yZy9zdHJ1Y3R3c2Y=">structWSF</a>, <a title=\"conStruct\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL29wZW5zdHJ1Y3RzLm9yZy9jb25zdHJ1Y3Q=">conStruct</a> and the <a title=\"Semantic Components\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL29wZW5zdHJ1Y3RzLm9yZy9zY29tcG9uZW50">Semantic Components</a>), encompassing more than 100 000 lines of new code and leveraging between 30 to 50 other open source software and libraries? Why have we open sourced all our software? Why has open source formed the core business strategy of <a title=\"Structured Dynamics LLC.\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0cnVjdHVyZWRkeW5hbWljcy5jb20v">Structured Dynamics</a> in the last three years? How have we been able to profitably sustain the company, even in the midst of the global economic crisis that began in 2008?</p>
<p>I will try to answer these questions in this blog post, perhaps even providing some guidance for newer startups that may follow behind us.</p>
<h3><strong>Why Open Sourcing?</strong></h3>
<p>Why did Structured Dynamics chose to open source all of its software? There are multiple reasons why people and businesses choose to go open source. For some, it is because they think that it is where the market place is moving. For others it is because they think that a community will emerge around their effort, and then get free resources that improve the piece of software. Some think that their software will promptly be reviewed by professional programmer. Others may think that their system will become more secure. Etc.</p>
<p>For Structured Dynamics the reason why we choose to go open source is somewhat different:</p>
<blockquote><p>We perceived that by open sourcing our complete software stack we could bootstrap the company without any external investment.</p></blockquote>
<h3><strong>Making a Living out of Open Source Projects</strong></h3>
<p>There are multiple ways to do a living from an open source project:</p>
<ul>
<li>Doing consultancy work related to the project</li>
<li>Implementing the software(s) into clients&#8217; computer environment(s)</li>
<li>Selling training classes</li>
<li>Selling support contracts</li>
<li>Selling maintenance contracts</li>
<li>Selling hosted instances of the software (the <a title=\"Software as a service\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Tb2Z0d2FyZV9hc19hX3NlcnZpY2U=">SaaS </a>model for one)</li>
<li>Selling development time to improve some part(s) of the software</li>
<li>Creating conferences around their open source projects</li>
<li>Selling proprietary extensions</li>
<li><em>I am probably missing a few, so please add them in a comment section below, and I will make sure to add them to this list.</em></li>
</ul>
<p>Depending on the software you are developing, and depending on the business plan of your company, you may be doing one &#8212; or multiple &#8212; of these things to generate some money from your open source projects.</p>
<p>At Structured Dynamics we are doing some of them: we do get consultancy contracts related to the <a title=\"Open Semantic Framework\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL29wZW5zdHJ1Y3RzLm9yZy9vcGVuLXNlbWFudGljLWZyYW1ld29yaw==">Open Semantic Framework</a> and we do implement OSF in our clients&#8217; computer environments.</p>
<p>But, more importantly, we are also doing development contracts related to the framework. In fact, each project we are working on is quite different. Our major projects involve companies that reside in totally different domains, have different needs and need to accommodate different kinds of users. However, most of the projects share the same core needs, and all of them advance the core technology in ways meaningful to our vision. We choose our customers &#8212; and , of course, <em>vice versa</em> &#8212; based on a true sense of partnership wherein both parties have their objectives furthered.</p>
<p>Let&#8217;s see how we use these relationships to drive the development of the Open Semantic Framework.</p>
<h3><strong>Open Source Project as a Pool of Resources</strong></h3>
<p>In the last three years, Structured Dynamics has attracted multiple companies and organizations that share our vision, and which are willing to invest in the Open Semantic Framework open source project. (See Mike's recent <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5ta2JlcmdtYW4uY29tLzk2OS9vZi1mbGFncG9sZXMtYW5kLWZpc2hlcy8=">post on business development</a> for a bit more on that aspect of things.) Each of these clients did want to use the OSF framework for their own needs. However, each of them did want to do something special that was not currently implemented in the framework.</p>
<p>What we created in these three years is a pool of resources that we used to develop the framework such that it accommodates the needs of each of our clients. Each of our clients then becomes a participant to the shared pool of innovation. Our clients have been willing to invest in the open source framework because they need their own features and because they know that they will benefit from what other participants of the pool will invest themselves down the road.</p>
<p>In that scenario, we are the managers of a pool of resources. We have the vision of where we want the framework to go, we know the roadmap of the project and we know the needs of each participant (our clients). What we do is to try to optimize the resources we get from each of our clients by developing the framework such that it can accommodate as broad of a spectrum of participants as possible. Then, we seek to find new participants that have some needs that will help us continue to develop the next steps of the roadmap. In this manner, we Jacob's Ladder our existing work to increase the capabilities for later clients, but earlier clients still benefit because they can upgrade to the later improvements. This is a self-sustaining model to continue to move the development of the framework forward.</p>
<p>By finding new clients, what we do is to give a return on investment to the other pool participants. Most of the new features that we develop for these new clients will benefit the other participants to the pool and will create new possibilities for them without any additional investment. All of our first clients have implemented what other participants later invest into the pool, thus crystallizing and augmenting their return on investment by using these new features.</p>
<h3><strong>Open Source is Not Just About Software</strong></h3>
<p>Open Source is not just about pieces of code, and this is quite important to understand. What we have open sourced with the Open Semantic Framework is much more than a series of code sources. We open sourced the <strong>entire</strong> framework:</p>
<ol start="1">
<li>The source codes</li>
<li>The documentation</li>
<li>The processes</li>
<li>The methodologies</li>
</ol>
<p>We term this comprehensive approach our <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5ta2JlcmdtYW4uY29tLzg4Mi9saXN0ZW5pbmctdG8tdGhlLWVudGVycHJpc2UtdG90YWwtb3Blbi1zb2x1dGlvbnMtcGFydC0xLw==">total</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5ta2JlcmdtYW4uY29tLzg4My9saXN0ZW5pbmctdG8tdGhlLWVudGVycHJpc2UtdG90YWwtb3Blbi1zb2x1dGlvbnMtcGFydC0yLw==">open</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5ta2JlcmdtYW4uY29tLzg4NC9saXN0ZW5pbmctdG8tdGhlLWVudGVycHJpc2UtdG90YWwtb3Blbi1zb2x1dGlvbnMtcGFydC0zLw==">solution</a>.</p>
<p>This distinction with other open source projects is an essential differentiator with our approach. We choose to open source all of the pieces related to the framework. What drove this decision is a simple sentence that shows our philosophy behind it:</p>
<blockquote><p>"We're Successful When We're Not Needed"</p></blockquote>
<p>If the APIs, processes and methodologies are not properly documented, it means that we would certainly be needed by our clients, which would mean that we failed to open source our solution. But since we are working to open source our code, our processes and our methodologies, we are on the way to successfully open source the Open Semantic Framework since we won&#8217;t be needed by our clients.</p>
<p>This business approach is not as crazy as it sounds. We are free to work on new and important innovations, and are not basing our company culture on dependency and a constant drain by our customers. I know, it does not sound like Larry Ellison, but sounds good to us and our clients. It is certainly not a maximum revenue objective built on the backs of individual clients.</p>
<p>Our life is more fun and our clients trust us with new stuff. Further, each step of the way, we are able to leverage our own framework for unbelievable productivity in what we deliver for the money. But that is a topic for another day.</p>
<p>We think Structured Dynamics' business approach is a contemporary winning strategy. Our customers get good and advanced capabilities at low cost and risk, while we get to work on innovative extensions that are raising the semantic baseline for the marketplace. Who knows if we will always continue this path, but for now it is leading to sustained development and market growth for open semantic frameworks, including our own OSF.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1558" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2011/10/17/open-sources-projects-as-a-pool-of-resources/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unnatural Open Source</title>
		<link>http://fgiasson.com/blog/index.php/2011/10/05/unnatural-open-source/</link>
		<comments>http://fgiasson.com/blog/index.php/2011/10/05/unnatural-open-source/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 13:14:53 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[conStruct]]></category>
		<category><![CDATA[Open Semantic Framework]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Semantic Components]]></category>
		<category><![CDATA[Structured Dynamics]]></category>
		<category><![CDATA[structWSF]]></category>
		<category><![CDATA[#business]]></category>
		<category><![CDATA[#developer]]></category>
		<category><![CDATA[#enterprise]]></category>
		<category><![CDATA[#fear]]></category>
		<category><![CDATA[#open source]]></category>

		<guid isPermaLink="false">http://fgiasson.com/blog/?p=1342</guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Unnatural Open Source&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=conStruct&amp;rft.subject=Open Semantic Framework&amp;rft.subject=Programming&amp;rft.subject=Semantic Components&amp;rft.subject=Structured Dynamics&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-10-05&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/10/05/unnatural-open-source/&amp;rft.language=English"></span>
I have never been an open source software advocate. In fact, like most people, I always wondered how companies could find a business advantage in developing open source softwares and how they could make money out of it to grow. It is nice to have open source softwares, but it is hard to imagine how [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Unnatural Open Source&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=conStruct&amp;rft.subject=Open Semantic Framework&amp;rft.subject=Programming&amp;rft.subject=Semantic Components&amp;rft.subject=Structured Dynamics&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-10-05&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/10/05/unnatural-open-source/&amp;rft.language=English"></span>
<table>
<tbody>
<tr>
<td>I have never been an open source software advocate. In fact, like most people, I always wondered how companies could find a business advantage in developing open source softwares and how they could make money out of it to grow. It is nice to have open source softwares, but it is hard to imagine how you could justify putting thousands of hours in open source software projects if it is not only by passion.</td>
<td><div style="margin:10px;overflow:hidden;display:table;line-height:0;text-align:center;width:179px;" class="alignnone"><img class=" size-medium wp-image-1538" style="shadow_curl; padding:0 !important; margin:0 !important; max-width:100% !important;" title="ESCHER ROOM" src="http://fgiasson.com/blog/wp-content/uploads/2011/09/ESCHER-ROOM-298x300.jpg" alt="" width="179" height="180" /><br/><img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="shadow_img" style="margin:0 !important;height:10px;width:100%;"></div></td>
</tr>
</tbody>
</table>
<p><span style="color: #ff0000;"><span style="color: #000000;">In this post I will explain what I think is the main factor that put people, businesses and organizations on guard when come the time to think about open source softwares. In fact, I think it has much more to do with our nature: how we naturally are as human being, and much less to do with any real business related factors.</span></span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;"> In a follow-up blog post, I will explain how <a title=\"Structured Dynamics LLC.\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0cnVjdHVyZWRkeW5hbWljcy5jb20=">Structured Dynamics</a> embraced open source software, how we developed the company around the concept, and how we are managing the development of our project such that it benefits all our clients along with the company. But first, let&#8217;s try to figure out why much people are suspicious regarding open source softwares.</span><br />
</span></p>
<h3>The Fear</h3>
<blockquote><p><em>"I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past I will turn the inner eye to see its path. Where the fear has gone there will be nothing. Only I will remain."</em></p>
<p><center><em>- Dune, Frank Herbert</em></center></p></blockquote>
<p>Have you ever heard someone telling you:</p>
<blockquote><p><em>I found an incredible business idea! I am pretty sure that I am the first one to think about that. I will get some good money down the road!</em></p></blockquote>
<p>Then, you naturally asked for more information about this great idea! And then the answer you got was something like:</p>
<blockquote><p><em>Hooo! But I can&#8217;t tell you, this is really secret right now, at least until everything is ready to go.</em></p></blockquote>
<p>Does this sound familiar? I does to me. I hear it often. But, why does people react that way? It is simply by fear: fearing that someone &#8220;steal&#8221; their ideas, start a company based on them, build projects or services that implemented them, and get rich while you are flipping burgers at McDonald&#8217;s.</p>
<p>To me, this is the main reason why people, organizations and businesses are suspicious regarding open source software: because of fear; fear of loosing something they don&#8217;t even have.</p>
<p>But the question is: is that rational? From my experience, and my understanding of how things works, I can certainly say that it is not. This way of thinking is not rational because it doesn&#8217;t take into account a few things:</p>
<ul>
<li>The ability of others to do something with your ideas</li>
<li>The ability of others to have the vision you have for your ideas</li>
<li>The willingness of others to spend all their time and energy to make these ideas working</li>
<li>People tend to do what they want to do, and not what others wantsÂ­</li>
</ul>
<p>The same behavior seems to happen with open source projects. When I am explaining to people what we are doing, one of the first reaction is: why your work is open and free? Don&#8217;t you fear that someone steal your project and ideas? How can you make money if it is free, people will just run with it for themselves no?</p>
<p>The simple answer to all these question is: no. No we don&#8217;t feature that anybody steal our projects and ideas just by cloning them from the source control. We don&#8217;t because of the four reasons listed above. We don&#8217;t because we trust our vision and our abilities to implement it in our various open source projects. And yes we can sustain the company pretty well with these projects and it is what I will cover in my following blog post.</p>
<h3>Conclusion</h3>
<p>Non-Open Source softwares are just like when someone has a business idea &#8220;for the next big thing&#8221; and that doesn&#8217;t want to share it with anybody else because he think that someone will take that idea and run with it by himself. In fact, it is quite the opposite. I learned with experience that there is only one person (or organization) that can make such a great idea a relative success: the person (or organization) that lives for that idea. An idea is just an idea, and has nothing great in it, until it gets implemented, until the idea lives by itself, propelled by it most dedicated advocate: its creators and their boundless enthusiasm. Any idea would fail without this&#8230; and would worth nothing; it would just be an idea.</p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1342" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2011/10/05/unnatural-open-source/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress&#8217;s Follow Button for Non-WordPress.com Users</title>
		<link>http://fgiasson.com/blog/index.php/2011/10/02/wordpresss-follow-button-for-non-wordpress-com-users/</link>
		<comments>http://fgiasson.com/blog/index.php/2011/10/02/wordpresss-follow-button-for-non-wordpress-com-users/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 22:19:38 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[#blog]]></category>
		<category><![CDATA[#blogging]]></category>
		<category><![CDATA[#email]]></category>
		<category><![CDATA[#share]]></category>
		<category><![CDATA[#wordpress]]></category>

		<guid isPermaLink="false">http://fgiasson.com/blog/?p=1471</guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=WordPress&#8217;s Follow Button for Non-WordPress.com Users&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Blogging&amp;rft.subject=Programming&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-10-02&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/10/02/wordpresss-follow-button-for-non-wordpress-com-users/&amp;rft.language=English"></span>
About two weeks ago, the WordPress.com team released a wonderful new tool called the Follow Button to all theirs WordPress.com users. This button is floating in the bottom-right corner of a blogs and let readers subscribing, by email, to the blog&#8217;s publications. Each time a new blog post is published, they receive an update in [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=WordPress&#8217;s Follow Button for Non-WordPress.com Users&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Blogging&amp;rft.subject=Programming&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-10-02&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/10/02/wordpresss-follow-button-for-non-wordpress-com-users/&amp;rft.language=English"></span>
<table>
<tbody>
<tr>
<td>About two weeks ago, the <a title=\"Wordpress.com\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dvcmRwcmVzcy5jb20=">WordPress.com</a> team released a wonderful new tool called the <a title=\"The Follow Button\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLmJsb2cud29yZHByZXNzLmNvbS8yMDExLzA5LzIxL21vcmUtdHJhZmZpYy1mb3IteW91ci1ibG9nLXdpdGgtdGhlLWZvbGxvdy1idXR0b24v">Follow Button</a> to all theirs WordPress.com users. This button is floating in the bottom-right corner of a blogs and let readers subscribing, by email, to the blog&#8217;s publications. Each time a new blog post is published, they receive an update in their inbox.</td>
<td valign="top"><img class="alignnone size-full wp-image-1513" title="wordpress-logo-stacked-bg" src="http://fgiasson.com/blog/wp-content/uploads/2011/10/wordpress-logo-stacked-bg.png" alt="" width="176" height="145" /></td>
</tr>
</tbody>
</table>
<p>The idea is far from new, and may even looks like old-school. However, the implementation they did is simple, really well done and really clever. Also, the wording they used in the tool is perfect (for example, using the word <em>Follow</em> instead of <em>Subscribe</em>).</p>
<p>The only problem is that this wonderful new tool is only available for WordPress.com users! As you may know, this blog is using WordPress, but it is a self-hosted instance. After doing some research, I couldn&#8217;t find any plugins or methods to install it on my blog. Also, the email service under this user interface is built into WordPress.com. As last resort, I checked their <a title=\"Jetpack WordPress Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2pldHBhY2subWUv">Jetpack plugin</a>, to see if it got added the Follow Button to it, but apparently they didn&#8217;t (it is probably too recent).</p>
<p>So, I was in a dilemma: I wanted this feature for my blog, I didn&#8217;t want to migrate everything to WordPress.com, and I didn&#8217;t had the time to write a plugin that does exactly this. So what I did is to take a few hours to hack my own Follow Button using what is already existing out there. In fact, I have been quite surprised to see how easy it turned out to be.</p>
<p>It as been as easy as installing the really good <a title=\"Subscribe2 WordPress Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dvcmRwcmVzcy5vcmcvZXh0ZW5kL3BsdWdpbnMvc3Vic2NyaWJlMi8=">Subscribe2 plugin</a> and to create the UI, from the original Follow Button using some HTML, CSS and JQuery code. After some re-wiring, I ended-up with my own self-hosted Follow Button.</p>
<p>This is what I want to share with you here, in this <em>Hors S&eacute;rie</em> blog post. I am pretty sure that many self-hosted WordPress blogger will want it, so I took an additional hour to write and publish this blog post.</p>
<p>I did two additional &#8220;improvements&#8221; to the concept:</p>
<ol>
<li>I changed the icon to put some color in there. Not only to make it less dull, but also to bring a little bit mo attention to it.</li>
<li>I also added a link to my RSS feed. To me, &#8220;Follow&#8221; is not just about emails, but it is also about other syndication mediums too. However, I kept the email as the first option to keep the spirit of the tool.</li>
</ol>
<p>Finally, I didn&#8217;t want to hack any piece of code in WordPress nor in any other WordPress plugin. The only thing that we will modify is the theme, by adding some code to it. The current implementation could be improved by upgrading Subscriber2 for example, but I didn&#8217;t want people to have to do this to enable the Follow Button on their blog.</p>
<h3>Step #1: Install Subscribe2</h3>
<p>First thing first. The first thing you will have to do is to install the WordPress plugin that will enable your users to subscribe, and to manage their subscriptions, to your blog via emails. We are using the really good <a title=\"Subscribe2 WordPress Plugin\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dvcmRwcmVzcy5vcmcvZXh0ZW5kL3BsdWdpbnMvc3Vic2NyaWJlMi8=">Subscribe2 WordPress Plugin</a> that gives these features to your WordPress instance.</p>
<p>To install this plugin using WordPress&#8217; automatic plugin installation system, follow these instructions. <a title=\"Subscribe2 installation instructions\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dvcmRwcmVzcy5vcmcvZXh0ZW5kL3BsdWdpbnMvc3Vic2NyaWJlMi9pbnN0YWxsYXRpb24v">Read the plugin&#8217;s installation instruction if you want to do this the manual way</a>:</p>
<blockquote>
<ol>
<li>Log in to your WordPress blog and visit Plugins-&gt;Add New.</li>
<li>Search for Subscribe2, click &#8220;Install Now&#8221; and then Activate the Plugin</li>
<li>Click the &#8220;Settings&#8221; admin menu link, and select &#8220;Subscribe2&#8243;</li>
<li>Configure the options to taste, including the email template and any categories which should be excluded from notification</li>
<li>Click the &#8220;Tools&#8221; admin menu link, and select &#8220;Subscribers&#8221;</li>
<li>Manually subscribe people as you see fit</li>
<li>Create a <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvZGV4LndvcmRwcmVzcy5vcmcvUGFnZXM=">WordPress Page</a> to display the subscription form. When creating the page, you may click the &#8220;S2&#8243; button on the QuickBar to automatically insert the subscribe2 token. Or, if you prefer, you may manually insert the subscribe2 shortcode or token: &#91;subscribe2&#93; or the HTML invisible <strong><em>Ensure the token is on a line by itself and that it has a blank line above and below.</em></strong> This token will automatically be replaced by dynamic subscription information and will display all forms and messages as necessary</li>
<li>In the WordPress &#8220;Settings&#8221; area for Subscribe2 select the page name in the &#8220;Appearance&#8221; section that of the WordPress page created in step 7</li>
</ol>
</blockquote>
<p>On this blog, I called the page created at step #7: <strong>Follow</strong>. Once you are done installing the plugin, you can test it by visiting your Follow page and by entering your own email (one that is not attached to any user of your account is preferable) and by checking in your inbox if you receive a subscription notification. If you haven&#8217;t, you may want to take a look at this <a title=\"Subscribe2 FAQ\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dvcmRwcmVzcy5vcmcvZXh0ZW5kL3BsdWdpbnMvc3Vic2NyaWJlMi9mYXEv">FAQ </a>to debug any possible issue with your outgoing email service.</p>
<h3>Step #2: Customize your Follow Page</h3>
<p>This next step is optional. Since that the form generated by the Subscribe2 plugin is really minimalist, you may want to customize it a little bit, to change its design and to add some explanation in the page, to help your readers to understand what is going on. Take a look at <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL2luZGV4LnBocC9nZXQtZXZlcnktbmV3LXBvc3Qtb24tdGhpcy1ibG9nLWRlbGl2ZXJlZC10by15b3VyLWluYm94Lw==">my own Follow page</a> to see what I did to customize that page.</p>
<h3>Step #3: Add the Follow Button code in you theme</h3>
<p>The third step is really what will morph the Subscribe2 plugin into the Follow Button. What we are doing here, is just to add the code, in your theme, to display the Follow Button.</p>
<p>The first thing you have to do, is to locate where the footer of the pages is generated in the theme. Open the theme folder of your blog: <code>/../wordpress/wp-content/themes/mytheme/</code>. Then you will have to open a few files to check where the <code>&lt;/body&gt;</code> ending HTML tag is generated. The file where that code is generated really depends on how the theme got designed. You can do a search, within all the PHP files in that folder for the string &#8220;<code>&lt;/body&gt;</code>&#8220;. This should give you the answer right away. Once you located that place, you are good to continue with the following instructions.</p>
<p><strong>Important note:</strong> It is possible that your Theme doesn&#8217;t use jQuery by default. If it is the case, then you have to edit the <code>header.php</code> (or whatever the name of the file where the header of your blog is generated) of your theme, and add the following line in the <code>&lt;head&gt;...&lt;/head&gt;</code> section of the page:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container html4strict railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span>”https:<span style="color: #66cc66;">//</span>ajax.googleapis.com<span style="color: #66cc66;">/</span>ajax<span style="color: #66cc66;">/</span>libs<span style="color: #66cc66;">/</span>jquery<span style="color: #66cc66;">/</span>1.6.4<span style="color: #66cc66;">/</span>jquery.min.js” <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span>”<span style="color: #000066;">text</span><span style="color: #66cc66;">/</span>javascript”&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>If you don&#8217;t have jQuery loaded, a JavaScript error will be returned, and the panel will &#8220;freeze&#8221; in the webpage. Once you make sure that jQuery was loaded, do proceed with this code:</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container html4strict railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">style</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screen&quot;</span>&gt;</span><br />
&nbsp; #bit, #bit * {}<br />
&nbsp; #bit {<br />
&nbsp; &nbsp; &nbsp; bottom: -300px;<br />
&nbsp; &nbsp; &nbsp; font: 13px &quot;Helvetica Neue&quot;,sans-serif;<br />
&nbsp; &nbsp; &nbsp; position: fixed;<br />
&nbsp; &nbsp; &nbsp; right: 10px;<br />
&nbsp; &nbsp; &nbsp; z-index: 999999;<br />
&nbsp; &nbsp; &nbsp; width: 230px;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; .loggedout-follow-typekit {<br />
&nbsp; &nbsp; &nbsp; margin-right: 4.5em;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit a.bsub {<br />
&nbsp; &nbsp; &nbsp; background-color: #464646;<br />
&nbsp; &nbsp; &nbsp; background-image: -moz-linear-gradient(center bottom , #3F3F3F, #464646 5px);<br />
&nbsp; &nbsp; &nbsp; background: -webkit-gradient(linear, left top, left bottom, from(#3F3F3F), to(#464646));<br />
&nbsp; &nbsp; &nbsp; filter: &nbsp;progid:DXImageTransform.Microsoft.gradient(startColorstr='#3F3F3F', endColorstr='#464646');&nbsp; &nbsp; <br />
<br />
&nbsp; &nbsp; &nbsp; border: 0 none;<br />
&nbsp; &nbsp; &nbsp; box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.2);<br />
&nbsp; &nbsp; &nbsp; color: #CCCCCC;<br />
&nbsp; &nbsp; &nbsp; display: block;<br />
&nbsp; &nbsp; &nbsp; float: right;<br />
&nbsp; &nbsp; &nbsp; font: 13px/28px &quot;Helvetica Neue&quot;,sans-serif;<br />
&nbsp; &nbsp; &nbsp; letter-spacing: normal;<br />
&nbsp; &nbsp; &nbsp; outline-style: none;<br />
&nbsp; &nbsp; &nbsp; outline-width: 0;<br />
&nbsp; &nbsp; &nbsp; overflow: hidden;<br />
&nbsp; &nbsp; &nbsp; padding: 0 10px 0 8px;<br />
&nbsp; &nbsp; &nbsp; text-decoration: none !important;<br />
&nbsp; &nbsp; &nbsp; text-shadow: 0 -1px 0 #444444;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit a.bsub {<br />
&nbsp; &nbsp; &nbsp; border-radius: 2px 2px 0 0;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit a.bsub span {<br />
&nbsp; &nbsp; &nbsp; background-attachment: scroll;<br />
&nbsp; &nbsp; &nbsp; background-clip: border-box;<br />
&nbsp; &nbsp; &nbsp; background-color: transparent;<br />
&nbsp; &nbsp; &nbsp; background-image: url(&quot;[[PATH-TO-THE-FAMFAM-ICON]]asterisk_orange.png&quot;);<br />
&nbsp; &nbsp; &nbsp; background-origin: padding-box;<br />
&nbsp; &nbsp; &nbsp; background-position: 2px 3px;<br />
&nbsp; &nbsp; &nbsp; background-repeat: no-repeat;<br />
&nbsp; &nbsp; &nbsp; background-size: 20% auto;<br />
&nbsp; &nbsp; &nbsp; padding-left: 18px;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit a:hover span, #bit a.bsub.open span {<br />
&nbsp; &nbsp; &nbsp; /*background-position: 0 -117px;*/<br />
&nbsp; &nbsp; &nbsp; color: #FFFFFF !important;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit a.bsub.open {<br />
&nbsp; &nbsp; &nbsp; background: none repeat scroll 0 0 #333333;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe {<br />
&nbsp; &nbsp; &nbsp; background: none repeat scroll 0 0 #464646;<br />
&nbsp; &nbsp; &nbsp; border-radius: 2px 0 0 0;<br />
&nbsp; &nbsp; &nbsp; color: #FFFFFF;<br />
&nbsp; &nbsp; &nbsp; margin-top: 27px;<br />
&nbsp; &nbsp; &nbsp; padding: 15px;<br />
&nbsp; &nbsp; &nbsp; width: 200px;<br />
&nbsp; &nbsp; &nbsp; float: right;<br />
&nbsp; &nbsp; &nbsp; margin-top: 0;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; div#bitsubscribe.open {<br />
&nbsp; &nbsp; &nbsp; box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe div {<br />
&nbsp; &nbsp; &nbsp; overflow: hidden;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit h3, #bit #bitsubscribe h3 {<br />
&nbsp; &nbsp; &nbsp; color: #FFFFFF;<br />
&nbsp; &nbsp; &nbsp; font-family: &quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;<br />
&nbsp; &nbsp; &nbsp; font-size: 20px;<br />
&nbsp; &nbsp; &nbsp; font-weight: 300;<br />
&nbsp; &nbsp; &nbsp; margin: 0 0 0.5em !important;<br />
&nbsp; &nbsp; &nbsp; text-align: left;<br />
&nbsp; &nbsp; &nbsp; text-shadow: 0 1px 0 #333333;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit #bitsubscribe p {<br />
&nbsp; &nbsp; &nbsp; color: #FFFFFF;<br />
&nbsp; &nbsp; &nbsp; font: 300 15px/1.3em &quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;<br />
&nbsp; &nbsp; &nbsp; margin: 0 0 1em;<br />
&nbsp; &nbsp; &nbsp; text-shadow: 0 1px 0 #333333;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe p a {<br />
&nbsp; &nbsp; &nbsp; margin: 20px 0 0;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bit #bitsubscribe p.bit-follow-count {<br />
&nbsp; &nbsp; &nbsp; font-size: 13px;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe input[type=&quot;submit&quot;] {<br />
&nbsp; &nbsp; &nbsp; -moz-transition: all 0.25s ease-in-out 0s;<br />
&nbsp; &nbsp; &nbsp; -webkit-transition: all 0.25s ease-in-out 0s;<br />
&nbsp; &nbsp; &nbsp; -o-transition: all 0.25s ease-in-out 0s;<br />
&nbsp; &nbsp; &nbsp; -ms-transition: all 0.25s ease-in-out 0s;<br />
&nbsp; &nbsp; &nbsp; transition: all 0.25s ease-in-out 0s; &nbsp; <br />
&nbsp; &nbsp; &nbsp; background: -moz-linear-gradient(center top , #333333 0%, #111111 100%) repeat scroll 0 0 transparent;<br />
&nbsp; &nbsp; &nbsp; background: -webkit-gradient(linear, left top, left bottom, from(#333333), to(#111111));<br />
&nbsp; &nbsp; &nbsp; filter: &nbsp;progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#111111');&nbsp; &nbsp; <br />
<br />
&nbsp; &nbsp; &nbsp; border: 1px solid #282828;<br />
&nbsp; &nbsp; &nbsp; border-radius: 11px 11px 11px 11px;<br />
&nbsp; &nbsp; &nbsp; box-shadow: 0 1px 0 #444444 inset;<br />
&nbsp; &nbsp; &nbsp; color: #CCCCCC;<br />
&nbsp; &nbsp; &nbsp; padding: 2px 20px;<br />
&nbsp; &nbsp; &nbsp; text-decoration: none;<br />
&nbsp; &nbsp; &nbsp; text-shadow: 0 1px 0 #000000;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe input[type=&quot;submit&quot;]:hover {<br />
&nbsp; &nbsp; &nbsp; background: -moz-linear-gradient(center top , #333333 0%, #222222 100%) repeat scroll 0 0 transparent;<br />
&nbsp; &nbsp; &nbsp; box-shadow: 0 1px 0 #4F4F4F inset;<br />
&nbsp; &nbsp; &nbsp; color: #FFFFFF;<br />
&nbsp; &nbsp; &nbsp; text-decoration: none;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe input[type=&quot;submit&quot;]:active {<br />
&nbsp; &nbsp; &nbsp; background: -moz-linear-gradient(center top , #111111 0%, #222222 100%) repeat scroll 0 0 transparent;<br />
&nbsp; &nbsp; &nbsp; box-shadow: 0 -1px 0 #333333 inset;<br />
&nbsp; &nbsp; &nbsp; color: #AAAAAA;<br />
&nbsp; &nbsp; &nbsp; text-decoration: none;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe input[type=&quot;text&quot;] {<br />
&nbsp; &nbsp; &nbsp; border-radius: 3px 3px 3px 3px;<br />
&nbsp; &nbsp; &nbsp; font: 300 15px &quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe input[type=&quot;text&quot;]:focus {<br />
&nbsp; &nbsp; &nbsp; border: 1px solid #000000;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe.open {<br />
&nbsp; &nbsp; &nbsp; display: block;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bsub-subscribe-button {<br />
&nbsp; &nbsp; &nbsp; margin: 0 auto;<br />
&nbsp; &nbsp; &nbsp; text-align: center;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe #bsub-credit {<br />
&nbsp; &nbsp; &nbsp; border-top: 1px solid #3C3C3C;<br />
&nbsp; &nbsp; &nbsp; font: 11px &quot;Helvetica Neue&quot;,sans-serif;<br />
&nbsp; &nbsp; &nbsp; margin: 0 0 -15px;<br />
&nbsp; &nbsp; &nbsp; padding: 7px 0;<br />
&nbsp; &nbsp; &nbsp; text-align: center;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe #bsub-credit a {<br />
&nbsp; &nbsp; &nbsp; background: none repeat scroll 0 0 transparent;<br />
&nbsp; &nbsp; &nbsp; color: #AAAAAA;<br />
&nbsp; &nbsp; &nbsp; text-decoration: none;<br />
&nbsp; &nbsp; &nbsp; text-shadow: 0 1px 0 #262626;<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; #bitsubscribe #bsub-credit a:hover {<br />
&nbsp; &nbsp; &nbsp; background: none repeat scroll 0 0 transparent;<br />
&nbsp; &nbsp; &nbsp; color: #FFFFFF;<br />
&nbsp; }<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">style</span>&gt;</span> &nbsp; &nbsp;<br />
<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">charset</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;utf-8&quot;</span>&gt;</span><br />
&nbsp; jQuery.extend(jQuery.easing, {<br />
&nbsp; &nbsp; &nbsp; easeOutCubic: function (x, t, b, c, d) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return c * ((t = t / d - 1) * t * t + 1) + b;<br />
&nbsp; &nbsp; &nbsp; }<br />
&nbsp; });<br />
&nbsp; jQuery(document).ready(function () {<br />
&nbsp; &nbsp; &nbsp; var isopen = false,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitHeight = jQuery('#bitsubscribe').height();<br />
&nbsp; &nbsp; &nbsp; setTimeout(function () {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit').animate({<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bottom: '-' + bitHeight - 30 + 'px'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 200);<br />
&nbsp; &nbsp; &nbsp; }, 300);<br />
&nbsp; &nbsp; &nbsp; jQuery('#bit a.bsub').click(function () {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isopen) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isopen = true;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit a.bsub').addClass('open');<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit #bitsubscribe').addClass('open')<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit').stop();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit').animate({<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bottom: '0px'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; duration: 400,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; easing: &quot;easeOutCubic&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isopen = false;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit').stop();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit').animate({<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bottom: '-' + bitHeight - 30 + 'px'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 200, function () {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit a.bsub').removeClass('open');<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery('#bit #bitsubscribe').removeClass('open');<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; });<br />
&nbsp; });<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span><br />
<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;bit&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;bsub&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;javascript:void(0)&quot;</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'bsub-text'</span>&gt;</span>Follow<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span><br />
&nbsp; <br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;bitsubscribe&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h3</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;loggedout-follow-field&quot;</span>&gt;</span>Follow this Blog<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h3</span>&gt;</span><br />
&nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[[PATH-TO-YOUR-FOLLOW-WORDPRESS-PAGE]]&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">accept-charset</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;utf-8&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;loggedout-follow&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>Get every new post on this blog delivered to your Inbox.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;bit-follow-count&quot;</span>&gt;</span>Join <span style="color: #009900;">&lt;?php echo $wpdb-&gt;</span>get_var(&quot;SELECT COUNT(id) FROM wp_subscribe2 WHERE active='1'&quot;); ?&gt; other followers:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;email&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;s2email&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;width: 95%; padding: 1px 2px&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Enter email address&quot;</span> <span style="color: #000066;">onfocus</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'this.value=(this.value==&quot;Enter email address&quot;) ? &quot;&quot; : this.value;'</span> <span style="color: #000066;">onblur</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'this.value=(this.value==&quot;&quot;) ? &quot;Enter email address&quot; : this.value;'</span> &nbsp;<span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;loggedout-follow-field&quot;</span><span style="color: #66cc66;">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ip&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;?php echo $_SERVER['REMOTE_ADDR']; ?&gt;</span></span>&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'bsub-subscribe-button'</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;subscribe&quot;</span> &nbsp;<span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Sign me up!&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;padding-top: 10px;&quot;</span>&gt;</span>Or subscribe to the RSS feed by clicking on the counter:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span> &nbsp;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; [[ADD-YOUR-RSS-FEED-LINK-HERE]]<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>The only thing you have to do is to copy/paste that code <strong>above</strong> the <code>&lt;/body&gt;</code> tag. Then, do the following three modifications to properly wire it in your blog:</p>
<ul>
<li>At line #41, replace <code>[[PATH-TO-THE-FAMFAM-ICON]]</code>with the path of the <code>asterisk_orange.png</code> icon, on your blog</li>
<li>At line #211, replace <code>[[PATH-TO-YOUR-FOLLOW-WORDPRESS-PAGE]]</code> by the URL of your <em>Follow</em> page (the one you created when you installed Subscribe2)</li>
<li>At line #228, replace <code>[[ADD-YOUR-RSS-FEED-LINK-HERE]]</code> by the link to your RSS feed</li>
</ul>
<p>You can get the free <code>asterisk_orange.png </code>icon image from the <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5mYW1mYW1mYW0uY29tL2xhYi9pY29ucy9zaWxrLw==">FamFamFam website</a>. The only thing you have to do, is to download that image, and to put it in the folder you defined for <code>[[PATH-TO-THE-FAMFAM-ICON]]</code>. However, you can use whatever image that you prefer, that may better fit the design of your blog.</p>
<h3>Step #4: Disable it For Mobile Devices</h3>
<p>Some mobile devices may have issues displaying this floating window. Sometimes, the window may be floating in the middle of the device&#8217;s screen without folding-back in the bottom of the page. For this reason, you may want to disable (remove) this option if the user is using a mobile device to read your blog. You can easily disable it if the web server detects that a mobile devise is requesting the webpage by adding these two blocks of code.</p>
<p>First, copy and paste this first block of code <strong>above</strong> the code of the Follow button (before line #1):</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container php railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp;<span style="color: #000088;">$useragent</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp;<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i'</span><span style="color: #339933;">,</span><span style="color: #000088;">$useragent</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">||</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i'</span><span style="color: #339933;">,</span><span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$useragent</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp;<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>Then copy and paste this second block of code <strong>below</strong> the code of the follow button (after line #231):</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container php railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>This code come from the <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2RldGVjdG1vYmlsZWJyb3dzZXIuY29tLw==">Detect Mobile Browser project</a> and is the best mobile device detection code I saw so far. What this code does, is not to include the Follow Button if the device that is requesting the webpage is a mobile device. Otherwise, the Follow Button is added to the HTML page.</p>
<h3>Step #5: Test it!</h3>
<p>If you are reading this step #5, it means that you finished to create your own, self-hosted, Follow Button!</p>
<p>Congratulation!</p>
<p>But the last thing that remains to be done, is to test it. Once you saved your file with the code above, just refresh any page of your blog. You should see appearing the Follow button on the bottom-right corner of your blog. If you click on it, you should see the form that let your readers subscribing to the system. If you add one of your emails, and click the subscribe button, you should get redirected to the Follow page. Finally you should receive a confirmation email that ask you to confirm your subscription by clicking on a link.</p>
<p>If all these steps properly works, it means that you are done and ready to provide that new functionality to the readers of your blog!</p>
<h3>Conclusion</h3>
<p>Even if this blog post is few pages long, I hope you found it easy to install and setup. If you have any question regarding this hack, don&#8217;t hesitate to ask them down there, in the comments section of this post. I will be happy to answer all of them.</p>
<p>Happy Hacking!</p>
<p>&nbsp;</p>
<h4>Translations</h4>
<p>This blog post as been translated in Federico Bozo <a title=\"El "Follow Button"de wordpress para usuarios no-wordpress.com\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvcmNob3dlYi5jb20vMjAxMS9zb2x1Y2lvbmVzL2VsLWZvbGxvdy1idXR0b25kZS13b3JkcHJlc3MtcGFyYS11c3Vhcmlvcy1uby13b3JkcHJlc3MtY29tLw==">in Spanish</a>. Other translations will be added to this section.</p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1471" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2011/10/02/wordpresss-follow-button-for-non-wordpress-com-users/feed/</wfw:commentRss>
		<slash:comments>101</slash:comments>
		</item>
		<item>
		<title>Benchmark of PHP&#8217;s main String Search Functions</title>
		<link>http://fgiasson.com/blog/index.php/2011/09/19/benchmark-of-phps-main-string-search-functions/</link>
		<comments>http://fgiasson.com/blog/index.php/2011/09/19/benchmark-of-phps-main-string-search-functions/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 17:57:51 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[structWSF]]></category>
		<category><![CDATA[#code]]></category>
		<category><![CDATA[#optimization]]></category>
		<category><![CDATA[#osf]]></category>
		<category><![CDATA[#php]]></category>
		<category><![CDATA[#umbel]]></category>

		<guid isPermaLink="false">http://fgiasson.com/blog/?p=1249</guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Benchmark of PHP&#8217;s main String Search Functions&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-09-19&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/09/19/benchmark-of-phps-main-string-search-functions/&amp;rft.language=English"></span>
I am currently upgrading the structWSF ontologies related web service endpoints along with the structOntology conStruct module to make them more performing so that we can load ontologies that have thousands of classes and properties (at least up to 30 000 of them). While testing these new upgrades with them UMBEL ontology, I noticed that [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Benchmark of PHP&#8217;s main String Search Functions&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=structWSF&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2011-09-19&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2011/09/19/benchmark-of-phps-main-string-search-functions/&amp;rft.language=English"></span>
<table>
<tbody>
<tr>
<td>I am currently upgrading the <a title=\"structWSF\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL29wZW5zdHJ1Y3RzLm9yZy9zdHJ1Y3R3c2Y=">structWSF</a> ontologies related web service endpoints along with the structOntology <a title=\"conStruct\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2RydXBhbC5vcmcvcHJvamVjdC9jb25zdHJ1Y3Q=">conStruct</a> module to make them more performing so that we can load ontologies that have thousands of classes and properties (at least up to 30 000 of them).</td>
<td valign="top"><div style="margin:10px;overflow:hidden;display:table;line-height:0;text-align:center;width:180px;" class="alignleft"><img class=" size-medium wp-image-1367 shadow_curl" title="benchmark" src="http://fgiasson.com/blog/wp-content/uploads/2011/09/benchmark-300x229.jpg" alt="" width="180" height="137"  style="padding:0 !important; margin:0 !important; max-width:100% !important;"><br/><img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="shadow_img" style="margin:0 !important;height:10px;width:100%;"></div></td>
</tr>
</tbody>
</table>
<p>While testing these new upgrades with them <a title=\"UMBEL Ontology\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VtYmVsLm9yZw==">UMBEL ontology</a>, I noticed that much of the time was spent by a few number of <code>stripos()</code> calls located in the <code>loadXML()</code> function of the <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3N0cnVjdHdzZi9zb3VyY2UvYnJvd3NlL2JyYW5jaGVzL2Rldi9mcmFtZXdvcmsvUHJvY2Vzc29yWE1MLnBocA=="><code>ProcessorXML.php</code></a> internal <a title=\"structXML\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2h3aWtpLm9wZW5zdHJ1Y3RzLm9yZy9pbmRleC5waHAvU3RydWN0WE1M">structXML</a> parser. They were used to extract the prefixes in the header of the structXML files, and then to resolve them into the XML file. I was using <code>stripos()</code> instead of <code>strpos()</code> to make the parsing of these structXML files case-insensitive even if XML is case-sensitive itself. However, due to their processing cost, I did change this behaviors by using the <code>strpos()</code> function instead. Here are the main reasons to this change:</p>
<ul>
<li>XML is itself case-sensitive, so don&#8217;t try to be too clever</li>
<li>These structXML files that are exchanged are mostly internal to structXML</li>
<li>Their parsing performances is critical</li>
</ul>
<h3>The Tests</h3>
<p>This is a non-scientific post about some experimentation I made related to the various PHP 5.3 string search functions. These tests have been performed on a small Amazon EC2 instance using <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5waHAtZGVidWdnZXIuY29tL2RiZy8=">DBG</a> and <a title=\"PhpED\" href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5udXNwaGVyZS5jb20vcHJvZHVjdHMvcGhwZWQuaHRt">PHPeD</a>.</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container php railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; <br />
<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce malesuada aliquet pharetra. Nunc tincidunt tempus eleifend. Cras aliquet risus eget tortor elementum at molestie erat auctor. Sed sapien nulla, auctor a aliquam in, ornare eget enim. Ut ac luctus nunc. Etiam et tortor felis, sed fringilla orci. Fusce laoreet ligula turpis, quis sodales enim. Pellentesque at sapien ut dolor malesuada placerat eu ac quam. Pellentesque purus elit, sodales in fringilla eu, egestas vitae ipsum. Nam condimentum, nisi ac tincidunt luctus, odio erat porta turpis, eget varius felis leo sit amet lorem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas quis pulvinar dui. Integer quis eros nibh. Donec in lectus vitae ligula euismod vulputate ut euismod enim. Ut vehicula, sapien at faucibus ornare, nulla lorem luctus purus, sed imperdiet augue purus quis enim.&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$explodedText</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot; &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">10000</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000088;">$word</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$word</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$explodedText</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #990000;">stripos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #990000;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #990000;">stristr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>The first test uses a text of 138 words. That text get exploded into an array where each value is a word of that text. Then, before each iteration, we randomly select a word that we will search, within the text, using each of the 4 search functions.</p>
<blockquote><p><em>Note that in the result images below, each of the line in the left-most column are the ones of the PHP code above.</em></p></blockquote>
<p>That first test starts with 10 000 iterations. Here are the results of the first run:</p>
<p style="text-align: center;"><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDExLzA5L3Rlc3QxLmdpZg=="><img class="aligncenter size-full wp-image-1275" title="PHP string search test #1" src="http://fgiasson.com/blog/wp-content/uploads/2011/09/test1.gif" alt="" width="450" height="68" /></a><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDExLzA5L3Rlc3QxMS5naWY="><br />
</a></p>
<p>The second test uses the same 138 words, but the test is performed 100 000 times:</p>
<p style="text-align: center;"><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDExLzA5L3Rlc3QyLmdpZg=="><img class="aligncenter size-full wp-image-1285" title="test2" src="http://fgiasson.com/blog/wp-content/uploads/2011/09/test2.gif" alt="" width="450" height="68" /></a></p>
<p>As we can see, <code>strpos()</code> and <code>strstr()</code> are clearly faster than their case-insensitive counterparts.</p>
<p>Now, let&#8217;s see what is the impact of the size of the text to search. We will now perform the two tests with 10 000 and 100 000 iterations but with a text that has 497 words.</p>
<div style="overflow:hidden;; " class="alignnone">
<div class="shadow_curl" style="margin:0 !important; max-width:100% !important;"><div class="codecolorer-container php railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; <br />
<span style="color: #000088;">$longText</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce malesuada aliquet pharetra. Nunc tincidunt tempus eleifend. Cras aliquet risus eget tortor elementum at molestie erat auctor. Sed sapien nulla, auctor a aliquam in, ornare eget enim. Ut ac luctus nunc. Etiam et tortor felis, sed fringilla orci. Fusce laoreet ligula turpis, quis sodales enim. Pellentesque at sapien ut dolor malesuada placerat eu ac quam. Pellentesque purus elit, sodales in fringilla eu, egestas vitae ipsum. Nam condimentum, nisi ac tincidunt luctus, odio erat porta turpis, eget varius felis leo sit amet lorem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas quis pulvinar dui. Integer quis eros nibh. Donec in lectus vitae ligula euismod vulputate ut euismod enim. Ut vehicula, sapien at faucibus ornare, nulla lorem luctus purus, sed imperdiet augue purus quis enim. Nunc eu consectetur quam. Duis nulla sem, tincidunt vel placerat at, ultricies eu est. Vestibulum sed nulla nunc, et tristique orci. Aliquam nulla sapien, lobortis in sagittis vitae, tincidunt ut felis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut condimentum, orci venenatis mollis faucibus, purus enim euismod massa, a imperdiet sapien arcu in sapien. Nulla convallis sodales pretium. Nulla facilisi. Maecenas molestie est tortor. Fusce congue, leo eu tristique sodales, odio leo facilisis lectus, in euismod odio tellus ut sapien. Fusce odio orci, facilisis eu convallis et, consectetur nec mauris. Nullam nulla lacus, volutpat sit amet pulvinar quis, pulvinar eget dolor. Curabitur sit amet odio sem, at dapibus tellus. Donec nec dictum eros. Morbi convallis libero ultrices magna varius suscipit. Duis bibendum volutpat felis non fermentum. Phasellus nunc mi, ornare et vulputate sed, pellentesque sed enim. Mauris suscipit, nisl quis tempor mollis, tortor nunc varius odio, eu dictum odio mi quis sapien. Morbi placerat, erat quis mattis iaculis, urna nisi faucibus nisi, eu mattis elit mauris eu quam. Mauris euismod tincidunt ante quis interdum. Phasellus elementum libero in arcu tempus tincidunt. Praesent in nunc eget nibh porta imperdiet eget eget mauris. Morbi pellentesque dapibus lacus, rutrum sollicitudin nisi fermentum vel. Cras tempor mattis urna, sit amet semper eros varius ut. Fusce erat elit, tempus non commodo et, egestas sit amet odio. Suspendisse libero neque, porttitor vel volutpat eget, placerat in mi. Proin pharetra leo in ligula porttitor vestibulum. Curabitur vel mauris nec lorem sollicitudin porttitor. Sed suscipit, mauris ac sollicitudin tempus, orci velit aliquet leo, vitae ornare mi nulla a tellus. Morbi turpis justo, vestibulum ac auctor sed, vulputate nec nisl. Quisque ut ultricies orci. Sed vel dolor at felis egestas venenatis in ut elit. Nam quis neque sem. Morbi turpis magna, porttitor vulputate dignissim commodo, auctor eu nibh. Ut at nisl tortor. Quisque cursus interdum mi ut molestie. Vivamus nec ipsum ipsum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed quis ipsum erat, quis dignissim nunc. Sed eu diam dapibus tortor fermentum dignissim. Phasellus ac turpis nisl, dictum consequat elit. Suspendisse at turpis quis eros pharetra imperdiet. Mauris ut nisl augue. &quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$explodedLongText</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot; &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$longText</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">500000</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000088;">$word</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$explodedLongText</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #990000;">stripos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #990000;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #990000;">stristr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<img src="http://fgiasson.com/blog/wp-content/plugins/shadows/shadow_curl.png" class="aligncenter shadow_img" style="margin:0 !important;height:10px;width:100%;"></div>
</div>
<p>That third test starts with 10 000 iterations. Here are the results of the third run:</p>
<p style="text-align: center;"><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDExLzA5L3Rlc3QzLmdpZg=="><img class="aligncenter size-full wp-image-1286" title="test3" src="http://fgiasson.com/blog/wp-content/uploads/2011/09/test3.gif" alt="" width="450" height="68" /></a></p>
<p>The fourth test uses the same 497 words, but the test is performed 100 000 times:</p>
<p style="text-align: center;"><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDExLzA5L3Rlc3Q0LmdpZg=="><img class="aligncenter size-full wp-image-1287" title="test4" src="http://fgiasson.com/blog/wp-content/uploads/2011/09/test4.gif" alt="" width="450" height="68" /></a></p>
<p>As we can see, even if we add more words, the same kind of performances are experienced.</p>
<h3>Conclusion</h3>
<p>After many runs (I only demonstrated a few here). I think I can affirm that <code>strpos()</code> and <code>strstr()</code> are way faster than their case-insensitive counterparts. However, <code>strpos()</code> seems a little bit faster than <code>strstr()</code>, but it seems to depends of the context, and which random words are being searched for. In any cases, according to PHP&#8217;s documentation, we should always use <code>strpos()</code> instead of <code>strstr()</code> because it supposedly use less memory.</p>
<p>There may also be some unknown memory considerations that may affect the code I used to test these functions. In any case, I can affirm that in a real context, where queries are sent to the Ontology: Read web service endpoint that hosts the UMBEL ontology, that <code>strpos()</code> is a way faster than <code>stripos()</code>.</p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1249" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2011/09/19/benchmark-of-phps-main-string-search-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack for the encoding of a URL into another URL problem with Apache and mod_rewrite</title>
		<link>http://fgiasson.com/blog/index.php/2006/07/19/hack_for_the_encoding_of_url_into_url_pr/</link>
		<comments>http://fgiasson.com/blog/index.php/2006/07/19/hack_for_the_encoding_of_url_into_url_pr/#comments</comments>
		<pubDate>Wed, 19 Jul 2006 20:49:40 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Hack for the encoding of a URL into another URL problem with Apache and mod_rewrite&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=Web&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2006-07-19&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2006/07/19/hack_for_the_encoding_of_url_into_url_pr/&amp;rft.language=English"></span>
&#160; While configuring my new dedicated server to support the new generation of Talk Digger, I encountered a really strange bug that emerged with the interaction of urlencode(), Apache and mod_rewrite. It took me about a working day to figure out what was the bug, where it could come from, searching information to know if [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Hack for the encoding of a URL into another URL problem with Apache and mod_rewrite&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=Web&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2006-07-19&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2006/07/19/hack_for_the_encoding_of_url_into_url_pr/&amp;rft.language=English"></span>
<p>&nbsp;</p>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><img src="http://fgiasson.com/blog/media/apache.jpeg" /></td>
<td>
While configuring my new dedicated server to support the new generation of Talk Digger, I encountered a really strange bug that emerged with the interaction of urlencode(), Apache and mod_rewrite.
</td>
</tr>
</table>
<p>It took me about a working day to figure out what was the bug, where it could come from, searching information to know if I am the only one on earth to have it, fixing it, etc. </p>
<p>I found out that I was not the only one to have that bug, but I never found any reliable source of information to fix it. Because I am using Open Source softwares, I think it is my duty to post the fix somewhere on the Web and this &#8220;somewhere&#8221; is on my blog. Normally I do not post such technical articles, but considering that it is an interesting bug, that many people expect it and that there is no central source of information that explain how to fix it from A to Z, so I decided to take a couple of minutes to write that article.</p>
<p>&nbsp;</p>
<p><strong>What is the context?</strong></p>
<p>I have to encode a URL into another URL.</p>
<p>For example, I would like to encode that url:</p>
<p>www.test.com/test.com?test=1&amp;test2=2</p>
<p>Into that other url:</p>
<p>www.foo.com/directory/www.test.com/test.com?test=1&amp;test2=2</p>
<p>To do that, I have to encode the first url; the result would be:</p>
<p>www.foo.com/directory/www.test.com%2Ftest.com?test=1&amp;test2=2</p>
<p>&nbsp;</p>
<p><strong>What is the bug?</strong></p>
<p>The problem we have is that when you try to apply RewriteRule(s) to these URL using Apache (1.3) and the mod_rewrite module, mod_rewrite will not be able match any of its rules with that url.</p>
<p>By example, if I have a rule like:</p>
<p>RewriteRule    ^directory/(.*)/?$  directory/redirect.php?url=$1  [L]</p>
<p>mod_rewrite will not be able match the rule with the URL even if it matches. The problem, as cited above, is the encoding process of URLs between Apache and mod-rewrite.</p>
<p>&nbsp;</p>
<p><strong>The explanation</strong></p>
<p>The problem seems to be that the url passed to mod_rewrite seem prematurely unencoded. With a single encoding (urlencode( ) in PHP) of a URL, the RewriteRule(s) will not be matched if the &#8220;%2F&#8221; character is in the URL, or if it is (no %2F character in the url) then the substitution will not be necessarily completed.</p>
<p>After having identified the problem I found the bug entry of the problem: <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2lzc3Vlcy5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0zNDYwMg==">ASF Bugzilla Bug 34602</a></p>
<p>It is the best source I found, but it was not complete to resolve the problem I had.</p>
<p>&nbsp;</p>
<p><strong>The simplest hack, but the ugliest!</strong></p>
<p>The simplest fix is to double encode the url you want to include in your other url. (by example, in php I would encode my url with: urlencode(urlencode(&#8220;www.test.com/test.com?test=1&amp;test2=2&#8221; )); ). That way, everything will work fine with mod_rewrite and it will match the rule.</p>
<p>The problem with that easy fix is that it adds a lot of ugly characters in your URL. Personally I find that unacceptable, especially when we know that mod_rewrite is there to create beautiful URL!</p>
<p>&nbsp;</p>
<p><strong>The second hack</strong></p>
<p>The second fix is to re-encode the url directly in the mod_rewrite module. We will re-encode all the url at the exception of the &#8220;%2F&#8221; character (because it is a glitch (bug?) not related with mod_rewrite but probably Apache itself). What you have to do is to create you own urlencode( ) method to encode all characters except &#8220;/&#8221;. That way everything will works as normally, except that the &#8220;/&#8221; character will not be encoded.</p>
<p>&nbsp;</p>
<p><strong>Security related to that hack</strong></p>
<p>I don&#8217;t think this fix add a security hole if we think about code injection in URL or other possible hole. I&#8217;ll have to further analyze that point to make sure of that.</p>
<p>&nbsp;</p>
<p><strong>Future work</strong></p>
<p>In the future it would be great to find where in Apache the &#8220;/&#8221; (%2F) character is prematurely decoded, or where we could encode it just before it is passed to mod_rewrite.</p>
<p>&nbsp;</p>
<p><strong>THE HACK</strong></p>
<p>Okay, there is how to install that hack on your web server.</p>
<p>I only tested it on Apache 1.3.36 and mod_rewrite. I have no idea if the same problem occurs with Apache 2.</p>
<p>&nbsp;</p>
<p><strong>Step #1</strong></p>
<p>The first step is to create your own urlencode( ) function that will encode a url without encoding the &#8220;/&#8221; character. A simple PHP function that would do the job could be (it is really not efficient, but it will do the job for now):</p>
<blockquote><p>function url_encode($url)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return str_replace(&#8220;%2F&#8221;, &#8220;/&#8221;, urlencode($url));<br />
}</p></blockquote>
<p>&nbsp;</p>
<p><strong>Step #2</strong></p>
<p>The second step is to change the code in mod_rewrite.c to re-encode the url.</p>
<p>You have to replace the mod_rewrite.c file into Apache&#8217;s source code at [/apache_1.3.36/src/modules/standard/] by this one:</p>
<blockquote><p><center><strong><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZnaWFzc29uLmNvbS9ibG9nL21lZGlhL21vZF9yZXdyaXRlLmM=">The hacked mod_rewrite.c file</a></strong></center></p></blockquote>
<p>&nbsp;</p>
<p><strong>Step #3</strong></p>
<p>Then you have to recompile/re-install your Apache web server.</p>
<p>&nbsp;</p>
<p><strong>Finished</strong></p>
<p>Everything should now work fine. In your server-side scripts (PHP for example), you will have to encode your url with the new url_encode( ) function. Then everything will work just fine with mod_rewrite and it will matches the rules as expected.</p>
<p>&nbsp;</p>
<p><strong>The last word</strong></p>
<p>I hope that this little tutorial will help you if you have the same problem as I had. Please point me any error/upgrade/code-enhancement in the comment section of that post, it will be really appreciated!</p>
<p><font face="Arial, Helvetica, sans-serif" size="-2">Technorati:   <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9tb2RfcmV3cml0ZQ==" rel=\"tag\" target=\"_blank\">mod_rewrite</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9hcGFjaGU=" rel=\"tag\" target=\"_blank\">apache</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9idWc=" rel=\"tag\" target=\"_blank\">bug</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9oYWNr" rel=\"tag\" target=\"_blank\">hack</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9maXg=" rel=\"tag\" target=\"_blank\">fix</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy91cmw=" rel=\"tag\" target=\"_blank\">url</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9lbmNvZGU=" rel=\"tag\" target=\"_blank\">encode</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy91cmxlbmNvZGU=" rel=\"tag\" target=\"_blank\">urlencode</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9waHA=" rel=\"tag\" target=\"_blank\">php</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9lc3BhY2U=" rel=\"tag\" target=\"_blank\">espace</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9vcGVu" rel=\"tag\" target=\"_blank\">open</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9zb3VyY2U=" rel=\"tag\" target=\"_blank\">source</a> | </font></p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=714" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2006/07/19/hack_for_the_encoding_of_url_into_url_pr/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>I am neither a painter nor a writer: I am a software designer</title>
		<link>http://fgiasson.com/blog/index.php/2006/04/09/i_am_neither_a_painter_nor_a_writer_i_am/</link>
		<comments>http://fgiasson.com/blog/index.php/2006/04/09/i_am_neither_a_painter_nor_a_writer_i_am/#comments</comments>
		<pubDate>Sun, 09 Apr 2006 14:03:36 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=I am neither a painter nor a writer: I am a software designer&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2006-04-09&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2006/04/09/i_am_neither_a_painter_nor_a_writer_i_am/&amp;rft.language=English"></span>
Will software design and development ever will be part of art schools? I doubt it, but why not? After all designing pieces of software is not only technique&#8230; it&#8217;s art. Like a writer, a painter or a sculptor, software designers use tools to make their ideas real: to share them with other people. Right now [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=I am neither a painter nor a writer: I am a software designer&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2006-04-09&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2006/04/09/i_am_neither_a_painter_nor_a_writer_i_am/&amp;rft.language=English"></span>
<p><strong>Will software design and development ever will be part of art schools?</strong> I doubt it, but why not? After all <strong>designing pieces of software is not only technique&#8230; it&#8217;s art</strong>. Like a writer, a painter or a sculptor, software designers use tools to make their ideas real: to share them with other people.</p>
<p>Right now I am prototyping ideas I have for enhancing Talk Digger. My creation process is much more like that of a writer than that of a software developer, an uber-geek.</p>
<p><strong>Ideas</strong> pass through my mind; I muse about their utility; I prototype them; I test them; I use them; I play with them; I talk about them with other people; I get feedbacks I integrate these feedbacks into my idea; I change my ideas; I change my works; I delete some prototypes; I go with the flow of my ideas and their <strong>evolution</strong>.</p>
<p><strong>This is my work.</strong></p>
<p>Sure there are rigid procedures in software development. Yeah there are procedures to design, develop, debug and support software development. Yeah you have to write specifications; yeah you have to perform test cases; yeah you have to do all that &#8230; and much more.</p>
<p>However, what I am talking about is the first process, <strong>the creative process</strong>, the one wherein the technical knowledge does not really matter, the one that will make your software usable; the one that will be so intuitive to use that nobody will think about it but will only think about what they have to do; the one that will help users save time when performing their work. No one needs technical knowledge to develop such software. What he needs is creativity: he needs to be an artist.</p>
<p>It is what I am doing right now. It is the reason why I am not writing that much. I am in a sort of creative mood where I prototype my ideas to make Talk Digger bigger, better and more useful. I try to do these things to achieve Talk Digger&#8217;s goal: (1) gathering the best information, (2) archiving it in the best way, (3) displaying it in a most meaningful way, (4) thinking about the best ways users could interact together, (5) having fun doing it.</p>
<p>What is Talk Digger&#8217;s goal: finding, tracking and entering conversations evolving on the Internet.</p>
<p>When I am <strong>prototyping some of my ideas</strong>, most of the time the &#8220;final&#8221; prototype, the one that has some real potential, is not what I was thinking about when I started developing it. Most of the time it is something that evolved during my development. It evolved with new ideas I had while writing it, using it, contemplating it. This step was crucial, otherwise I would never had these ideas that make a first good idea, a final really good one (it is what I think and what I hope, however it is up to the users to confirm or not whether my final really good idea was in fact that good).</p>
<p>It is certain that when I will have finished these prototypes, when I will start developing the real system, that I will use all the techniques I know to make that application scalable: it is more than essential. However, I think that some developers, and many of their bosses, forget the importance of the creativity process in software development: how the first steps are so important to create an application that will reach the tipping point with users.</p>
<p>I hope that computer sciences degrees add an &#8220;art and creativity&#8221; course into their courses corpus.</p>
<p><font face="Arial, Helvetica, sans-serif" size="-2">Technorati:   <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9EZXZlbG9wbWVudA==" rel=\"tag\" target=\"_blank\">Development</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9zb2Z0d2FyZQ==" rel=\"tag\" target=\"_blank\">software</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9hcnQ=" rel=\"tag\" target=\"_blank\">art</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9pbWFnaW5hdGlvbg==" rel=\"tag\" target=\"_blank\">imagination</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9jcmVhdGl2aXR5" rel=\"tag\" target=\"_blank\">creativity</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy90ZWNobmlxdWU=" rel=\"tag\" target=\"_blank\">technique</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9zeXN0ZW0=" rel=\"tag\" target=\"_blank\">system</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy90YWxrZGlnZ2Vy" rel=\"tag\" target=\"_blank\">talkdigger</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9hcnRpc3Q=" rel=\"tag\" target=\"_blank\">artist</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9wcm90b3R5cGU=" rel=\"tag\" target=\"_blank\">prototype</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy90ZXN0" rel=\"tag\" target=\"_blank\">test</a> | </font></p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=649" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2006/04/09/i_am_neither_a_painter_nor_a_writer_i_am/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Review of Foundations of Ajax</title>
		<link>http://fgiasson.com/blog/index.php/2005/10/09/review_of_foundations_of_ajax/</link>
		<comments>http://fgiasson.com/blog/index.php/2005/10/09/review_of_foundations_of_ajax/#comments</comments>
		<pubDate>Sun, 09 Oct 2005 21:09:21 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Review of Foundations of Ajax&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=Web&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2005-10-09&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2005/10/09/review_of_foundations_of_ajax/&amp;rft.language=English"></span>
Ajax interactive interface techniques are a spreading everywhere since the arrival of web applications like Google Suggest, Google Maps, GMail and many other high profiled web applications. It is even truer considering that Ajax techniques are intimately bounded with the most popular Web 2.0 applications. Despite the fact that the term is used everywhere and [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Review of Foundations of Ajax&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=Web&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2005-10-09&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2005/10/09/review_of_foundations_of_ajax/&amp;rft.language=English"></span>
<p>Ajax interactive interface techniques are a spreading everywhere since the arrival of web applications like <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5nb29nbGUuY29tL3dlYmhwP2NvbXBsZXRlPTEmYW1wO2hsPWVu">Google Suggest</a>, <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21hcHMuZ29vZ2xlLmNvbS8=">Google Maps</a>, <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2dtYWlsLmNvbQ==">GMail</a> and many other high profiled web applications. It is even truer considering that Ajax techniques are intimately bounded with the most popular <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9XZWJfMi4w">Web 2.0</a> applications. </p>
<p>Despite the fact that the term is used everywhere and that more and more web developers are using its techniques, Ajax remain mysterious and his techniques misused and sometime obscure. Dedicated web sites to Ajax&#8217;s development are opening and people start to standardize its development techniques and deployment.</p>
<p>If you start checking how to develop Ajax applications, and think that Ajax is a Greco legendary warrior, you will probably be lost in all the paths you searches will lead you. It is not an easy task, at first, to know what Ajax is and is not. Many web technologies are implied in Ajax application development like: JavaScript, XML, server-side programming languages, many different browser technologies, etc. Trying to make some order in all this information is a daunting task.</p>
<p>Mrs. Parker of <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5hcHJlc3MuY29tLw==">Apress</a> contacted me last week to ask me if I would like to review one of their new books: <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5hcHJlc3MuY29tL2Jvb2svYm9va0Rpc3BsYXkuaHRtbD9iSUQ9MTAwNDI=">Foundations of Ajax</a>. Considering what I said before on current state of Ajax development techniques&#8217; documentation, I naturally said yes. I would had like to read that book before starting to develop Talk Digger, the Ajax interface&#8217;s development pain would had been greatly diminished. My goal by reviewing this book is: helping you to find the right tools and techniques to start on the right foot when developing web interfaces using Ajax techniques.</p>
<p><strong>To whom the book is intended?</strong></p>
<p>The book is intended to intermediate and expert web developers. The premise of the authors is that you already developed and implemented web sites and applications. They will not spend time to teach you what a server-side programming language is or how to create a function in JavaScript; they will teach you what are the best Ajax techniques and  the available tools.</p>
<p><strong>Where Ajax came from?</strong></p>
<p>The first chapter is dedicated to the history of Ajax: where it came from and what motivated the development of technologies supporting it. The history of Ajax is the history of the evolution of web applications: CGI, Applets, Java, Netscape, the browsers war, servlets, server-side programming languages, Flash, DOM, DHTML, XML, etc. </p>
<p>How Ajax emerged from this evolution line? How should I use it? What do I need to know prior starting to develop Ajax applications? What do I need take into consideration when starting the design of my next Ajax application? All these questions will be clearly answered by the authors.</p>
<p><strong>I want asynchronism</strong></p>
<p>The most important feature of Ajax techniques is the possibility given to a web browser to asynchronously interact with a web server using an object called XMLHttpRequest. What it is all about? Which possibilities this object gives you? How could you use it to enhance the usability of you web site?</p>
<p><strong>Then, what do I do with that information?</strong></p>
<p>Once you mastered the asynchronous interaction between your application and a web server, you have to master the techniques to dynamically change the content of a web page. You have to take the received information and display it to the user by changing the DOM document of the web page. The authors will explain how a DOM document works and how to modify them to make a web page dynamics.</p>
<p>Many basic Ajax techniques used on popular websites are then explained: how to validate code, how to create an auto-refreshing web page, how to display a progress bar, how to create tooltips, how to automatically update a webpage, how to access a web-service, and how to create an auto-completion combo-box. </p>
<p>At that point you have all the knowledge necessary to create Ajax applications. The only other thing will you need is imagination and creativity to make all these things interacting together in such a way that people will say: &#8216;Wow!&#8217; when they will use your interface.</p>
<p><strong>I learned how to develop Ajax applications &#8211; now what are the tools that can help me to develop web applications with Ajax techniques?</strong></p>
<p>Any developer wants a development environment with the best development tools. They want these tools to help them to quickly write better code. This is the exact purpose of the second part of the book: creating a toolbox for Ajax developers. The authors will describe the best available tools, what they are used for, and what is the best way to use them to develop Ajax applications.</p>
<p>You will find tools to write documentation on your JavaScript scripts, to validate the content of your HTML files, to inspect your DOM documents, and to compress and obfuscate your JavaScript code.</p>
<p>A whole chapter is dedicated on JSUnit: a unit-testing program for JavaScript. They explain how to install and use it. You think that you are losing your time implementing unit tests into your applications? Well, it depends on the length and complexity of the project you are working on. However, more often then not, you will save a lot of time on the long run. It helps you to validate that the new changes you do in one script do not affect any other functionalities of your web application before putting the modification online. Do not forget, we are talking about a web application: as soon as you save it on the web server the modifications are took into account by all users.</p>
<p>Finally, what would be a developer&#8217;s toolbox without debugging capabilities? Nothing. JavaScript debuggers for both FireFox and Internet Explorer are described at length. </p>
<p><strong>Conclusion</strong></p>
<p>What I liked while reading this book is that the authors tell you the truth about the current state of Ajax applications&#8217; developing. Technologies that support Ajax are old, but their interactions are young. I expected, and always expect, various programming errors and problems on many web browsers while developing <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy50YWxrZGlnZ2VyLmNvbQ==">Talk Digger</a> or <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5sZWt0b3JhLmNvbQ==">Lektora</a>. Many times you have to use some programming tricks to make it works the same way on all the available browsers on the market. I can&#8217;t hide it to you: it is sometime a real pain. The authors are aware of that situation and tell it to you without reserve.</p>
<p>This is a definitive book for web developers having to spring into Ajax&#8217;s application development world. It will show you the most effective programming techniques, tips, and tricks to create interactive web pages. It will explain you how to use the best free available tools to create your Ajax developer&#8217;s toolbox. It is an interesting reading striped of any fluff with an incalculable number of illustrations and examples.</p>
<div class="tags">tags technorati : <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9BamF4" rel=\"tag\">Ajax</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9wcm9ncmFtbWluZw==" rel=\"tag\">programming</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9kZXZlbG9wbWVudA==" rel=\"tag\">development</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9hcHJlc3M=" rel=\"tag\">apress</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9ib29r" rel=\"tag\">book</a> <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9mb3VuZGF0aW9u" rel=\"tag\">foundation</a> </div>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=477" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2005/10/09/review_of_foundations_of_ajax/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Ajax and the Semantic Web</title>
		<link>http://fgiasson.com/blog/index.php/2005/09/26/ajax_and_the_semantic_web/</link>
		<comments>http://fgiasson.com/blog/index.php/2005/09/26/ajax_and_the_semantic_web/#comments</comments>
		<pubDate>Tue, 27 Sep 2005 01:56:38 +0000</pubDate>
		<dc:creator>Frederick Giasson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Ajax and the Semantic Web&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=Semantic Web&amp;rft.subject=Web&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2005-09-26&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2005/09/26/ajax_and_the_semantic_web/&amp;rft.language=English"></span>
Ajax and the Semantic Web: currently two buzz terms; one that describe a new way to create interactive web interface; the other that describe documents in such a way that computers could &#8220;understand&#8221; their semantic meaning. Tim Berners-Lee wrote something interesting: RDF-AJAX: 7 letters that open a window on a new world. We have two [...]]]></description>
			<content:encoded><![CDATA[	
	<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&amp;rfr_id=info%3Asid%2Focoins.info%3Agenerator&amp;rft.title=Ajax and the Semantic Web&amp;rft.aulast=Giasson&amp;rft.aufirst=Frederick&amp;rft.subject=Programming&amp;rft.subject=Semantic Web&amp;rft.subject=Web&amp;rft.source=Frederick Giasson&#8217;s Weblog&amp;rft.date=2005-09-26&amp;rft.type=blogPost&amp;rft.format=text&amp;rft.identifier=http://fgiasson.com/blog/index.php/2005/09/26/ajax_and_the_semantic_web/&amp;rft.language=English"></span>
<p><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BamF4XyUyOHByb2dyYW1taW5nJTI5">Ajax</a> and the <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TZW1hbnRpY193ZWI=">Semantic Web</a>: currently two buzz terms; one that describe a new way to create interactive web interface; the other that describe documents in such a way that computers could &#8220;understand&#8221; their semantic meaning.</p>
<p><a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5jb25zb3J0aXVtaW5mby5vcmcvYnVsbGV0aW5zL3NlbWFudGljd2ViLnBocA==">Tim Berners-Lee wrote something interesting: RDF-AJAX</a>: 7 letters that open a window on a new world. We have two layers: one that shows things (Ajax), and the other that describe, by their semantic meaning, things (Semantic Web document).</p>
<p><center><br />
<img src="http://fgiasson.com/blog/media/ajax-rdf.gif" border="0" alt="" /><br />
</center></p>
<p>You have to see the interactions of these two layers as the man-machine interactions. The Ajax layer will read a Semantic Web Document (RDF, for example) and make it human readable. The document will be computer readable by other software agents.</p>
<p>Big deal, you are thinking? Think about it. Right now, databases information is serialized in HTML files to help human to read and understand its information. Good, however, what happen if I wish to create a software agent to help me to automate some processes? There is the big deal. What I want is to serialize the databases information in Semantic Web formats, like RDF, instead of HTML. That way, the information help in these databases will be computer readable and understandable. Then, the problem is that I will not be, anymore, able to read and understand these big chunks of RDF documents.</p>
<p>There is the utility of the Ajax layer: to make RDF, or any other Semantic Web format, documents human readable. We could use an Ajax library that would understand RDF documents, and display their content in a browser. That way a single web page could be both processed by computers and humans. The Web would not be composed of HTML documents anymore, but Semantic Web formats ones. </p>
<p>There is another view of the future Web.</p>
<p><font face="Arial, Helvetica, sans-serif" size="-2">Technorati:   <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy93ZWIyLjA=" rel=\"tag\" target=\"_blank\">web2.0</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9zZW1hbnRpYw==" rel=\"tag\" target=\"_blank\">semantic</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy93ZWI=" rel=\"tag\" target=\"_blank\">web</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9mdXR1cmU=" rel=\"tag\" target=\"_blank\">future</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9hamF4" rel=\"tag\" target=\"_blank\">ajax</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9yZGY=" rel=\"tag\" target=\"_blank\">rdf</a> | <a href="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RlY2hub3JhdGkuY29tL3RhZy9vbnRvbG9naWVz" rel=\"tag\" target=\"_blank\">ontologies</a> | </font></p>
 <img src="http://fgiasson.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=470" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://fgiasson.com/blog/index.php/2005/09/26/ajax_and_the_semantic_web/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (Requested URI is rejected)
Database Caching 13/19 queries in 0.013 seconds using disk: basic

Served from: fgiasson.com @ 2012-05-23 08:07:02 -->
