<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>chuyeow.wtf</title>
  <subtitle>Go, Ruby, Rails, Firefox, Anime, Mac</subtitle>
  <link rel="self" type="application/atom+xml" href="https://chuyeow.wtf/categories/web-development/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://chuyeow.wtf"/>
  <generator uri="https://www.getzola.org/">Zola</generator>
  <updated>2009-11-25T19:13:21+00:00</updated>
  <id>https://chuyeow.wtf/categories/web-development/feed.xml</id>
  <entry>
    <title>Firefox quick tip: view images in a new tab quickly</title>
    <published>2009-11-25T19:13:21+00:00</published>
    <updated>2009-11-25T19:13:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2009/11/25/firefox-quick-tip-view-images-in-a-new-tab-quickly/"/>
    <id>https://chuyeow.wtf/2009/11/25/firefox-quick-tip-view-images-in-a-new-tab-quickly/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2009/11/25/firefox-quick-tip-view-images-in-a-new-tab-quickly/">&lt;p&gt;A mini-tip on viewing images quickly in a new tab in Firefox. Useful for web devs who want to look at the URL of an image quickly.&lt;&#x2F;p&gt;
&lt;p&gt;As an example, here&#x27;s the &lt;a href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;user&#x2F;mugumogu&quot;&gt;Youtube webpage&lt;&#x2F;a&gt; of the owner of &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Maru_the_Cat&quot;&gt;Maru the Cat&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;ff3-middle-click-step-1.png&quot; alt=&quot;ff3-middle-click-step-1&quot; title=&quot;ff3-middle-click-step-1&quot; width=&quot;320&quot; height=&quot;148&quot; class=&quot;alignnone size-full wp-image-1186&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To open the thumbnail image of Maru in a new tab, right-click the image, and then &lt;strong&gt;middle-click&lt;&#x2F;strong&gt; the &lt;strong&gt;View Image&lt;&#x2F;strong&gt; item from the context menu:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;ff3-middle-click-step-2.png&quot; alt=&quot;ff3-middle-click-step-2&quot; title=&quot;ff3-middle-click-step-2&quot; width=&quot;416&quot; height=&quot;222&quot; class=&quot;alignnone size-full wp-image-1185&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It should open up in a new tab:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;ff3-middle-click-step-3.png&quot; alt=&quot;ff3-middle-click-step-3&quot; title=&quot;ff3-middle-click-step-3&quot; width=&quot;507&quot; height=&quot;226&quot; class=&quot;alignnone size-full wp-image-1184&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can also do the same for background images (middle-click &lt;strong&gt;View Background Image&lt;&#x2F;strong&gt; from the right-click context menu).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New in Rails: ActiveResource timeouts and why it matters</title>
    <published>2008-04-22T22:25:57+00:00</published>
    <updated>2008-04-22T22:25:57+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/"/>
    <id>https://chuyeow.wtf/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/">&lt;p&gt;If you&#x27;ve ever used ActiveResource or for that matter, coded anything that involves interacting with a remote API, you&#x27;ve probably had the misfortune of having that API go down or become unresponsive. The experienced old geezers would already have forseen the problem and set a timeout on those API calls. For the rest of us, it&#x27;s a good time to get acquainted with the idea of &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fail-fast&quot;&gt;fail-fast&lt;&#x2F;a&gt; and how &lt;em&gt;no response is better than a slow response&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So what happens when the API you&#x27;re accessing via ActiveResource or &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; (or whatever, really, so long as there&#x27;s a network socket involved!) becomes unresponsive?&lt;&#x2F;p&gt;
&lt;h3&gt;Unfettered outbound remote connections can kill your server&lt;&#x2F;h3&gt;
&lt;p&gt;ActiveResource (or &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; or whatever you&#x27;re using) would block while waiting for the API to return. What did we learn about blocking IO in Operating Systems 101? That your process or thread gets stuck waiting for a response that&#x27;s what. So now your Mongrel&#x2F;Thin&#x2F;Ebb&#x2F;X web server process basically stuck waiting for a response from an API that might return a response in 30 seconds, or maybe it&#x27;ll never return at all. It won&#x27;t be long before all your web server processes get blocked and its time to &quot;kill dash nine&quot; (&lt;code&gt;kill -9&lt;&#x2F;code&gt;) some processes and bring out the 500 error page. Yes, your server has been incapacitated and your website is now basically offline.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;im-in-ur-serverz.gif&quot; alt=&quot;im in ur serverz making thingz better&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Timeouts and you&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;re using Net::HTTP you can easily safeguard yourself against errors like this by setting a timeout on the socket connection. Like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def fetch_something_from_some_api(uri)
  http = Net::HTTP.new(uri.host, uri.port)
  http.read_timeout = timeout
&lt;p&gt;response = http.start { http.request(Net::HTTP::Get.new(&quot;#{uri.path}?#{uri.query}&quot;)) }
response.is_a?(Net::HTTPSuccess) ? do_something_with(response.body) : nil
rescue Timeout::Error
logger.warn(&quot;Timeout accessing #{uri}: #{$!}&quot;)
nil
rescue
logger.warn(&quot;Error accessing #{uri}: #{$!}&quot;)
nil
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take note that you really do need to explicitly rescue from the &lt;code&gt;Timeout::Error&lt;&#x2F;code&gt; (or &lt;code&gt;Interrupt&lt;&#x2F;code&gt;) since it&#x27;s a child of the &lt;code&gt;Interrupt&lt;&#x2F;code&gt; class and not a &lt;code&gt;StandardError&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Any good client library should also allow you to specify a timeout on the socket connection so read the API documentation.&lt;&#x2F;p&gt;
&lt;h3&gt;So what&#x27;s this about ActiveResource?&lt;&#x2F;h3&gt;
&lt;p&gt;So back to ActiveResource: Michael Koziarski was kind enough to commit my 2 patches (&lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;105910429d5873dce677ef32eef5f705e0625d86&quot;&gt;this&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;cf32baf915442ffe153ec0e4d8148f147776c30a&quot;&gt;this&lt;&#x2F;a&gt;) to ActiveResource so now on &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;tree&#x2F;master&quot;&gt;edge Rails&lt;&#x2F;a&gt;, you can do this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Person &amp;lt; ActiveResource::Base
  self.site = &#x27;http:&#x2F;&#x2F;api.people.com:3000&#x2F;&#x27;
  self.timeout = 5
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This sets the timeout to 5 seconds on the underlying &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; instance that ActiveResource uses. The default timeout (to be exact, the &lt;code&gt;read_timeout&lt;&#x2F;code&gt;) for &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; is &lt;strong&gt;60 seconds&lt;&#x2F;strong&gt; on most Ruby implementations (that includes MRI). That&#x27;s far too long if your ActiveResource call is in a public-facing controller!&lt;&#x2F;p&gt;
&lt;p&gt;If you are using ActiveResource anywhere and haven&#x27;t safeguarded your application with a timeout, I think it&#x27;s a good idea to fix it by using edge Rails or at least applying the &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;105910429d5873dce677ef32eef5f705e0625d86&quot;&gt;patch&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;cf32baf915442ffe153ec0e4d8148f147776c30a&quot;&gt;2nd ActiveResource patch&lt;&#x2F;a&gt; introduces the &lt;code&gt;ActiveResource::TimeoutError&lt;&#x2F;code&gt; exception that you should rescue from whenever you make an ActiveResource call. When this happens, it&#x27;s up to your application to decide what to do (like show a placating we&#x27;re sorry message). At least your application is still able to do something!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Generating migrations gets easier - Rails 2.0 a feature a day #6</title>
    <published>2007-12-24T16:58:07+00:00</published>
    <updated>2007-12-24T16:58:07+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/24/generating-migrations-gets-easier-rails-20-a-feature-a-day-6/"/>
    <id>https://chuyeow.wtf/2007/12/24/generating-migrations-gets-easier-rails-20-a-feature-a-day-6/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/24/generating-migrations-gets-easier-rails-20-a-feature-a-day-6/">&lt;p&gt;You may not have noticed this yet, but Rails 2.0 has a new convenient syntax for generating ActiveRecord migrations. Go ahead, run the migration generator with &lt;code&gt;script&#x2F;generate migration&lt;&#x2F;code&gt;. I&#x27;ll wait.&lt;&#x2F;p&gt;
&lt;p&gt;Yup, you can now specify the columns you want to add in your migration by passing attribute&#x2F;type pairs to the migration generator. Ergo,&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;script&#x2F;generate migration AddMoreToAnime episodes:integer licensed:boolean&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will generate a migration like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class AddMoreToAnime &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :animes, :episodes, :integer
    add_column :animes, :licensed, :boolean
  end
&lt;p&gt;def self.down
remove_column :animes, :licensed
remove_column :animes, :episodes
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This ties in pretty nicely with the syntax for the model generator (&lt;code&gt;script&#x2F;generate model&lt;&#x2F;code&gt;), which also accepts attribute pairs. Tiny change but &quot;it&#x27;s all about consistency&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;For the geeks among you, check out the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7422&quot;&gt;related changeset&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9166&quot;&gt;ticket&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, Pratik Naik&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;Pratik Naik&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;recommendation&#x2F;new&#x2F;person&#x2F;5424-pratik-naik&quot;&gt;WorkingWithRails profile&lt;&#x2F;a&gt;), probably better known as lifofifo or just lifo, is an active Rails contributor and can be found on &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;rails-contrib&quot;&gt;#rails-contrib&lt;&#x2F;a&gt; and &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;rubyonrails&quot;&gt;#rubyonrails&lt;&#x2F;a&gt; nearly 24&#x2F;7. Almost everyone who&#x27;s used Rails has used code that lifo has written. Oh, and lifo also &lt;a href=&quot;http:&#x2F;&#x2F;weblog.workingwithrails.com&#x2F;2007&#x2F;11&#x2F;1&#x2F;hackfest-winner-interview-pratik-naik&quot;&gt;won one of the monthly Rails Hackfests&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;He also keeps a &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;pretty good blog&lt;&#x2F;a&gt; where he posts mostly on Rails hacking and tips.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Concatenate your stylesheets and JavaScripts in 3 seconds - Rails 2.0 a feature a day #3</title>
    <published>2007-12-12T23:25:39+00:00</published>
    <updated>2007-12-12T23:25:39+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/12/concatenate-your-stylesheets-and-javascripts-in-3-seconds-rails-20-a-feature-a-day-3/"/>
    <id>https://chuyeow.wtf/2007/12/12/concatenate-your-stylesheets-and-javascripts-in-3-seconds-rails-20-a-feature-a-day-3/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/12/concatenate-your-stylesheets-and-javascripts-in-3-seconds-rails-20-a-feature-a-day-3/">&lt;p&gt;I don&#x27;t think I need to explain how &lt;a href=&quot;http:&#x2F;&#x2F;developer.yahoo.com&#x2F;performance&#x2F;rules.html#num_http&quot;&gt;concatenating your 5 stylesheets and 12 JavaScript files into single files&lt;&#x2F;a&gt; each makes your webpages load faster. Unless you&#x27;re using multiple asset hosts (Rails 2 allows for &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6161&quot;&gt;multiple asset hosts&lt;&#x2F;a&gt;), then it becomes tricky to say for sure which method is better, but I digress.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;re a bunch of really useful plugins that help you bundle your JS and CSS files, most of them offering minifying&#x2F;packing of JS and stripping of comments and whitespace in CSS as well. I was a big fan (still love it) of &lt;a href=&quot;http:&#x2F;&#x2F;synthesis.sbecker.net&#x2F;pages&#x2F;asset_packager&quot;&gt;Asset Packager&lt;&#x2F;a&gt;, but newer plugins like &lt;a href=&quot;http:&#x2F;&#x2F;blog.jcoglan.com&#x2F;packr&#x2F;&quot;&gt;PackR&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;bundle-fu&#x2F;&quot;&gt;Bundle-fu&lt;&#x2F;a&gt; work great too.&lt;&#x2F;p&gt;
&lt;p&gt;With Rails 2.0 though, unless you want the minifying&#x2F;packing&#x2F;comment-stripping features, you can do away with installing a packager plugin. Remember your trusty &lt;code&gt;javascript_include_tag&lt;&#x2F;code&gt; and &lt;code&gt;stylesheet_link_tag&lt;&#x2F;code&gt;? They now accept a &lt;code&gt;:cache&lt;&#x2F;code&gt; option:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# :cache =&amp;gt; true creates a cached javascript named all.js.
&amp;lt;%= javascript_include_tag :all, :cache =&amp;gt; true %&amp;gt;
# This becomes:
# &amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;all.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;
&lt;h1 id=&quot;you-can-name-your-javascript-too-by-passing-a-name-instead-of-true&quot;&gt;You can name your javascript too, by passing a name instead of true.&lt;&#x2F;h1&gt;
&lt;p&gt;&amp;lt;%= javascript_include_tag &#x27;jquery&#x27;, &#x27;swfobject&#x27;, &#x27;application&#x27;, :cache =&amp;gt; &#x27;base&#x27; %&amp;gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;this-becomes&quot;&gt;This becomes:&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;script-type-text-javascript-src-javascripts-base-js-script&quot;&gt;&amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;base.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;same-deal-for-stylesheets&quot;&gt;Same deal for stylesheets...&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;cache-true-creates-a-stylesheet-named-all-css&quot;&gt;:cache =&amp;gt; true creates a stylesheet named all.css.&lt;&#x2F;h1&gt;
&lt;p&gt;&amp;lt;%= stylesheet_link_tag :all, :cache =&amp;gt; true %&amp;gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;this-becomes-1&quot;&gt;This becomes:&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;link-href-stylesheets-all-css-media-screen-rel-stylesheet-type-text-css&quot;&gt;&amp;lt;link href=&quot;&#x2F;stylesheets&#x2F;all.css&quot;  media=&quot;screen&quot; rel=&quot;Stylesheet&quot; type=&quot;text&#x2F;css&quot; &#x2F;&amp;gt;&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;you-can-name-your-stylesheet-like-for-javascript-include-tag&quot;&gt;You can name your stylesheet like for javascript_include_tag.&lt;&#x2F;h1&gt;
&lt;p&gt;&amp;lt;%= stylesheet_link_tag &#x27;yui&#x2F;reset-fonts-grids&#x27;, &#x27;application&#x27;, :cache =&amp;gt; &#x27;styles&#x27; %&amp;gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;this-becomes-2&quot;&gt;This becomes:&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;link-href-stylesheets-styles-css-media-screen-rel-stylesheet-type-text-css&quot;&gt;&amp;lt;link href=&quot;&#x2F;stylesheets&#x2F;styles.css&quot;  media=&quot;screen&quot; rel=&quot;Stylesheet&quot; type=&quot;text&#x2F;css&quot; &#x2F;&amp;gt;&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course, this only takes place if caching is turned on (&lt;code&gt;ActionController::Base.perform_caching&lt;&#x2F;code&gt;), which is on by default in the production environment and off in the development environment.&lt;&#x2F;p&gt;
&lt;p&gt;For those who want to look at some code, check out &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6164&quot;&gt;the changeset&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, DHH&lt;&#x2F;h3&gt;
&lt;p&gt;Well, &lt;a href=&quot;http:&#x2F;&#x2F;loudthinking.com&#x2F;&quot;&gt;DHH&lt;&#x2F;a&gt; hardly needs any mention. David has_one &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;David_Heinemeier_Hansson&quot;&gt;Wikipedia entry&lt;&#x2F;a&gt;. Nice little touch on this new feature though, I love the convenience.&lt;&#x2F;p&gt;
&lt;p&gt;I promise, like &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;09&#x2F;rails-20-a-feature-a-day&#x2F;&quot;&gt;I&#x27;d said before&lt;&#x2F;a&gt;, to cover contributions by someone less &quot;mainstream&quot; in the next &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;09&#x2F;rails-20-a-feature-a-day&#x2F;&quot;&gt;Rails 2 &quot;feature a day&quot;&lt;&#x2F;a&gt; blog post.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Firefox 3, Beta</title>
    <published>2007-11-20T17:23:57+00:00</published>
    <updated>2007-11-20T17:23:57+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/11/20/firefox-3-beta/"/>
    <id>https://chuyeow.wtf/2007/11/20/firefox-3-beta/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/11/20/firefox-3-beta/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.com&#x2F;en-US&#x2F;firefox&#x2F;3.0b1&#x2F;releasenotes&#x2F;&quot;&gt;Firefox 3 Beta 1&lt;&#x2F;a&gt; is out! Check out the pretty sweet &lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.com&#x2F;en-US&#x2F;firefox&#x2F;3.0b1&#x2F;releasenotes&#x2F;#whatsnew&quot;&gt;list of changes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;firefox-3.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you want to try it, you&#x27;ll probably want to &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;08&#x2F;20&#x2F;how-to-have-firefox-3-and-firefox-2-running-at-the-same-time&#x2F;&quot;&gt;run Firefox 3 and Firefox 2 at the same time&lt;&#x2F;a&gt;. Only this time you should remember to rename Firefox 3 so that it doesn&#x27;t override your install of Firefox 2.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d blogged about some of the changes previously if you care for some screenshots of &lt;em&gt;some&lt;&#x2F;em&gt; of the new features (Mozilla Links &lt;a href=&quot;http:&#x2F;&#x2F;mozillalinks.org&#x2F;wp&#x2F;category&#x2F;subject&#x2F;firefox3&#x2F;&quot;&gt;covers a good number of new Firefox 3 changes&lt;&#x2F;a&gt; too):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;09&#x2F;18&#x2F;whats-new-in-firefox-3-download-resume&#x2F;&quot;&gt;Resumable downloading: users can now resume downloads after restarting the browser or resetting your network connection.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;05&#x2F;05&#x2F;growl-integration-in-firefox-3&#x2F;&quot;&gt;supports Growl for notifications of completed downloads and available updates.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;09&#x2F;07&#x2F;smarter-and-less-annoying-password-manager-in-firefox-3&#x2F;&quot;&gt;Easier password management: an information bar replaces the old password dialog so you can now save passwords after a successful login.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;09&#x2F;13&#x2F;open-in-tabs-fixed-in-firefox-3-at-last&#x2F;&quot;&gt;Optimized Open in Tabs behavior: opening a folder of bookmarks in tabs now appends the new tabs rather than overwriting.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>New in Rails: a request profiler for profiling your app</title>
    <published>2007-10-26T10:01:30+00:00</published>
    <updated>2007-10-26T10:01:30+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/10/26/new-in-rails-a-request-profiler-for-profiling-your-app/"/>
    <id>https://chuyeow.wtf/2007/10/26/new-in-rails-a-request-profiler-for-profiling-your-app/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/10/26/new-in-rails-a-request-profiler-for-profiling-your-app/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;bitsweat.net&#x2F;&quot;&gt;Jeremy Kemper&lt;&#x2F;a&gt; (aka bitsweat) &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8016&quot;&gt;committed&lt;&#x2F;a&gt; a very useful tool into the Rails trunk not too long ago: a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;actionpack&#x2F;lib&#x2F;action_controller&#x2F;request_profiler.rb&quot;&gt;request profiler&lt;&#x2F;a&gt;! It&#x27;s a human-friendly wrapper script around the &lt;a href=&quot;http:&#x2F;&#x2F;ruby-prof.rubyforge.org&#x2F;&quot;&gt;ruby-prof library&lt;&#x2F;a&gt;, a nice ruby code profiler, that lets you run multiple requests against a URI in your application and get a detailed code profile report in text and HTML.&lt;&#x2F;p&gt;
&lt;p&gt;Wanna try it out? Update your vendor&#x2F;rails to at least revision 8016, run &lt;code&gt;rake rails:update&lt;&#x2F;code&gt; to copy the new &lt;code&gt;script&#x2F;performance&#x2F;request&lt;&#x2F;code&gt; script into your app&#x27;s &lt;code&gt;script&lt;&#x2F;code&gt; directory, install the ruby-prof gem (&lt;code&gt;sudo gem install ruby-prof&lt;&#x2F;code&gt;), then let it loose on your app.&lt;&#x2F;p&gt;
&lt;p&gt;The options are pretty simple, just pass the script the URI you wanna profile. There&#x27;re options for specifying how many requests you want to process, and for profiling POST requests, there&#x27;s one for&lt;br &#x2F;&gt;
specifying a POST fixture file.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;USAGE: script&#x2F;performance&#x2F;request uri [options]
    -u, --uri [URI]                  Request URI. Defaults to http:&#x2F;&#x2F;localhost:3000&#x2F;
    -n, --times [0000]               How many requests to process. Defaults to 1000.
    -b, --benchmark                  Benchmark instead of profiling
        --method [GET]               HTTP request method. Defaults to GET.
        --fixture [FILE]             Path to POST fixture file
        --open [CMD]                 Command to open profile results. Defaults to &quot;open %s &amp;&quot;
    -h, --help                       Show this help&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At the end of the run, you get a text and HTML report with the methods called and the time spent in them. If you haven&#x27;t seen a code profile before, it looks something like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;rails-request-prof-text-output_thumb.png&quot; alt=&quot;Rails request profiler text output report&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Very nice stuff! It&#x27;s &lt;em&gt;extremely&lt;&#x2F;em&gt; convenient to have profiling like this built into Rails itself - personally I&#x27;ve not even run any profiling on my Rails code because it seemed like a hassle (though I do run httperf benchmarks and take note the number of requests per second). With code profiling, you can easily see which parts of your code are the bottlenecks and optimize away - it&#x27;s a godsend that it&#x27;s so easy to do it in Rails!&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, this is all still new stuff I imagine and subject to change (and improvements), but still very exciting for those of us who are hitting performance bottlenecks in our Rails apps (and are not already doing code profiling).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New in Edge Rails: helper for creating form labels</title>
    <published>2007-09-25T10:40:55+00:00</published>
    <updated>2007-09-25T10:40:55+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/09/25/new-in-edge-rails-helper-for-creating-form-labels/"/>
    <id>https://chuyeow.wtf/2007/09/25/new-in-edge-rails-helper-for-creating-form-labels/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/09/25/new-in-edge-rails-helper-for-creating-form-labels/">&lt;p&gt;Edge Rails now comes with a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7541&quot;&gt;helper for creating form labels&lt;&#x2F;a&gt;, so in your views, instead of doing this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% form_for(:user, @user, :url =&gt; user_path(@user)) do |f| -%&amp;gt;
&lt;strong&gt;&amp;lt;label for=&quot;user_login&quot;&amp;gt;Login&amp;lt;&#x2F;label&amp;gt;&lt;&#x2F;strong&gt;
&amp;lt;%= f.text_field :login %&amp;gt;
&amp;lt;end&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where the &lt;code&gt;&amp;lt;label&amp;gt;&lt;&#x2F;code&gt; is given a &lt;code&gt;for&lt;&#x2F;code&gt; attribute of &lt;code&gt;user_login&lt;&#x2F;code&gt; (since the convention for form input ids is &lt;code&gt;{MODEL_NAME}_{ATTRIBUTE_NAME}&lt;&#x2F;code&gt;), you can instead now do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;%= label(:user, :login) %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Quite a bit neater. Makes it easier to explain to beginners how they should use &lt;code&gt;&amp;lt;label&amp;gt;&lt;&#x2F;code&gt;s appropriately since the syntax is similar to the other form helpers. Now give your &lt;code&gt;&amp;lt;label&amp;gt;&lt;&#x2F;code&gt;s proper &lt;code&gt;for&lt;&#x2F;code&gt; attributes if you&#x27;re not doing so already.&lt;&#x2F;p&gt;
&lt;p&gt;This makes plugins like this &lt;a href=&quot;http:&#x2F;&#x2F;simple-rails-plugins.googlecode.com&#x2F;svn&#x2F;form-label-helper&#x2F;&quot;&gt;form label helper plugin&lt;&#x2F;a&gt; obsolete.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Dugg? No problem with WordPress</title>
    <published>2007-09-13T18:53:25+00:00</published>
    <updated>2007-09-13T18:53:25+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/09/13/dugg-no-problem-with-wordpress/"/>
    <id>https://chuyeow.wtf/2007/09/13/dugg-no-problem-with-wordpress/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/09/13/dugg-no-problem-with-wordpress/">&lt;p&gt;An &lt;a href=&quot;&#x2F;2007&#x2F;08&#x2F;13&#x2F;mmorpg-called-outside&#x2F;&quot;&gt;old post I wrote on a spoof &lt;acronym title=&quot;Massively Multiplayer Online Role-Playing Game&quot;&gt;MMORPG&lt;&#x2F;acronym&gt; named &quot;Outside&quot;&lt;&#x2F;a&gt; was &lt;a href=&quot;http:&#x2F;&#x2F;digg.com&#x2F;offbeat_news&#x2F;Incredible_MMORPG_called_Outside_PIC&quot;&gt;Dugg&lt;&#x2F;a&gt; not too long ago and I was quite pleased to find that my server and the blogging software (&lt;a href=&quot;http:&#x2F;&#x2F;wordpress.org&#x2F;&quot;&gt;WordPress&lt;&#x2F;a&gt;) that I use was handling the load extremely well. Quite obviously I was getting more hits in a day than entire months:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;blog-stats-after-getting-dugg.png&quot; alt=&quot;Blog stats after getting Dugg&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;My setup is a Virtual Private Server (VPS) with 256MB RAM hosted at &lt;a href=&quot;http:&#x2F;&#x2F;www.slicehost.com&#x2F;&quot;&gt;SliceHost&lt;&#x2F;a&gt; and this blog is served off &lt;a href=&quot;http:&#x2F;&#x2F;nginx.net&#x2F;&quot;&gt;Nginx&lt;&#x2F;a&gt; and PHP FastCGI processes to handle PHP scripts. The wonderful (because it just works and is really easy to setup) &lt;a href=&quot;http:&#x2F;&#x2F;mnm.uib.es&#x2F;gallir&#x2F;wp-cache-2&#x2F;&quot;&gt;WP-Cache WordPress plugin&lt;&#x2F;a&gt; keeps a cache of pages that&#x27;s swept at logical times (i.e. whenever there are any updates or comments).&lt;&#x2F;p&gt;
&lt;p&gt;I may be a Rails&#x2F;merb fanboy, but this awesome piece of blog software that can stand up to the &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Digg_effect&quot;&gt;Digg Effect&lt;&#x2F;a&gt; with ease is &lt;strong&gt;great&lt;&#x2F;strong&gt;. WordPress &lt;code&gt;FTW&lt;&#x2F;code&gt;!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Don&#x27;t trust web apps (or how Google Reader and my ISP conspired to lose all my feeds)</title>
    <published>2007-08-17T18:33:11+00:00</published>
    <updated>2007-08-17T18:33:11+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/08/17/dont-trust-web-apps-or-how-google-reader-and-my-isp-conspired-to-lose-all-my-feeds/"/>
    <id>https://chuyeow.wtf/2007/08/17/dont-trust-web-apps-or-how-google-reader-and-my-isp-conspired-to-lose-all-my-feeds/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/08/17/dont-trust-web-apps-or-how-google-reader-and-my-isp-conspired-to-lose-all-my-feeds/">&lt;p&gt;About a month ago, I logged in to Google Reader to see a shocking thing - all my subscriptions were gone and I was subscribed to some feeds that I&#x27;ve never heard of.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;greader-subs-all-gone.png&quot; alt=&quot;All my feed subscriptions gone from Google Reader&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I would say I&#x27;m a pretty heavy Google Reader user, checking my several hundred subscriptions several times a day, so it was pretty distressing. I posted a &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;Google-Labs-Reader&#x2F;t&#x2F;2e9436dd16c5f6e2&quot;&gt;thread at the Google Reader Google Group&lt;&#x2F;a&gt; (the link doesn&#x27;t work now because they&#x27;ve moved the Google Group somewhere else for some reason) and several other people responded that they were seeing the same weirdness.&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;I had the same problem, and here&#x27;s the really weird part: I got YOUR feeds! If you look at the top of the page you can see the account you&#x27;re supposedly logged in with. Well, I saw your account there. And this was before I read this message. I also saw some other names every so often. Right now it says &lt;em&gt;email censored&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe it&#x27;s some weird mix up with the ISP. Do you use SingNet?&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;Some time later I started seeing other people&#x27;s accounts:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;greader-other-accounts.png&quot; alt=&quot;Seeing other people’s accounts in Google Reader&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem affected only &lt;a href=&quot;http:&#x2F;&#x2F;www.singnet.com.sg&#x2F;&quot;&gt;Singnet&lt;&#x2F;a&gt; (a major local ISP) users in Singapore (about 7 other users in Singapore using Singnet responded with the same problems). No one really knew what the problem was and neither the Google Reader team nor Singnet (someone sent them an email) responded.&lt;&#x2F;p&gt;
&lt;p&gt;My guess was Singnet started caching Google Reader at a proxy and somehow managed to bypass all the credentials that was needed to modify any feed subscriptions. Sounds like a pretty nasty security bug to me.&lt;&#x2F;p&gt;
&lt;p&gt;The aftermath:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Google Reader no longer has my feed subscriptions (I didn&#x27;t manage to recover them so it&#x27;s still in the sad state of having only 1 feed subscription to some UK property shite).&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;ve manually rebuilt my OPML file (containing my feed subscriptions).&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;m now using &lt;a href=&quot;http:&#x2F;&#x2F;www.newsfirerss.com&#x2F;&quot;&gt;NewsFire&lt;&#x2F;a&gt;. It&#x27;s not decentralized so I can&#x27;t sync it between machines, which really sucks since I have 2 primary machines, but I&#x27;m wary of using online feed readers right now.&lt;&#x2F;li&gt;
&lt;li&gt;I regularly export my OPML file and check it into Subversion.&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;m looking for a reliable decentralized feed reader once again (having used &lt;a href=&quot;http:&#x2F;&#x2F;bloglines.com&#x2F;&quot;&gt;Bloglines&lt;&#x2F;a&gt; and of course, &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2006&#x2F;10&#x2F;24&#x2F;google-reader-a-bloglines-users-perspective&#x2F;&quot;&gt;Google Reader&lt;&#x2F;a&gt; prior to the catastrophe).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>Adium themes use plain old XHTML, CSS and JS</title>
    <published>2007-07-28T14:07:18+00:00</published>
    <updated>2007-07-28T14:07:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/28/adium-themes-use-plain-old-xhtml-css-and-js/"/>
    <id>https://chuyeow.wtf/2007/07/28/adium-themes-use-plain-old-xhtml-css-and-js/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/28/adium-themes-use-plain-old-xhtml-css-and-js/">&lt;p&gt;Just a quick note of something I found out while reading &lt;a href=&quot;http:&#x2F;&#x2F;www.transcendingcss.com&#x2F;&quot;&gt;Transcending CSS&lt;&#x2F;a&gt;: all the &lt;a href=&quot;http:&#x2F;&#x2F;adiumxtras.com&#x2F;&quot;&gt;themes&lt;&#x2F;a&gt; (message styles, contact list styles, etc.) in &lt;a href=&quot;http:&#x2F;&#x2F;adiumx.com&#x2F;&quot;&gt;Adium&lt;&#x2F;a&gt; are crafted with our old friends XHTML, CSS and JS. I opened up a few &lt;a href=&quot;http:&#x2F;&#x2F;adiumxtras.com&#x2F;&quot;&gt;AdiumXtras&lt;&#x2F;a&gt; to see for myself and true enough, &lt;code&gt;&amp;lt;div&amp;gt;&lt;&#x2F;code&gt;s and CSS rules make up the style. Very smart decision by the Adium developers.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Some of the world&#x27;s hottest startups - Bezurk on Business 2.0</title>
    <published>2007-07-27T18:15:18+00:00</published>
    <updated>2007-07-27T18:15:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/27/some-of-the-worlds-hottest-startups-bezurk-on-business-20/"/>
    <id>https://chuyeow.wtf/2007/07/27/some-of-the-worlds-hottest-startups-bezurk-on-business-20/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/27/some-of-the-worlds-hottest-startups-bezurk-on-business-20/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;money.cnn.com&#x2F;magazines&#x2F;business2&#x2F;index.html&quot;&gt;Business 2.0&lt;&#x2F;a&gt; recently published an &lt;a href=&quot;http:&#x2F;&#x2F;money.cnn.com&#x2F;galleries&#x2F;2007&#x2F;biz2&#x2F;0707&#x2F;gallery.web_world.biz2&#x2F;index.html&quot;&gt;article on the world&#x27;s hottest startups outside the US&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;money.cnn.com&#x2F;galleries&#x2F;2007&#x2F;biz2&#x2F;0707&#x2F;gallery.web_world.biz2&#x2F;8.html&quot;&gt;Bezurk was picked&lt;&#x2F;a&gt;. Nice to know that ;)&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;a href=&quot;http:&#x2F;&#x2F;money.cnn.com&#x2F;galleries&#x2F;2007&#x2F;biz2&#x2F;0707&#x2F;gallery.web_world.biz2&#x2F;8.html&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;bezurk-on-business-20.png&quot; alt=&quot;Bezurk on Business 2.0&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>YSlow - Firefox extension that helps to optimize your web pages</title>
    <published>2007-07-26T13:24:51+00:00</published>
    <updated>2007-07-26T13:24:51+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/26/yslow-firefox-extension-that-helps-to-optimize-your-web-pages/"/>
    <id>https://chuyeow.wtf/2007/07/26/yslow-firefox-extension-that-helps-to-optimize-your-web-pages/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/26/yslow-firefox-extension-that-helps-to-optimize-your-web-pages/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;developer.yahoo.com&#x2F;yslow&#x2F;&quot;&gt;YSlow&lt;&#x2F;a&gt; is a Firefox extension that works with &lt;a href=&quot;http:&#x2F;&#x2F;getfirebug.com&#x2F;&quot;&gt;Firebug&lt;&#x2F;a&gt; to grade your web pages&#x27; performance and gives you advice on how to fix any problems. Awesome. It has &lt;a href=&quot;http:&#x2F;&#x2F;www.jslint.com&#x2F;&quot;&gt;JSLint&lt;&#x2F;a&gt; built into it too. And yes I got a big freaking &lt;strong&gt;F&lt;&#x2F;strong&gt;. Via &lt;a href=&quot;http:&#x2F;&#x2F;arunthampi.wordpress.com&#x2F;&quot;&gt;Arun&lt;&#x2F;a&gt; (&lt;acronym title=&quot;In Real Life&quot;&gt;IRL&lt;&#x2F;acronym&gt;).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>MySQL command line &quot;secret&quot;</title>
    <published>2007-07-19T18:02:25+00:00</published>
    <updated>2007-07-19T18:02:25+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/19/mysql-command-line-secret/"/>
    <id>https://chuyeow.wtf/2007/07/19/mysql-command-line-secret/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/19/mysql-command-line-secret/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;rubyisawesome.com&#x2F;&quot;&gt;Tom Preston-Werner&lt;&#x2F;a&gt; (of Gravatar and Chronic fame) &lt;a href=&quot;http:&#x2F;&#x2F;rubyisawesome.com&#x2F;2007&#x2F;7&#x2F;10&#x2F;mysql-secrets-g-instead-of&quot;&gt;wrote about this neat MySQL command line &quot;trick&quot;&lt;&#x2F;a&gt; where instead of ending your SELECT statements with the usual semi-colon, using a &quot;\G&quot; gives you a very readable output.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mysql&gt; select * from locations where location_code = &#x27;SIN&#x27;  limit 1\G
*************************** 1. row ***************************
          location_code: SIN
          location_name: Singapore Changi Apt 
multi_airport_city_code: SIN
          location_type: A
      location_sub_type: A
           country_code: SG
             state_code: 
                 active: 1
               latitude: 01.22.00N
              longitude: 103.59.00E
1 row in set (0.10 sec)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very useful, especially when SELECTing multiple fields where the output becomes unfit for visual consumption (you know what I mean, just go SELECT some stuff in your MySQL command line and you&#x27;ll see if you don&#x27;t).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>God and your web server</title>
    <published>2007-07-18T23:43:38+00:00</published>
    <updated>2007-07-18T23:43:38+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/18/god-and-your-web-server/"/>
    <id>https://chuyeow.wtf/2007/07/18/god-and-your-web-server/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/18/god-and-your-web-server/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;god.rubyforge.org&#x2F;&quot;&gt;God&lt;&#x2F;a&gt; is a new process monitoring Ruby framework with a rather apt name (no, it&#x27;s not &lt;em&gt;that&lt;&#x2F;em&gt; &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;God&quot;&gt;God&lt;&#x2F;a&gt;). The config files looks something like that:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;God.meddle do |god|
  god.watch do |w|
    ...
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Interesting code to write. And feels safe too to have God watching over your mongrels. Oh and you can use it to clean up stale mongrel PID files without &lt;a href=&quot;http:&#x2F;&#x2F;textsnippets.com&#x2F;posts&#x2F;show&#x2F;931&quot;&gt;patching mongrel_rails&lt;&#x2F;a&gt;. Right now I use &lt;a href=&quot;http:&#x2F;&#x2F;www.tildeslash.com&#x2F;monit&#x2F;&quot;&gt;monit&lt;&#x2F;a&gt; a lot and it&#x27;s really rather unDRY to have repeated configs for each mongrel on the server (is there a better way of doing this in monit?). God would be able to DRY it up.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Better JSON output from Rails with the Jsonifier plugin</title>
    <published>2007-07-11T12:46:38+00:00</published>
    <updated>2007-07-11T12:46:38+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/11/better-json-output-from-rails-with-the-jsonifier-plugin/"/>
    <id>https://chuyeow.wtf/2007/07/11/better-json-output-from-rails-with-the-jsonifier-plugin/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/11/better-json-output-from-rails-with-the-jsonifier-plugin/">&lt;p&gt;&lt;ins&gt;Update: Edge Rails now does whatever Jsonifier does (and more). Check out my blog &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;10&#x2F;10&#x2F;new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity&#x2F;&quot;&gt;post on JSON serialization maturity in edge Rails&lt;&#x2F;a&gt;. This means that this plugin is virtually obsolete if you&#x27;re using edge Rails.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve tried to output JSON from your Rails applications before, you&#x27;d probably have noticed how inadequate it all seems. Let&#x27;s look at the kind of output (pretty-printed for easier reading) you get from calling &lt;code&gt;to_json&lt;&#x2F;code&gt; on your typical User model:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{
  attributes: {
    id: 1,
    name: &quot;Konata&quot;,
    awesome: true,
    created_at: &quot;07&#x2F;01&#x2F;2007&quot;
  }
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some of the common problems developers who write applications that speak JSON have with this are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;attributes&lt;&#x2F;code&gt; part is often unnecessary cruft when consuming ActiveRecord objects as JSON.&lt;&#x2F;li&gt;
&lt;li&gt;There&#x27;s no obvious way to control which attributes are shown in the JSON (e.g. you may want to hide private or lengthy attributes). The way to workaround this is either to write your own &lt;code&gt;to_json&lt;&#x2F;code&gt; instance method for your ActiveRecord model, or to use a Rails plugin (like &lt;a href=&quot;http:&#x2F;&#x2F;geekblog.vodpod.com&#x2F;?p=9&quot;&gt;acts_as_json&lt;&#x2F;a&gt;) or a &lt;a href=&quot;http:&#x2F;&#x2F;json.rubyforge.org&#x2F;&quot;&gt;gem&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Including 2nd (or higher order) associations is tricky (as above, you can achieve this by defining your own &lt;code&gt;to_json&lt;&#x2F;code&gt; instance methods).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;Under the hood of the current ActiveRecord#to_json&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;to_json&lt;&#x2F;code&gt; method for ActiveRecord objects falls back on using that defined in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&quot;&gt;ActiveSupport&#x27;s JSON classes&lt;&#x2F;a&gt;. The way it&#x27;s currently done, there are a bunch of JSON encoder classes defined for various types - when you call &lt;code&gt;to_json&lt;&#x2F;code&gt; on an ActiveRecord object it simply uses &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&#x2F;encoders&#x2F;object.rb&quot;&gt;&lt;code&gt;Object#to_json&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By the way, see that &lt;code&gt;created_at: &quot;07&#x2F;01&#x2F;2007&quot;&lt;&#x2F;code&gt; bit in the example above which is the JSON output for a Date attribute? That&#x27;s in MM&#x2F;DD&#x2F;YYYY format. Yup, 1st July 2007 not 7th January 2007 you &quot;rest of the world you&quot;. Ouch, but at least you can use JavaScript&#x27;s &lt;code&gt;Date.parse()&lt;&#x2F;code&gt; on it directly as detailed in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8399&quot;&gt;this patch&lt;&#x2F;a&gt;. And before you ask, yes, &lt;code&gt;Date.parse()&lt;&#x2F;code&gt; doesn&#x27;t understand the YYYY-MM-DD format.&lt;&#x2F;p&gt;
&lt;h3&gt;Can has Rails patch?&lt;&#x2F;h3&gt;
&lt;p&gt;So about 2 days ago, I wrote a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8920&quot;&gt;Rails patch to boost ActiveRecord#to_json with an options hash&lt;&#x2F;a&gt;. Yep much like what you can do with &lt;a href=&quot;http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActiveRecord&#x2F;XmlSerialization.html#M000910&quot;&gt;&lt;code&gt;ActiveRecord#to_xml&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I hope it gets committed into the core some day. I mean, gosh, isn&#x27;t Rails all about Web 2.0 mashups. It even has that fancy &lt;code&gt;render :json&lt;&#x2F;code&gt; thing. I do believe JSON output needs to be treated more seriously in Rails rather than the half-hearted attempt at JSON encoding. No? Well, if the patch doesn&#x27;t get accepted I&#x27;ll still have &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;my plugin&lt;&#x2F;a&gt; (&lt;a href=&quot;#jsonifier-plugin&quot;&gt;see below&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, let&#x27;s see some examples:&lt;&#x2F;p&gt;
&lt;h3&gt;Some examples, see?&lt;&#x2F;h3&gt;
&lt;p&gt;Assuming User and Post models where User has_many Posts:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david = User.find(1)
david.to_json  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;No more &lt;code&gt;attributes&lt;&#x2F;code&gt; cruft!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;:only&lt;&#x2F;code&gt; and &lt;code&gt;:except&lt;&#x2F;code&gt; work the same way that as for &lt;code&gt;ActiveRecord#to_xml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:only =&gt; :name)                 # {name: &quot;David&quot;}
david.to_json(:only =&gt; [:id, :name])          # {id: 1, name: &quot;David&quot;}
david.to_json(:except =&gt; :created_at)         # {id: 1, name: &quot;David&quot;, awesome: true}
david.to_json(:except =&gt; [:id, :created_at])  # {name: &quot;David&quot;, awesome: true}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can use the &lt;code&gt;:methods&lt;&#x2F;code&gt; options as well to include any methods on the object.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:methods =&gt; :permalink)
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, permalink =&gt; &quot;1-David&quot;}
david.to_json(:methods =&gt; [:permalink, :interestingness])
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #   permalink =&gt; &quot;1-David&quot;, :interestingness =&gt; 666}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;:include&lt;&#x2F;code&gt; option lets you include associations.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:include =&gt; :posts)
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #    posts: [{id: 1, author_id: 1, title: &quot;Welcome to the weblog&quot;}, \
  #            {id: 2, author_id: 1, title: &quot;So I was thinking&quot;}]}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;:only&lt;&#x2F;code&gt;, &lt;code&gt;:except&lt;&#x2F;code&gt;, and &lt;code&gt;:methods&lt;&#x2F;code&gt; works on the included associations as well:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:include =&gt; { :posts =&gt; { :only =&gt; :title } })
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #    posts: [{title: &quot;Welcome to the weblog&quot;}, \
  #            {title: &quot;So I was thinking&quot;}]}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, 2nd level (and higher order) associations work too:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:include =&gt; { :posts =&gt; { \
                              :include =&gt; { :comments =&gt; { \
                                              :only =&gt; :body } }, \
                              :only =&gt; :title } })
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #    posts: [{comments: [{body: &quot;1st post!&quot;}, {body: &quot;OMGWTFBBQ!&quot;}], \
  #             title: &quot;Welcome to the weblog&quot;}, \
  #            {comments: [{body: &quot;Don&#x27;t think too hard&quot;}], \
  #             title: &quot;So I was thinking&quot;}]}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Please do give any feedback at the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8920&quot;&gt;Rails patch for ActiveRecord#to_json&lt;&#x2F;a&gt; or here. I wanna know what you feel about adding this functionality into the Rails core!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jsonifier-plugin&quot;&gt;Jsonifier plugin&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve rolled the patch into a plugin: Jsonifier. The &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;Jsonifier Trac&lt;&#x2F;a&gt; is at &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Git repository:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier.git&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Github project page:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;http:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To install the plugin:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ruby script&#x2F;plugin install git:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier.git&lt;&#x2F;code&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt; or &lt;code&gt;git clone&lt;&#x2F;code&gt; the repository manually into the &lt;code&gt;vendor&#x2F;plugins&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;h3&gt;A note on valid JSON&lt;&#x2F;h3&gt;
&lt;p&gt;The JSON Rails spits out by default is not strictly valid JSON since the &lt;a href=&quot;http:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc4627.txt?number=4627&quot;&gt;JSON specifications&lt;&#x2F;a&gt; require keys to be double quoted. To get strictly valid JSON, add&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ActiveSupport::JSON.unquote_hash_key_identifiers = false&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;in your environment.rb (or in the Rails initializers directory if you&#x27;re on edge). See &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;06&#x2F;20&#x2F;how-to-get-strictly-valid-json-from-rails&#x2F;&quot;&gt;my blog post on how to get strictly valid JSON from Rails&lt;&#x2F;a&gt; for more info.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Prototype 1.5.1 is baaaaad for Safari 1 and 2 users</title>
    <published>2007-06-21T19:15:00+00:00</published>
    <updated>2007-06-21T19:15:00+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/06/21/prototype-151-is-baaaaad-for-safari-1-and-2-users/"/>
    <id>https://chuyeow.wtf/2007/06/21/prototype-151-is-baaaaad-for-safari-1-and-2-users/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/06/21/prototype-151-is-baaaaad-for-safari-1-and-2-users/">&lt;p&gt;Read the &lt;a href=&quot;http:&#x2F;&#x2F;prototypejs.org&#x2F;2007&#x2F;6&#x2F;20&#x2F;prototype-1-5-1-1-bugfix-release&quot;&gt;bug fix announcement&lt;&#x2F;a&gt;. Upgrade! This was causing extremely puzzling crashes in Safari on Macs (pre-Safari 3 beta) on &lt;a href=&quot;http:&#x2F;&#x2F;www.bezurk.com&#x2F;hotels&#x2F;singapore&#x2F;singapore&quot;&gt;one of our applications&lt;&#x2F;a&gt; and I&#x27;m glad (in some ways) that the problem lay with the Prototype library.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Bezurk featured on Channel NewsAsia</title>
    <published>2007-06-20T18:31:30+00:00</published>
    <updated>2007-06-20T18:31:30+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/06/20/bezurk-featured-on-channel-newsasia/"/>
    <id>https://chuyeow.wtf/2007/06/20/bezurk-featured-on-channel-newsasia/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/06/20/bezurk-featured-on-channel-newsasia/">&lt;p&gt;The company I work for was featured on a short &quot;&lt;a href=&quot;http:&#x2F;&#x2F;www.channelnewsasia.com&#x2F;ptm&#x2F;surftime&#x2F;&quot;&gt;Surf Time&lt;&#x2F;a&gt;&quot; segment on &lt;a href=&quot;http:&#x2F;&#x2F;www.channelnewsasia.com&#x2F;&quot;&gt;Channel NewsAsia&lt;&#x2F;a&gt;&#x27;s TV channel. Catch the &lt;a href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=mmVznPcPjdI&quot;&gt;Bezurk Surf Time video on YouTube&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>How to get strictly valid JSON from Rails</title>
    <published>2007-06-20T11:47:59+00:00</published>
    <updated>2007-06-20T11:47:59+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/06/20/how-to-get-strictly-valid-json-from-rails/"/>
    <id>https://chuyeow.wtf/2007/06/20/how-to-get-strictly-valid-json-from-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/06/20/how-to-get-strictly-valid-json-from-rails/">&lt;p&gt;&lt;ins&gt;Update: Edge Rails (and the forthcoming Rails 2.0) will emit only valid JSON. Read &lt;a href=&quot;&#x2F;2007&#x2F;10&#x2F;10&#x2F;new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity&#x2F;&quot;&gt;JSON serialization of ActiveRecord objects reaches maturity for more details&lt;&#x2F;a&gt;.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve worked with &lt;a href=&quot;http:&#x2F;&#x2F;www.json.org&#x2F;&quot;&gt;JSON&lt;&#x2F;a&gt; long enough in Rails, you&#x27;d probably have noticed that the JSON the convenient &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&#x2F;encoders&#x2F;object.rb&quot;&gt;Object#to_json&lt;&#x2F;a&gt; method spits out is not strictly JSON-compliant (according to the &lt;a href=&quot;http:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc4627&quot;&gt;RFC 4627&lt;&#x2F;a&gt;, which states that object keys should be &quot;strings&quot;, and &quot;strings&quot; should be double-quoted). Here&#x27;s an example of what &lt;code&gt;to_json&lt;&#x2F;code&gt; produces when called on an ActiveRecord instance:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{
  id: 6589,
  code: &quot;SIN&quot;,
  name: &quot;Singapore&quot;,
  type: &quot;City&quot;
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice how the keys (id, code, name, type) are not surrounded with double quotes. While this is generally not a problem if working purely in Rails, since Prototype and Rails itself can decode JSON like this, you&#x27;d run into problems with more finicky JSON parsers and decoders. PHP&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;php.net&#x2F;json_decode&quot;&gt;json_decode&lt;&#x2F;a&gt; is a perfect example - it demands that the object keys be double-quoted (or it fails to decode your JSON, silently returning NULL).&lt;&#x2F;p&gt;
&lt;p&gt;For a while I couldn&#x27;t figure out why Rails was doing it and &lt;a href=&quot;http:&#x2F;&#x2F;www.google.com.sg&#x2F;search?q=rails+invalid+json&quot;&gt;Google was of no help&lt;&#x2F;a&gt;. I decided to look at the Rails code since this can&#x27;t be a huge oversight on the Rails community, can it? Sure enough, I found the &quot;solution&quot; in the encoding portion of the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&#x2F;encoding.rb&quot;&gt;ActiveSupport::JSON&lt;&#x2F;a&gt; module:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
  # When +true+, Hash#to_json will omit quoting string or symbol keys
  # if the keys are valid JavaScript identifiers.  Note that this is
  # technically improper JSON (all object keys must be quoted), so if
  # you need strict JSON compliance, set this option to +false+.
  mattr_accessor :unquote_hash_key_identifiers
  @@unquote_hash_key_identifiers = true&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doh! All that&#x27;s left to do is to put &lt;code&gt;ActiveSupport::JSON.unquote_hash_key_identifiers = false&lt;&#x2F;code&gt; in your &lt;code&gt;environment.rb&lt;&#x2F;code&gt; (or in the Rails initializers directory if you&#x27;re on edge) and your Rails app will start producing strictly valid JSON (and is friendlier to other non-Rails applications):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{
  &quot;id&quot;: 6589,
  &quot;code&quot;: &quot;SIN&quot;,
  &quot;name&quot;: &quot;Singapore&quot;,
  &quot;type&quot;: &quot;City&quot;
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;unquote_hash_key_identifiers&lt;&#x2F;code&gt; was added in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;5486&quot;&gt;changeset 5486&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Get your Rails tests results via Growl notifications</title>
    <published>2007-04-01T14:25:05+00:00</published>
    <updated>2007-04-01T14:25:05+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/04/01/get-your-testing-results-via-growl-notifications/"/>
    <id>https://chuyeow.wtf/2007/04/01/get-your-testing-results-via-growl-notifications/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/04/01/get-your-testing-results-via-growl-notifications/">&lt;p&gt;I&#x27;ve been using Autotest (part of the &lt;a href=&quot;http:&#x2F;&#x2F;www.zenspider.com&#x2F;ZSS&#x2F;Products&#x2F;ZenTest&#x2F;&quot;&gt;ZenTest&lt;&#x2F;a&gt; package) while testing my Rails applications and never thought of asking for more. After all, getting my tests (well, &lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;&quot;&gt;specs&lt;&#x2F;a&gt; actually) run automatically whenever I make a relevant change &lt;em&gt;and&lt;&#x2F;em&gt; having &lt;code&gt;diff&lt;&#x2F;code&gt;-level granularity on which tests Autotest re-runs is pretty damn useful enough. That is, until I came across this &lt;a href=&quot;http:&#x2F;&#x2F;marcus.ahnve.net&#x2F;2007&#x2F;03&#x2F;30&#x2F;rspec-and-autotest&#x2F;&quot;&gt;RSpec and Autotest with Growl notifications blog entry&lt;&#x2F;a&gt; (on &lt;a href=&quot;http:&#x2F;&#x2F;javablogs.com&#x2F;&quot;&gt;JavaBlogs&lt;&#x2F;a&gt;, no less!)&lt;&#x2F;p&gt;
&lt;p&gt;How&#x27;re these for &lt;span style=&quot;color: #900;&quot;&gt;red&lt;&#x2F;span&gt;&#x2F;&lt;span style=&quot;color: #090;&quot;&gt;green&lt;&#x2F;span&gt; test results?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Tests (specs) passing!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;growl-green-autotest.png&quot; alt=&quot;Growl notification of tests passing&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Tests (specs) failing :(&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;growl-red-autotest.png&quot; alt=&quot;Growl notification of tests failing :(&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Much better! Now I don&#x27;t have to glance at my terminal window (I recently realized how painful it is while coding with a single monitor) and get unobtrusive notifications.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, this is Mac-only (or wherever &lt;a href=&quot;http:&#x2F;&#x2F;growl.info&#x2F;&quot;&gt;Growl&lt;&#x2F;a&gt; is supported). I had to follow links to several blog entries to get it setup nicely (see &lt;a href=&quot;http:&#x2F;&#x2F;blog.labratz.net&#x2F;articles&#x2F;2006&#x2F;09&#x2F;13&#x2F;growl-autotest-rails-with-zentest-3-4-0&quot;&gt;Growl + Autotest Rails with Zentest 3.4.0&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;blog.internautdesign.com&#x2F;2006&#x2F;11&#x2F;12&#x2F;autotest-growl-goodness&quot;&gt;Green goodness with autotest + growl&lt;&#x2F;a&gt; - those are my references).&lt;&#x2F;p&gt;
&lt;p&gt;Basically you need &lt;a href=&quot;http:&#x2F;&#x2F;growl.info&#x2F;&quot;&gt;Growl&lt;&#x2F;a&gt; installed, and the &lt;a href=&quot;http:&#x2F;&#x2F;growl.info&#x2F;documentation&#x2F;growlnotify.php&quot;&gt;&lt;code&gt;growlnotify&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; tool in your path. &lt;code&gt;growlnotify&lt;&#x2F;code&gt; can be found in the &lt;code&gt;Extras&#x2F;growlnotify&lt;&#x2F;code&gt; directory in the Growl dmg (for example, after you&#x27;ve mounted the Growl-0.x.x.dmg, you can find it here: &lt;code&gt;&#x2F;Volumes&#x2F;Growl&#x2F;Extras&#x2F;growlnotify&lt;&#x2F;code&gt;). Just copy the &lt;code&gt;growlnotify&lt;&#x2F;code&gt; executable into your path (I copied it into &lt;code&gt;&#x2F;opt&#x2F;local&#x2F;bin&lt;&#x2F;code&gt; since I&#x27;m using Darwin Ports and don&#x27;t have a &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;code&gt; directory). Verify it&#x27;s running by entering:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;growlnotify -m &quot;Testing growlnotify&quot; Boo Ya!&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;into a terminal window. You should see a Growl notification.&lt;&#x2F;p&gt;
&lt;p&gt;Now, you need to create an Autotest hook by creating an autotest init file in your home directory named &lt;code&gt;.autotest&lt;&#x2F;code&gt;, and copy this chunk of text in:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
module Autotest::Growl
  def self.growl title, msg, img, pri=0, sticky=&quot;&quot; 
    system &quot;growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}&quot; 
  end
&lt;p&gt;Autotest.add_hook :ran_command do |at|
output = at.results.last.slice(&#x2F;(\d+)\s.*specifications?,\s(\d+)\s.*failures?&#x2F;)
if output =~ &#x2F;[1-9]\sfailures?&#x2F;
growl &quot;Test Results&quot;, &quot;#{output}&quot;, &quot;&#x2F;Data&#x2F;Pictures&#x2F;Icons&#x2F;rails_fail.png&quot;, 2, &quot;-s&quot;
else
growl &quot;Test Results&quot;, &quot;#{output}&quot;, &quot;&#x2F;Data&#x2F;Pictures&#x2F;Icons&#x2F;rails_ok.png&quot;
end
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Replace the paths to the pass&#x2F;fail icons (as you can see, mine are in &lt;code&gt;&#x2F;Data&#x2F;Pictures&#x2F;Icons&#x2F;&lt;&#x2F;code&gt;) with the correct paths to any images you want to display (grab them from &lt;a href=&quot;http:&#x2F;&#x2F;blog.internautdesign.com&#x2F;2006&#x2F;11&#x2F;12&#x2F;autotest-growl-goodness&quot;&gt;Green goodness with autotest + growl&lt;&#x2F;a&gt; or roll your own). You can change the parameters passed to &lt;code&gt;growlnotify&lt;&#x2F;code&gt; however you want (use &lt;code&gt;growlnotify -h&lt;&#x2F;code&gt; to see what parameters it acccepts). The &lt;code&gt;pri&lt;&#x2F;code&gt; parameter sets the priority level of the message (test failures come up with a priority of 2, hence the red background of the Growl notification). Passing &lt;code&gt;-s&lt;&#x2F;code&gt; to &lt;code&gt;sticky&lt;&#x2F;code&gt; tells Growl to keep the notification sticky. If you&#x27;re running your (auto)tests on a remote server (e.g. in a Continuous Integration system), you can even use &lt;code&gt;growlnotify&lt;&#x2F;code&gt; to send remote notifications (see the &lt;code&gt;-H&lt;&#x2F;code&gt; switch) to your development workstations!&lt;&#x2F;p&gt;
&lt;p&gt;Lovely! I love you, MacBook Pro serial no. W86280NAVWW (despite your broken DVD drive and you randomly freezing up on me when you get too hot).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Setting up svnsync-ed (mirrored) SVN repositories on Ubuntu (part 2 of 2)</title>
    <published>2007-03-31T23:12:31+00:00</published>
    <updated>2007-03-31T23:12:31+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/31/setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-2-of-2/"/>
    <id>https://chuyeow.wtf/2007/03/31/setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-2-of-2/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/31/setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-2-of-2/">&lt;p&gt;&lt;ins&gt;Note: if you haven&#x27;t already, you may want to read &lt;a href=&quot;&#x2F;2007&#x2F;03&#x2F;29&#x2F;setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-1-of-2&#x2F;&quot;&gt;part 1 of this article&lt;&#x2F;a&gt; first.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Phew, and that was all the work you needed to do to migrate your Subversion repository to another server. We&#x27;ve barely touched that other server that we wanted to use for mirroring the repository!&lt;&#x2F;p&gt;
&lt;h3&gt;&quot;Bootstrapping&quot; your mirror SVN server for svnsync&lt;&#x2F;h3&gt;
&lt;p&gt;This mirror SVN server also needs Subversion 1.4.x installed, so go ahead and do the (almost) same things we&#x27;ve done in &lt;a href=&quot;&#x2F;2007&#x2F;03&#x2F;29&#x2F;setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-1-of-2&#x2F;&quot;&gt;part 1&lt;&#x2F;a&gt; to get Subversion installed. You should be able to use the &lt;code&gt;.deb&lt;&#x2F;code&gt; package generated by &lt;code&gt;checkinstall&lt;&#x2F;code&gt; on your main Subversion server to install Subversion 1.4.x on the mirror SVN server. Just scp it to the mirror SVN server and install it (&lt;code&gt;dpkg -i subversion-1.4.3.deb&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;With Subversion installed, create a new Subversion repository (using &lt;code&gt;svnadmin create&lt;&#x2F;code&gt;, remember?), but &lt;em&gt;don&#x27;t&lt;&#x2F;em&gt; load the repository dump like we did on the main SVN server in &lt;a href=&quot;&#x2F;2007&#x2F;03&#x2F;29&#x2F;setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-1-of-2&#x2F;&quot;&gt;part 1&lt;&#x2F;a&gt; (of course, since we are going to be mirroring the repository!).&lt;&#x2F;p&gt;
&lt;h3&gt;Setting up svnsync to mirror your repository&lt;&#x2F;h3&gt;
&lt;p&gt;First, create a SVN user for svnsync to use - let&#x27;s call this the &#x27;svnsync user&#x27;. The easiest (and best) way to do this is edit the svnserve.conf and passwd files:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;conf&#x2F;svnserve.conf&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
# Uncomment this line.
password-db = passwd
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;conf&#x2F;passwd&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
svnsync = secret
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This gives read and write access to the &#x27;svnsync user&#x27;. The &lt;code&gt;svnsync&lt;&#x2F;code&gt; program will authenticate with our repositories as this user via the &lt;code&gt;svn:&#x2F;&#x2F;&lt;&#x2F;code&gt; protocol (i.e. via svnserve).&lt;&#x2F;p&gt;
&lt;p&gt;Next, we need to create a &lt;code&gt;pre-revprop-change&lt;&#x2F;code&gt; hook for the destination repository. The &lt;a href=&quot;http:&#x2F;&#x2F;svn.collab.net&#x2F;repos&#x2F;svn&#x2F;trunk&#x2F;notes&#x2F;svnsync.txt&quot;&gt;svnsync documentation&lt;&#x2F;a&gt; has a detailed explanation. Create a &lt;code&gt;hooks&#x2F;pre-revprop-change&lt;&#x2F;code&gt; file under your destination repository&#x27;s directory.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
#!&#x2F;bin&#x2F;sh
USER=&quot;$3&quot;
&lt;p&gt;if [ &quot;$USER&quot; = &quot;svnsync&quot; ]; then exit 0; fi&lt;&#x2F;p&gt;
&lt;p&gt;echo &quot;Only the svnsync user can change revprops&quot; &amp;gt;&amp;amp;2
exit 1&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Make it executable, and then initialize the sync:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
chmod +x hooks&#x2F;pre-revprop-change
svnsync init file:&#x2F;&#x2F;&#x2F;var&#x2F;svn&#x2F;repositories&#x2F;destination_repos svn:&#x2F;&#x2F;source.host&#x2F;source_repos&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don&#x27;t worry, this only sets up the sync - there&#x27;s no actual data copying yet. Syncing your repository data may take a long time if you have a big source repository, so I suggest using &lt;code&gt;nohup&lt;&#x2F;code&gt; to run the code overnight (or something), or at least saving the output in a log. Either way, the command to start the sync is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;svnsync sync --username svnsync file:&#x2F;&#x2F;&#x2F;var&#x2F;svn&#x2F;repositories&#x2F;testsync&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should start seeing svnsync committing in changes from your source repository. Instant gratification (well, almost)! Should your svnsync process get aborted or killed, you can remove the hanging lock by running:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;svn propdel svn:sync-lock --revprop -r 0&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3&gt;Setting up &#x27;on-the-fly&#x27; syncing&lt;&#x2F;h3&gt;
&lt;p&gt;So now you have your source and destination repositories synced, but what happens when you start committing changes to your source repository? Nothing! That&#x27;s because svnsync is merely a passive syncing tool (meaning you have to run it to sync, instead of it knowing when to sync automatically).&lt;&#x2F;p&gt;
&lt;p&gt;There are two ways you can setup &#x27;real-time&#x27; syncing:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
    Use &lt;code&gt;cron&lt;&#x2F;code&gt; (or a similar scheduler) on the destination repository server. Add something like this to your &lt;code&gt;crontab&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;* * * * * &#x2F;usr&#x2F;local&#x2F;bin&#x2F;svnsync --non-interactive sync svn:&#x2F;&#x2F;source.host&#x2F;source_repos&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;    This basically runs svnsync on your destination repository server every minute to pull down any changes to your source repository.
  &lt;&#x2F;li&gt;
&lt;li&gt;Add a post-commit hook to the source repository. I found this &lt;a href=&quot;http:&#x2F;&#x2F;journal.paul.querna.org&#x2F;articles&#x2F;2006&#x2F;09&#x2F;14&#x2F;using-svnsync&quot;&gt;svnsync entry by Paul Querna&lt;&#x2F;a&gt; that has a sample post-commit hook. If I recall correctly I tried it but it didn&#x27;t work for me, so I settled on using cron to sync up my repositories.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3&gt;Things that I skipped&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;re some things that I skipped over while writing this, mainly to do with SVN authentication.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
    If you&#x27;re accessing your repository via the &lt;code&gt;svn+ssh:&#x2F;&#x2F;&lt;&#x2F;code&gt; protocol, you&#x27;ve to manage the (group) permissions of the repository files in the filesystem appropriately (basically the repository should be group writable by your users). &lt;code&gt;chmod&lt;&#x2F;code&gt; and &lt;code&gt;chown&lt;&#x2F;code&gt; are your friends, as is &lt;acronym title=&quot;Network Information Service&quot;&gt;NIS&lt;&#x2F;acronym&gt; (or something similar) to manage your users. I use these steps to create a new SVN repository that gets access via the &lt;code&gt;svn+ssh:&#x2F;&#x2F;&lt;&#x2F;code&gt; protocol:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
sudo mkdir &#x2F;var&#x2F;svn&#x2F;repositories&#x2F;funky_project
mkdir &#x2F;tmp&#x2F;funky_project
mkdir &#x2F;tmp&#x2F;funky_project&#x2F;trunk
mkdir &#x2F;tmp&#x2F;funky_project&#x2F;branches
mkdir &#x2F;tmp&#x2F;funky_project&#x2F;tags
sudo svnadmin create &#x2F;var&#x2F;svn&#x2F;repositories&#x2F;funky_project
sudo svn import &#x2F;tmp&#x2F;YourProjectNameHere file:&#x2F;&#x2F;&#x2F;&#x2F;var&#x2F;svn&#x2F;repositories&#x2F;funky_project -m &quot;Initial import.&quot;
rm -rf &#x2F;tmp&#x2F;funky_project
sudo chown -R www-data:www-data &#x2F;var&#x2F;svn&#x2F;repositories&#x2F;funky_project
sudo chmod -R g+w &#x2F;var&#x2F;svn&#x2F;repositories&#x2F;funky_project
    &lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;    As you can see, my SVN users are part of the www-data group, and the repository directory is made group-writable.
  &lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;svn:&#x2F;&#x2F;&lt;&#x2F;code&gt; protocol has authentication configuration files in the &lt;code&gt;conf&#x2F;&lt;&#x2F;code&gt; directory of your repository. The SVN book has a &lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.svnserve.html#svn.serverconfig.svnserve.auth&quot;&gt;section explaining how to configure authentication&lt;&#x2F;a&gt; for &lt;code&gt;svnserve&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Apache httpd can be used to expose your SVN repositories via the WebDAV protocol. This allows for the very commonly seen &lt;code&gt;http:&#x2F;&#x2F;&lt;&#x2F;code&gt; repository URLs (especially for Open Source projects). Configuration is a little more involved and you would probably have to install Apache from source as well. The SVN book has &lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.httpd.html&quot;&gt;the details&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;Wrapping up&lt;&#x2F;h3&gt;
&lt;p&gt;I hope someone found this entry useful - I know I could have used one when I was setting up Subversion and svnsync.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Setting up svnsync-ed (mirrored) SVN repositories on Ubuntu (part 1 of 2)</title>
    <published>2007-03-29T01:34:36+00:00</published>
    <updated>2007-03-29T01:34:36+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/29/setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-1-of-2/"/>
    <id>https://chuyeow.wtf/2007/03/29/setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-1-of-2/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/29/setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-1-of-2/">&lt;p&gt;This is a 2-part journal on setting up migrating and upgrading a Subversion repository, and then using svnsync to mirror the newly created repository. (&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;03&#x2F;31&#x2F;setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-2-of-2&#x2F;&quot;&gt;Part 2&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;h3&gt;Initial setup&lt;&#x2F;h3&gt;
&lt;p&gt;Ever since &lt;a href=&quot;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;&quot;&gt;Subversion&lt;&#x2F;a&gt; 1.4 was &lt;a href=&quot;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;svn_1.4_releasenotes.html&quot;&gt;released&lt;&#x2F;a&gt;, I&#x27;d been eying the new &lt;a href=&quot;http:&#x2F;&#x2F;svn.collab.net&#x2F;repos&#x2F;svn&#x2F;trunk&#x2F;notes&#x2F;svnsync.txt&quot;&gt;svnsync&lt;&#x2F;a&gt; tool because we had a single repository that was not, erm, &lt;em&gt;really&lt;&#x2F;em&gt; backed up (we had daily server backups and occasional manual repository dumps but that was it). svnsync promised to make repository mirroring simple, and after doing some repository migration and upgrading, I can assure you it really does make things easier than any other (more manual) repository backup solutions I had seen before. This is a walkthrough of how you can upgrade your pre-1.4 &lt;acronym title=&quot;Subversion&quot;&gt;SVN&lt;&#x2F;acronym&gt; repositories to 1.4.x, and setup svnsync to mirror your repositories. It&#x27;s going to be very biased to Ubuntu but I&#x27;m sure you can translate any Ubuntu specific steps to your favorite distros.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s our initial setup:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A pre-1.4 (it was version 1.2.3) SVN repository that needed to be upgraded &lt;em&gt;and&lt;&#x2F;em&gt; migrated to another server.&lt;&#x2F;li&gt;
&lt;li&gt;2 cleanly installed Ubuntu 6.06 &lt;acronym title=&quot;Long Term Support&quot;&gt;LTS&lt;&#x2F;acronym&gt; &lt;acronym title=&quot;Virtual Private Servers&quot;&gt;VPSs&lt;&#x2F;acronym&gt;, one of which is the intended target for the repository migration. The other would mirror the new 1.4.x repository (using svnsync).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;An un-installable Subversion 1.4.x?&lt;&#x2F;h3&gt;
&lt;p&gt;I wish I could have simply ran &lt;code&gt;sudo apt-get install subversion&lt;&#x2F;code&gt; and have Ubuntu pull down the latest 1.4.x .debs. Unfortunately, the version of Subversion in the Ubuntu apt-get repository is still 1.3.1 (which doesn&#x27;t have svnsync). If anyone knows a reliable way to install Subversion 1.4.x via apt-get, let me know! I looked around for a good edge sources.list but came back empty-handed.&lt;&#x2F;p&gt;
&lt;p&gt;I balk at installing stuff from source because I never did figure out how to easily clean out the stuff that gets installed. All thanks to this reluctance, I went digging around and found &lt;a href=&quot;http:&#x2F;&#x2F;asic-linux.com.mx&#x2F;~izto&#x2F;checkinstall&#x2F;&quot;&gt;checkinstall&lt;&#x2F;a&gt;. This thing is &lt;strong&gt;awesome&lt;&#x2F;strong&gt; - I wonder why I didn&#x27;t manage to find it earlier.&lt;&#x2F;p&gt;
&lt;p&gt;What &lt;code&gt;checkinstall&lt;&#x2F;code&gt; basically allows you to do is, instead of running the usual &lt;code&gt;make install&lt;&#x2F;code&gt; after the usual &lt;code&gt;configure&lt;&#x2F;code&gt; and &lt;code&gt;make&lt;&#x2F;code&gt; steps, it creates a Debian package (it also does RPMs and Slackware packages) for you that is easily un-installable with &lt;code&gt;dpkg&lt;&#x2F;code&gt;, and then proceeds to install the files just as it would have for any other deb.&lt;&#x2F;p&gt;
&lt;p&gt;On Ubuntu it&#x27;s really easy to install &lt;a href=&quot;http:&#x2F;&#x2F;asic-linux.com.mx&#x2F;~izto&#x2F;checkinstall&#x2F;&quot;&gt;checkinstall&lt;&#x2F;a&gt;, just:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install checkinstall&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, you no longer should type &#x27;make install&#x27; - always use the &#x27;checkinstall&#x27; command instead:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
.&#x2F;configure
make
sudo checkinstall # instead of &quot;make install&quot;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;checkinstall&lt;&#x2F;code&gt; will ask you a bunch of stuff but you can just go with the defaults for most of them - I did name my packages &#x27;XXX &lt;strong&gt;from source&lt;&#x2F;strong&gt;&#x27;, like &#x27;Subversion 1.4.3 from source&#x27; so it&#x27;s easier to check which packages are &lt;code&gt;checkinstall&lt;&#x2F;code&gt;-generated with a simple grep to &lt;code&gt;dpkg -l&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;checkinstall&lt;&#x2F;code&gt; generates a .deb (Debian) package before it actually installs your software (Subversion, in this case). It should tell you right at the end of its installation process about where to find this .deb and how to uninstall your newly installed (from source!) package (something like &lt;code&gt;dpkg -r subversion-1.4.3&lt;&#x2F;code&gt;). Don&#x27;t delete this .deb yet as we will be using it to install Subversion 1.4.x on our mirror SVN server.&lt;&#x2F;p&gt;
&lt;h3&gt;Installing an un-installable Subversion 1.4.x on Ubuntu&lt;&#x2F;h3&gt;
&lt;p&gt;Now, blessed with our new checkinstall-granted powers, we can install Subversion from source without any qualms. Before we start, be sure to purge any existing Subversion packages you may have installed (do note that if you&#x27;re using any packages that depend on the official Ubuntu Subversion packages, you may run into library version problems).&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
dpkg -l | grep svn
dpkg -l | grep subversion
&lt;p&gt;sudo dpkg --purge subversion
sudo dpkg --purge libsvn0&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now, it&#x27;s time to get the source. Get it from the &lt;a href=&quot;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;&quot;&gt;official Subversion website&lt;&#x2F;a&gt;. Look for the source code download - the file should be something like this: &lt;a href=&quot;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;downloads&#x2F;subversion-1.4.3.tar.gz&quot;&gt;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;downloads&#x2F;subversion-1.4.3.tar.gz&lt;&#x2F;a&gt;. Remember to get SVN dependencies (something like this: &lt;a href=&quot;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;downloads&#x2F;subversion-deps-1.4.3.tar.gz&quot;&gt;http:&#x2F;&#x2F;subversion.tigris.org&#x2F;downloads&#x2F;subversion-deps-1.4.3.tar.gz&lt;&#x2F;a&gt;) as well as these are needed for access to &#x27;http:&#x2F;&#x2F;&#x27; scheme SVN repositories. If you want to use Subversion to connect to a server via a http:&#x2F;&#x2F; or https:&#x2F;&#x2F; URL, you will require these dependencies (more specifically, the Neon library).&lt;&#x2F;p&gt;
&lt;p&gt;Use something efficient like wget, curl or &lt;a href=&quot;http:&#x2F;&#x2F;wilmer.gaast.net&#x2F;main.php&#x2F;axel.html&quot;&gt;Axel&lt;&#x2F;a&gt; (&lt;em&gt;love&lt;&#x2F;em&gt; Axel) to get the sources on the server where you want to install Subversion. Unpack them to the same directory. configure. make. &lt;strong&gt;checkinstall&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
tar zxf subversion-1.4.3.tar.gz
tar zxf subversion-deps-1.4.3.tar.gz 
cd subversion-1.4.3
.&#x2F;configure  # Be sure to read the INSTALL file for any options you may want to set (such as SSL)
make
sudo checkinstall&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you get a warning &quot;configure: WARNING: we have configured without BDB filesystem support&quot; during your &lt;code&gt;configure&lt;&#x2F;code&gt; step, you&#x27;ll get by just fine. Unless you specifically want your Subversion repositories in Berkeley DB format, we can ignore the warning (Subversion will use FSFS filesystem for your repositories) - see &lt;a href=&quot;http:&#x2F;&#x2F;svn.collab.net&#x2F;repos&#x2F;svn&#x2F;trunk&#x2F;notes&#x2F;fsfs&quot;&gt;FSFS notes&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.reposadmin.planning.html#svn.reposadmin.basics.backends&quot;&gt;Choosing a Data Store&lt;&#x2F;a&gt; if you want to make an educated decision.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, now with a brand new Subversion 1.4.x installed, we are finally ready for the real work - migrating your Subversion repository!&lt;&#x2F;p&gt;
&lt;h3&gt;Dumping and importing a repository&lt;&#x2F;h3&gt;
&lt;p&gt;Dumping a Subversion repository is dead easy:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
svnadmin dump &#x2F;path&#x2F;to&#x2F;repository &gt; repository_name.dump&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Depending on how big your repository is, you could end up with a pretty large dump file. gzip it, then scp it over to your new server, then gunzip it. Use svnadmin to load the repository dump.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
cd &#x2F;var&#x2F;svn  # I like to keep my svn repositories under &#x2F;var&#x2F;svn
mkdir repository_name
svnadmin create repository_name
svnadmin load repository_name &amp;lt; &#x2F;path&#x2F;to&#x2F;repository_name.dump&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you have a good pipe between the source and destination servers, you can do this in a one-liner:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;svnadmin dump &#x2F;path&#x2F;to&#x2F;repository | ssh -C [IP&#x2F;domain of destination server] svnadmin load &#x2F;path&#x2F;to&#x2F;new_repository&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, all this dumping would require a temporary suspension of any repository write actions otherwise you&#x27;re just going to have an inconsistent dump - just send out an email to your fellow developers and disable svn access.&lt;&#x2F;p&gt;
&lt;h3&gt;Setting up access to your new repository&lt;&#x2F;h3&gt;
&lt;p&gt;Now, you have a Subversion repository that is only accessible via the local filesystem (file:&#x2F;&#x2F; &#x27;protocol&#x27;), which isn&#x27;t very useful. We&#x27;ll need to setup remote access. Your Subversion repository can be accessed in a variety of ways, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.svnserve.html&quot;&gt;svnserve&lt;&#x2F;a&gt; standalone daemon (svn:&#x2F;&#x2F;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.svnserve.html&quot;&gt;svnserve&lt;&#x2F;a&gt; with &lt;code&gt;inetd&lt;&#x2F;code&gt; (svn:&#x2F;&#x2F;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.svnserve.html&quot;&gt;svnserve&lt;&#x2F;a&gt; over a SSH tunnel (svn+ssh:&#x2F;&#x2F;)&lt;&#x2F;li&gt;
&lt;li&gt;over the HTTP protocol (http:&#x2F;&#x2F; and https:&#x2F;&#x2F;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.svnserve.html&quot;&gt;svnserve documentation&lt;&#x2F;a&gt; details how to deal with the first 3, and setting up http:&#x2F;&#x2F; and https:&#x2F;&#x2F; access to your protocol is really a subject that deserves its own tutorial. Try the &lt;a href=&quot;http:&#x2F;&#x2F;svnbook.red-bean.com&#x2F;nightly&#x2F;en&#x2F;svn.serverconfig.httpd.html&quot;&gt;SVN book&lt;&#x2F;a&gt; or Google.&lt;&#x2F;p&gt;
&lt;p&gt;Personally I prefer svn+ssh:&#x2F;&#x2F; access for internal projects since it allows me to unify authentication for my Subversion repositories with UNIX user accounts. Be wary of an angry cadre Windows developers though, since they need to take quite a good number of steps to setup public key authentication and integrate it with their svn clients on Windows machines. Integration with TortoiseSVN is quite a pain, though my Windows-using colleague at work found these useful: &lt;a href=&quot;http:&#x2F;&#x2F;www.mono-project.com&#x2F;Putty_and_TortoiseSvn&quot;&gt;Putty and TortoiseSVN&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;brondsema.net&#x2F;blog&#x2F;index.php&#x2F;2005&#x2F;05&#x2F;03&#x2F;using_cygwin_keychain_svn_ssh_and_tortoi&quot;&gt;Using Cygwin, Keychain, SVN+SSH and TortoiseSVN in Windows&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4&gt;svn:&#x2F;&#x2F; access&lt;&#x2F;h4&gt;
&lt;p&gt;I also expose my repositories via svn:&#x2F;&#x2F; (as we&#x27;ll see later, this is useful for allowing access to a svnsync user without messing around with any UNIX user accounts) and use the &lt;code&gt;xinetd&lt;&#x2F;code&gt; daemon (&lt;code&gt;apt-get install xinetd&lt;&#x2F;code&gt; on Ubuntu to install) to launch svnserve process. If you&#x27;re taking this path, create a file (I name it &#x27;svn&#x27;) in &lt;code&gt;&#x2F;etc&#x2F;xinet.d&lt;&#x2F;code&gt; to tell xinetd about svnserve.&lt;&#x2F;p&gt;
&lt;p&gt;In &#x2F;etc&#x2F;xinet.d&#x2F;svn:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
service svn
{
        port                    = 3690
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = www-data
        server                  = &#x2F;usr&#x2F;local&#x2F;bin&#x2F;svnserve
        server_args             = -i -r &#x2F;var&#x2F;svn
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that I needed to use the full path to svnserve (do a &lt;code&gt;which svnserve&lt;&#x2F;code&gt; to get the full path, making sure this is the 1.4.x version that you just installed). The &lt;code&gt;server_args&lt;&#x2F;code&gt; parameter also bears some explanation. The &lt;code&gt;-i&lt;&#x2F;code&gt; option tells svnserve to use inetd (xinetd is a variant of inetd, sorta). The &lt;code&gt;-r &#x2F;var&#x2F;svn&lt;&#x2F;code&gt; option tells svnserve to only expose repositories below that path. This basically translates your repository at &lt;code&gt;&#x2F;var&#x2F;svn&#x2F;my_cool_project&lt;&#x2F;code&gt; to be accessible via &lt;code&gt;svn:&#x2F;&#x2F;your.hostname&#x2F;my_cool_project&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4&gt;svn+ssh:&#x2F;&#x2F; access&lt;&#x2F;h4&gt;
&lt;p&gt;Accessing your repository this way basically logs in to the host server of your repository over SSH, invokes the svnserve process, and accesses your repository in a very file:&#x2F;&#x2F;-like manner. What this means is that your repository path is taken from the root of your filesystem. An example: a repository located in &lt;code&gt;&#x2F;var&#x2F;svn&#x2F;my_cool_project&lt;&#x2F;code&gt; would be available at &lt;code&gt;svn+ssh:&#x2F;&#x2F;your.hostname&#x2F;var&#x2F;svn&#x2F;my_cool_project&lt;&#x2F;code&gt;. For this reason I often symlink &lt;code&gt;&#x2F;svn&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;var&#x2F;svn&lt;&#x2F;code&gt; (to get repository URLs like &lt;code&gt;svn+ssh:&#x2F;&#x2F;your.hostname&#x2F;svn&#x2F;my_cool_project&lt;&#x2F;code&gt; instead).&lt;&#x2F;p&gt;
&lt;h3&gt;Relocating working copies&lt;&#x2F;h3&gt;
&lt;p&gt;Now, all your working copies are still pointing to the old Subversion server - no need to fret, a simple &lt;code&gt;svn switch&lt;&#x2F;code&gt; fixes things:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;svn switch --relocate [from] [to]&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Replace &#x27;[from]&#x27; and &#x27;[to]&#x27; with the source and destination Subversion repository URLs.&lt;&#x2F;p&gt;
&lt;p&gt;Remember to stop access to your old server so no one is making commits to the wrong place.&lt;&#x2F;p&gt;
&lt;h3&gt;Setting up svnsync&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;d intended to write this entire piece in one blog post, but I&#x27;m running out of steam at this point. In &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;03&#x2F;31&#x2F;setting-up-svnsync-ed-mirrored-svn-repositories-on-ubuntu-part-2-of-2&#x2F;&quot;&gt;Part 2&lt;&#x2F;a&gt;, we&#x27;ll actually setup svnsync for some repository mirroring goodness!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>DRYing up link_to_remote for degradable URLs</title>
    <published>2007-03-24T23:20:08+00:00</published>
    <updated>2007-03-24T23:20:08+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/24/drying-up-link_to_remote-for-degradable-urls/"/>
    <id>https://chuyeow.wtf/2007/03/24/drying-up-link_to_remote-for-degradable-urls/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/24/drying-up-link_to_remote-for-degradable-urls/">&lt;p&gt;I like to keep my links in my Rails applications that make AJAX requests degradable in non-JavaScript browsers so I often find myself doing this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
link_to_remote &#x27;Show details&#x27;,
  { :url =&gt; { :action =&gt; &#x27;show&#x27;, :id =&gt; post.id } },
  { :href =&gt; url_for({ :action =&gt; &#x27;show&#x27;, :id =&gt; post.id }) }&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows me to get HTML links like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;a href=&quot;http:&#x2F;&#x2F;www.example.com&#x2F;posts&#x2F;show&#x2F;123&quot; onclick=&quot;...&quot;&amp;gt;Show details&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;instead of the usual (if the :href parameter is not specified):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;a href=&quot;#&quot; onclick=&quot;...&quot;&amp;gt;Show details&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You&#x27;ve probably already noticed the duplication right there in the &lt;code&gt;:url&lt;&#x2F;code&gt; key of the 2nd parameter (options) and the &lt;code&gt;:href&lt;&#x2F;code&gt; key of the 3rd parameter (HTML options) that litters my &lt;acronym title=&quot;embedded Ruby&quot;&gt;Erb&lt;&#x2F;acronym&gt; templates where link_to_remote calls are prevalent. I got tired of editing and copying and pasting the &lt;code&gt;url_for&lt;&#x2F;code&gt; parameters so I monkey patched Rails&#x27; PrototypeHelper class in ActionPack (&lt;code&gt;actionpack&#x2F;lib&#x2F;action_view&#x2F;helpers&#x2F;prototype_helper.rb&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;To do this, I had to replace Rails&#x27; &lt;code&gt;link_to_remote&lt;&#x2F;code&gt; method definition. Thanks to living and breathing code examples in Rails that do this, I was able to promptly come up with this module that I placed into the &lt;code&gt;lib&#x2F;&lt;&#x2F;code&gt; directory of my Rails application and &lt;code&gt;require&lt;&#x2F;code&gt; it in my &lt;code&gt;environment.rb&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
module Bezurk #:nodoc:
  module ActionView #:nodoc:
    module PrototypeHelperExtensions
      def self.included(base)
        base.alias_method_chain :link_to_remote, :degradation
      end
&lt;pre&gt;&lt;code&gt;  def link_to_remote_with_degradation(name, options = {}, html_options = {})
    html_options[:href] = url_for(options[:url]) if !html_options.has_key?(:href)
    link_to_remote_without_degradation(name, options, html_options)
  end
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;end
end&lt;&#x2F;p&gt;
&lt;p&gt;ActionView::Helpers::PrototypeHelper.send(:include,
Bezurk::ActionView::PrototypeHelperExtensions)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The modification to &lt;code&gt;link_to_remote&lt;&#x2F;code&gt; itself is dead simple: it checks for the non-existence of a &lt;code&gt;:href&lt;&#x2F;code&gt; key in the &lt;code&gt;html_options&lt;&#x2F;code&gt; parameter and sets the &lt;code&gt;:href&lt;&#x2F;code&gt; option in the &lt;code&gt;html_options&lt;&#x2F;code&gt; parameter hash to the &lt;code&gt;url_for&lt;&#x2F;code&gt; the &lt;code&gt;:url&lt;&#x2F;code&gt; value in the &lt;code&gt;options&lt;&#x2F;code&gt; parameter hash. It then calls the original &lt;code&gt;link_to_remote&lt;&#x2F;code&gt; to do what it does best.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve submitted a (trivially simple) patch to Rails in my opened &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;7904&quot;&gt;ticket #7904 - DRY up link_to_remote for degradable URLs&lt;&#x2F;a&gt;. Let&#x27;s hope this makes it in so I can kill my monkey patch!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Validate that favicon</title>
    <published>2007-03-10T13:50:55+00:00</published>
    <updated>2007-03-10T13:50:55+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/10/validate-that-favicon/"/>
    <id>https://chuyeow.wtf/2007/03/10/validate-that-favicon/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/10/validate-that-favicon/">&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;www.html-kit.com&#x2F;favicon&#x2F;validator&#x2F;&quot;&gt;Favicon validator&lt;&#x2F;a&gt; ensures that you have a correctly created &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Favicon&quot;&gt;favicon&lt;&#x2F;a&gt;. If you&#x27;re wondering why your favicon works in some browsers but not in others (like IE), it probably has an incorrect format.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;favicon-validator.png&quot; alt=&quot;Favicon validator results&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I also learnt from validating my favicons that you can actually place more than 1 version of the favicon image into the .ico file (it seems to be a container for these images rather than being an image itself).&lt;&#x2F;p&gt;
&lt;p&gt;Oh, and the same site also has a very handy &lt;a href=&quot;http:&#x2F;&#x2F;www.html-kit.com&#x2F;favicon&#x2F;&quot;&gt;Favicon generator&lt;&#x2F;a&gt; - I used this to fix some of my favicons, which used to be GIFs renamed with the .ico file extension. Very handy. &lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Firefox tips sharing session at WebSG meetup</title>
    <published>2007-03-03T03:07:20+00:00</published>
    <updated>2007-03-03T03:07:20+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/03/firefox-tips-sharing-session-at-websg-meetup/"/>
    <id>https://chuyeow.wtf/2007/03/03/firefox-tips-sharing-session-at-websg-meetup/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/03/firefox-tips-sharing-session-at-websg-meetup/">&lt;p&gt;&lt;ins&gt;&lt;a href=&quot;http:&#x2F;&#x2F;theory.isthereason.com&#x2F;&quot;&gt;Kevin&lt;&#x2F;a&gt; has uploaded a &lt;a href=&quot;http:&#x2F;&#x2F;video.google.com&#x2F;videoplay?docid=-1204328739390477176&quot;&gt;video of my session&lt;&#x2F;a&gt; on Google Video - it&#x27;s kinda grainy and really soft.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I was at the 2nd &lt;a href=&quot;http:&#x2F;&#x2F;websg.org&#x2F;&quot;&gt;WebSG&lt;&#x2F;a&gt; (Web Standards Group Singapore) meetup (&lt;a href=&quot;http:&#x2F;&#x2F;websg.org&#x2F;archives&#x2F;2007&#x2F;03&#x2F;recap_of_meetup_2.php&quot;&gt;read about the recap of the meetup&lt;&#x2F;a&gt;) on Wednesday (28 Feb 2007) where I hosted a short session on some Firefox tips. It&#x27;s all thanks the urgings and encouragement of &lt;a href=&quot;http:&#x2F;&#x2F;tribolum.com&#x2F;&quot;&gt;Lucian&lt;&#x2F;a&gt; (the organizer) that I finally got down to publicly sharing my Firefox knowledge ever since I wrote &lt;a href=&quot;http:&#x2F;&#x2F;sitepoint.com&#x2F;books&#x2F;firefox1&#x2F;&quot;&gt;Firefox Secrets&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;me-websg-meetup-2_thumb.png&quot; alt=&quot;Me at WebSG meetup 2&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I was asked to blog about this (since I didn&#x27;t have any presentation slides), so here it is, for those of you who missed anything in my mumbling or frantic keystrokes.&lt;&#x2F;p&gt;
&lt;h3&gt;Keyboard shortcuts you should know&lt;&#x2F;h3&gt;
&lt;p&gt;Note: Mac users should replace Ctrl with the Cmd key for any of the keystrokes listed below.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-L&lt;&#x2F;strong&gt; puts your cursor in the address bar, &lt;strong&gt;Ctrl-K&lt;&#x2F;strong&gt; puts your cursor in the search bar.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-T&lt;&#x2F;strong&gt; opens a new tab and puts your cursor in the address bar, but&lt;&#x2F;li&gt;
&lt;li&gt;I forgot to mention this during the session, but I personally prefer using Ctrl-L or Ctrl-K, typing in the new URL or search query, and hitting &lt;strong&gt;Alt-Enter&lt;&#x2F;strong&gt; open the new page or search result in a new tab - it just feels more accessible than Ctrl-T. Most people I observe still use Ctrl-T though.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-Shift-T&lt;&#x2F;strong&gt; re-opens closed tabs. Keep hitting it to reopen more closed tabs in your history. This is a &lt;em&gt;big&lt;&#x2F;em&gt; time saver. Newly built into Firefox 2.0.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-Tab&lt;&#x2F;strong&gt; and &lt;strong&gt;Ctrl-Shift-Tab&lt;&#x2F;strong&gt; brings you to the next and previous tab. If you&#x27;re having trouble remembering both, just remember that the usual convention is a Shift does the reverse. So all you need is to remember Ctrl-Tab, and adding a Shift modifier does the reverse (i.e. goes to the previous tab instead of the next).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-F&lt;&#x2F;strong&gt; brings up the Find bar, and you can start typing in whatever you want to find on the page &lt;em&gt;and&lt;&#x2F;em&gt; in any input fields. Use &lt;strong&gt;Ctrl-G&lt;&#x2F;strong&gt; and &lt;strong&gt;Ctrl-Shift-G&lt;&#x2F;strong&gt; to go to the next and previous occurences respectively. The Find bar is good, but...&lt;&#x2F;li&gt;
&lt;li&gt;I forgot to mention (as &lt;a href=&quot;http:&#x2F;&#x2F;www.daemonite.net&#x2F;&quot;&gt;Zul&lt;&#x2F;a&gt; mentioned to me after) during the session that &lt;strong&gt;Quick Find&lt;&#x2F;strong&gt; is much better. Just hit &lt;strong&gt;&#x2F;&lt;&#x2F;strong&gt; and start typing as you would for the normal Find bar, and the Quick Find bar will go away after several seconds. Much better in most cases than the Find bar which likes to stick around until you close it. And why is this important? Because the Find bar takes up screen real estate, especially for those of us using wide screens.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;Getting rid of the close button on all tabs&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve been told how annoying Firefox 2.0 is when it insists on putting a close button on each tab.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;firefox-close-buttons-on-each-tab.png&quot; alt=&quot;Firefox 2.0 - close buttons on each tab&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Accidental closing of tabs when you try to select them is one big complaint. Well, you can turn it off and go back to the good olde Firefox 1.5 days of a single close button on the extreme right of the tab bar. Enter &lt;strong&gt;about:config&lt;&#x2F;strong&gt; in your address bar, filter for &lt;strong&gt;browser.tabs.closeButtons&lt;&#x2F;strong&gt;, double click on the preference entry that shows up, and change the value from the default of 1, to 3. If you don&#x27;t want the close button on the right of the tab bar, enter a value of 2 (this assumes you&#x27;re going to close tabs with either Ctrl-W or middle-clicking on the tab - this is my prefered setup).&lt;&#x2F;p&gt;
&lt;h3&gt;Backing up your profile&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;mozbackup.jasnapaka.com&#x2F;&quot;&gt;MozBackup&lt;&#x2F;a&gt; is all you ever need if you use Windows exclusively. This neat little (Windows-only) application backs up your profile into a single file - all you need is to use a very simple wizard. And of course, you can restore your profile just as easily. I loved this when I was still using Windows.&lt;&#x2F;p&gt;
&lt;p&gt;Like I said, people using other operating systems can easily DIY - just read &lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.org&#x2F;support&#x2F;firefox&#x2F;profile&quot;&gt;Mozilla&#x27;s official documentation on Firefox profiles&lt;&#x2F;a&gt;. You&#x27;re probably using either Mac OS X or some Linux distro - you can do this without any hand-holding ;)&lt;&#x2F;p&gt;
&lt;h4&gt;What about backing up extensions?&lt;&#x2F;h4&gt;
&lt;p&gt;Some people asked me during and after my session about backing up extensions. &lt;a href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;firefox&#x2F;2109&#x2F;&quot;&gt;FEBE&lt;&#x2F;a&gt; is one extension you can look at unless you use a Mac (I tried the beta version that supports Mac OS X, but gave up when I couldn&#x27;t get it to use the correct binaries for zipping and unzipping.)&lt;&#x2F;p&gt;
&lt;p&gt;My personal take on backing up extensions: &lt;em&gt;don&#x27;t&lt;&#x2F;em&gt; back them up. I prefer to dump a list of extensions (I use &lt;a href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;firefox&#x2F;3746&#x2F;&quot;&gt;the Extension List Dumper extension&lt;&#x2F;a&gt;) that I have installed and just re-install them again. This is no big chore for me now since I have significantly fewer extensions installed than back in the day. I just like starting clean, after having had bad experiences with restoring extensions from backup before.&lt;&#x2F;p&gt;
&lt;p&gt;Still, if you really want to back up your extensions, I say just go ahead and see if it works (MozBackup and FEBE should work).&lt;&#x2F;p&gt;
&lt;h3&gt;Profiles and &quot;why is my Firefox so damn slow?&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;This is one thing I had planned to mention but I got kinda threw off kilter when the slowness of the wireless internet connection made me worried about quitting Firefox (didn&#x27;t want to quit Firefox, load up another profile, only to find that it&#x27;d take another 5 mins to get my demo tabs loaded again).&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, some questions I often get is, &quot;why is my Firefox so slow?&quot; and &quot;why does Firefox use up so much RAM&#x2F;CPU?&quot; The first thing I suspect is a busted profile. Whenever I experience intolerable slowness in my Firefox setup, I dump and restore my profile into a newly created profile, minus all the tab history information (and of course, never restoring backed up extensions). Sometimes I even start clean new profiles, importing only bookmarks. You&#x27;ll very likely notice immediately that Firefox is back to its old speediness. And if anything happens, you still have your old profile with you.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not that certain of what exactly causes Firefox to get too slow over time, but my suspicions lie with:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Firefox saving browsing history in all the bazillion tabs you have open - that&#x27;s a lot of data to be carrying around&lt;&#x2F;li&gt;
&lt;li&gt;broken&#x2F;bad extensions&lt;&#x2F;li&gt;
&lt;li&gt;a busted profile
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;profile-manager&quot;&gt;Profile management for productivity&lt;&#x2F;h3&gt;
&lt;p&gt;Firefox hides its Profile Manager from you. You can access it by passing the &lt;strong&gt;-profilemanager&lt;&#x2F;strong&gt; switch to your Firefox executable. For Windows users, it&#x27;s actually &lt;strong&gt;--profilemanager&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;firefox-profile-manager.png&quot; alt=&quot;Firefox profile manager&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Profile Manager is really handy for people who need to remove distractions. For me, I setup different profiles for work and for play so I don&#x27;t become distracted the &quot;play&quot; tabs I have open while I&#x27;m working (I&#x27;m beginning to like the &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;03&#x2F;02&#x2F;tab-groups-for-firefox-best-extension-since-sliced-bread-er-tabbed-browsing&#x2F;&quot;&gt;Tab Groups extension for segregating tabs&lt;&#x2F;a&gt; more though). Also really handy for setting up clean profiles for running user demos (I setup a WebSG profile for my presentation and installed specific extensions I wanted to talk about) - don&#x27;t really want to have your naughty browser history showing up in some autocomplete heh.&lt;&#x2F;p&gt;
&lt;h3&gt;Some extensions I dig&lt;&#x2F;h3&gt;
&lt;p&gt;I also demoed some extensions that I find essential.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;firefox&#x2F;26&#x2F;&quot;&gt;Download Statusbar&lt;&#x2F;a&gt; for unobtrusive downloads.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;addons.mozilla.org&#x2F;firefox&#x2F;12&#x2F;&quot;&gt;All-in-One Gestures&lt;&#x2F;a&gt; for easily accessible Back and Forward gestures when you happen to have your hand on the mouse. Like I said, I don&#x27;t use any of the other gestures because they all require memorization (I use too much of my memory storing keyboard shortcuts).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;mozilla.code65536.com&#x2F;&quot;&gt;Super DragAndGo&lt;&#x2F;a&gt; for drag and drop searching. Great time saver when you are doing online research.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;chrispederick.com&#x2F;work&#x2F;webdeveloper&#x2F;&quot;&gt;Web Developer toolbar&lt;&#x2F;a&gt; for its convenient Disable Cache, browser resizing, and HTML validation shortcut (Ctrl-Shift-A).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;addons.mozilla.org&#x2F;firefox&#x2F;1290&#x2F;&quot;&gt;UrlParams&lt;&#x2F;a&gt; for easy viewing and editing of GET or POST parameters.&lt;&#x2F;li&gt;
&lt;li&gt;And of course, &lt;a href=&quot;http:&#x2F;&#x2F;getfirebug.com&#x2F;&quot;&gt;Firebug&lt;&#x2F;a&gt; - godsend for web developers, web designers, and especially AJAX developers like &lt;a href=&quot;http:&#x2F;&#x2F;www.bezurk.com&#x2F;&quot;&gt;us&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Oh, and &lt;a href=&quot;http:&#x2F;&#x2F;boinx.com&#x2F;mousepose&#x2F;&quot;&gt;Mousepose&lt;&#x2F;a&gt; was the application I used to get my keystrokes to show up on the screen. It&#x27;s simple yet extremely helpful for presentations, though I probably should have used the mouse spotlight feature more. Oh well, I did just buy the license for it a few hours before the meetup - goes to show how unprepared I was heh.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s late and I&#x27;ll blog more on the event and the people I met another day.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Finally, Bezurk and news.com.au co-brand is up and running</title>
    <published>2007-02-25T01:01:18+00:00</published>
    <updated>2007-02-25T01:01:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/02/25/finally-bezurk-and-newscomau-co-brand-is-up-and-running/"/>
    <id>https://chuyeow.wtf/2007/02/25/finally-bezurk-and-newscomau-co-brand-is-up-and-running/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/02/25/finally-bezurk-and-newscomau-co-brand-is-up-and-running/">&lt;p&gt;It was a few weeks later than planned, but finally (actually, about 3 days ago), &lt;a href=&quot;http:&#x2F;&#x2F;www.bezurk.com&#x2F;&quot;&gt;we&lt;&#x2F;a&gt;&#x27;re up on the &lt;a href=&quot;http:&#x2F;&#x2F;www.news.com.au&#x2F;travel&quot;&gt;News.com.au Travel section&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;No thanks to a &lt;a href=&quot;http:&#x2F;&#x2F;meyerweb.com&#x2F;eric&#x2F;thoughts&#x2F;2004&#x2F;09&#x2F;16&#x2F;when-browsers-attack&#x2F;&quot;&gt;CSS bug in IE6&lt;&#x2F;a&gt;, we were delayed by a week. The last thing we expected was a CSS bug hanging IE6 with all the JavaScript we were pushing out, but yeah, well, it was. At least now my conscience is clear - everything works nicely in IE6, IE7, Firefox, Safari and Opera.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Determining web page size - the wrong way</title>
    <published>2007-02-05T20:03:27+00:00</published>
    <updated>2007-02-05T20:03:27+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/02/05/determining-web-page-size-the-wrong-way/"/>
    <id>https://chuyeow.wtf/2007/02/05/determining-web-page-size-the-wrong-way/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/02/05/determining-web-page-size-the-wrong-way/">&lt;p&gt;Got an email today that disputed web page sizes I reported (diplomatically telling me to get my facts right):&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;Regarding the size, if you save the homepage as webpage complete you can get the size of the iframes files individually.&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;&amp;lt;teenage-angst&amp;gt;Ick... Learn to use &lt;a href=&quot;http:&#x2F;&#x2F;getfirebug.com&#x2F;&quot;&gt;Firebug&lt;&#x2F;a&gt; or a &lt;a href=&quot;http:&#x2F;&#x2F;www.websiteoptimization.com&#x2F;services&#x2F;analyze&#x2F;&quot;&gt;Web Page Analyzer&lt;&#x2F;a&gt;. Or anything else that does better than saving the page from a web browser.&amp;lt;&#x2F;teenage-angst&amp;gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Essential Firebug video for web developers</title>
    <published>2007-01-28T14:41:45+00:00</published>
    <updated>2007-01-28T14:41:45+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/01/28/essential-firebug-video-for-web-developers/"/>
    <id>https://chuyeow.wtf/2007/01/28/essential-firebug-video-for-web-developers/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/01/28/essential-firebug-video-for-web-developers/">&lt;p&gt;If you&#x27;re doing web development or design of any sort, you have to check out &lt;a href=&quot;http:&#x2F;&#x2F;www.yuiblog.com&#x2F;blog&#x2F;2007&#x2F;01&#x2F;26&#x2F;video-hewitt-firebug&#x2F;&quot;&gt;Joe Hewitt&#x27;s talk on Firebug at Yahoo!&lt;&#x2F;a&gt; - download the movie or watch it online, just make sure you watch it.&lt;&#x2F;p&gt;
&lt;p&gt;If you aren&#x27;t already using &lt;a href=&quot;http:&#x2F;&#x2F;getfirebug.com&#x2F;&quot;&gt;Firebug&lt;&#x2F;a&gt;, this will convince you. If you are, you&#x27;ll probably find some gems in there that you didn&#x27;t know before. I didn&#x27;t know that you could log events to elements on the fly, or press the up and down arrow keys to adjust numerical values (such as margins and paddings), or edit the values in the box model layout diagram, or hover over variable names to see a tooltip of their values in the JavaScript debugger, or conditional breakpoints.&lt;&#x2F;p&gt;
&lt;p&gt;Now if only it were able to detect JavaScript syntax errors that cause an entire JS file to be ignored by the browser. &lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>BarCamp Singapore Jan 2007</title>
    <published>2007-01-21T00:21:21+00:00</published>
    <updated>2007-01-21T00:21:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/01/21/barcamp-singapore-jan-2007/"/>
    <id>https://chuyeow.wtf/2007/01/21/barcamp-singapore-jan-2007/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/01/21/barcamp-singapore-jan-2007/">&lt;p&gt;I just got back from &lt;a href=&quot;http:&#x2F;&#x2F;barcamp.org&#x2F;BarCampSingapore&quot;&gt;BarCamp Singapore&lt;&#x2F;a&gt; a few hours ago. I was only vaguely familiar with the &lt;a href=&quot;http:&#x2F;&#x2F;barcamp.org&#x2F;TheRulesOfBarCamp&quot;&gt;Rules of BarCamp&lt;&#x2F;a&gt; prior to this, and actually only found out about the event from &lt;a href=&quot;http:&#x2F;&#x2F;blog.yanime.org&#x2F;&quot;&gt;Choon Keat&lt;&#x2F;a&gt; (of &lt;a href=&quot;http:&#x2F;&#x2F;rssfwd.com&#x2F;&quot;&gt;RssFwd&lt;&#x2F;a&gt; fame - check it out if you haven&#x27;t already) 2 days ago.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, props to the organizers for putting this together (especially the free BarCamp t-shirts from Yahoo!). Personally, I felt the icebreaker game took up too much time that could have been used for the sharing sessions - the tech track of sessions were crammed up towards the end of BarCamp.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;barcampsingapore.png&quot; alt=&quot;BarCamp Singapore logo&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notably, &lt;a href=&quot;http:&#x2F;&#x2F;poundbang.in&#x2F;&quot;&gt;Harish Mallipeddi&lt;&#x2F;a&gt;, who interned at &lt;a href=&quot;http:&#x2F;&#x2F;www.bezurk.com&#x2F;&quot;&gt;Bezurk&lt;&#x2F;a&gt; for a couple of months, shared with us an introduction to &lt;a href=&quot;http:&#x2F;&#x2F;www.djangoproject.com&#x2F;&quot;&gt;Django&lt;&#x2F;a&gt; together with some working code on a site he is working on. I didn&#x27;t know a whole lot about Django before and was impressed that there is a &quot;free&quot; admin application for Django applications. We (Choon Keat, Harish, and I) had a small debate over Django&#x27;s templating system (briefly, Django has it&#x27;s own templating system for its views, whereas Rails ERB is basically Ruby code mixed in HTML). To this day I am still convinced that PHP is already a templating language despite my old &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepoint.com&#x2F;article&#x2F;smarty-php-template-engine&quot;&gt;Smarty card-carrying days&lt;&#x2F;a&gt;. Relating back to the Django templating system, Choon Keat and I didn&#x27;t like the idea of having to learn to use a templating language when the base language itself (Ruby or Python) would suffice. Obviously Python syntax wasn&#x27;t suitable for web designer consumption so Django had to come up with its own templating language.&lt;&#x2F;p&gt;
&lt;p&gt;Michael from &lt;a href=&quot;http:&#x2F;&#x2F;www.petrolwatch.com.sg&#x2F;&quot;&gt;PetrolWatch&lt;&#x2F;a&gt; showed us some flashy scriptaculous effects on his site and demoed the Ruby on Rails-inspired &lt;a href=&quot;http:&#x2F;&#x2F;www.cakephp.org&#x2F;&quot;&gt;CakePHP&lt;&#x2F;a&gt;. It&#x27;s a nice framework if you had to use PHP and performance is a concern (it&#x27;s true, Rails apps run more heavily than PHP scripts, and the difference in performance is very clear in servers with minimal resources). But the lack of a good testing framework was discouraging. Still, I must say I&#x27;d have used it (or a similiar framework) if Rails didn&#x27;t exist or if I was tied to using PHP for web development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;blog.yanime.org&#x2F;&quot;&gt;Choon Keat&lt;&#x2F;a&gt; showed the non-believers the power of Rails&#x27; &lt;code&gt;script&#x2F;console&lt;&#x2F;code&gt; as well as the flexibility of Ruby in allowing developers to make their own extensions to existing classes (aka &quot;who needs hooks from God?&quot;). I probably should have stepped in and showed some basic Rails migrations stuff that would have impressed (hopefully) the Django and CakePHP fanbase (all 2 of them) - but my laptop was running out of battery (and I was shy).&lt;&#x2F;p&gt;
&lt;p&gt;Oh and I saw a good number of Macs there, and at least 3 laptops running a Linux distro of some sort. Cool.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Job Ad: Java Web Developer for Bezurk</title>
    <published>2006-09-22T20:37:35+00:00</published>
    <updated>2006-09-22T20:37:35+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/09/22/job-ad-java-web-developer-for-bezurk/"/>
    <id>https://chuyeow.wtf/2006/09/22/job-ad-java-web-developer-for-bezurk/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/09/22/job-ad-java-web-developer-for-bezurk/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;bezurk.com&#x2F;&quot;&gt;We&lt;&#x2F;a&gt;&#x27;re on the lookout for a &lt;a href=&quot;http:&#x2F;&#x2F;singapore.craigslist.org&#x2F;sof&#x2F;209737528.html&quot;&gt;Java Web Developer (ad on Craigslist)&lt;&#x2F;a&gt;. I managed to get &quot;Ruby on Rails&quot; into the ad copy somewhere heh - it gets kinda lonely working in a development team of Java heads. Anyway, we&#x27;re looking for a great Java developer to work with us in Singapore - if you&#x27;re up for it, &lt;a href=&quot;mailto:devel@bezurk.com&quot;&gt;send us your resume&lt;&#x2F;a&gt;. I would really like to get someone with some interest in Rails development to work together with on some upcoming (Rails) projects (you know, like after all the real work is done).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Unobtrusive IFrame shim - a half solution</title>
    <published>2006-08-01T19:33:50+00:00</published>
    <updated>2006-08-01T19:33:50+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/01/unobtrusive-iframe-shim-a-half-solution/"/>
    <id>https://chuyeow.wtf/2006/08/01/unobtrusive-iframe-shim-a-half-solution/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/01/unobtrusive-iframe-shim-a-half-solution/">&lt;p&gt;Something that really bugged me when using &lt;a href=&quot;http:&#x2F;&#x2F;developer.yahoo.com&#x2F;yui&#x2F;calendar&#x2F;&quot;&gt;YUI Calendars&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;developer.yahoo.com&#x2F;yui&#x2F;autocomplete&quot;&gt;YUI AutoComplete&lt;&#x2F;a&gt; widgets was how IFrame shims are currently being managed in libraries and home-brewed code (we use IFrame shims in many places as well). YUI Calendars doesn&#x27;t have a built-in IFrame shim, YUI AutoComplete has its own, and we use our own IFrame shim library.&lt;&#x2F;p&gt;
&lt;p&gt;For the uninitiated, IFrame shims are basically IFrames dynamically inserted (hence &quot;shim&quot;) under overlaying DOM elements so that any &amp;lt;select&amp;gt; elements do not show through in IE 5.5 and above. A common example would be dynamically generated divs that float on top of drop downs in forms, such as the Yahoo! Calendar widget example below.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;see-thru-select-box.png&quot; alt=&quot;An example of the select box see through problem in IE 5.5+&quot; &#x2F;&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So anyway, the thing that&#x27;s bugging me is the awkwardness in inserting IFrame shims where they are needed and the duplication of unnecessary code to create, show, and hide the IFrame shims. Ideally, I&#x27;d like to do something like this to attach IFrame shims and forget about them:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;var iframeShim = new net.codefront.IFrameShim(&#x27;elementId&#x27;);&lt;&#x2F;div&gt;
&lt;p&gt;Or the conceptually nicer way of attaching IFrame shim &quot;behavior&quot;:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;net.codefront.IFrameShim.attachShim($(&#x27;elementId&#x27;));&lt;&#x2F;div&gt;
&lt;p&gt;No need for manually displaying and hiding the IFrame shim, polluting display logic and event handlers. I don&#x27;t care how all that shimming is done nor should I have to. I don&#x27;t want to have to call displayShim() whenever I display a floating div and hideShim() when I hide it. It should be smart enough to display the shim when the overlay is showing and to hide when the overlay is no longer visible.&lt;&#x2F;p&gt;
&lt;p&gt;As it is, I am seeing code duplicated in many places to manage these IFrame shims, and that&#x27;s a &lt;a href=&quot;http:&#x2F;&#x2F;c2.com&#x2F;xp&#x2F;CodeSmell.html&quot;&gt;bad smell&lt;&#x2F;a&gt;. Ahh ahh, before I go further, I am completely aware that I could be completely off-base and such a miraculous time-saver of a library already exists. If so, I want to know!&lt;&#x2F;p&gt;
&lt;p&gt;Trying to fix this problem, I came up with this &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;examples&#x2F;iframeshim.js&quot;&gt;bit of JavaScript&lt;&#x2F;a&gt;, which you shouldn&#x27;t bother reading. The idea is to allow me to do this:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;var shim = new com.bezurk.widget.IFrameShim(&#x27;myFloatingCalendar&#x27;);&lt;br &#x2F;&gt;
shim.manualShim = false;&lt;br &#x2F;&gt;
shim.manualDeshim = false;&lt;&#x2F;div&gt;
&lt;p&gt;And I have a &#x27;myFloatingCalendar&#x27; element that&#x27;s automagically shimmed whenever it&#x27;s displayed. (The shim.manualShim and shim.manualDeshim are defaulted to false, and are shown purely for explanatory purposes.)&lt;&#x2F;p&gt;
&lt;p&gt;There is one problem though - I can&#x27;t figure out an elegant way to &quot;listen&quot; to the display and hide events of the element that&#x27;s shimmed. The way I&#x27;ve done it is to rely on &lt;a href=&quot;http:&#x2F;&#x2F;www.sergiopereira.com&#x2F;articles&#x2F;prototype.js.html#Reference.PeriodicalExecuter&quot;&gt;Prototype&#x27;s PeriodicalExecuter&lt;&#x2F;a&gt; (extended to support a stop() method) to poll for the visibility of the element. Naturally this is an ugly hack and causes noticeable flicker.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve looked at custom events (YUI and Dojo have &lt;em&gt;very nice&lt;&#x2F;em&gt; event handling libraries) but can&#x27;t see how to hook this up unobtrusively. If you have a suggestion or a solution, I want to hear it!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>The first rule of Maintenance is - you do not talk about Maintenance</title>
    <published>2006-07-05T17:57:02+00:00</published>
    <updated>2006-07-05T17:57:02+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/07/05/the-first-rule-of-maintenance-is-you-do-not-talk-about-maintenance/"/>
    <id>https://chuyeow.wtf/2006/07/05/the-first-rule-of-maintenance-is-you-do-not-talk-about-maintenance/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/07/05/the-first-rule-of-maintenance-is-you-do-not-talk-about-maintenance/">&lt;p&gt;What would Tyler Durden do if he had to bring down his Web 2.0 service for maintenance?&lt;&#x2F;p&gt;
&lt;p&gt;Someone in the office thought &lt;a href=&quot;http:&#x2F;&#x2F;www.bezurk.com&#x2F;maintenance.html&quot;&gt;this message&lt;&#x2F;a&gt; would be appropriate.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Wufoo - Cool AJAX form builder</title>
    <published>2006-03-26T17:45:41+00:00</published>
    <updated>2006-03-26T17:45:41+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/03/26/wufoo-cool-ajax-form-builder/"/>
    <id>https://chuyeow.wtf/2006/03/26/wufoo-cool-ajax-form-builder/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/03/26/wufoo-cool-ajax-form-builder/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;wufoo.com&#x2F;&quot;&gt;Wufoo&lt;&#x2F;a&gt; - try the &lt;a href=&quot;http:&#x2F;&#x2F;wufoo.com&#x2F;demo&#x2F;&quot;&gt;demo&lt;&#x2F;a&gt;. Very impressive (strange how I find this more impressive than Ajax Write).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Simple anti-comment spam measure</title>
    <published>2004-11-05T17:47:18+00:00</published>
    <updated>2004-11-05T17:47:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/11/05/simple-anti-comment-spam-measure/"/>
    <id>https://chuyeow.wtf/2004/11/05/simple-anti-comment-spam-measure/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/11/05/simple-anti-comment-spam-measure/">&lt;p&gt;Thanks to &lt;a href=&quot;http:&#x2F;&#x2F;www.e.kth.se&#x2F;~strang&#x2F;blog&#x2F;archives&#x2F;2004&#x2F;10&#x2F;spam_measures_m.html&quot;&gt;Patrick Strang&lt;&#x2F;a&gt; who pointed me to &lt;a href=&quot;http:&#x2F;&#x2F;www.stefangeens.com&#x2F;000381.html&quot;&gt;Steven Geen&#x27;s simple anti-comment spam measure&lt;&#x2F;a&gt; for MovableType, I managed to stem the current flow of &quot;Please approve this comment&quot; emails flooding my inbox. This has been happening since last Saturday! Argh! Why are they doing this even when everything goes into the moderation queue?&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, it&#x27;s so simple to get this into WordPress - just edit wp-comments.php and wp-comments-post.php to add the field to the comment form (see below) and die() when the correct &quot;letter of the day&quot; isn&#x27;t entered. (Though die()ing isn&#x27;t the most elegant way, but WordPress does this for the other fields as well.)&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;anti-spam-todays-letter.png&quot; alt=&quot;Screenshot of anti-spam field&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Check out the &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2004&#x2F;11&#x2F;05&#x2F;simple-anti-comment-spam-measure&#x2F;#commentReply&quot;&gt;comment form&lt;&#x2F;a&gt; if the picture above is too small. Sorry to have to put you commentors through this, but it&#x27;s really for my sanity. At least it isn&#x27;t one of those randomly-generated graphical thingies that really ensures you are human (or an equivalent intelligent lifeform).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>MySQL 4.1 production-ready</title>
    <published>2004-10-28T11:27:39+00:00</published>
    <updated>2004-10-28T11:27:39+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/10/28/mysql-41-production-ready/"/>
    <id>https://chuyeow.wtf/2004/10/28/mysql-41-production-ready/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/10/28/mysql-41-production-ready/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.mysql.com&#x2F;news-and-events&#x2F;press-release&#x2F;release_2004_32.html&quot;&gt;MySQL Version 4.1 Certified as Production-Ready&lt;&#x2F;a&gt;. Still waiting for the &lt;a href=&quot;http:&#x2F;&#x2F;dev.mysql.com&#x2F;downloads&#x2F;mysql&#x2F;4.1.html&quot;&gt;MySQL 4.1.7&lt;&#x2F;a&gt; ebuild (relevant bugs - &lt;a href=&quot;http:&#x2F;&#x2F;bugs.gentoo.org&#x2F;show_bug.cgi?id=62582&quot;&gt;MySQL 4.1.6 ebuild&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;bugs.gentoo.org&#x2F;show_bug.cgi?id=67871&quot;&gt;request to include mysql 4.1.6 in portage and add ~amd64&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>How &quot;well designed, popular and accessible&quot; is your website?</title>
    <published>2004-10-27T23:58:28+00:00</published>
    <updated>2004-10-27T23:58:28+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/10/27/how-well-designed-popular-and-accessible-is-your-website/"/>
    <id>https://chuyeow.wtf/2004/10/27/how-well-designed-popular-and-accessible-is-your-website/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/10/27/how-well-designed-popular-and-accessible-is-your-website/">&lt;p&gt;You&#x27;d probably already have heard of or seen &lt;a href=&quot;http:&#x2F;&#x2F;sitescore.silktide.com&#x2F;&quot;&gt;Silktide Sitescore&lt;&#x2F;a&gt; that purports to &quot;rate how well designed, popular and accessible your website is&quot;. A while back it used to tell me I was a criminal for having an inaccessible website. I got sub-5 scores and a close-to-zero score for accessibility. I was surprised but attributed it the script doing something wrong somewhere (it is automated after all and &lt;a href=&quot;http:&#x2F;&#x2F;www.contentquality.com&#x2F;&quot;&gt;Cynthia&lt;&#x2F;a&gt; did tell me my site was OK in terms of accessibility).&lt;&#x2F;p&gt;
&lt;p&gt;Recently, after reading &lt;a href=&quot;http:&#x2F;&#x2F;www.ingoal.info&#x2F;archives&#x2F;2004&#x2F;10&#x2F;26&#x2F;silktide-sitescore-update&#x2F;&quot;&gt;Ingoal&#x27;s post on an update to his score&lt;&#x2F;a&gt;, I tried out Silktide again and to my surprise, got a respectable 8.6. (&lt;a href=&quot;http:&#x2F;&#x2F;www.ingoal.info&#x2F;archives&#x2F;2004&#x2F;10&#x2F;26&#x2F;silktide-sitescore-update&#x2F;&quot;&gt;Ingoal&#x27;s&lt;&#x2F;a&gt; a fellow Advisor at &lt;a href=&quot;http:&#x2F;&#x2F;sitepoint.com&#x2F;&quot;&gt;SitePoint&lt;&#x2F;a&gt; - this guy &lt;em&gt;knows&lt;&#x2F;em&gt; computers.) After some fixing some XHTML-validation borkage, I eked out a 10 for accessibility and managed to get a 9.2 overall score (and a 9.3 once). That puts me in the top 10 (true to &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2004&#x2F;10&#x2F;27&#x2F;made-it-into-spread-firefox-weekly-roll-call-top-5-climbers&#x2F;&quot;&gt;form&lt;&#x2F;a&gt;, I&#x27;m right at the bottom at number 10 below &lt;a href=&quot;http:&#x2F;&#x2F;sitepoint.com&#x2F;&quot;&gt;SitePoint&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;silktide-sitescores.png&quot; alt=&quot;Screenshot of Silktide SiteScore rankings with chuyeow.wtf in 10th position&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not sure it means anything except that it goes to show what a poor boy I must be to keep posting about rankings and scores. Perhaps it&#x27;s my low self-esteem working here.&lt;&#x2F;p&gt;
&lt;p&gt;But I have to say again, &lt;strong&gt;thank you&lt;&#x2F;strong&gt; for your donations to Firefox and keep donating whether you do so via my donation link or not! (What am I talking about? &lt;a href=&quot;http:&#x2F;&#x2F;www.spreadfirefox.com&#x2F;?q=node&#x2F;view&#x2F;3749&quot;&gt;Read more&lt;&#x2F;a&gt;. &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2004&#x2F;10&#x2F;24&#x2F;6-more-days-to-show-your-support-for-firefox&#x2F;&quot;&gt;This too&lt;&#x2F;a&gt;.)&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Portions of Spamx plugin for Geeklog minimally based on MT-Blacklist Updater</title>
    <published>2004-10-24T14:07:52+00:00</published>
    <updated>2004-10-24T14:07:52+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/10/24/portions-of-spamx-plugin-for-geeklog-minimally-based-on-mt-blacklist-updater/"/>
    <id>https://chuyeow.wtf/2004/10/24/portions-of-spamx-plugin-for-geeklog-minimally-based-on-mt-blacklist-updater/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/10/24/portions-of-spamx-plugin-for-geeklog-minimally-based-on-mt-blacklist-updater/">&lt;p&gt;Part of the &lt;a href=&quot;http:&#x2F;&#x2F;www.pigstye.net&#x2F;gplugs&#x2F;staticpages&#x2F;index.php&#x2F;spamx&quot;&gt;Spamx plugin&lt;&#x2F;a&gt; for &lt;a href=&quot;http:&#x2F;&#x2F;geeklog.net&quot;&gt;Geeklog&lt;&#x2F;a&gt; (a PHP blogging script) proclaims to be based on &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;scripts&#x2F;blacklistupdater&#x2F;&quot;&gt;MT-Blacklist Updater&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;cvs.geeklog.net&#x2F;co.php&#x2F;geeklog-1.3&#x2F;plugins&#x2F;spamx&#x2F;MassDelete.Admin.class.php&quot;&gt;MassDelete.Admin.class.php&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;cvs.geeklog.net&#x2F;co.php&#x2F;geeklog-1.3&#x2F;plugins&#x2F;spamx&#x2F;Import.Admin.class.php&quot;&gt;Import.Admin.class.php&lt;&#x2F;a&gt;). I hardly see the similarity though.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>LiveSearch hack for WordPress</title>
    <published>2004-10-24T00:06:57+00:00</published>
    <updated>2004-10-24T00:06:57+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/10/24/livesearch-hack-for-wordpress/"/>
    <id>https://chuyeow.wtf/2004/10/24/livesearch-hack-for-wordpress/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/10/24/livesearch-hack-for-wordpress/">&lt;p&gt;I found this old link on &lt;a href=&quot;http:&#x2F;&#x2F;blog.bitflux.ch&#x2F;wiki&#x2F;LiveSearch&quot;&gt;LiveSearch&lt;&#x2F;a&gt; that I&#x27;d wanted to implement here but never got around to doing so until now. It&#x27;s really quite a bit of a hack right now, with most of the code coming from the &lt;a href=&quot;http:&#x2F;&#x2F;blog.bitflux.ch&#x2F;wiki&#x2F;LiveSearch&quot;&gt;LiveSearch page on the Bitflux Blog wiki&lt;&#x2F;a&gt; and with direct calls to PHP&#x27;s MySQL functions to get it to work with WordPress.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of replacing the default WordPress search box, I decided to add another one instead (that you can see right now on the left just below the &quot;standard&quot; search box) and label it a &quot;LiveSearch&quot; box. I do this because livesearch.js seems to crash Firefox randomly on occasion (as mentioned on &lt;a href=&quot;http:&#x2F;&#x2F;blog.bitflux.ch&#x2F;archive&#x2F;livesearch_roundup.html&quot;&gt;Bitflux blog&lt;&#x2F;a&gt;). Besides, it&#x27;s hardly fully done, as it currently only does simple SQL LIKE matching on post titles, and the CSS is somewhat inelegant.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, what I did was to add livesearch.js to the WordPress index template, and added the LiveSearch form.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;form id=&quot;livesearchform&quot; method=&quot;get&quot; action=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;livesearch.php&quot;&amp;gt;&lt;br &#x2F;&gt;
  &amp;lt;input autocomplete=&quot;off&quot; id=&quot;livesearch&quot; name=&quot;q&quot; onkeypress=&quot;liveSearchStart()&quot; type=&quot;text&quot; &#x2F;&amp;gt;&lt;br &#x2F;&gt;
  &amp;lt;input id=&quot;submitted&quot; name=&quot;submitted&quot; value=&quot;yes&quot; type=&quot;hidden&quot; &#x2F;&amp;gt;&lt;br &#x2F;&gt;
  &amp;lt;div id=&quot;LSResult&quot; style=&quot;display: none;&quot;&amp;gt;&amp;lt;div id=&quot;LSShadow&quot;&amp;gt;&amp;lt;&#x2F;div&amp;gt;&amp;lt;&#x2F;div&amp;gt;&lt;br &#x2F;&gt;
&amp;lt;&#x2F;form&amp;gt;&lt;&#x2F;div&gt;
&lt;p&gt;Next, I hacked out a livesearch.php script (&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;livesearch.phps&quot;&gt;source listing for livesearch.php&lt;&#x2F;a&gt;) that performs the relevant query on WordPress&#x27; wp_posts table (may be differently named on your installation) and returns an XML document containing the matching post titles and their URLs. The tricky part was to map the matching post titles to their URLs (since I&#x27;m using SEO-friendly permalinks). All it took was to include the wp-blog-header.php file and have the get_permalink(ID) function return the correct URL.&lt;&#x2F;p&gt;
&lt;p&gt;The other tricky part involved preventing searches in the LiveSearch box from going to the livesearch.php page, because that&#x27;d return an XML page that the user would hardly know how to proceed from. Adding a hidden form field was a quick hack, but it works just fine and redirects the user to the search results page that WordPress spews.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;&#x2F;&#x2F; If the LiveSearch form was actually submitted (as opposed to being requested&lt;br &#x2F;&gt;
&#x2F;&#x2F; via a XMLHttpRequest, we redirect to the standard WP search page.&lt;br &#x2F;&gt;
if( isset($_GET[&#x27;submitted&#x27;]) &amp;&amp; $_GET[&#x27;submitted&#x27;] == &#x27;yes&#x27; ) {&lt;br &#x2F;&gt;
  header(&#x27;Location: &#x27; . get_settings(&#x27;siteurl&#x27;) . &#x27;&#x2F;?s=&#x27; . $_GET[&#x27;q&#x27;]);&lt;br &#x2F;&gt;
  exit;&lt;br &#x2F;&gt;
}&lt;&#x2F;div&gt;
&lt;p&gt;Well, that&#x27;s it for now. It feels really like a hackjob but it works just fine. Perhaps someone could roll this up into a WordPress plugin or we could get LiveSearch as a feature in WordPress in future (as &lt;a href=&quot;http:&#x2F;&#x2F;s9y.org&#x2F;&quot;&gt;Serendipity&lt;&#x2F;a&gt; already does).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>WordPress hosting up for grabs</title>
    <published>2004-10-17T20:28:03+00:00</published>
    <updated>2004-10-17T20:28:03+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/10/17/wordpress-hosting-up-for-grabs/"/>
    <id>https://chuyeow.wtf/2004/10/17/wordpress-hosting-up-for-grabs/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/10/17/wordpress-hosting-up-for-grabs/">&lt;p&gt;&lt;ins&gt;Update: All gone! Thanks everyone!&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;ins&gt;Update: seeing how pathetic the (non-)response has been, I&#x27;ve lowered the donation amount to USD2. C&#x27;mon people. Even as a gift for your non-tech-savvy uncle&#x2F;auntie&#x2F;grandma who wants to blog, it&#x27;s a good deal!&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;ins&gt;Update: There &lt;del datetime=&quot;2004-10-5T14:3:37--8:00&quot;&gt;are 3 of the accounts&lt;&#x2F;del&gt; is 1 account left. Thanks Jannah and Phu for making the donations to WordPress!&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Jeff Holman of &lt;a href=&quot;http:&#x2F;&#x2F;www.revisemedia.com&#x2F;&quot;&gt;Revise Media&lt;&#x2F;a&gt; wrote me awhile back to put up ads for his new &lt;a href=&quot;http:&#x2F;&#x2F;www.revisemedia.com&#x2F;services&#x2F;wordpress&#x2F;&quot;&gt;WordPress weblog hosting&lt;&#x2F;a&gt; service, and I gladly agreed because I was kind of a WordPress fan (caution: heavy understatement in use). His ad is on the left where you&#x27;ve probably been seeing it for awhile (if you&#x27;re not reading via a feed reader). (On the subject of ads, well, they fund the webhosting for this blog and then a little more.)&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, Jeff offered to give me 5 &lt;a href=&quot;http:&#x2F;&#x2F;www.revisemedia.com&#x2F;services&#x2F;wordpress&#x2F;compare.html&quot;&gt;Plus plans&lt;&#x2F;a&gt; &lt;ins&gt;(1 year subscription)&lt;&#x2F;ins&gt; for free to give away to you, my dearest readers. There was supposed to be some contest, but I gave up trying to think of a good idea for one. So I spoke with Jeff on this other idea I had and he has agreed to let them go for a &lt;a href=&quot;http:&#x2F;&#x2F;wordpress.org&#x2F;donate&#x2F;&quot;&gt;donation to WordPress&lt;&#x2F;a&gt; (rather than for &quot;free&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;Well, the Plus plans are going at $9.95&#x2F;year each, and I ask of you to &lt;a href=&quot;http:&#x2F;&#x2F;wordpress.org&#x2F;donate&#x2F;&quot;&gt;make a donation to WordPress&lt;&#x2F;a&gt; of at least &lt;del&gt;$5&lt;&#x2F;del&gt; &lt;ins&gt;$2&lt;&#x2F;ins&gt; (this amount was of my choosing). &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;contact&#x2F;&quot;&gt;Write me&lt;&#x2F;a&gt; first (or leave a comment) if you&#x27;re thinking of donating and claiming a free Plus plan - Jeff has 5 of them for me to give away.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>PHP 5.0.2 and 4.3.9</title>
    <published>2004-09-25T13:05:05+00:00</published>
    <updated>2004-09-25T13:05:05+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/09/25/php-502-and-439/"/>
    <id>https://chuyeow.wtf/2004/09/25/php-502-and-439/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/09/25/php-502-and-439/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.php.net&#x2F;&quot;&gt;PHP&lt;&#x2F;a&gt; 5.0.2 and 4.3.9 final are out - maintenance releases both. GIF support is back in the GD extension.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Why not to use MySQL</title>
    <published>2004-09-06T21:57:21+00:00</published>
    <updated>2004-09-06T21:57:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/09/06/why-not-to-use-mysql/"/>
    <id>https://chuyeow.wtf/2004/09/06/why-not-to-use-mysql/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/09/06/why-not-to-use-mysql/">&lt;p&gt;MySQL probably is the lowest common denominator for a &lt;acronym title=&quot;Relational Database Management System&quot;&gt;RDBMS&lt;&#x2F;acronym&gt; in the webhosting world - you can&#x27;t leave &#x2F;home without it. This blog wouldn&#x27;t exist without MySQL (someday WordPress will be database-independent). Sometimes I hear people say MySQL isn&#x27;t a real RDBMS, or that it lacks certain features that causes it to suck&amp;trade;. I work extensively with MySQL and there are times when I wish for stuff like referential integrity (available with InnoDB tables, but most hosts don&#x27;t provide it) so I don&#x27;t have to code constraint checks in the application. I wish for transactions (again supported by InnoDB). I wish for a PL&#x2F;SQL equivalent.&lt;&#x2F;p&gt;
&lt;p&gt;Now, these guys, they&#x27;ve got &lt;a href=&quot;http:&#x2F;&#x2F;sql-info.de&#x2F;mysql&#x2F;gotchas.html&quot;&gt;MySQL gotchas&lt;&#x2F;a&gt; and an &lt;a href=&quot;http:&#x2F;&#x2F;vulcanus.its.tudelft.nl&#x2F;~acm&#x2F;got&#x2F;antimysql.php&quot;&gt;anti-MySQL list&lt;&#x2F;a&gt; listing some niggly inconsistencies and general bad behavior in MySQL. And after reading that, I&#x27;ll never trust what MySQL does to my data again (silently change my data would you, mysqld?).&lt;&#x2F;p&gt;
&lt;p&gt;(Yes, the entry title is grammatically incorrect on purpose.)&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Setting up AWStats on Gentoo</title>
    <published>2004-08-28T22:06:14+00:00</published>
    <updated>2004-08-28T22:06:14+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/08/28/setting-up-awstats-on-gentoo/"/>
    <id>https://chuyeow.wtf/2004/08/28/setting-up-awstats-on-gentoo/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/08/28/setting-up-awstats-on-gentoo/">&lt;p&gt;Some notes to myself on setting up &lt;a href=&quot;http:&#x2F;&#x2F;awstats.sourceforge.net&#x2F;&quot;&gt;AWStats&lt;&#x2F;a&gt; on a &lt;a href=&quot;http:&#x2F;&#x2F;www.gentoo.org&#x2F;&quot;&gt;Gentoo&lt;&#x2F;a&gt; box.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, emerge the awstats package. I added the &quot;vhosts&quot; USE flag because it&#x27;s listed as a USE flag that awstats reads, and I need support for virtual hosts (although I don&#x27;t know for sure what it does - I reckon it has something to do with the &lt;span class=&quot;monospaced&quot;&gt;webapps-config&lt;&#x2F;span&gt; package that&#x27;s a dependency).&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;emerge -pv awstats&lt;br &#x2F;&gt;USE=&quot;vhosts&quot; emerge awstats&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Don&#x27;t&lt;&#x2F;strong&gt; use the webapp-config program that the emerge process tells you to use at the end unless you know what you are doing. There have been reports that it isn&#x27;t exactly ideal in the &lt;a href=&quot;http:&#x2F;&#x2F;forums.gentoo.org&#x2F;&quot;&gt;Gentoo forums&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Make a symbolic link to the Apache configuration directives we need to add to Apache in a convenient location. You may also want to make the file owner-writable (&lt;span class=&quot;monospaced&quot;&gt;chmod u+w&lt;&#x2F;span&gt;) since it&#x27;s read-only.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;ln -s &#x2F;usr&#x2F;share&#x2F;webapps&#x2F;awstats&#x2F;6.1&#x2F;postinst-en.txt &#x2F;etc&#x2F;apache2&#x2F;conf&#x2F;awstats.conf&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I had to add this bit to &lt;span class=&quot;monospaced&quot;&gt;&#x2F;etc&#x2F;apache2&#x2F;conf&#x2F;awstats.conf&lt;&#x2F;span&gt; prevent a 403 error when accessing the ScriptAliased &#x2F;awstats directory.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;directory &quot;&#x2F;usr&#x2F;share&#x2F;webapps&#x2F;awstats&#x2F;6.1&#x2F;hostroot&#x2F;cgi-bin&#x2F;&quot;&amp;gt;&lt;br &#x2F;&gt;Options +ExecCGI +FollowSymLinks&lt;br &#x2F;&gt;AllowOverride None&lt;br &#x2F;&gt;Order allow,deny&lt;br &#x2F;&gt;Allow from all&amp;lt;&#x2F;directory&amp;gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Include the AWStats-required configuration directives in the main Apache config file (mine&#x27;s &#x2F;etc&#x2F;apache2&#x2F;conf&#x2F;apache2.conf).&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;Include conf&#x2F;awstats.conf&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I&#x27;m using name-based virtual hosts, with logs for each of them (they are in the included vhosts&#x2F;vhosts.conf file). AWStats by default parses the &lt;a href=&quot;http:&#x2F;&#x2F;httpd.apache.org&#x2F;docs-2.0&#x2F;logs.html#combined&quot;&gt;Combined log format&lt;&#x2F;a&gt; and this is what I specify for my access logs as well. An example VirtualHost directive:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br &#x2F;&gt;ServerName chuyeow.wtf&lt;br &#x2F;&gt;DocumentRoot &#x2F;www&#x2F;codefront.net&#x2F;htdocs&#x2F;blog&lt;br &#x2F;&gt;ServerPath &#x2F;blog&lt;br &#x2F;&gt;&lt;strong&gt;CustomLog &#x2F;var&#x2F;log&#x2F;apache2&#x2F;chuyeow.wtf&#x2F;access_log combined&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;ErrorLog &#x2F;var&#x2F;log&#x2F;apache2&#x2F;chuyeow.wtf&#x2F;error_log&lt;br &#x2F;&gt;&amp;lt;&#x2F;VirtualHost&amp;gt;&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Now, create an AWStats configuration file for each virtual-host.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;cp &#x2F;etc&#x2F;awstats&#x2F;awstats.model.conf &#x2F;etc&#x2F;awstats&#x2F;awstats.chuyeow.wtf.conf&lt;&#x2F;div&gt;
&lt;p&gt;Notice that the configuration file name is of the format &quot;awstats.&lt;em&gt;domain.tld&lt;&#x2F;em&gt;.conf&quot;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Edit the configuration file (&#x2F;etc&#x2F;awstats&#x2F;awstats.chuyeow.wtf.conf). The important things to change are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;LogFile (point this to your access log)&lt;&#x2F;li&gt;
&lt;li&gt;SiteDomain (your site&#x27;s domain name)&lt;&#x2F;li&gt;
&lt;li&gt;HostAliases (any aliases your site may have)&lt;&#x2F;li&gt;
&lt;li&gt;DirData (AWStats database where your results will be stored. This has to be writable by the Apache user if the AllowToUpdateStatsFromBrowser option is turned on.)&lt;&#x2F;li&gt;
&lt;li&gt;DirCgi (AWStats CGI directory)&lt;&#x2F;li&gt;
&lt;li&gt;DirIcons (AWStats icons directory)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Restart Apache.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;&#x2F;etc&#x2F;init.d&#x2F;apache2 restart&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;You can access AWStats from www.example.com&#x2F;awstats&#x2F;awstats.pl?config=www.example.com.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Set password-protection for the AWStats directory.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Run AWStats from the command line to update it. You&#x27;d likely want to set up a cron job for this.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;&#x2F;usr&#x2F;bin&#x2F;awstats_updateall.pl now -awstatsprog=&#x2F;usr&#x2F;share&#x2F;webapps&#x2F;awstats&#x2F;6.1&#x2F;hostroot&#x2F;cgi-bin&#x2F;awstats.pl -configdir=&#x2F;etc&#x2F;awstats&#x2F;&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Useful links:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;awstats.sourceforge.net&#x2F;docs&#x2F;awstats_setup.html&quot;&gt;AWStats documentation on installation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>Split a webpage into 2 with this bookmarklet</title>
    <published>2004-07-18T00:40:14+00:00</published>
    <updated>2004-07-18T00:40:14+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/07/18/split-a-webpage-into-2-with-this-bookmarklet/"/>
    <id>https://chuyeow.wtf/2004/07/18/split-a-webpage-into-2-with-this-bookmarklet/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/07/18/split-a-webpage-into-2-with-this-bookmarklet/">&lt;p&gt;Cedric asked for &lt;a href=&quot;http:&#x2F;&#x2F;beust.com&#x2F;weblog&#x2F;archives&#x2F;000153.html&quot;&gt;Document-splitting in Web browsers&lt;&#x2F;a&gt; and promptly &lt;a href=&quot;http:&#x2F;&#x2F;www.jmesnil.net&#x2F;weblog&#x2F;2004&#x2F;07&#x2F;bookmarklet-to-split-html-document.html&quot;&gt;got it&lt;&#x2F;a&gt; (read the comment by &lt;a href=&quot;http:&#x2F;&#x2F;www.jmesnil.net&#x2F;weblog&#x2F;&quot;&gt;Jeff Mesnil&lt;&#x2F;a&gt; in Cedric&#x27;s blog entry).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.jmesnil.net&#x2F;weblog&#x2F;&quot;&gt;Jeff Mesnil&lt;&#x2F;a&gt; whipped up &lt;a href=&quot;http:&#x2F;&#x2F;www.jmesnil.net&#x2F;weblog&#x2F;2004&#x2F;07&#x2F;bookmarklet-to-split-html-document.html&quot;&gt;2 bookmarklets&lt;&#x2F;a&gt; in the space of less than one and a half hours that allows you to split a browser into 2 frames. How does it do that? It loads the current URL in a frameset consisting of 2 frames (both showing the same URL). A simple, yet genius, idea.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a screenshot of a blog entry split vertically:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;screenshots&#x2F;webbrowser-split-vertical.png&quot; title=&quot;Click to view a bigger image&quot;&gt;&lt;img alt=&quot;Screenshot of webbrowser split vertically&quot; src=&quot;&#x2F;assets&#x2F;webbrowser-split-vertical-s.gif&quot; width=&quot;320&quot; height=&quot;240&quot; border=&quot;0&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice how it could be useful when cross-referencing something on the same webpage, particularly if it&#x27;s a long vertical-scrolling page. A perfect use case would be referring back to a long blog entry when making a comment.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the same page split horizontally.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;screenshots&#x2F;webbrowser-split-horizontal.png&quot; title=&quot;Click to view a bigger image&quot;&gt;&lt;img alt=&quot;Screenshot of webbrowser split horizontally&quot; src=&quot;&#x2F;assets&#x2F;webbrowser-split-horizontal-s.gif&quot; width=&quot;320&quot; height=&quot;240&quot; border=&quot;0&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are probably lots of other use cases for a webpage splitter. Cedric&#x27;s in particular is this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;Just recently, I was reading an article that showed a figure at the top and which constantly referred to this figure in the rest of the article.&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;Thanks &lt;a href=&quot;http:&#x2F;&#x2F;www.jmesnil.net&#x2F;weblog&#x2F;&quot;&gt;Jeff&lt;&#x2F;a&gt; for writing the bookmarklets and &lt;a href=&quot;http:&#x2F;&#x2F;beust.com&#x2F;weblog&#x2F;&quot;&gt;Cedric&lt;&#x2F;a&gt; for thinking of it.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>admin=false</title>
    <published>2004-07-15T10:06:44+00:00</published>
    <updated>2004-07-15T10:06:44+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/07/15/adminfalse/"/>
    <id>https://chuyeow.wtf/2004/07/15/adminfalse/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/07/15/adminfalse/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;thedailywtf.com&#x2F;&quot;&gt;TheDailyWTF&lt;&#x2F;a&gt; is great. If you develop or have developed web applications before, you will appreciate this entry: &lt;a href=&quot;http:&#x2F;&#x2F;thedailywtf.com&#x2F;archive&#x2F;2004&#x2F;07&#x2F;14&#x2F;561.aspx&quot;&gt;Admin=False&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>PHP 5 released!</title>
    <published>2004-07-14T10:18:31+00:00</published>
    <updated>2004-07-14T10:18:31+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/07/14/php-5-released/"/>
    <id>https://chuyeow.wtf/2004/07/14/php-5-released/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/07/14/php-5-released/">&lt;p&gt;Freshly-baked newsbit: &lt;a href=&quot;http:&#x2F;&#x2F;www.php.net&#x2F;&quot;&gt;PHP 5.0.0&lt;&#x2F;a&gt; has just been released not too long ago. How long will it take for PHP 5 to become mainstream in webservers around the world? It&#x27;s anybody&#x27;s guess.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Online promotion of software products</title>
    <published>2004-07-13T01:09:38+00:00</published>
    <updated>2004-07-13T01:09:38+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/07/13/online-promotion-of-software-products/"/>
    <id>https://chuyeow.wtf/2004/07/13/online-promotion-of-software-products/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/07/13/online-promotion-of-software-products/">&lt;p&gt;Another call for help and advice. I can&#x27;t really resist it because I&#x27;ve been seeing so much success in my appeals for assistance before.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m looking for advice&#x2F;articles&#x2F;tutorials on online promotion, more specifically online promotion of software products.&lt;&#x2F;p&gt;
&lt;p&gt;At the moment, I have these on my list of things to do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Google Adwords&lt;&#x2F;li&gt;
&lt;li&gt;Submission to software listing sites&lt;&#x2F;li&gt;
&lt;li&gt;SEO&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What else is there and why?&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Table names and case sensitivity - bad MySQL</title>
    <published>2004-06-17T23:18:02+00:00</published>
    <updated>2004-06-17T23:18:02+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/06/17/table-names-and-case-sensitivity-bad-mysql/"/>
    <id>https://chuyeow.wtf/2004/06/17/table-names-and-case-sensitivity-bad-mysql/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/06/17/table-names-and-case-sensitivity-bad-mysql/">&lt;p&gt;This issue has wasted a good part of a day trying to figure out why my database-driven pages failed to work correctly after dumping a database from my Windows dev machine into a Linux box - I just had to whine about this.&lt;&#x2F;p&gt;
&lt;p&gt;Following database naming conventions (actually, there are many, not all of which advocate using mixed case naming schemes), I decided to use mixed case table names when developing on my Windows box. So a table containing localization (or &lt;acronym title=&quot;localization&quot;&gt;L10n&lt;&#x2F;acronym&gt;) information for widgets would be named `Widget_L10n`, and the lookup table for widget to purchases would be named `Widget_Purchases`. No problem. Everything worked fine on the dev machine.&lt;&#x2F;p&gt;
&lt;p&gt;When the time came to move into live testing, I dumped the contents of the database into a file and proceeded to import into the production database server. Of course, nothing worked. I checked the database contents - everything was there. I checked the scripts - everything was good to go; if it works in the dev machine, it should rightly work in the production. I then checked the dump file, thinking it unlikely that something was wrong there but checking anyway - everything seemed fine. I went back to the MySQL client (I was using MySQL Front) and it hit me - the table names were in lowercase. And the PHP scripts were (correctly) using the mixed-case table names. Gah! The database dump file contained queries with the table names in lowercase, so they &lt;em&gt;were&lt;&#x2F;em&gt; lowercase in the Linux box while I was using queries with mixed-case names. At that point I hated myself for forgetting how MySQL stores table names - as a name of the file that stores the table. The manual &lt;a href=&quot;http:&#x2F;&#x2F;dev.mysql.com&#x2F;doc&#x2F;mysql&#x2F;en&#x2F;Name_case_sensitivity.html&quot;&gt;said so&lt;&#x2F;a&gt; and I even read that before.&lt;&#x2F;p&gt;
&lt;p&gt;Lesson learnt: use all lowercase identifier names in MySQL for portability across Windows and operating&#x2F;file systems where lettercase matters (such as Linux and Mac OX X UFS volumes). Throw the existing database naming conventions you have out the door.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Who cares about Web standards?</title>
    <published>2004-06-13T20:08:33+00:00</published>
    <updated>2004-06-13T20:08:33+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/06/13/who-cares-about-web-standards/"/>
    <id>https://chuyeow.wtf/2004/06/13/who-cares-about-web-standards/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/06/13/who-cares-about-web-standards/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;webstandards.org&#x2F;&quot;&gt;The Web Standards Project&lt;&#x2F;a&gt; asks of anyone and everyone &quot;involved in web production in any capacity&quot; to take a &lt;a href=&quot;http:&#x2F;&#x2F;www.webstandards.org&#x2F;survey&#x2F;200406&quot;&gt;survey on Web Standards and it&#x27;s relevance to you&lt;&#x2F;a&gt; in a recent press release, &lt;a href=&quot;http:&#x2F;&#x2F;webstandards.org&#x2F;press&#x2F;releases&#x2F;archive&#x2F;2004&#x2F;06&#x2F;08&#x2F;&quot;&gt;Web Standards: Who Cares Anyway?&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Most salient question in the survey: &lt;strong&gt;What roadblocks or challenges have affected your use of Web standards?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;All of the above&quot; applies to my position to a certain extent, but the biggest challenges I experience in my capacity of as a web developer for &lt;a href=&quot;http:&#x2F;&#x2F;www.muvee.com&#x2F;&quot;&gt;muvee Technologies&lt;&#x2F;a&gt; (yes, I just got employed, 2 weeks ago) relate to that of lack of team and management knowledge and support. The current webpages are coded in old school tables, using Dreamweaver. Everyone else on the web team uses Dreamweaver. There&#x27;s absolutely nothing wrong with that, because a WYSIWYG editor is the best for productivity. And I take nothing away from the frontend designer and media designer - they are a class act when it comes to design.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m probably the oddity in the team, the only guy using a text editor to crunch out PHP scripts using the HTML webpages that are done by the creative department. And I am the only one to see invalid HTML, unclosed tags, and spacer images that Dreamweaver generates. Does it matter to the designers? Not one bit because they don&#x27;t see it and the pages still turn out find in the important browsers. Does it matter to me? Yes, it is annoying because I&#x27;ve been coding to Web Standards wherever I can, but &lt;strong&gt;it is something I can and should live with&lt;&#x2F;strong&gt;. There are honestly far more important things to do, as I have been reminded, than cleaning the HTML towards Web Standards-production code. I can&#x27;t argue with that. The website &lt;strong&gt;works&lt;&#x2F;strong&gt; (well, it doesn&#x27;t work in Opera, but fixing it is going to be a touchy subject I&#x27;ll bring up after I&#x27;m more settled into my position), so what&#x27;s the point of wasting time making changes that don&#x27;t produce any tangible benefit (to them). I can&#x27;t argue with that too, yet.&lt;&#x2F;p&gt;
&lt;p&gt;But when the time comes when there aren&#x27;t more important things to do, I will be faced with an urge to propose a shift towards Web Standards. How will that turn out? One word - &lt;strong&gt;badly&lt;&#x2F;strong&gt;. Why? Because the designers are not going to like it. They (nor the company, I&#x27;d guess) would not be willing to toss away what they&#x27;ve used for years to produce their webpages. Unless Dreamweaver starts becoming a far better webpage editor in terms of the code it generates, I don&#x27;t think they&#x27;d like looking at raw HTML code (and I don&#x27;t blame them either). I&#x27;d probably become public enemy number one in the web team if I start proposing these changes, even if I suggest to undertake the conversion to Web Standards all by myself. I don&#x27;t have a case, yet.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, take the &lt;a href=&quot;http:&#x2F;&#x2F;www.webstandards.org&#x2F;survey&#x2F;200406&quot;&gt;survey&lt;&#x2F;a&gt;, let WaSP know what&#x27;s happening in the real world, and also let me know if and how you&#x27;ve managed to convince your department&#x2F;company to switch to Web Standards. Please do share your experiences, especially those that end in sucess, because that&#x27;s where I believe everyone has lots to learn from.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Seen elsewhere - Free eBook &quot;Budget Design&quot;</title>
    <published>2004-06-10T02:35:25+00:00</published>
    <updated>2004-06-10T02:35:25+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/06/10/seen-elsewhere-free-ebook-budget-design/"/>
    <id>https://chuyeow.wtf/2004/06/10/seen-elsewhere-free-ebook-budget-design/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/06/10/seen-elsewhere-free-ebook-budget-design/">&lt;p&gt;Didier Hilhorst and Dan Rubin of &lt;a href=&quot;http:&#x2F;&#x2F;superfluousbanter.org&#x2F;&quot;&gt;SuperfluousBanter&lt;&#x2F;a&gt; fame have written and released for free (for 7 days) &lt;a href=&quot;http:&#x2F;&#x2F;sinelogic.com&#x2F;&quot;&gt;Budget Design: Increase Profit by Improving Process&lt;&#x2F;a&gt;. After 7 days, it&#x27;ll set you back $9.&lt;&#x2F;p&gt;
&lt;p&gt;All web developers should take a look at it (even if your budget is larger than the US trade deficit), because it&#x27;s quality stuff from 2 quality web developers (and now, writers).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Sorry, no more hot-linking, please</title>
    <published>2004-05-23T17:11:44+00:00</published>
    <updated>2004-05-23T17:11:44+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/05/23/sorry-no-more-hot-linking-please/"/>
    <id>https://chuyeow.wtf/2004/05/23/sorry-no-more-hot-linking-please/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/05/23/sorry-no-more-hot-linking-please/">&lt;p&gt;Yup that&#x27;s it, no more hot-linking of images (and CSS files as well) on this site, please. Thanks to pippo&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepoint.com&#x2F;forums&#x2F;showpost.php?postid=846842&amp;postcount=5&quot;&gt;&lt;br &#x2F;&gt;
How can I prevent hot-linking images?&lt;&#x2F;a&gt; post, any hot-link requests to this site will be redirected to this image below instead:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;hotlinking.gif&quot; alt=&quot;Image shown in place of hot-linked images&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I know there have been cases of legitimate hot-linking (at least in my view they are legitimate), such as from forum threads (legitimate because I don&#x27;t expect your run-of-the-mill forum member to have webspace). So this &quot;sorry&quot; goes to you guys. If I notice hot-linking from forum threads in the future, I&#x27;ll be sure to add you to the allowed list of referrers. In fact, I&#x27;ve already added &lt;a href=&quot;http:&#x2F;&#x2F;gathering.tweakers.net&#x2F;forum&#x2F;&quot;&gt;http:&#x2F;&#x2F;gathering.tweakers.net&#x2F;forum&#x2F;&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;mozillapl.org&#x2F;forum&#x2F;&quot;&gt;http:&#x2F;&#x2F;mozillapl.org&#x2F;forum&#x2F;&lt;&#x2F;a&gt; to   the &quot;allowed list&quot; in my &lt;a href=&quot;&#x2F;htaccess.txt&quot;&gt;.htaccess&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I did this because there have been people who have been leeching my image files, list bullets and even my CSS(!), and I think that is bad form. If you want an image from this site, download it, and upload it on your server. So far every image and screenshot I&#x27;ve ever posted is available for &quot;free&quot; despite the &lt;a href=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;licenses&#x2F;by-nc-sa&#x2F;1.0&#x2F;&quot;&gt;Creative Commons Attribution-NonCommercial-ShareAlike 1.0 license&lt;&#x2F;a&gt;, and should be in the future unless I turn into the Picasso of graphic design soon.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Bookmarklet lays out topography of a webpage</title>
    <published>2004-04-07T01:42:31+00:00</published>
    <updated>2004-04-07T01:42:31+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/04/07/bookmarklet-lays-out-topography-of-a-webpage/"/>
    <id>https://chuyeow.wtf/2004/04/07/bookmarklet-lays-out-topography-of-a-webpage/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/04/07/bookmarklet-lays-out-topography-of-a-webpage/">&lt;p&gt;Joseph Pearson of &lt;a href=&quot;http:&#x2F;&#x2F;www.make-believe.org&#x2F;&quot;&gt;Make Believe&lt;&#x2F;a&gt; has coded a &lt;a href=&quot;http:&#x2F;&#x2F;www.make-believe.org&#x2F;posts&#x2F;04&#x2F;04&#x2F;01&#x2F;0&quot;&gt;topographic page layout bookmarklet&lt;&#x2F;a&gt; that shows the layout of a webpage. Basically, it recolors the elements of a webpage, giving more deeply nested elements a lighter color. The effect is that you can see the &quot;topography&quot; of a webpage, which makes it that much easier to detect unclosed divs or for those situations where something is wrongly positioned but you just don&#x27;t know why. Another of those must-have web development bookmarklets.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>The best list of CSS filters, so far</title>
    <published>2004-03-01T17:43:08+00:00</published>
    <updated>2004-03-01T17:43:08+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/03/01/the-best-list-of-css-filters-so-far/"/>
    <id>https://chuyeow.wtf/2004/03/01/the-best-list-of-css-filters-so-far/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/03/01/the-best-list-of-css-filters-so-far/">&lt;p&gt;Chris of &lt;a href=&quot;http:&#x2F;&#x2F;www.dithered.com&#x2F;&quot;&gt;dithered.com&lt;&#x2F;a&gt; has compiled a list of &lt;a href=&quot;http:&#x2F;&#x2F;www.dithered.com&#x2F;css_filters&#x2F;index.html&quot;&gt;CSS filters&lt;&#x2F;a&gt;. For those not in the know, CSS filters are techniques that hide CSS rules from browsers who misinterpret, abuse or just plain don&#x27;t understand them.&lt;&#x2F;p&gt;
&lt;p&gt;In more personal news, I&#x27;ve been slaving away at putting out a technical paper and a thesis for my honors project. Now you know why I&#x27;ve been so quiet. Well, you can read my scrapped together &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;about&#x2F;&quot;&gt;About&lt;&#x2F;a&gt; page (that finally has some content) to keep yourself entertained. Yeah, right.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Textpattern - a promising CMS sprouts its wings</title>
    <published>2004-02-25T01:05:01+00:00</published>
    <updated>2004-02-25T01:05:01+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/02/25/textpattern-a-promising-cms-sprouts-its-wings/"/>
    <id>https://chuyeow.wtf/2004/02/25/textpattern-a-promising-cms-sprouts-its-wings/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/02/25/textpattern-a-promising-cms-sprouts-its-wings/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;textpattern.com&#x2F;&quot;&gt;Textpattern&lt;&#x2F;a&gt;, a content management system written in PHP by &lt;a href=&quot;http:&#x2F;&#x2F;textism.com&#x2F;&quot;&gt;Dean Allen&lt;&#x2F;a&gt; (of &lt;a href=&quot;http:&#x2F;&#x2F;textism.com&#x2F;&quot;&gt;Textism&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;textism.com&#x2F;tools&#x2F;textile&#x2F;&quot;&gt;Textile&lt;&#x2F;a&gt; fame), has just been released to the public.&lt;&#x2F;p&gt;
&lt;p&gt;Curiousity piqued by what it promised to offer about a year ago (when it was in closed development), I made it a point to check out Textpattern once any release is made. I took a quick install and run through of Textpattern gamma 1.11 and am pleased to report that it delivers on its promises. This has the makings of the next big weblog publishing tool (bigger than MT?), or even the next big CMS. More on this after I play around with it a bit more.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>list-style-image alignment quirk in IE&#x2F;Win and Opera?</title>
    <published>2004-02-20T19:47:43+00:00</published>
    <updated>2004-02-20T19:47:43+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/02/20/list-style-image-alignment-quirk-in-iewin-and-opera/"/>
    <id>https://chuyeow.wtf/2004/02/20/list-style-image-alignment-quirk-in-iewin-and-opera/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/02/20/list-style-image-alignment-quirk-in-iewin-and-opera/">&lt;p&gt;Take a look at this &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;examples&#x2F;liststyleimage.html&quot;&gt;example page&lt;&#x2F;a&gt; I set up in IE&#x2F;Win or Opera, and then in a Gecko-based browser.&lt;&#x2F;p&gt;
&lt;p&gt;Notice that the positions of the list images in IE&#x2F;Win and Opera are misaligned - they&#x27;re not in line with the text, but seem to be vertical-aligned to the top. After a bit of hair-pulling, I figured out that is because I applied &quot;line-height:180%;&quot;. Setting the line-height back to 100% for the &amp;lt;ul&amp;gt; works, but then I had to resort to adding margins to the &amp;lt;li&amp;gt; elements to simulate a line-height so that it&#x27;ll be consistent throughout the document.&lt;&#x2F;p&gt;
&lt;p&gt;Does anybody have an explanation why IE and Opera does it this way while Gecko browsers render it the other, seemingly correct, way?&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Tooltips with CSS</title>
    <published>2004-01-22T16:18:27+00:00</published>
    <updated>2004-01-22T16:18:27+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/01/22/tooltips-with-css/"/>
    <id>https://chuyeow.wtf/2004/01/22/tooltips-with-css/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/01/22/tooltips-with-css/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.madaboutstyle.com&#x2F;tooltip2.html&quot; title=&quot;Read on how to create tooltips using purely CSS&quot;&gt;Pure CSS tooltips&lt;&#x2F;a&gt; by SantaKlauss shows you how to display tooltips using purely CSS. The idea is not unlike &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2003&#x2F;11&#x2F;28&#x2F;getting_funky_with_nice_titles.php&quot; title=&quot;Read my entry on Nice Titles&quot;&gt;Nice Titles&lt;&#x2F;a&gt;, though the execution is very different - Nice Titles uses the DOM to extract the nicetitles, the tooltips use only CSS.&lt;&#x2F;p&gt;
&lt;p&gt;The smart part is when printing: the tooltips are &quot;inlined&quot; and bracketed appropriately so that they show up in the normal flow of the document when printing.&lt;&#x2F;p&gt;
&lt;p&gt;Still, I consider the execution to be semantically incorrect since the tooltip requires the anchor tag &amp;lt;a&amp;gt; to work - the text that is &quot;tooltipped&quot; is &lt;em&gt;not&lt;&#x2F;em&gt; an anchor. A better way would have been to use a standard &amp;lt;span&amp;gt; tag. Of course, this then breaks in IE because IE only supports the &lt;span class=&quot;monospaced&quot;&gt;:hover&lt;&#x2F;span&gt; pseudo-class on the &amp;lt;a&amp;gt; tag. Thanks to &lt;a href=&quot;http:&#x2F;&#x2F;www.xs4all.nl&#x2F;~peterned&#x2F;csshover.html&quot; title=&quot;Read as  Peter Nederlof explains how to use IE behaviors to simulate hover effects on any element in IE&quot;&gt;whatever:hover&lt;&#x2F;a&gt;, however, this can easily be fixed. Also, there seems to be no need for the z-index fix as mentioned (tested on IE&#x2F;Win 5, 5.5 and 6). The CSS is below:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
body {&lt;br &#x2F;&gt;
  behavior:url(&#x2F;htc&#x2F;csshover.htc);&lt;br &#x2F;&gt;
}&lt;br &#x2F;&gt;
span.info{&lt;br &#x2F;&gt;
  position:relative;&lt;br &#x2F;&gt;
  background-color:#ecc;&lt;br &#x2F;&gt;
  color:#000;&lt;br &#x2F;&gt;
  text-decoration:none&lt;br &#x2F;&gt;
}&lt;br &#x2F;&gt;
span.info:hover { background-color:#e96 }&lt;br &#x2F;&gt;
span.info span.tooltip { display: none }&lt;br &#x2F;&gt;
span.info:hover span.tooltip {&lt;br &#x2F;&gt;
  display:block;&lt;br &#x2F;&gt;
  position:absolute;&lt;br &#x2F;&gt;
  top:2em; left:2em; width:15em;&lt;br &#x2F;&gt;
  border:1px solid #0cf;&lt;br &#x2F;&gt;
  background-color:#cff;&lt;br &#x2F;&gt;
  color:#000;&lt;br &#x2F;&gt;
  text-align: center&lt;br &#x2F;&gt;
}
&lt;&#x2F;div&gt;
&lt;p&gt;Here&#x27;s an &lt;a href=&quot;&#x2F;examples&#x2F;csstooltips.html&quot; title=&quot;Check out my example on CSS tooltips&quot;&gt;example&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>HTTP error pages for weblogs!</title>
    <published>2004-01-13T00:11:28+00:00</published>
    <updated>2004-01-13T00:11:28+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2004/01/13/http-error-pages-for-weblogs/"/>
    <id>https://chuyeow.wtf/2004/01/13/http-error-pages-for-weblogs/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2004/01/13/http-error-pages-for-weblogs/">&lt;p&gt;Check out the custom error pages over at &lt;a href=&quot;http:&#x2F;&#x2F;www.1976design.com&#x2F;blog&quot; title=&quot;Go to Dunstan&#x27;s blog&quot;&gt;Dunstan Orchard&#x27;s blog&lt;&#x2F;a&gt; as linked in his weblog entry entitled &lt;a href=&quot;http:&#x2F;&#x2F;www.1976design.com&#x2F;blog&#x2F;archive&#x2F;2004&#x2F;01&#x2F;10&#x2F;error-handling&#x2F;&quot; title=&quot;Read Dunstan Orchard&#x27;s blog entry on &amp;quot;Friendly error handling&amp;quot;&quot;&gt;Friendly error handling&lt;&#x2F;a&gt;. Now that is cool. One other thing is certain - Dunstan really has too much time on his hands. Heh. I think I&#x27;m just jealous.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Ungreeking, a color wheel, and GIFs</title>
    <published>2003-12-21T22:34:21+00:00</published>
    <updated>2003-12-21T22:34:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/12/21/ungreeking-a-color-wheel-and-gifs/"/>
    <id>https://chuyeow.wtf/2003/12/21/ungreeking-a-color-wheel-and-gifs/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/12/21/ungreeking-a-color-wheel-and-gifs/">&lt;p&gt;Some things that could prove useful to myself in future:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;ungreek.toolbot.com&#x2F;&quot; title=&quot;Check out ungreek at its website&quot;&gt;ungreek&lt;&#x2F;a&gt; is what you could call a &lt;em&gt;lorem ipsum&lt;&#x2F;em&gt; generator - it generates placeholder text from a variety of sources including the Old Testament, the US constitution and even the &lt;a href=&quot;http:&#x2F;&#x2F;www.zvon.org&#x2F;tmRFC&#x2F;RFC1630&#x2F;Output&#x2F;index.html&quot; title=&quot;Read the Internet RFC 1630&quot;&gt;Internet RFC 1630&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.ficml.org&#x2F;jemimap&#x2F;style&#x2F;color&#x2F;wheel.html&quot; title=&quot;Try out the 4096 Color Wheel&quot;&gt;4096 Color Wheel&lt;&#x2F;a&gt; is a color wheel written in JavaScript. Nice to have an instant swatch at the side.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.uncommoncontent.org&#x2F;p2p&#x2F;index.php&quot; title=&quot;Go to the Pixel2Pixel website&quot;&gt;Pixel2Pixel&lt;&#x2F;a&gt; is a PHP script that allows you to change any color in your GIF images on the fly. Just upload your image and choose what colors you want changed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Easy .htaccess</title>
    <published>2003-12-18T23:21:45+00:00</published>
    <updated>2003-12-18T23:21:45+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/12/18/easy-htaccess/"/>
    <id>https://chuyeow.wtf/2003/12/18/easy-htaccess/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/12/18/easy-htaccess/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.bitesizeinc.net&#x2F;index.php&#x2F;htaccesser.html&quot; title=&quot;Try out Dot HtAccesser&quot;&gt;Dot HtAccesser&lt;&#x2F;a&gt; is a web-based tool that generates .htaccess files for you via a simple form. Writing the right .htaccess file isn&#x27;t exactly rocket science, but we are fortunately spared reading up when in doubt, especially when the official Apache &lt;a href=&quot;http:&#x2F;&#x2F;httpd.apache.org&#x2F;docs&#x2F;howto&#x2F;htaccess.html&quot; title=&quot;Read the offical Apache .htacess tutorial&quot;&gt;.htaccess tutorial&lt;&#x2F;a&gt; is so sparse.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>CSS selectors translator</title>
    <published>2003-12-01T03:21:45+00:00</published>
    <updated>2003-12-01T03:21:45+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/12/01/css-selectors-translator/"/>
    <id>https://chuyeow.wtf/2003/12/01/css-selectors-translator/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/12/01/css-selectors-translator/">&lt;p&gt;Confused by CSS selectors like &lt;span class=&quot;monospaced&quot;&gt;a:not([href*=&quot;codefront&quot;])&lt;&#x2F;span&gt; and &lt;span class=&quot;monospaced&quot;&gt;body &amp;gt; h2:not(:first-of-type):not(:last-of-type);&lt;&#x2F;span&gt;? &lt;a href=&quot;http:&#x2F;&#x2F;gallery.theopalgroup.com&#x2F;selectoracle&#x2F;&quot; title=&quot;Check out the SelectORacle&quot;&gt;SelectORacle&lt;&#x2F;a&gt; can translate that into plain English (or Spanish) for you.&lt;&#x2F;p&gt;
&lt;p&gt;Very neat idea that&#x27;s apparently the brainchild of &lt;a href=&quot;http:&#x2F;&#x2F;www.meyerweb.com&#x2F;&quot; title=&quot;Go to Eric Meyer&#x27;s personal website&quot;&gt;Eric Meyer&lt;&#x2F;a&gt; (the CSS guy), and implemented in &lt;a href=&quot;http:&#x2F;&#x2F;python.org&#x2F;&quot; title=&quot;Go to the website for the Python programming language&quot;&gt;Python&lt;&#x2F;a&gt; by Kevin Jacobs.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Getting funky with Nice Titles</title>
    <published>2003-11-28T01:33:15+00:00</published>
    <updated>2003-11-28T01:33:15+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/11/28/getting-funky-with-nice-titles/"/>
    <id>https://chuyeow.wtf/2003/11/28/getting-funky-with-nice-titles/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/11/28/getting-funky-with-nice-titles/">&lt;p&gt;Dunstan wrote up on an &lt;a href=&quot;http:&#x2F;&#x2F;www.1976design.com&#x2F;blog&#x2F;archive&#x2F;2003&#x2F;11&#x2F;21&#x2F;nice-titles&#x2F;&quot; title=&quot;Read Dunstan&#x27;s entry on &amp;quot;Nice Titles revised&amp;quot;&quot;&gt;improved Nice Titles script&lt;&#x2F;a&gt; in his beautiful and very interesting &lt;a href=&quot;http:&#x2F;&#x2F;www.1976design.com&#x2F;blog&#x2F;&quot; title=&quot;Read Dunstan&#x27;s blog&quot;&gt;blog&lt;&#x2F;a&gt;. What are &lt;a href=&quot;http:&#x2F;&#x2F;www.kryogenix.org&#x2F;code&#x2F;browser&#x2F;nicetitle&#x2F;&quot; title=&quot;Read up on the original Nice Titles&quot;&gt;Nice Titles&lt;&#x2F;a&gt; you say? They are the brainchild of &lt;a href=&quot;http:&#x2F;&#x2F;www.kryogenix.org&#x2F;&quot; title=&quot;Go to Stuart Langridge&#x27;s personal website&quot;&gt;Stuart Langridge&lt;&#x2F;a&gt; and appear on this site when you hover over a hyperlink with the &lt;span class=&quot;monospaced&quot;&gt;title&lt;&#x2F;span&gt; attribute set. If you&#x27;re using Mozilla or Mozilla Firebird, the CSS takes advantage of the &lt;span class=&quot;monospaced&quot;&gt;-moz-opacity&lt;&#x2F;span&gt; to give the popup div some transparency, and &lt;span class=&quot;monospaced&quot;&gt;-moz-border-radius&lt;&#x2F;span&gt; for rounded corners (other browsers will render an opaque rectangle).&lt;&#x2F;p&gt;
&lt;p&gt;Why Nice Titles? Firstly, they are kinda cool. And I like the way the URL is displayed in the popup div. Control over the delay between mouseovers and the div popping up helps to have title dialogs show up faster (or slower) than the browser default - I personally find the delay a little too long for &quot;standard&quot; titles.&lt;&#x2F;p&gt;
&lt;p&gt;All this is done using purely DOM methods (DOM is a W3C standard) and will work in all &lt;em&gt;correctly-implemented&lt;&#x2F;em&gt; DOM-compliant browsers. Of course, this method degrades gracefully in the face of text browsers, limited browsers in mobile devices, screen readers, etc. Want it for your site? It&#x27;s as easy as uploading the CSS and JS files to your webserver and linking to them. Any existing &lt;span class=&quot;monospaced&quot;&gt;title&lt;&#x2F;span&gt;s will magically become a Nice Title.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Required reading: Floats and Positioning</title>
    <published>2003-11-11T22:02:18+00:00</published>
    <updated>2003-11-11T22:02:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/11/11/required-reading-floats-and-positioning/"/>
    <id>https://chuyeow.wtf/2003/11/11/required-reading-floats-and-positioning/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/11/11/required-reading-floats-and-positioning/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.positioniseverything.net&#x2F;&quot;&gt;Position Is Everything&lt;&#x2F;a&gt; has some very coherent, very required reading on positioning and floating with &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;&#x2F;acronym&gt;: &lt;a href=&quot;http:&#x2F;&#x2F;www.positioniseverything.net&#x2F;articles&#x2F;flow-pos.html&quot;&gt;Flowing and Positioning: Two Page Models&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.positioniseverything.net&#x2F;articles&#x2F;float-theory.html&quot;&gt;Float: The Theory&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By the way, &lt;a href=&quot;http:&#x2F;&#x2F;www.positioniseverything.net&#x2F;&quot;&gt;Position Is Everything&lt;&#x2F;a&gt; is a great place for CSS demos and articles. Bookmarked!&lt;&#x2F;p&gt;
&lt;p&gt;Source: &lt;a href=&quot;http:&#x2F;&#x2F;simon.incutio.com&#x2F;archive&#x2F;2003&#x2F;11&#x2F;11&#x2F;requiredReading&quot;&gt;Simon Willison&#x27;s Weblog&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>View your website in Lynx, without Lynx</title>
    <published>2003-10-30T16:25:26+00:00</published>
    <updated>2003-10-30T16:25:26+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/10/30/view-your-website-in-lynx-without-lynx/"/>
    <id>https://chuyeow.wtf/2003/10/30/view-your-website-in-lynx-without-lynx/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/10/30/view-your-website-in-lynx-without-lynx/">&lt;p&gt;Came across this while reading the &lt;a href=&quot;http:&#x2F;&#x2F;www.amazon.com&#x2F;exec&#x2F;obidos&#x2F;ASIN&#x2F;0735712018&#x2F;ref%3Dnosim&#x2F;jeffreyzeldmanprA&#x2F;104-3883014-6280709&quot; title=&quot;Designing With Web Standards by Jeffrey Zeldman&quot;&gt;little orange book by Jeffrey Zeldman&lt;&#x2F;a&gt; - &lt;a href=&quot;http:&#x2F;&#x2F;www.delorie.com&#x2F;web&#x2F;lynxview.html&quot;&gt;Lynx Viewer&lt;&#x2F;a&gt;. It&#x27;s a pretty neato &lt;a href=&quot;http:&#x2F;&#x2F;www.delorie.com&#x2F;web&#x2F;lynxview.cgi?see-script&quot; title=&quot;View the source of the Perl script&quot;&gt;Perl CGI script&lt;&#x2F;a&gt;. Very useful for checking how your site looks to that minority of people who still use a text browser. Also very interesting to see how &lt;a href=&quot;http:&#x2F;&#x2F;www.delorie.com&#x2F;web&#x2F;lynxview.cgi?url=http:&#x2F;&#x2F;www.cnet.com&#x2F;&quot; title=&quot;CNet in Lynx&quot;&gt;many&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;www.delorie.com&#x2F;web&#x2F;lynxview.cgi?url=http:&#x2F;&#x2F;www.nus.edu.sg&#x2F;&quot; title=&quot;NUS homepage in Lynx&quot;&gt;sites&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;www.delorie.com&#x2F;web&#x2F;lynxview.cgi?url=http:&#x2F;&#x2F;www.zdnet.com&#x2F;&quot; title=&quot;ZDNet in Lynx&quot;&gt;break&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;See how important it is to separate presentation from structure, and to follow accessibility guidelines? At least, as important as it is for these sites not to lose the proportion of viewers who either use text browsers or are visually-handicapped and use a screen reader.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, here&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;www.delorie.com&#x2F;web&#x2F;lynxview.cgi?url=https:&#x2F;&#x2F;chuyeow.wtf&#x2F;&quot;&gt;redemption in a blog when viewed in Lynx&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>I&#x27;ve got Mini-tab Shapes</title>
    <published>2003-10-27T06:19:00+00:00</published>
    <updated>2003-10-27T06:19:00+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/10/27/ive-got-mini-tab-shapes/"/>
    <id>https://chuyeow.wtf/2003/10/27/ive-got-mini-tab-shapes/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/10/27/ive-got-mini-tab-shapes/">&lt;p&gt;I&#x27;ve always been wanting to try out &lt;a href=&quot;http:&#x2F;&#x2F;www.simplebits.com&#x2F;tips&#x2F;minitab_shapes.html&quot;&gt;Mini-tab Shapes&lt;&#x2F;a&gt; and finally got down to doing so. Granted, the whole thing was a no-brainer since all that had to be done was to copy the source in that page and tweak the CSS to suit the rest of the site.&lt;&#x2F;p&gt;
&lt;p&gt;Initially though, I&#x27;d wanted to put up tabs like those in the &lt;a href=&quot;http:&#x2F;&#x2F;alistapart.com&#x2F;articles&#x2F;slidingdoors&#x2F;&quot;&gt;Sliding Doors of CSS&lt;&#x2F;a&gt; article at &lt;a href=&quot;http:&#x2F;&#x2F;alistapart.com&#x2F;&quot;&gt;A List Apart&lt;&#x2F;a&gt;, but my graphic design skills weren&#x27;t up to the task - I had problems coming up with tabs that weren&#x27;t child-like doodles. So I settled for mini-tabs.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, for those of you who&#x27;ve been visiting lately, you&#x27;d probably also have noticed the new look. Hate it? Like it? Let me know!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;&#x2F;strong&gt;: &lt;a href=&quot;http:&#x2F;&#x2F;www.thesunreport.org&#x2F;&quot;&gt;The Sun Report&lt;&#x2F;a&gt; has &lt;a href=&quot;http:&#x2F;&#x2F;www.thesunreport.org&#x2F;exp&#x2F;minitabs&#x2F;vertical.html&quot;&gt;Vertical Mini-tabs, inspired by Mini-tab shapes!&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Mimicking Magazines, with CSS</title>
    <published>2003-10-10T15:58:58+00:00</published>
    <updated>2003-10-10T15:58:58+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/10/10/mimicking-magazines-with-css/"/>
    <id>https://chuyeow.wtf/2003/10/10/mimicking-magazines-with-css/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/10/10/mimicking-magazines-with-css/">&lt;p&gt;Anton Andreasson of &lt;a href=&quot;http:&#x2F;&#x2F;standardice.com&#x2F;&quot;&gt;Standardice&lt;&#x2F;a&gt; has put together &quot;&lt;a href=&quot;http:&#x2F;&#x2F;standardice.com&#x2F;experimental&#x2F;magazines.html&quot;&gt;Mimicking Magazines&lt;&#x2F;a&gt;&quot; which is a collection of web styles that mimic those of magazines (the kind that are made up of trees), using CSS. Very nice. Should get better as more is collected. Maybe he should allow user-contributions or put together something like a &lt;a href=&quot;http:&#x2F;&#x2F;www.csszengarden.com&#x2F;&quot;&gt;CSS Zen Garden&lt;&#x2F;a&gt; thing.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Winner of SitePointForums.com CSS contest announced</title>
    <published>2003-10-08T15:49:56+00:00</published>
    <updated>2003-10-08T15:49:56+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/10/08/winner-of-sitepointforumscom-css-contest-announced/"/>
    <id>https://chuyeow.wtf/2003/10/08/winner-of-sitepointforumscom-css-contest-announced/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/10/08/winner-of-sitepointforumscom-css-contest-announced/">&lt;p&gt;A while back I &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2003&#x2F;09&#x2F;02&#x2F;css_contest_at_sitepointforumscom.php&quot; title=&quot;Weblog entry on CSS contest at SitePointForums.com&quot;&gt;wrote on&lt;&#x2F;a&gt; the CSS contest at SitePointForums.com called &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;showthread.php?threadid=116294&quot;&gt;The Beauty of Style&lt;&#x2F;a&gt;. Well, after some hiccups over the judging, the winner has finally been &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;showthread.php?threadid=131835&quot; title=&quot;Contest winner announcement thread at SitePoint Forums&quot;&gt;announced&lt;&#x2F;a&gt;. All credit to &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;member.php?userid=22841&quot; title=&quot;zoo&#x27;s user profile&quot;&gt;zoo&lt;&#x2F;a&gt; (Rick) for handling the contest very nicely despite the many difficulties and speed bumps.&lt;&#x2F;p&gt;
&lt;p&gt;Personally, I liked &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;zanzibar&#x2F;&quot;&gt;Zanzibar&lt;&#x2F;a&gt; as well, and would have liked it to win over &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;deadend_prophecy&#x2F;&quot;&gt;Deadend Prophecy&lt;&#x2F;a&gt; which I&#x27;ve found breaks in IE 5.0 (on Windows). Nevertheless, it&#x27;s still a stunning design, and I don&#x27;t really give too much of a care for IE 5.0 myself.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Vinnie on tables and CSS</title>
    <published>2003-09-23T16:28:17+00:00</published>
    <updated>2003-09-23T16:28:17+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/09/23/vinnie-on-tables-and-css/"/>
    <id>https://chuyeow.wtf/2003/09/23/vinnie-on-tables-and-css/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/09/23/vinnie-on-tables-and-css/">&lt;p&gt;A fellow Advisor at &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;&quot;&gt;SitePoint Forums&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;www.vinniegarcia.com&#x2F;&quot;&gt;Vinnie Garcia&lt;&#x2F;a&gt;, has a &lt;a href=&quot;http:&#x2F;&#x2F;blog.vinniegarcia.com&#x2F;&quot;&gt;blog&lt;&#x2F;a&gt;! And how&#x27;s this for a &lt;a href=&quot;http:&#x2F;&#x2F;blog.vinniegarcia.com&#x2F;oldstuff&#x2F;000003.html&quot; title=&quot;On tables, layouts, and CSS&quot;&gt;3rd blog entry&lt;&#x2F;a&gt;? In that entry titled &quot;&lt;a href=&quot;http:&#x2F;&#x2F;blog.vinniegarcia.com&#x2F;oldstuff&#x2F;000003.html&quot;&gt;On tables, layouts, and CSS&lt;&#x2F;a&gt;&quot;, Vinnie makes a very coherent argument on using tables for layouts - probably one of the most practical viewpoints to date.&lt;&#x2F;p&gt;
&lt;p&gt;We can love using CSS for our layouts fanatically, but we must also come to realise that sometimes tables will allow you to design truly cross-browser sites. At this time I&#x27;ve yet to find a 3-column CSS layout that doesn&#x27;t break with varying column heights, without resorting to hacks. If a hack is required, I think I&#x27;d stick to using a table, thank you. At least until browsers are capable.&lt;&#x2F;p&gt;
&lt;p&gt;Vinnie sums up pretty nicely with this &lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;I guess the moral of this rant is to remind everyone that while using Web standards is a smarter way to work, let&#x27;s not get bogged down in theory and worrying about validation.&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&gt;
</content>
  </entry>
  <entry>
    <title>CSS rollovers without preloading</title>
    <published>2003-09-13T13:59:30+00:00</published>
    <updated>2003-09-13T13:59:30+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/09/13/css-rollovers-without-preloading/"/>
    <id>https://chuyeow.wtf/2003/09/13/css-rollovers-without-preloading/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/09/13/css-rollovers-without-preloading/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.pixy.cz&#x2F;&quot;&gt;Petr Stanicek&lt;&#x2F;a&gt; has devised a clever technique to do image rollovers without resorting to JavaScript and with no need for preloading. Check out the &lt;a href=&quot;http:&#x2F;&#x2F;www.pixy.cz&#x2F;blogg&#x2F;clanky&#x2F;cssnopreloadrollovers&#x2F;example.html&quot; title=&quot;Some examples&quot;&gt;examples&lt;&#x2F;a&gt; to see if you can figure it out for yourself before reading his explanation - that &quot;eureka!&quot; feeling would be that much more gratifying.&lt;&#x2F;p&gt;
&lt;p&gt;For the eternally constipated, zoom over to &quot;&lt;a href=&quot;http:&#x2F;&#x2F;www.pixy.cz&#x2F;blogg&#x2F;clanky&#x2F;cssnopreloadrollovers&#x2F;&quot;&gt;Fast rollovers, no preload needed&lt;&#x2F;a&gt;&quot; for the explanation. (via &lt;a href=&quot;http:&#x2F;&#x2F;simon.incutio.com&#x2F;archive&#x2F;2003&#x2F;09&#x2F;10&#x2F;jsFreeRollovers&quot;&gt;Simon Willison&#x27;s Weblog&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>CSS contest at SitePointForums.com</title>
    <published>2003-09-02T14:39:56+00:00</published>
    <updated>2003-09-02T14:39:56+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/09/02/css-contest-at-sitepointforumscom/"/>
    <id>https://chuyeow.wtf/2003/09/02/css-contest-at-sitepointforumscom/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/09/02/css-contest-at-sitepointforumscom/">&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;&quot;&gt;SitePoint Forums&lt;&#x2F;a&gt; community has recently organized a CSS website design competition called &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;showthread.php?threadid=116294&quot;&gt;The Beauty of Style&lt;&#x2F;a&gt;, very much in the style of &lt;a href=&quot;http:&#x2F;&#x2F;csszengarden.com&#x2F;&quot;&gt;CSS Zen Garden&lt;&#x2F;a&gt;. If you&#x27;re thinking of taking part, sorry, the submission date is over, and judging is currently in progress.&lt;&#x2F;p&gt;
&lt;p&gt;You can take a look at the &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;list&quot;&gt;submitted entries&lt;&#x2F;a&gt; though. Some of them are very good, like &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;Crispy&#x2F;&quot;&gt;Crispy&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;zanzibar&#x2F;&quot;&gt;Zanzibar&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;lichen&#x2F;&quot;&gt;Lichen&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;SPstyle&#x2F;&quot;&gt;SP Style&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;contest.prestontalk.com&#x2F;index&#x2F;the_box&#x2F;&quot;&gt;The Box&lt;&#x2F;a&gt; (slightly broken in Mozilla).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Stumped by regular expressions? Try the Regex Coach</title>
    <published>2003-08-28T18:21:26+00:00</published>
    <updated>2003-08-28T18:21:26+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/28/stumped-by-regular-expressions-try-the-regex-coach/"/>
    <id>https://chuyeow.wtf/2003/08/28/stumped-by-regular-expressions-try-the-regex-coach/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/28/stumped-by-regular-expressions-try-the-regex-coach/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;peter.mapledesign.co.uk&#x2F;weblog&#x2F;&quot;&gt;Peter Bowyer&lt;&#x2F;a&gt;&#x27;s entry on &lt;a href=&quot;http:&#x2F;&#x2F;peter.mapledesign.co.uk&#x2F;weblog&#x2F;archives&#x2F;the_regex_coach_interactive_regular_expressions.html&quot; title=&quot;The Regex Coach - interactive regular expressions&quot;&gt;The Regex Coach - interactive regular expressions&lt;&#x2F;a&gt; alerted me to the very excellent &lt;a href=&quot;http:&#x2F;&#x2F;www.weitz.de&#x2F;regex-coach&#x2F;&quot;&gt;Regex Coach&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Regex Coach allows you to experiment with your regular expression (regex) and quickly determine how it would match your target string. It would be a very useful tool for trying out all any examples in any tutorials or books you may be reading. Also serves as a good testing platform for verifying your regex interactively (as opposed to writing it in your script, running it, and then checking the results). I wish I had this when I was learning regex.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>2nd installment of A Second Voice</title>
    <published>2003-08-28T16:38:51+00:00</published>
    <updated>2003-08-28T16:38:51+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/28/2nd-installment-of-a-second-voice/"/>
    <id>https://chuyeow.wtf/2003/08/28/2nd-installment-of-a-second-voice/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/28/2nd-installment-of-a-second-voice/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;&quot; title=&quot;Dave Shea&#x27;s blog&quot;&gt;Dave Shea&lt;&#x2F;a&gt; has published the 2nd installment of &quot;&lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;secondvoice&#x2F;&quot;&gt;A Second Voice&lt;&#x2F;a&gt;&quot;. This 2nd article is entitled &lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;cgi-bin&#x2F;mt&#x2F;mezzo&#x2F;archives&#x2F;000238.asp&quot; title=&quot;Standards: Designing For the Future&quot;&gt;Standards: Designing For the Future&lt;&#x2F;a&gt; by &lt;a href=&quot;http:&#x2F;&#x2F;www.accessify.com&#x2F;blog&#x2F;&quot; title=&quot;Ian Lloyd&#x27;s blog&quot;&gt;Ian Lloyd&lt;&#x2F;a&gt;. In it, Ian gives a personal account of his experiences promoting &lt;a href=&quot;http:&#x2F;&#x2F;www.webstandards.org&#x2F;&quot;&gt;Web Standards&lt;&#x2F;a&gt; in the workplace and his thoughts on what&#x27;s holding people back from accepting and practising them.&lt;&#x2F;p&gt;
&lt;p&gt;As &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2003&#x2F;08&#x2F;10&#x2F;web_designer_article_series_a_second_voice.php&quot;&gt;before&lt;&#x2F;a&gt;, I&#x27;m posting this in hope it gets passed on as &quot;word of blog&quot;. Essential reading for web developers and designers alike.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Dealing with colors</title>
    <published>2003-08-21T18:44:40+00:00</published>
    <updated>2003-08-21T18:44:40+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/21/dealing-with-colors/"/>
    <id>https://chuyeow.wtf/2003/08/21/dealing-with-colors/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/21/dealing-with-colors/">&lt;p&gt;Several tools to help the web developer in color scheming and color management.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.iconico.com&#x2F;colorpic&#x2F;&quot;&gt;Iconico&#x27;s Color Picker&lt;&#x2F;a&gt; is a free Windows application that helps you pick colors and save them to your swatch. Very good for picking colors from sites and pictures. My only grouse is that it doesn&#x27;t allow you to save your swatch.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.colorschemer.com&#x2F;&quot;&gt;Color Schemer&lt;&#x2F;a&gt; helps to create a color scheme when given a particular color. The resulting schemes don&#x27;t always work though.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.meyerweb.com&#x2F;eric&#x2F;tools&#x2F;color-blend&#x2F;&quot;&gt;Color Blender&lt;&#x2F;a&gt; does as its name suggests - it blends 2 colors into 1. The results can surprise you - you may just find your new favorite color with some experimentation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;andy.greyledge.net&#x2F;ColorChip&#x2F;&quot;&gt;ColorChip&lt;&#x2F;a&gt; is a PHP class that, given a single color, produces the complementary color, nearby hues, a light to dark version of the color, and more. You have to &lt;a href=&quot;http:&#x2F;&#x2F;andy.greyledge.net&#x2F;ColorChip&#x2F;example.php&quot; title=&quot;Try out the demo of ColorChip&quot;&gt;try it&lt;&#x2F;a&gt; to be impressed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>Tracking entry referrers with PHP in MT</title>
    <published>2003-08-16T19:30:18+00:00</published>
    <updated>2003-08-16T19:30:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/16/tracking-entry-referrers-with-php-in-mt/"/>
    <id>https://chuyeow.wtf/2003/08/16/tracking-entry-referrers-with-php-in-mt/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/16/tracking-entry-referrers-with-php-in-mt/">&lt;p&gt;I&#x27;ve always wanted to track referrers for each entry and at the same time be able to tell which entries are the more popular ones by keeping track of each entry&#x27;s hit count.&lt;&#x2F;p&gt;
&lt;p&gt;So I did the &lt;em&gt;smart&lt;&#x2F;em&gt; thing first by Googling to see if anyone else had done it. I found the &lt;a href=&quot;http:&#x2F;&#x2F;mt-plugins.org&#x2F;archives&#x2F;entry&#x2F;awstatsreferers.php&quot;&gt;AWStatsReferers&lt;&#x2F;a&gt; MT plugin at the &lt;a href=&quot;http:&#x2F;&#x2F;mt-plugins.org&#x2F;&quot;&gt;MT Plugin Directory&lt;&#x2F;a&gt; but it requires your host to have &lt;a href=&quot;http:&#x2F;&#x2F;awstats.sourceforge.net&#x2F;&quot;&gt;AWStats&lt;&#x2F;a&gt; installed. My host doesn&#x27;t, and I wasn&#x27;t going to get them to install AWStats just so I can track referrers for my blog. &lt;a href=&quot;http:&#x2F;&#x2F;www.textism.com&#x2F;tools&#x2F;refer&#x2F;&quot;&gt;Refer&lt;&#x2F;a&gt; is a referrer tracking script that turned up - it actually seems like it could do what I wanted with a little tweaking, but a look at the code left me thinking there should be a simpler way to achieve my more specific goals (i.e. track referers and, consequently, hit count for each entry).&lt;&#x2F;p&gt;
&lt;p&gt;So, hey, I decided to whip up a simple hack of sorts using PHP and a database table to store the referrers.&lt;&#x2F;p&gt;
&lt;span id=&quot;continue-reading&quot;&gt;&lt;&#x2F;span&gt;&lt;a name=&quot;tutorial&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Tracking entry referrers with PHP in MT&lt;&#x2F;h3&gt;
&lt;p&gt;Requirements: MovableType, webhost that supports PHP, database (MySQL in this tutorial)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;del&gt;
&lt;p&gt;A plain text version of this tutorial is also available &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2003&#x2F;08&#x2F;16&#x2F;tracking_entry_referrers_with_php_in_mt.txt&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;&#x2F;del&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
First off, any page where you wish to display the referrers or hit count, including your archives and main index page, need to have a .php extension (or any other extension that will cause the file to be pre-processed by PHP). You can do so by renaming your &lt;em&gt;Archive File Templates&lt;&#x2F;em&gt; to have a .php extension (go to &lt;em&gt;Weblog Config&lt;&#x2F;em&gt; -&gt; &lt;em&gt;Archiving&lt;&#x2F;em&gt;). The same goes for your main index page (go to &lt;em&gt;Templates&lt;&#x2F;em&gt;) .
&lt;&#x2F;li&gt;
&lt;li&gt;Create the database table. The SQL is:&lt;br &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;CREATE TABLE `mt_entryhits` (&lt;br &#x2F;&gt;
  `entry_id` INT(11) NOT NULL&lt;br &#x2F;&gt;
    REFERENCES mt_entry(entry_id)&lt;br &#x2F;&gt;
    ON DELETE CASCADE&lt;br &#x2F;&gt;
    ON UPDATE CASCADE,&lt;br &#x2F;&gt;
  `referer` VARCHAR(255) NOT NULL&lt;br &#x2F;&gt;
);&lt;&#x2F;div&gt;
&lt;p&gt;You can use either phpMyAdmin, the MySQL command-line client or whatever suits your boat.
&lt;&#x2F;li&gt;
&lt;li&gt;Create a file named &lt;span class=&quot;monospaced&quot;&gt;db-config.php&lt;&#x2F;span&gt; with the following code:&lt;br &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;?php&lt;br &#x2F;&gt;
$host = &#x27;host&#x27;;  &#x2F;&#x2F; database server hostname&lt;br &#x2F;&gt;
$user = &#x27;user&#x27;;  &#x2F;&#x2F; database username&lt;br &#x2F;&gt;
$password = &#x27;password&#x27;;  &#x2F;&#x2F;  database password&lt;br &#x2F;&gt;
$database = &#x27;database&#x27;;  &#x2F;&#x2F; MT database&lt;br &#x2F;&gt;
?&amp;gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Replace the values of the variables as per your configuration. Upload it in your blog&#x27;s top level directory (i.e. the &lt;em&gt;Local Site Path&lt;&#x2F;em&gt; of your weblog, as specified in the &lt;em&gt;Weblog Configuration&lt;&#x2F;em&gt; screen).
&lt;&#x2F;li&gt;
&lt;li&gt;
Login to your MovableType installation and  &lt;em&gt;Manage your weblog&lt;&#x2F;em&gt;. Go to &lt;em&gt;Manage&lt;&#x2F;em&gt; -&gt; &lt;em&gt;Templates&lt;&#x2F;em&gt; -&gt; &lt;em&gt;Archive-Related Templates&lt;&#x2F;em&gt; -&gt; &lt;em&gt;Individual Entry Archive&lt;&#x2F;em&gt;.
&lt;&#x2F;li&gt;
&lt;li&gt;
At the top of the template, add the following lines:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;?php&lt;br &#x2F;&gt;
error_reporting(0);&lt;&#x2F;p&gt;
&lt;p&gt;include( &#x27;&amp;lt;$MTBlogSitePath$&amp;gt;db-config.php&#x27; );&lt;&#x2F;p&gt;
&lt;p&gt;mysql_connect( $host, $user, $password );&lt;br &#x2F;&gt;
mysql_select_db( $database );&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;&#x2F; this is the list of referrers you don&#x27;t want to record&lt;br &#x2F;&gt;
&#x2F;&#x2F; use the following format within the parentheses:&lt;br &#x2F;&gt;
&#x2F;&#x2F;   &#x27;http:&#x2F;&#x2F;domain1.com&#x27;, &#x27;http:&#x2F;&#x2F;domain2.com&#x27;, ...&lt;br &#x2F;&gt;
&#x2F;&#x2F; leave it blank if you want to record all referrers&lt;br &#x2F;&gt;
$ignore_list = array( &#x27;http:&#x2F;&#x2F;referrer.you.want.to.ignore&#x27; );&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;&#x2F; check referrer string to determine if we want to record it&lt;br &#x2F;&gt;
$ignore_referrer = false;&lt;br &#x2F;&gt;
foreach( $ignore_list as $ignore ) {&lt;br &#x2F;&gt;
  if( stristr( $_SERVER[&#x27;HTTP_REFERER&#x27;], $ignore ) !== false ) {&lt;br &#x2F;&gt;
    $ignore_referrer = true;&lt;br &#x2F;&gt;
     break;&lt;br &#x2F;&gt;
  }&lt;br &#x2F;&gt;
}&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;&#x2F; record the referer&lt;br &#x2F;&gt;
if( !$ignore_referrer ) {&lt;br &#x2F;&gt;
  mysql_query( &quot;INSERT INTO mt_entryhits(entry_id, referer) VALUES (&amp;lt;$MTEntryID$&amp;gt;, &#x27;{$_SERVER[&#x27;HTTP_REFERER&#x27;]}&#x27;)&quot; );&lt;br &#x2F;&gt;
}&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;&#x2F; get the no. of times this entry has been read&lt;br &#x2F;&gt;
$rs = mysql_query( &#x27;SELECT COUNT(*) FROM mt_entryhits WHERE entry_id=&amp;lt;$MTEntryID$&amp;gt;&#x27; );&lt;br &#x2F;&gt;
$row = mysql_fetch_row( $rs );&lt;br &#x2F;&gt;
$hits = $row[0];&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;&#x2F; get the list of referers&lt;br &#x2F;&gt;
$sql =&lt;br &#x2F;&gt;
&#x27;SELECT referer, COUNT(*) AS count&lt;br &#x2F;&gt;
FROM mt_entryhits&lt;br &#x2F;&gt;
WHERE entry_id=&lt;$MTEntryID$&gt;&lt;br &#x2F;&gt;
GROUP BY referer&lt;br &#x2F;&gt;
ORDER BY count DESC&#x27;;&lt;&#x2F;p&gt;
&lt;p&gt;$rs = mysql_query( $sql );&lt;br &#x2F;&gt;
?&amp;gt;
&lt;&#x2F;p&gt;&lt;&#x2F;div&gt;
&lt;p&gt;This code snippet is specific to MySQL - you should be able to change it easily for PostgreSQL or SQLite (if not, &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;contact&#x2F;&quot;&gt;let me know&lt;&#x2F;a&gt; and I&#x27;ll post code snippets for those &lt;acronym title=&quot;Relational Database Management Systems&quot;&gt;RDBMS&lt;&#x2F;acronym&gt;s too). Of course, you can plug in a database abstraction library like the excellent &lt;a href=&quot;php.weblogs.com&#x2F;adodb&quot;&gt;ADODB&lt;&#x2F;a&gt;, but I leave out that portable solution in favor of database-specific built-in function calls because MovableType supports only MySQL, PostgreSQL, or SQLite.
&lt;&#x2F;li&gt;
&lt;li&gt;
In the same template (the &lt;em&gt;Individual Entry Archive&lt;&#x2F;em&gt; template), look for a good place to display the entry hit count and insert the following code:&lt;br &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
Read &amp;lt;?=$hits?&amp;gt; time&amp;lt;?php if($hits != 1) echo &#x27;s&#x27;;?&amp;gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I place them in the &quot;Posted by&quot; bit at the end of each entry, which for the default MT template is&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;span class=&quot;posted&quot;&amp;gt;Posted by &amp;lt;$MTEntryAuthor$&amp;gt; at &amp;lt;$MTEntryDate$&amp;gt;&lt;br &#x2F;&gt;
&amp;lt;MTEntryIfAllowPings&amp;gt;&lt;br &#x2F;&gt;
| &amp;lt;a href=&quot;&amp;lt;$MTCGIPath$&amp;gt;&amp;lt;$MTTrackbackScript$&amp;gt;?__mode=view&amp;entry_id=&amp;lt;$MTEntryID$&amp;gt;&quot; onclick=&quot;OpenTrackback(this.href); return false&quot;&amp;gt;TrackBack&amp;lt;&#x2F;a&amp;gt;&lt;br &#x2F;&gt;
&amp;lt;&#x2F;MTEntryIfAllowPings&amp;gt;&lt;br &#x2F;&gt;
&lt;span style=&quot;color:red;&quot;&gt;| Read &amp;lt;?=$hits?&amp;gt; time&amp;lt;?php if($hits != 1) echo &#x27;s&#x27;;?&amp;gt;&lt;&#x2F;span&gt;&lt;br &#x2F;&gt;
&amp;lt;br &#x2F;&amp;gt;&amp;lt;&#x2F;span&amp;gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
Now, it&#x27;s time to display the referrers. Again in the same template, add the following code where you wish to display the referrers.&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;?php&lt;br &#x2F;&gt;
&#x2F;&#x2F; display the list of referers&lt;br &#x2F;&gt;
echo &#x27;&amp;lt;div class=&quot;sidetitle&quot;&amp;gt;Referrers&amp;lt;&#x2F;div&amp;gt;&#x27;, &quot;\n&quot;;&lt;br &#x2F;&gt;
echo &#x27;&amp;lt;div class=&quot;side&quot;&amp;gt;&#x27;, &quot;\n&quot;;&lt;br &#x2F;&gt;
echo &#x27;&amp;lt;ul&amp;gt;&#x27;, &quot;\n&quot;;&lt;br &#x2F;&gt;
while( $row = mysql_fetch_assoc( $rs ) ) {&lt;&#x2F;p&gt;
&lt;p&gt;  $referer = $row[&#x27;referer&#x27;];&lt;br &#x2F;&gt;
  $count = $row[&#x27;count&#x27;];&lt;&#x2F;p&gt;
&lt;p&gt;  echo &#x27;&amp;lt;li&amp;gt;&#x27;;&lt;&#x2F;p&gt;
&lt;p&gt;  if( strpos( $referer, &#x27;http:&#x2F;&#x2F;&#x27; ) !== false ) {&lt;br &#x2F;&gt;
    echo &#x27;&amp;lt;a href=&quot;&#x27;, $referer, &#x27;&quot; target=&quot;_blank&quot;&amp;gt;&#x27;;&lt;&#x2F;p&gt;
&lt;p&gt;    &#x2F;&#x2F; truncate URL if too long&lt;br &#x2F;&gt;
    if( strlen($referer) &amp;gt; 90 ) {&lt;br &#x2F;&gt;
      $referer = substr($referer, 0, 90) . &#x27;...&#x27;;&lt;br &#x2F;&gt;
    }&lt;br &#x2F;&gt;
    echo $referer, &#x27;(&#x27;, $count, &#x27;)&#x27;;&lt;br &#x2F;&gt;
    echo &#x27;&amp;lt;&#x2F;a&amp;gt;&#x27;;&lt;br &#x2F;&gt;
  }&lt;br &#x2F;&gt;
  else {&lt;br &#x2F;&gt;
    &#x2F;&#x2F; truncate URL if too long&lt;br &#x2F;&gt;
    if( strlen($referer) &amp;gt; 90 ) {&lt;br &#x2F;&gt;
      $referer = substr($referer, 0, 90) . &#x27;...&#x27;;&lt;br &#x2F;&gt;
    }&lt;&#x2F;p&gt;
&lt;p&gt;    &#x2F;&#x2F; handle cases where there is no referrer&lt;br &#x2F;&gt;
    if( $referer == &#x27;&#x27; ) {&lt;br &#x2F;&gt;
      $referer = &#x27;Direct hit or unknown referrer&#x27;;&lt;br &#x2F;&gt;
    }&lt;br &#x2F;&gt;
    echo $referer, &#x27;(&#x27;, $count, &#x27;)&#x27;;&lt;br &#x2F;&gt;
  }&lt;br &#x2F;&gt;
  echo &#x27;&amp;lt;&#x2F;li&amp;gt;&#x27;;&lt;br &#x2F;&gt;
  echo &quot;\n&quot;;&lt;br &#x2F;&gt;
}&lt;br &#x2F;&gt;
echo &quot;\n&quot;;&lt;br &#x2F;&gt;
echo &#x27;&amp;lt;&#x2F;ul&amp;gt;&#x27;, &quot;\n&quot;;&lt;br &#x2F;&gt;
echo &#x27;&amp;lt;&#x2F;div&amp;gt;&#x27;;&lt;br &#x2F;&gt;
?&amp;gt;
&lt;&#x2F;p&gt;&lt;&#x2F;div&gt;
&lt;p&gt;You can format the &lt;acronym title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;&#x2F;acronym&gt; to suit your current template.
&lt;&#x2F;li&gt;
&lt;li&gt;
Phew! The hardest part is now over. All that&#x27;s left is to display the number of times each entry has been read in the other archive pages and the main page (&lt;em&gt;Main Index&lt;&#x2F;em&gt;). I&#x27;ll only work through the changes to the &lt;em&gt;Main Index&lt;&#x2F;em&gt; template, since it will be similar for the other templates (&lt;em&gt;Category Archive&lt;&#x2F;em&gt;, &lt;em&gt;Date-Based Archive&lt;&#x2F;em&gt;, any other templates you have created that displays blog entries).&lt;&#x2F;p&gt;
&lt;p&gt;At the top of the template, add the following lines:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;?php&lt;br &#x2F;&gt;
error_reporting(0);&lt;&#x2F;p&gt;
&lt;p&gt;include( &#x27;&amp;lt;$MTBlogSitePath$&amp;gt;db-config.php&#x27; );&lt;&#x2F;p&gt;
&lt;p&gt;mysql_connect( $host, $user, $password );&lt;br &#x2F;&gt;
mysql_select_db( $database );&lt;br &#x2F;&gt;
?&amp;gt;
&lt;&#x2F;p&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Look for the &lt;span class=&quot;monospaced&quot;&gt;&amp;lt;MTEntries&amp;gt;&lt;&#x2F;span&gt; tag in the template and add the following lines after it:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;?php&lt;br &#x2F;&gt;
&#x2F;&#x2F; get the no. of times this entry has been read&lt;br &#x2F;&gt;
$rs = mysql_query( &#x27;SELECT COUNT(*) FROM mt_entryhits WHERE entry_id=&amp;lt;$MTEntryID$&amp;gt;&#x27; );&lt;br &#x2F;&gt;
$row = mysql_fetch_row( $rs );&lt;br &#x2F;&gt;
$hits = $row[0];&lt;br &#x2F;&gt;
?&amp;gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Now that we&#x27;ve the number of hits in the variable &lt;span class=&quot;monospaced&quot;&gt;$hits&lt;&#x2F;span&gt;, we can display the entry hit count as before by adding the following line of code within the &lt;span class=&quot;monospaced&quot;&gt;&amp;lt;MTEntries&amp;gt;&lt;&#x2F;span&gt; tag:&lt;&#x2F;p&gt;
&lt;div class=&quot;code&quot;&gt;
Read &amp;lt;?=$hits?&amp;gt; time&amp;lt;?php if($hits != 1) echo &#x27;s&#x27;;?&amp;gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
Do the same for the other archive templates (&lt;em&gt;Category Archive&lt;&#x2F;em&gt;, &lt;em&gt;Date-Based Archive&lt;&#x2F;em&gt;, any other templates you have created that displays blog entries).
&lt;&#x2F;li&gt;
&lt;li&gt;
Rebuild your site and you&#x27;re done!
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;
Thanks to everyone who gave comments and asked questions at the &lt;a href=&quot;http:&#x2F;&#x2F;www.movabletype.org&#x2F;support&#x2F;&quot;&gt;MovableType support forums&lt;&#x2F;a&gt; and elsewhere, who pointed out things I overlooked.&lt;&#x2F;p&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;&#x2F;strong&gt;: &lt;a href=&quot;http:&#x2F;&#x2F;www.tbotcotw.com&#x2F;&quot; title=&quot;Matt Moore&#x27;s blog&quot;&gt;Matt Moore&lt;&#x2F;a&gt; has an alternative (based on this very post! ;-)) that includes collection of the page title of the referrer, and also the search terms used to get to your blog entry. Check out his entry entitled &quot;&lt;a href=&quot;http:&#x2F;&#x2F;www.tbotcotw.com&#x2F;archives&#x2F;001159.php&quot;&gt;How to collect referrer data&lt;&#x2F;a&gt;&quot;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Beginning Web Design series</title>
    <published>2003-08-15T04:50:06+00:00</published>
    <updated>2003-08-15T04:50:06+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/15/beginning-web-design-series/"/>
    <id>https://chuyeow.wtf/2003/08/15/beginning-web-design-series/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/15/beginning-web-design-series/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.itnextgen.net&#x2F;pseudo&#x2F;&quot;&gt;Paul Scrivens&lt;&#x2F;a&gt; has started a series of mini-articles for beginning web designers, starting with &lt;a href=&quot;http:&#x2F;&#x2F;www.itnextgen.net&#x2F;pseudo&#x2F;archives&#x2F;web_design&#x2F;beginning_web_design_ch_1.php&quot;&gt;Ch. 1&lt;&#x2F;a&gt; which points out some of the best sites to study as prime case studies for color, layout and liquid design.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;&quot;&gt;Mezzoblue&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;exp.hicksdesign.co.uk&#x2F;index.php&quot;&gt;hicksdesign&lt;&#x2F;a&gt; are 2 of the best-looking blogs out there.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Getting with the style switcher</title>
    <published>2003-08-11T13:53:25+00:00</published>
    <updated>2003-08-11T13:53:25+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/11/getting-with-the-style-switcher/"/>
    <id>https://chuyeow.wtf/2003/08/11/getting-with-the-style-switcher/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/11/getting-with-the-style-switcher/">&lt;p&gt;I&#x27;ve always been fascinated with JavaScript-based style switchers, like those at &lt;a href=&quot;http:&#x2F;&#x2F;alistapart.com&#x2F;&quot;&gt;A List Apart&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;devedge.netscape.com&#x2F;&quot;&gt;Netscape DevEdge&lt;&#x2F;a&gt;. It&#x27;s fun to have a (limited) amount of customizability, without having to reload the webpage like those done using server-side scripting. It&#x27;s like a shiny toy for your users to play.&lt;&#x2F;p&gt;
&lt;p&gt;I got myself one of those using &lt;a href=&quot;http:&#x2F;&#x2F;www.idontsmoke.co.uk&#x2F;&quot;&gt;Paul Sowden&#x27;s&lt;&#x2F;a&gt; Style Switcher and following the (simple) instructions at his A List Apart tutorial entitled &quot;&lt;a href=&quot;http:&#x2F;&#x2F;www.alistapart.com&#x2F;stories&#x2F;alternate&#x2F;&quot;&gt;Alternative Style: Working With Alternate Style Sheets&lt;&#x2F;a&gt;&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;And so, &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;&quot;&gt;redemption in a blog&lt;&#x2F;a&gt; now sports a new &lt;a href=&quot;&#x2F;about&#x2F;switcher&#x2F;&quot; onclick=&quot;setActiveStyleSheet(&#x27;default&#x27;); return false;&quot; onkeypress=&quot;setActiveStyleSheet(&#x27;default&#x27;); return false;&quot; title=&quot;Switch to the default style&quot;&gt;Default&lt;&#x2F;a&gt; style and a &lt;a href=&quot;&#x2F;about&#x2F;switcher&#x2F;&quot; onclick=&quot;setActiveStyleSheet(&#x27;clean&#x27;); return false;&quot; onkeypress=&quot;setActiveStyleSheet(&#x27;clean&#x27;); return false;&quot; title=&quot;Switch to Clean style&quot;&gt;Clean&lt;&#x2F;a&gt; style, along with the &lt;a href=&quot;&#x2F;about&#x2F;switcher&#x2F;&quot; onclick=&quot;setActiveStyleSheet(&#x27;original&#x27;); return false;&quot; onkeypress=&quot;setActiveStyleSheet(&#x27;original&#x27;); return false;&quot; title=&quot;Switch to Original style&quot;&gt;Original&lt;&#x2F;a&gt; style.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Redesigning made easy with &quot;edit styles&quot; bookmarklet</title>
    <published>2003-08-11T13:09:14+00:00</published>
    <updated>2003-08-11T13:09:14+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/11/redesigning-made-easy-with-edit-styles-bookmarklet/"/>
    <id>https://chuyeow.wtf/2003/08/11/redesigning-made-easy-with-edit-styles-bookmarklet/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/11/redesigning-made-easy-with-edit-styles-bookmarklet/">&lt;p&gt;I&#x27;ve recently redesigned &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;&quot;&gt;redemption in a blog&lt;&#x2F;a&gt;, optimizing the &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;&#x2F;acronym&gt; and reducing line width for more optimal reading. I did this quickly and painlessly with a gem of a bookmarklet, the &lt;a href=&quot;javascript:(function(){function init(){var newline=unescape(%22%%22+%220A%22),importCount=0,L=[];dead=false;oldCSS=null;x=opener;ta=document.f.ta;ta.select();if(x.editStyles){ta.value=x.editStyles.innerHTML;update();return;}ta.value=%22&#x2F;* Type CSS rules here and they will be applied%22+newline+%22to pages from &#x27;%22+location.host+%22&#x27;%22+newline+%22immediately as long as you keep this window open. *&#x2F;%22+newline+newline;function add(s){if(!s.disabled){var y={sheet:s,readable:true,label:%22Imported%22,inline:false,shorturl:%22%22,fulltext:%22%22};try{for(var k=0,m;m=s.cssRules[k];++k)if(m.type==3)add(m.styleSheet);}catch(er){y.readable=false;}L.push(y);if(s.ownerNode){y.label=s.ownerNode.tagName.toUpperCase()+%22-tag%22;if(!s.ownerNode.getAttribute(%22src%22)&amp;&amp;!s.ownerNode.href)y.inline=true;}if(y.inline){y.label=%22Inline %22+y.label;y.fulltext=fix(s.ownerNode.innerHTML);}else if(s.href.substr(0,13)==%22data:text&#x2F;css%22){y.shorturl=%22 contained in a data: URL%22;y.fulltext=fix(unescape(s.href.slice(14)));}else{++importCount;y.importtext=%22@import \%22%22+s.href+%22\%22;%22;y.shorturl=%22 %22+s.href.split(&#x27;&#x2F;&#x27;).reverse()[0];if(!y.readable){y.fulltext=%22&#x2F;* Out-of-domain; imported above. *&#x2F;%22;}else if(s.href.substr(0,5)!=%22http:%22){y.fulltext=%22&#x2F;* Non-http; imported above. *&#x2F;%22;}else{var loadingText=%22&#x2F;* Loading (%22+(L.length-1)+%22) *&#x2F;%22;y.fulltext=loadingText;var p=new XMLHttpRequest();p.onload=function(e){ta.value=ta.value.replace(y.importtext+newline,%22%22);y.fulltext=p.responseText;ta.value=ta.value.replace(loadingText,fix(y.fulltext));ta.value=ta.value.replace(firstNote+newline,%22%22);};p.open(%22GET%22,s.href);p.send(null);}}}}function fix(s){while((s[0]==newline)&amp;&amp;s.length&gt;1)s=s.slice(1);while((s[s.length-1]==newline)&amp;&amp;s.length&gt;1)s=s.substr(0,s.length-1);s=s.replace(&#x2F;@import.*;&#x2F;ig,function(){return %22&#x2F;* %22+RegExp.lastMatch+%22 *&#x2F;%22;});return s;}for(var i=0,ss;ss=x.document.styleSheets[i];++i)add(ss);var imports=%22%22,main=%22%22;var firstNote=%22&#x2F;**** Style sheets whose contents could be loaded were ****&#x2F;%22+newline+%22&#x2F;**** imported instead.  Rule order may be incorrect   ****&#x2F;%22+newline+%22&#x2F;**** as a result. ****&#x2F;%22+newline;if(importCount){ta.value+=firstNote;}for(var i=0;ss=L[i];++i){if(ss.importtext){imports+=ss.importtext+newline;}main+=%22&#x2F;**** %22+ss.label+%22 style sheet%22+ss.shorturl+%22 ****&#x2F;%22+newline;main+=newline;main+=ss.fulltext;main+=newline;main+=newline;main+=newline;}ta.value+=imports+newline+main;update();}function update(){try{if(!x||x.closed){ta.style.backgroundColor=%22#ddd%22;return;}x.editStyles;}catch(er){ta.style.backgroundColor=%22#fdc%22;setTimeout(update,150);dead=true;return;}if(dead){dead=false;ta.style.backgroundColor=%22%22;oldCSS=null;}if(!x.editStyles){var newSS;newSS=x.document.createElement(%22style%22);newSS.type=%22text&#x2F;css%22;x.document.getElementsByTagName(%22head%22)[0].appendChild(newSS);x.editStyles=newSS;oldCSS=null;for(var i=0,ss;ss=x.document.styleSheets[i];++i)ss.disabled=true;}if(oldCSS!=ta.value){oldCSS=ta.value;x.editStyles.innerHTML=ta.value;}setTimeout(update,150);}y=open(&#x27;&#x27;,&#x27;&#x27;,&#x27;resizable,scrollbars=yes,width=550,height=520&#x27;);y.document.write(&#x27;&lt;title&gt;Edit Styles&lt;&#x2F;title&gt;&lt;br &#x2F;&gt;
&lt;style&gt;.ec { width: 100%; height: 100%; border: none; margin: 0px; padding: 0px; }&lt;&#x2F;style&gt;
&lt;p&gt;&lt;body class=%22ec%22&gt;&lt;br &#x2F;&gt;
&lt;form name=%22f%22 style=%22margin: 0px;%22 class=%22ec%22&gt;&lt;textarea name=%22ta%22 wrap=%22soft%22 style=%22margin: 0px; border: 0px; width:100%; height:100%;%22 class=%22ec%22&gt;&lt;&#x2F;textarea&gt;&lt;script&gt;&#x27;+update+init+&#x27;init();&lt;&#x27;+&#x27;&#x2F;script&gt;&#x27;);y.document.close();})()&quot;&gt;&quot;edit styles&quot; bookmarklet&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;edit styles&quot; bookmarklet allows on-the-fly editing of the active &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;&#x2F;acronym&gt; file of any webpage. Try it out - &lt;a href=&quot;javascript:(function(){function init(){var newline=unescape(%22%%22+%220A%22),importCount=0,L=[];dead=false;oldCSS=null;x=opener;ta=document.f.ta;ta.select();if(x.editStyles){ta.value=x.editStyles.innerHTML;update();return;}ta.value=%22&#x2F;* Type CSS rules here and they will be applied%22+newline+%22to pages from &#x27;%22+location.host+%22&#x27;%22+newline+%22immediately as long as you keep this window open. *&#x2F;%22+newline+newline;function add(s){if(!s.disabled){var y={sheet:s,readable:true,label:%22Imported%22,inline:false,shorturl:%22%22,fulltext:%22%22};try{for(var k=0,m;m=s.cssRules[k];++k)if(m.type==3)add(m.styleSheet);}catch(er){y.readable=false;}L.push(y);if(s.ownerNode){y.label=s.ownerNode.tagName.toUpperCase()+%22-tag%22;if(!s.ownerNode.getAttribute(%22src%22)&amp;&amp;!s.ownerNode.href)y.inline=true;}if(y.inline){y.label=%22Inline %22+y.label;y.fulltext=fix(s.ownerNode.innerHTML);}else if(s.href.substr(0,13)==%22data:text&#x2F;css%22){y.shorturl=%22 contained in a data: URL%22;y.fulltext=fix(unescape(s.href.slice(14)));}else{++importCount;y.importtext=%22@import \%22%22+s.href+%22\%22;%22;y.shorturl=%22 %22+s.href.split(&#x27;&#x2F;&#x27;).reverse()[0];if(!y.readable){y.fulltext=%22&#x2F;* Out-of-domain; imported above. *&#x2F;%22;}else if(s.href.substr(0,5)!=%22http:%22){y.fulltext=%22&#x2F;* Non-http; imported above. *&#x2F;%22;}else{var loadingText=%22&#x2F;* Loading (%22+(L.length-1)+%22) *&#x2F;%22;y.fulltext=loadingText;var p=new XMLHttpRequest();p.onload=function(e){ta.value=ta.value.replace(y.importtext+newline,%22%22);y.fulltext=p.responseText;ta.value=ta.value.replace(loadingText,fix(y.fulltext));ta.value=ta.value.replace(firstNote+newline,%22%22);};p.open(%22GET%22,s.href);p.send(null);}}}}function fix(s){while((s[0]==newline)&amp;&amp;s.length&gt;1)s=s.slice(1);while((s[s.length-1]==newline)&amp;&amp;s.length&gt;1)s=s.substr(0,s.length-1);s=s.replace(&#x2F;@import.*;&#x2F;ig,function(){return %22&#x2F;* %22+RegExp.lastMatch+%22 *&#x2F;%22;});return s;}for(var i=0,ss;ss=x.document.styleSheets[i];++i)add(ss);var imports=%22%22,main=%22%22;var firstNote=%22&#x2F;**** Style sheets whose contents could be loaded were ****&#x2F;%22+newline+%22&#x2F;**** imported instead.  Rule order may be incorrect   ****&#x2F;%22+newline+%22&#x2F;**** as a result. ****&#x2F;%22+newline;if(importCount){ta.value+=firstNote;}for(var i=0;ss=L[i];++i){if(ss.importtext){imports+=ss.importtext+newline;}main+=%22&#x2F;**** %22+ss.label+%22 style sheet%22+ss.shorturl+%22 ****&#x2F;%22+newline;main+=newline;main+=ss.fulltext;main+=newline;main+=newline;main+=newline;}ta.value+=imports+newline+main;update();}function update(){try{if(!x||x.closed){ta.style.backgroundColor=%22#ddd%22;return;}x.editStyles;}catch(er){ta.style.backgroundColor=%22#fdc%22;setTimeout(update,150);dead=true;return;}if(dead){dead=false;ta.style.backgroundColor=%22%22;oldCSS=null;}if(!x.editStyles){var newSS;newSS=x.document.createElement(%22style%22);newSS.type=%22text&#x2F;css%22;x.document.getElementsByTagName(%22head%22)[0].appendChild(newSS);x.editStyles=newSS;oldCSS=null;for(var i=0,ss;ss=x.document.styleSheets[i];++i)ss.disabled=true;}if(oldCSS!=ta.value){oldCSS=ta.value;x.editStyles.innerHTML=ta.value;}setTimeout(update,150);}y=open(&#x27;&#x27;,&#x27;&#x27;,&#x27;resizable,scrollbars=yes,width=550,height=520&#x27;);y.document.write(&#x27;&lt;title&gt;Edit Styles&lt;&#x2F;title&gt;&lt;br &#x2F;&gt;
&lt;style&gt;.ec { width: 100%; height: 100%; border: none; margin: 0px; padding: 0px; }&lt;&#x2F;style&gt;
&lt;p&gt;&lt;body class=%22ec%22&gt;&lt;br &#x2F;&gt;
&lt;form name=%22f%22 style=%22margin: 0px;%22 class=%22ec%22&gt;&lt;textarea name=%22ta%22 wrap=%22soft%22 style=%22margin: 0px; border: 0px; width:100%; height:100%;%22 class=%22ec%22&gt;&lt;&#x2F;textarea&gt;&lt;script&gt;&#x27;+update+init+&#x27;init();&lt;&#x27;+&#x27;&#x2F;script&gt;&#x27;);y.document.close();})()&quot;&gt;click here&lt;&#x2F;a&gt; (only in &lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.org&#x2F;&quot;&gt;Mozilla&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.mozilla.org&#x2F;products&#x2F;firebird&#x2F;&quot;&gt;Mozilla Firebird&lt;&#x2F;a&gt; - all the more reason to switch, if you haven&#x27;t). Changing the CSS changes the webpage immediately, allowing for a great way to try out new styling painlessly and saving you the constant edit-reload cycle. This is a must-have tool for the web designer&#x2F;developer. Drag it to your bookmark toolbar. Don&#x27;t style your site without it.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Web designer article series: A Second Voice</title>
    <published>2003-08-10T23:58:16+00:00</published>
    <updated>2003-08-10T23:58:16+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/10/web-designer-article-series-a-second-voice/"/>
    <id>https://chuyeow.wtf/2003/08/10/web-designer-article-series-a-second-voice/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/10/web-designer-article-series-a-second-voice/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;&quot;&gt;Dave Shea&lt;&#x2F;a&gt; has started a new series of articles on &lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;&quot;&gt;Mezzoblue&lt;&#x2F;a&gt; titled &quot;&lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;secondvoice&#x2F;&quot;&gt;A Second Voice&lt;&#x2F;a&gt;&quot;. It is a group effort consisting of web designer specialists in their field, including Usability, Design and Programming. The &lt;a href=&quot;http:&#x2F;&#x2F;www.mezzoblue.com&#x2F;cgi-bin&#x2F;mt&#x2F;mezzo&#x2F;archives&#x2F;000215.asp#000215&quot; title=&quot;Accessibility: Build it, and They Will Come&quot;&gt;1st article on accessibility&lt;&#x2F;a&gt; by Nic Steenhout reads easily.&lt;&#x2F;p&gt;
&lt;p&gt;This is definitely one to watch and bookmark. I&#x27;m just passing it along as &quot;word of blog&quot;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Designing with web standards slides online</title>
    <published>2003-08-08T07:02:47+00:00</published>
    <updated>2003-08-08T07:02:47+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/08/08/designing-with-web-standards-slides-online/"/>
    <id>https://chuyeow.wtf/2003/08/08/designing-with-web-standards-slides-online/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/08/08/designing-with-web-standards-slides-online/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;zeldman.com&#x2F;&quot;&gt;Jeffrey Zeldman&lt;&#x2F;a&gt; has put up the &lt;a href=&quot;http:&#x2F;&#x2F;www.happycog.com&#x2F;lectures&#x2F;dwws&#x2F;&quot;&gt;slides for the Web Design World keynote&lt;&#x2F;a&gt;. For those of you still unfamiliar with &lt;a href=&quot;http:&#x2F;&#x2F;webstandards.org&#x2F;&quot;&gt;Web Standards&lt;&#x2F;a&gt;, the slides (in HTML) would be a pretty good run through of what web standards can do for you and your website. CSS layouts are used by commercial websites like &lt;a href=&quot;http:&#x2F;&#x2F;www.happycog.com&#x2F;lectures&#x2F;dwws&#x2F;25.html&quot;&gt;EPSN&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.happycog.com&#x2F;lectures&#x2F;dwws&#x2F;26.html&quot;&gt;Wired.com&lt;&#x2F;a&gt; to good effect. Some that don&#x27;t &lt;a href=&quot;http:&#x2F;&#x2F;www.happycog.com&#x2F;lectures&#x2F;dwws&#x2F;2.html&quot;&gt;break&lt;&#x2F;a&gt; or ask you to download X browser (with MS IE being the most common - check out &lt;a href=&quot;http:&#x2F;&#x2F;zone.msn.com&#x2F;blog.asp&quot;&gt;MSN Gaming Zone&lt;&#x2F;a&gt; in Firebird).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>&amp;reg_id is not ®_id</title>
    <published>2003-07-27T12:37:39+00:00</published>
    <updated>2003-07-27T12:37:39+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/07/27/reg_id-is-not-_id/"/>
    <id>https://chuyeow.wtf/2003/07/27/reg_id-is-not-_id/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/07/27/reg_id-is-not-_id/">&lt;p&gt;Another reason to hope Microsoft gets it right in IE 7, seeing as they are reluctant to fix IE 6: I was making changes to a website for a client and mostly tested the site in Mozilla Firebird 0.6 - I forgot to test the site in IE, but that was a fault on my part on thinking it would be alright. It wasn&#x27;t. The JS popup loads an invalid page because of the query string, which had become file.php?event_id=3&amp;reg;_id=12345.&lt;&#x2F;p&gt;
&lt;p&gt;Apparently, IE was being _too_ smart in converting the &amp;reg into &amp;reg; even though the ending semi-colon &#x27;;&#x27; was missing. Changing to &amp;amp;amp;reg_id didn&#x27;t help either. It is a subtle bug though, since it only happens when loading via &lt;tt&gt;window.open(this.href)&lt;&#x2F;tt&gt;. I had to fix it by making reg_id the first query string parameter.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>MovableType for your site (not blog)</title>
    <published>2003-07-20T13:51:46+00:00</published>
    <updated>2003-07-20T13:51:46+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/07/20/movabletype-for-your-site-not-blog/"/>
    <id>https://chuyeow.wtf/2003/07/20/movabletype-for-your-site-not-blog/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/07/20/movabletype-for-your-site-not-blog/">&lt;p&gt;&lt;a title=&quot;A Whole Lotta Features&quot; href=&quot;http:&#x2F;&#x2F;a.wholelottanothing.org&#x2F;features.blah&#x2F;entry&#x2F;007162&quot;&gt;Beyond the Blog&lt;&#x2F;a&gt; walks through the modification of &lt;a href=&quot;http:&#x2F;&#x2F;movabletype.org&quot;&gt;MovableType&lt;&#x2F;a&gt; for use in managing entire sites. &lt;a href=&quot;http:&#x2F;&#x2F;boxesandarrows.com&#x2F;&quot;&gt;Boxes and Arrows&lt;&#x2F;a&gt; is a prime example of an entire website powered by MT.&lt;&#x2F;p&gt;
&lt;p&gt;This is very interesting to me, because I&#x27;ve been searching high and low for a free, lightweight, usable Content Management System (CMS) for CodeFront.net but all my experimentation and evaluation has turned up naught. Perhaps it would be good for me to do a little under-the-hood tweaking of MT myself.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Bookmarklets for the web designer</title>
    <published>2003-07-16T17:17:28+00:00</published>
    <updated>2003-07-16T17:17:28+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/07/16/bookmarklets-for-the-web-designer/"/>
    <id>https://chuyeow.wtf/2003/07/16/bookmarklets-for-the-web-designer/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/07/16/bookmarklets-for-the-web-designer/">&lt;p&gt;I&#x27;ve made &lt;a href=&quot;http:&#x2F;&#x2F;simon.incutio.com&#x2F;&quot;&gt;Simon Willison&#x27;s blog&lt;&#x2F;a&gt; one of my daily reads, and was reading some of the archives in the CSS category when I chanced upon a &lt;a href=&quot;http:&#x2F;&#x2F;simon.incutio.com&#x2F;archive&#x2F;2003&#x2F;06&#x2F;03&#x2F;bookmarkletsAndCSS&quot;&gt;1-month old entry&lt;&#x2F;a&gt; that was an absolute gem.&lt;&#x2F;p&gt;
&lt;p&gt;To be honest, I didn&#x27;t previously bother with bookmarklets because I thought they were cool, but lacking in practicality. Until I saw this...&lt;&#x2F;p&gt;
&lt;div class=&quot;pullquote&quot;&gt;
With this, you can experiment with the CSS styles of your website(s) for those &#x27;what if?&#x27; moments...
&lt;&#x2F;div&gt;
&lt;p&gt;I&#x27;ve replicated the &#x27;edit styles&#x27; bookmarklet here. Just click on it, or drag it to your bookmark toolbar if you think it&#x27;s useful (don&#x27;t think too much - it IS).&lt;br &#x2F;&gt;
 &amp;raquo; &lt;a href=&quot;javascript:(function(){function init(){var newline=unescape(&amp;quot;%&amp;quot;+&amp;quot;0A&amp;quot;),importCount=0,L=[];dead=false;oldCSS=null;x=opener;ta=document.f.ta;ta.select();if(x.editStyles){ta.value=x.editStyles.innerHTML;update();return;}ta.value=&amp;quot;&#x2F;* Type CSS rules here and they will be applied&amp;quot;+newline+&amp;quot;to pages from &#x27;&amp;quot;+location.host+&amp;quot;&#x27;&amp;quot;+newline+&amp;quot;immediately as long as you keep this window open. *&#x2F;&amp;quot;+newline+newline;function add(s){if(!s.disabled){var y={sheet:s,readable:true,label:&amp;quot;Imported&amp;quot;,inline:false,shorturl:&amp;quot;&amp;quot;,fulltext:&amp;quot;&amp;quot;};try{for(var k=0,m;m=s.cssRules[k];++k)if(m.type==3)add(m.styleSheet);}catch(er){y.readable=false;}L.push(y);if(s.ownerNode){y.label=s.ownerNode.tagName.toUpperCase()+&amp;quot;-tag&amp;quot;;if(!s.ownerNode.getAttribute(&amp;quot;src&amp;quot;)&amp;&amp;!s.ownerNode.href)y.inline=true;}if(y.inline){y.label=&amp;quot;Inline &amp;quot;+y.label;y.fulltext=fix(s.ownerNode.innerHTML);}else if(s.href.substr(0,13)==&amp;quot;data:text&#x2F;css&amp;quot;){y.shorturl=&amp;quot; contained in a data: URL&amp;quot;;y.fulltext=fix(unescape(s.href.slice(14)));}else{++importCount;y.importtext=&amp;quot;@import \&amp;quot;&amp;quot;+s.href+&amp;quot;\&amp;quot;;&amp;quot;;y.shorturl=&amp;quot; &amp;quot;+s.href.split(&#x27;&#x2F;&#x27;).reverse()[0];if(!y.readable){y.fulltext=&amp;quot;&#x2F;* Out-of-domain; imported above. *&#x2F;&amp;quot;;}else if(s.href.substr(0,5)!=&amp;quot;http:&amp;quot;){y.fulltext=&amp;quot;&#x2F;* Non-http; imported above. *&#x2F;&amp;quot;;}else{var loadingText=&amp;quot;&#x2F;* Loading (&amp;quot;+(L.length-1)+&amp;quot;) *&#x2F;&amp;quot;;y.fulltext=loadingText;var p=new XMLHttpRequest();p.onload=function(e){ta.value=ta.value.replace(y.importtext+newline,&amp;quot;&amp;quot;);y.fulltext=p.responseText;ta.value=ta.value.replace(loadingText,fix(y.fulltext));ta.value=ta.value.replace(firstNote+newline,&amp;quot;&amp;quot;);};p.open(&amp;quot;GET&amp;quot;,s.href);p.send(null);}}}}function fix(s){while((s[0]==newline)&amp;&amp;s.length&gt;1)s=s.slice(1);while((s[s.length-1]==newline)&amp;&amp;s.length&gt;1)s=s.substr(0,s.length-1);s=s.replace(&#x2F;@import.*;&#x2F;ig,function(){return &amp;quot;&#x2F;* &amp;quot;+RegExp.lastMatch+&amp;quot; *&#x2F;&amp;quot;;});return s;}for(var i=0,ss;ss=x.document.styleSheets[i];++i)add(ss);var imports=&amp;quot;&amp;quot;,main=&amp;quot;&amp;quot;;var firstNote=&amp;quot;&#x2F;**** Style sheets whose contents could be loaded were ****&#x2F;&amp;quot;+newline+&amp;quot;&#x2F;**** imported instead.  Rule order may be incorrect   ****&#x2F;&amp;quot;+newline+&amp;quot;&#x2F;**** as a result. ****&#x2F;&amp;quot;+newline;if(importCount){ta.value+=firstNote;}for(var i=0;ss=L[i];++i){if(ss.importtext){imports+=ss.importtext+newline;}main+=&amp;quot;&#x2F;**** &amp;quot;+ss.label+&amp;quot; style sheet&amp;quot;+ss.shorturl+&amp;quot; ****&#x2F;&amp;quot;+newline;main+=newline;main+=ss.fulltext;main+=newline;main+=newline;main+=newline;}ta.value+=imports+newline+main;update();}function update(){try{if(!x||x.closed){ta.style.backgroundColor=&amp;quot;#ddd&amp;quot;;return;}x.editStyles;}catch(er){ta.style.backgroundColor=&amp;quot;#fdc&amp;quot;;setTimeout(update,150);dead=true;return;}if(dead){dead=false;ta.style.backgroundColor=&amp;quot;&amp;quot;;oldCSS=null;}if(!x.editStyles){var newSS;newSS=x.document.createElement(&amp;quot;style&amp;quot;);newSS.type=&amp;quot;text&#x2F;css&amp;quot;;x.document.getElementsByTagName(&amp;quot;head&amp;quot;)[0].appendChild(newSS);x.editStyles=newSS;oldCSS=null;for(var i=0,ss;ss=x.document.styleSheets[i];++i)ss.disabled=true;}if(oldCSS!=ta.value){oldCSS=ta.value;x.editStyles.innerHTML=ta.value;}setTimeout(update,150);}y=open(&#x27;&#x27;,&#x27;&#x27;,&#x27;resizable,scrollbars=yes,width=550,height=520&#x27;);y.document.write(&#x27;&lt;title&gt;Edit Styles&lt;&#x2F;title&gt;&lt;br &#x2F;&gt;
&lt;style&gt;.ec { width: 100%; height: 100%; border: none; margin: 0px; padding: 0px; }&lt;&#x2F;style&gt;
&lt;p&gt;&lt;body class=&amp;quot;ec&amp;quot;&gt;&lt;br &#x2F;&gt;
&lt;form name=&amp;quot;f&amp;quot; style=&amp;quot;margin: 0px;&amp;quot; class=&amp;quot;ec&amp;quot;&gt;&lt;textarea name=&amp;quot;ta&amp;quot; wrap=&amp;quot;soft&amp;quot; style=&amp;quot;margin: 0px; border: 0px; width:100%; height:100%;&amp;quot; class=&amp;quot;ec&amp;quot;&gt;&lt;&#x2F;textarea&gt;&lt;script&gt;&#x27;+update+init+&#x27;init();&lt;&#x27;+&#x27;&#x2F;script&gt;&#x27;);y.document.close();})()&quot;&gt;edit styles bookmarklet&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With this, you can experiment with the CSS styles of your website(s) for those &#x27;what if?&#x27; moments. You can also change how a site looks to your liking (too small font sizes, glaring background colors) at the click of a bookmarklet and some CSS editing.&lt;&#x2F;p&gt;
&lt;p&gt;For more useful bookmarklets, visit &lt;a href=&quot;http:&#x2F;&#x2F;www.squarefree.com&#x2F;bookmarklets&#x2F;&quot;&gt;Jesse&#x27;s Bookmarklets site&lt;&#x2F;a&gt;, in particular the &lt;a href=&quot;http:&#x2F;&#x2F;www.squarefree.com&#x2F;bookmarklets&#x2F;webdevel.html&quot;&gt;Web Development Bookmarklets section&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Pull quotes for your blog</title>
    <published>2003-07-16T16:26:19+00:00</published>
    <updated>2003-07-16T16:26:19+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/07/16/pull-quotes-for-your-blog/"/>
    <id>https://chuyeow.wtf/2003/07/16/pull-quotes-for-your-blog/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/07/16/pull-quotes-for-your-blog/">&lt;div class=&quot;pullquote&quot;&gt;
... I decided to steal the idea and implementation for my blog.
&lt;&#x2F;div&gt;
&lt;p&gt;After reading an &lt;a href=&quot;http:&#x2F;&#x2F;www.adampolselli.com&#x2F;archives&#x2F;000034.php&quot;&gt;entry on pull quotes&lt;&#x2F;a&gt; in &lt;a href=&quot;http:&#x2F;&#x2F;www.adampolselli.com&#x2F;&quot;&gt;Adam Polselli&#x27;s blog&lt;&#x2F;a&gt;, I decided to steal the idea and implementation for my blog.&lt;&#x2F;p&gt;
&lt;p&gt;All you got to do is define a CSS class and apply it to the &amp;lt;div&amp;gt; that will contain your pull quote, like so (copied directly from &lt;a href=&quot;http:&#x2F;&#x2F;www.adampolselli.com&#x2F;archives&#x2F;000034.php&quot;&gt;Adam&#x27;s blog entry&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre&gt;div.pullquote {
float: right;
width: 150px;
margin: 10px;
margin-left: 15px;
margin-right: 0;
padding: 0;
color: #333;
font-family: georgia, palatino, serif;
font-size: 20px;
text-align: center;
line-height: 24px;
}
&lt;&#x2F;pre&gt;
&lt;p&gt;All credit goes to Adam for that bit of CSS.&lt;br &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>A handy color picker</title>
    <published>2003-07-15T14:33:35+00:00</published>
    <updated>2003-07-15T14:33:35+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/07/15/a-handy-color-picker/"/>
    <id>https://chuyeow.wtf/2003/07/15/a-handy-color-picker/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/07/15/a-handy-color-picker/">&lt;p&gt;I found this very handy color picker imaginatively named &lt;a title=&quot;Iconico - Color Picker&quot; href=&quot;http:&#x2F;&#x2F;www.iconico.com&#x2F;colorpic&#x2F;&quot;&gt;Color Picker&lt;&#x2F;a&gt; from &lt;a href=&quot;http:&#x2F;&#x2F;www.iconico.com&quot;&gt;Iconico&lt;&#x2F;a&gt;. The good thing about it is that it comes as a ready to run single-file executable (Windows only though). It is also freeware.&lt;&#x2F;p&gt;
&lt;p&gt;Only thing I find lacking is the absence of a palette-saving feature.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rounded tables with CSS</title>
    <published>2003-07-14T14:02:22+00:00</published>
    <updated>2003-07-14T14:02:22+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/07/14/rounded-tables-with-css/"/>
    <id>https://chuyeow.wtf/2003/07/14/rounded-tables-with-css/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/07/14/rounded-tables-with-css/">&lt;p&gt;I had cause to create rounded tables in my recent freelance work and rather than use the &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepoint.com&#x2F;article&#x2F;392&quot;&gt;&quot;old&quot; way&lt;&#x2F;a&gt; of doing it, I decided to set out to see if this can be more easily achived with &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;&#x2F;acronym&gt;.&lt;br &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;pullquote&quot;&gt;
And no it isn&#x27;t possible to do so until CSS3 &lt;a href=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;css3-box&#x2F;#name-11&quot;&gt;border-radius&lt;&#x2F;a&gt; is supported in browsers.
&lt;&#x2F;div&gt;
&lt;p&gt;
And no it isn&#x27;t possible to do so until CSS3 &lt;a href=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;css3-box&#x2F;#name-11&quot;&gt;border-radius&lt;&#x2F;a&gt; is supported in browsers. It is, however, possible to do so using Mozilla&#x27;s &lt;tt&gt;-moz-border-radius&lt;&#x2F;tt&gt;, which works in Gecko browsers like Mozilla, Firebird and Netscape 6. It is proprietary though so it won&#x27;t work anywhere else.&lt;&#x2F;p&gt;
&lt;pre&gt;
.roundedCorners {
  -moz-border-radius: 20px;
}
&lt;&#x2F;pre&gt;
&lt;p&gt;Still, it wasn&#x27;t a fruitless search as it turned out easier, erm, hacks to achieve rounded goodness, as demonstrated &lt;a href=&quot;http:&#x2F;&#x2F;www.webweaver.org&#x2F;dan&#x2F;css&#x2F;corners&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;br &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>CMS - Mambo Open Source 4.5</title>
    <published>2003-06-20T12:58:17+00:00</published>
    <updated>2003-06-20T12:58:17+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/06/20/cms-mambo-open-source-45/"/>
    <id>https://chuyeow.wtf/2003/06/20/cms-mambo-open-source-45/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/06/20/cms-mambo-open-source-45/">&lt;p&gt;Looking forward to the release of &lt;a href=&quot;http:&#x2F;&#x2F;mamboserver.com&#x2F;&quot;&gt;Mambo Open Source 4.5&lt;&#x2F;a&gt;. From the screenshots &lt;a href=&quot;http:&#x2F;&#x2F;www.mamboserver.com&#x2F;images&#x2F;config.png&quot;&gt;here&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.mamboserver.com&#x2F;images&#x2F;content.png&quot;&gt;here&lt;&#x2F;a&gt;, it looks very promising, and most important of all, easy to configure, administer and use without requiring a messy or non-intuitive process.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Young (and talented) web developers, designers</title>
    <published>2003-06-10T15:06:44+00:00</published>
    <updated>2003-06-10T15:06:44+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2003/06/10/young-and-talented-web-developers-designers/"/>
    <id>https://chuyeow.wtf/2003/06/10/young-and-talented-web-developers-designers/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2003/06/10/young-and-talented-web-developers-designers/">&lt;p&gt;Judging from this thread titled &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;showthread.php?threadid=94721&quot;&gt;Your Age&lt;&#x2F;a&gt; at &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;&quot;&gt;SitePoint Forums&lt;&#x2F;a&gt;, the web development and web design world is full of young talent. Patrick O&#x27;Keefe (&lt;a href=&quot;http:&#x2F;&#x2F;www.sitepointforums.com&#x2F;member.php?userid=7985&quot;&gt;iFroggy&lt;&#x2F;a&gt;) is only 18 but runs a webhosting business, a webdesign business, and is webmaster of many popular communities. Marc James (mjames) is 17 and runs a successful sports-related site at &lt;a href=&quot;http:&#x2F;&#x2F;www.sports-central.org&#x2F;&quot;&gt;Sports Central&lt;&#x2F;a&gt;, among other achievements. Those are just 2 exemplary individuals who are young and are making successful web-related careers.&lt;&#x2F;p&gt;
&lt;p&gt;I wonder - are there and prodigies that are committers or project leads of Open Source projects like those under the Jakarta project umbrella?&lt;&#x2F;p&gt;
</content>
  </entry>
</feed>
