<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Henrik Sjökvist</title>
    <link>http://henriksjokvist.net/</link>
    <atom:link href="http://henriksjokvist.net/rss.xml" rel="self" type="application/rss+xml" />
    <description></description>
    <language>en-us</language>
    <pubDate>Mon, 07 Jan 2013 07:37:19 -0800</pubDate>
    <lastBuildDate>Mon, 07 Jan 2013 07:37:19 -0800</lastBuildDate>

    
    <item>
      <title>Asset pipeline woes on Heroku</title>
      <link>http://henriksjokvist.net/archive/2012/3/asset-pipeline-woes-on-heroku/</link>
      <pubDate>Thu, 22 Mar 2012 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2012/3/asset-pipeline-woes-on-heroku</guid>
      <description>&lt;p&gt;I ran into a confusing issue on Heroku where Devise/ActiveAdmin makes a
DB call during the precompile process. On Heroku the DB isn't available
at that point, causing the precompilation to fail.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;-----&amp;gt; Preparing app for Rails asset pipeline&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       Running: rake assets:precompile&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       rake aborted!&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       could not connect to server: Connection refused&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       Is the server running on host &amp;quot;127.0.0.1&amp;quot; and accepting&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       TCP/IP connections on port 5432?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can work around this in two ways. Either precompile locally and
deploy the precompiled assets, or turn on the labs feature in Heroku.
This makes the DB available during the precompilation, and also let's
you use a more recent ruby. 1.9.3-p125 was the latest one available as
I'm writing this.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; heroku plugins:install https://github.com/heroku/heroku-labs.git
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; heroku labs:enable user_env_compile -a myapp
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; heroku config:add &lt;span class=&quot;nv&quot;&gt;RUBY_VERSION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ruby-1.9.3-p125
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
    </item>
    
    <item>
      <title>Deploying with rbenv and Capistrano</title>
      <link>http://henriksjokvist.net/archive/2012/2/deploying-with-rbenv-and-capistrano/</link>
      <pubDate>Mon, 20 Feb 2012 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2012/2/deploying-with-rbenv-and-capistrano</guid>
      <description>&lt;p&gt;&lt;em&gt;UPDATE:&lt;/em&gt; I've updated the post to reflect changes in rbenv 0.4.0.&lt;/p&gt;

&lt;p&gt;I've recently decided to move away from &lt;a href=&quot;https://rvm.beginrescueend.com/&quot;&gt;RVM&lt;/a&gt; in favor of &lt;a href=&quot;https://github.com/sstephenson/rbenv&quot;&gt;rbenv&lt;/a&gt;. I thought RVM was a bit too finicky to use in production and I wanted something simpler that I could wrap my head around.&lt;/p&gt;

&lt;p&gt;This post is more or less an attempt to collect what I figured out from reading &lt;a href=&quot;https://github.com/sstephenson/rbenv/issues/101&quot;&gt;an issue thread on GitHub&lt;/a&gt;, George Ornbo's &lt;a href=&quot;http://shapeshed.com/using-rbenv-to-manage-rubies/&quot;&gt;great post about rbenv&lt;/a&gt; and the &lt;a href=&quot;https://github.com/sstephenson/rbenv/wiki/Deploying-with-rbenv&quot;&gt;rbenv wiki page on deployment&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;On the server&lt;/h2&gt;

&lt;p&gt;As the deployment user (in my case &lt;code&gt;deploy&lt;/code&gt;), run the &lt;code&gt;rbenv-installer&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl -L https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add rbenv to your PATH. The second command adds shims and autocompletion:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo 'export PATH=&quot;$HOME/.rbenv/bin:$PATH&quot;' &amp;gt;&amp;gt; ~/.profile
$ echo 'eval &quot;$(rbenv init -)&quot;' &amp;gt;&amp;gt; ~/.profile
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Reload the profile, install one or more rubies and then rehash to refresh
the shims:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ source ~/.profile
$ rbenv install 1.9.3-p327
$ rbenv rehash
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Set your new rbenv ruby as the new system-wide default ruby for this user:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rbenv global 1.9.3-p327
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it's time to go ahead and install your Passenger, Unicorn, or what have you.&lt;/p&gt;

&lt;h2&gt;Capistrano&lt;/h2&gt;

&lt;p&gt;Now, let's turn our attention to Capistrano and our &lt;code&gt;deploy.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We want Bundler to handle our gems and we want it to package everything
locally with the app. The &lt;code&gt;--binstubs&lt;/code&gt; flag means any gem executables will be added
to &lt;code&gt;&amp;lt;app&amp;gt;/bin&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;bundler/capistrano&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:bundle_flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--deployment --quiet --binstubs&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you don't want to use a globally installed Bundler, you need to add a
binstub for it manually and tell Capistrano to use that:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:bundle_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;release_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/bin/bundle&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The binstub itself (&lt;code&gt;&amp;lt;app&amp;gt;/bin/bundle&lt;/code&gt;) should look like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;gt;= 0&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^_(.*)_$/&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Gem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correct?&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$1&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bundler&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Gem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bin_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bundler&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bundle&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Since the &lt;code&gt;.profile&lt;/code&gt; &lt;code&gt;PATH&lt;/code&gt; settings we added earlier won't get run by Capistrano we need to add the rbenv paths to our &lt;code&gt;deploy.rb&lt;/code&gt;.
Note that we add the &lt;code&gt;shims&lt;/code&gt; folder directly here instead of running &lt;code&gt;rbenv init -&lt;/code&gt;. It's easier and autocomplete is wasted on Capistrano.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:default_environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;&amp;#39;PATH&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That's pretty much it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Module Puppy - Giving Hubot a drop of Drupal knowledge</title>
      <link>http://henriksjokvist.net/archive/2012/1/module-puppy---giving-hubot-a-drop-of-drupal-knowledge/</link>
      <pubDate>Tue, 31 Jan 2012 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2012/1/module-puppy---giving-hubot-a-drop-of-drupal-knowledge</guid>
      <description>&lt;p&gt;We've been using the delightful &lt;a href=&quot;http://hubot.github.com&quot;&gt;Hubot&lt;/a&gt; chat bot with Campfire for a while now and I've been looking to ways to add Drupal-related features to it.&lt;/p&gt;

&lt;p&gt;One idea was to add a &lt;code&gt;module me &amp;lt;query&amp;gt;&lt;/code&gt; command that searches for modules. Unfortunately drupal.org doesn't offer an API, but the update module uses a &lt;a href=&quot;http://updates.drupal.org/release-history/project-list/all&quot;&gt;humongous XML file&lt;/a&gt; that contains some useful information like name, short name, creator and url for all projects hosted on drupal.org.&lt;/p&gt;

&lt;p&gt;I wrote a little &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;Sinatra&lt;/a&gt; app called &lt;a href=&quot;http://modulepuppy.heroku.com&quot;&gt;Module Puppy&lt;/a&gt; that pulls down and parses relevant data from this XML file and makes it available via a simple JSON API. The app is hosted on &lt;a href=&quot;http://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt; which uses PostgreSQL as the default database. This meant that I could use the very nice multi-column search feature in PostgreSQL (easy with the &lt;a href=&quot;https://github.com/tenderlove/texticle&quot;&gt;texticle&lt;/a&gt; gem).&lt;/p&gt;

&lt;p&gt;Hubot talks to the Sinatra app using &lt;a href=&quot;https://github.com/github/hubot-scripts/blob/master/src/scripts/modulepuppy.coffee&quot;&gt;a small CoffeeScript plugin&lt;/a&gt;,
part of the &lt;a href=&quot;https://github.com/github/hubot-scripts&quot;&gt;hubot-scripts&lt;/a&gt; community scripts collection.&lt;/p&gt;

&lt;p&gt;This makes Hubot listen for the phrase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;there's a module for &amp;lt;something&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and also, the more direct command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;bot name&amp;gt; module me &amp;lt;something&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In practice, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/hubot-modulepuppy.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Powered by Jekyll</title>
      <link>http://henriksjokvist.net/archive/2012/1/powered-by-jekyll/</link>
      <pubDate>Tue, 17 Jan 2012 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2012/1/powered-by-jekyll</guid>
      <description>&lt;p&gt;In line with my recent infatuation with all things Ruby, I went ahead
and migrated my old Drupal blog to &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;.
Hopefully having a more lightweight blogging solution will compel me to
actually finish and post some more stuff here. Time will tell...&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Safari960 - A 960.gs grid overlay extension for Safari</title>
      <link>http://henriksjokvist.net/archive/2010/7/safari960-a-960-gs-grid-overlay-extension-for-safari/</link>
      <pubDate>Tue, 06 Jul 2010 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2010/7/safari960-a-960-gs-grid-overlay-extension-for-safari</guid>
      <description>&lt;p&gt;I've used various grid bookmarklets in the past, but they always do a lot more than I need and I never like the defaults. Yesterday I finally decided to roll up my sleeves and scratch my itch by making a very simple &lt;a href=&quot;http://960.gs&quot;&gt;960.gs&lt;/a&gt; grid overlay extension for Safari.&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;It's available for download &lt;a href=&quot;/safari960&quot;&gt;here&lt;/a&gt; and the code is on &lt;a href=&quot;http://github.com/henrrrik/Safari960&quot;&gt;GitHub&lt;/a&gt;. If you like it, help me improve it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Changed the download link to point to the &lt;a href=&quot;/safari960&quot;&gt;project page&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>IE testing in your local dev environment using VirtualBox </title>
      <link>http://henriksjokvist.net/archive/2010/7/ie-testing-in-your-local-dev-environment-using-virtualbox/</link>
      <pubDate>Thu, 01 Jul 2010 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2010/7/ie-testing-in-your-local-dev-environment-using-virtualbox</guid>
      <description>&lt;p&gt;I do my web development on my laptop and set up each site as a virtual hosts (e.g. &lt;em&gt;site1.localhost&lt;/em&gt;, &lt;em&gt;site2.localhost&lt;/em&gt;). In every project you eventually need to do the dreaded IE testing, but how do you access these sites from a virtualized Windows running in VirtualBox?&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;The (physical) &lt;em&gt;host&lt;/em&gt; (in VirtualBox terminology) machine can be accessed from (virtual) &lt;em&gt;guests&lt;/em&gt; using the IP 10.0.2.2. To access individual virtual hosts on the host machine you need to use the same host name on the Windows box.&lt;/p&gt;

&lt;p&gt;In Windows, fire up Notepad as Administrator and edit the hosts file located at: &lt;code&gt;%windir%\system32\drivers\etc\hosts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We add a line with our virtual hosts and save it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;10.0.2.2    site1.localhost site2.localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to access site1.localhost and site2.localhost from Windows.&lt;/p&gt;

&lt;p&gt;I've set up a convenient shortcut on the Windows desktop for editing the hosts file. Here's how you do it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a shortcut to Notepad on your desktop and change its name to &quot;hosts&quot;.&lt;/li&gt;
&lt;li&gt;Right-click it, select Properties.&lt;/li&gt;
&lt;li&gt;Go to the Shortcut tab and change the Target path to:
&lt;code&gt;%windir%\system32\notepad.exe %windir%\system32\drivers\etc\hosts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Click Advanced and check &quot;Run as Administrator&quot;. Click OK in both dialogs to save your settings.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Your hosts file is now just a double-click away.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Joomla has a security problem: The benefits of centralized contrib hosting</title>
      <link>http://henriksjokvist.net/archive/2010/6/joomla-has-a-security-problem-the-benefits-of-centralized-contrib-hosting/</link>
      <pubDate>Tue, 01 Jun 2010 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2010/6/joomla-has-a-security-problem-the-benefits-of-centralized-contrib-hosting</guid>
      <description>&lt;p&gt;I'm helping a client do a security audit of one of their servers. A couple of their sites are running Joomla, which I have very little experience with, so as part of this I set out to compile a list of available exploits to compare against their Joomla versions and installed components. What I discovered was frankly stunning.&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Platform&lt;/th&gt;&lt;th&gt;Number of exploits&lt;/th&gt; 
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Drupal&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;http://www.exploit-db.com/list.php?description=drupal&quot;&gt;9&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Typo3&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;http://www.exploit-db.com/list.php?description=typo3&quot;&gt;2&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Wordpress&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;http://www.exploit-db.com/list.php?description=wordpress&quot;&gt;70&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Joomla&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;http://www.exploit-db.com/list.php?description=joomla&quot;&gt;637&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Source: &lt;a href=&quot;http://www.exploit-db.com/&quot;&gt;The Exploit Database&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's important to emphasize that just one critical hole in your site is enough, so running Drupal or Typo3 might still get you hacked. However, it's clear that the Joomla community has a very serious security problem. Judging from the number of SQL injection exploits on the list it seems like it might be a question of educating contributors.&lt;/p&gt;

&lt;p&gt;I believe that Drupal's low number is a strong testament to the benefits of hosting contributed code on drupal.org. This approach means that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to apply for a CVS account and as part of that your first contributed code &lt;a href=&quot;http://drupal.org/node/539608&quot;&gt;will get vetted&lt;/a&gt; by someone experienced.&lt;/li&gt;
&lt;li&gt;Hosted code is audited by the &lt;a href=&quot;http://drupal.org/node/32750&quot;&gt;drupal.org Security Team&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;A low bar of entry for new contributors is great, but can be dangerous without a strong security support structure.&lt;/p&gt;

&lt;p&gt;Note: A &lt;a href=&quot;http://www.searchfactory.se/blogg/2010/6/sakerhetsfordelarna-med-centraliserad-kod&quot;&gt;Swedish version&lt;/a&gt; of this entry is available over at the &lt;a href=&quot;http://www.searchfactory.se&quot;&gt;Searchfactory&lt;/a&gt; blog.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Serving the same H.264 video file to everyone, from Internet Explorer to iPhone</title>
      <link>http://henriksjokvist.net/archive/2009/10/serving-the-same-h-264-video-file-to-everyone-from-internet-explorer-to-iphone/</link>
      <pubDate>Thu, 15 Oct 2009 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2009/10/serving-the-same-h-264-video-file-to-everyone-from-internet-explorer-to-iphone</guid>
      <description>&lt;p&gt;In a comment on my previous post &lt;a href=&quot;http://henriksjokvist.net/archive/2009/2/using-the-html5-video-tag-with-a-flash-fallback&quot;&gt;Using the HTML5 &amp;lt;video&amp;gt; tag with a Flash fallback&lt;/a&gt;, Rob Colburn suggested serving everyone the same H.264 video file.&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;The big upside is that we only need to convert the video into one format. The downside is that we lose legacy Flash compatibility and Firefox 3.5+ and Opera 10+ users get Flash instead of HTML5 video.&lt;/p&gt;

&lt;p&gt;This can be accomplished the following JavaScript code. Note that also I've replaced JWPlayer with &lt;a href=&quot;http://code.google.com/p/flashy/&quot;&gt;Flashy&lt;/a&gt;, a GPL-licensed alternative.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;video&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Are we dealing with a browser that supports &amp;lt;video&amp;gt;? &lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;browser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mozilla&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;browser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;opera&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// If no, or Firefox or Opera, use Flash.&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;allowFullScreen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;flashvars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;video&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;video.m4v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;poster&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;snapshot.jpg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;maintainAspectRatio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;false&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;swfobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;embedSWF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;videoPlayer.swf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;demo-video-flash&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;480&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;272&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;9.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;expressInstall.swf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;flashvars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here's the &lt;a href=&quot;http://henriksjokvist.net/examples/html5-video-v2/&quot;&gt;example in action&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Getting a Huawei E220 3G modem to work under Snow Leopard</title>
      <link>http://henriksjokvist.net/archive/2009/9/getting-a-huawei-e220-3g-modem-to-work-under-snow-leopard/</link>
      <pubDate>Fri, 25 Sep 2009 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2009/9/getting-a-huawei-e220-3g-modem-to-work-under-snow-leopard</guid>
      <description>&lt;p&gt;I had some problems getting my Huawei E220 3G USB modem running under Snow Leopard. The drivers from Telia and huawei.com didn't work. Turns out Huawei has another site over at huaweidevice.com with updated drivers.&lt;/p&gt;

&lt;p&gt;Here are the steps I took.&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;Note that I don't use the Mobile Connect application. I stuck my SIM card in a mobile phone and disabled the PIN. That way I don't need Mobile Connect to enter it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the &lt;a href=&quot;http://www.huaweidevice.com/resource/mini/200910149695/testmobile1014/index.html&quot;&gt;latest MobileConnectDriver Mac package from Huawei&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Install it and reboot.&lt;/li&gt;
&lt;li&gt;Plug in the modem and wait for the light to go blue. It should be automatically detected as a new network interface by Mac OS X.&lt;/li&gt;
&lt;li&gt;Open System preferences and the Network pane. Select the &lt;strong&gt;HUAWEI Mobile&lt;/strong&gt; interface in the list and enter &lt;em&gt;*99#&lt;/em&gt; as the telephone number. Then click &lt;strong&gt;Advanced&lt;/strong&gt;. Set &lt;strong&gt;Model&lt;/strong&gt; to &lt;strong&gt;GRPS GSM/3G&lt;/strong&gt;, set the &lt;strong&gt;APN&lt;/strong&gt; to whatever your provider uses (Telia uses &lt;em&gt;online.telia.se&lt;/em&gt;) and hit &lt;strong&gt;Apply&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Voilà, you can now click the &lt;strong&gt;Connect&lt;/strong&gt; button to connect. I recommend enabling the &lt;strong&gt;Show modem status in menu bar&lt;/strong&gt; option for easy access.&lt;/p&gt;

&lt;p&gt;&lt;ins&gt;Updated the driver link.&lt;/ins&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A DiggBar Killer/Blocker for Drupal</title>
      <link>http://henriksjokvist.net/archive/2009/4/a-diggbar-killer-blocker-for-drupal/</link>
      <pubDate>Sun, 12 Apr 2009 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2009/4/a-diggbar-killer-blocker-for-drupal</guid>
      <description>&lt;p&gt;In the interest of web hygiene I've created a simple module based on  &lt;a href=&quot;http://farukat.es/journal/2009/04/225-javascript-diggbar-killer-not-blocker&quot;&gt;Faruk Ateş DiggBar remover script &lt;/a&gt; that removes the bar and optionally redirects the user to a specific page.&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href=&quot;http://drupal.org/project/diggbar_blocker/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Using the HTML5 &lt;video&gt; tag with a Flash fallback</title>
      <link>http://henriksjokvist.net/archive/2009/2/using-the-html5-video-tag-with-a-flash-fallback/</link>
      <pubDate>Fri, 27 Feb 2009 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2009/2/using-the-html5-video-tag-with-a-flash-fallback</guid>
      <description>&lt;p&gt;The HTML5 &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag makes it possible to embed video clips in web pages much like how the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag works for images. The browser itself provides the playback functionality without any need for plugins like Quicktime or Flash.&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;&lt;ins&gt;Update: Firefox 3.5+ doesn't like the .ogm extension for the Ogg Theora video file, I've changed it to .ogg.&lt;/ins&gt;&lt;/p&gt;

&lt;p&gt;In it's simplest form, the tag can look like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;video&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;someclip.mp4&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;controls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Safari (version 3.1 onwards) and Firefox 3.1b2 support &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;. Opera has released &lt;a href=&quot;http://dev.opera.com/articles/view/a-call-for-video-on-the-web-opera-vid/&quot;&gt;experimental builds&lt;/a&gt; demonstrating preliminary support.&lt;/p&gt;

&lt;p&gt;Safari plays back MPEG4 (and at least on the Mac, anything that QuickTime can play). Firefox currently only supports Ogg Theora.&lt;/p&gt;

&lt;p&gt;This lack of (default) codec support overlap can be overcome by providing both formats in the same &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;video&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;controls&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video.m4v&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video/mp4&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- MPEG4 for Safari --&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video.ogg&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video/ogg&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Ogg Theora for Firefox 3.1b2 --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/video&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;For legacy browsers that don't support &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; we need to use an alternative. An easy solution is to degrade to Flash using &lt;a href=&quot;http://code.google.com/p/swfobject/&quot;&gt;SWFObject&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's the HTML:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;demo-video-flash&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;video&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;demo-video&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;poster=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;snapshot.jpg&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;controls&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video.m4v&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video/mp4&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- MPEG4 for Safari --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video.ogg&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;video/ogg&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Ogg Theora for Firefox 3.1b2 --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/video&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We place the &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag inside the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that we use to attach the SWFObject object.&lt;/p&gt;

&lt;p&gt;Now for some JavaScript:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ... a dash of jQuery.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;video&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Are we dealing with a browser that supports &amp;lt;video&amp;gt;?&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// If no, use Flash.&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;allowfullscreen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;allowscriptaccess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;always&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;flashvars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;video.f4v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;snapshot.jpg&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;swfobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;embedSWF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;player.swf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;demo-video-flash&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;480&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;272&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;9.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;expressInstall.swf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;flashvars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The browser support detection is done by creating a video element and attempting to play it. If this fails, the Flash player is inserted using SWFObject.&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href=&quot;/examples/html5-video/&quot;&gt;example in action&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A downside to this approach as opposed to using Flash or another plugin is obviously that we currently need to provide three versions of every clip we want to embed (MPEG4, Ogg and FLV).&lt;/p&gt;

&lt;p&gt;Hopefully the browser makers will have settled on a baseline codec by the time the final versions of Firefox 3.1 and Opera 10 (or whatever version finally brings the support) are released.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Markdown WYSIWYM solution for Drupal (or: Markdown for clients that don't sport neck beards)</title>
      <link>http://henriksjokvist.net/archive/2009/1/a-markdown-wysiwym-solution-for-drupal-or-markdown-for-clients-that-dont-sport-neck-beards/</link>
      <pubDate>Tue, 27 Jan 2009 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2009/1/a-markdown-wysiwym-solution-for-drupal-or-markdown-for-clients-that-dont-sport-neck-beards</guid>
      <description>&lt;p&gt;&lt;ins&gt;&lt;strong&gt;UPDATE: This project was removed from drupal.org because the security team had concerns about using a client-side markdown parser. I didn't share those concerns (nor, apparently, do GitHub and StackExchange who are both using Showdown.js), but whatever, &lt;a href=&quot;http://www.youtube.com/watch?v=K2PPgcNjols&quot;&gt;the Dude abides&lt;/a&gt;.&lt;/strong&gt;&lt;/ins&gt;&lt;/p&gt;

&lt;p&gt;WYSIWYG editors like FCKeditor and TinyMCE are popular, but in some ways they do more harm than good.&lt;/p&gt;

&lt;h2&gt;They generate lots of unnecessary HTML&lt;/h2&gt;

&lt;p&gt;You may think to yourself &lt;cite&gt;&quot;Sure, but I'll just filter that stuff out using an input filter&quot;&lt;/cite&gt;. While that will clean up your output somewhat, that unholy mess will still get saved in your database and can cause problems down the line if you want to repurpose your content. Also, if you display the content in teaser form somewhere on your site filtering is necessary since Drupal could potentially insert a teaser break before a closing &lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt; generated by the WYSIWYG causing your layout to fall apart.&lt;/p&gt;

&lt;h2&gt;Pasting from MS Word makes for awful results&lt;/h2&gt;

&lt;p&gt;Pasting content from Word often generates atrocious results even when using the &quot;Paste from Word&quot; functions. A good example is bullet lists which both FCKeditor and TinyMCE turn into a series of lines preceded by &lt;code&gt;&amp;amp;bull;&lt;/code&gt; entities instead of a proper HTML unordered list. This is obviously very unfortunate since it often looks identical to a properly formatted list in the browser. Many people like to do their writing in Word and it's hard to convince a client to paste the stuff into Windows Notepad as an extra step just to remove cruft that they can't even see, not to mention making your implementation seem very primitive.&lt;/p&gt;

&lt;h2&gt;An easier Markdown&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt; is a simple plain text formatting syntax. Markdown syntax can be translated into HTML in Drupal using an input filter with the &lt;a href=&quot;http://drupal.org/project/markdown&quot;&gt;Markdown filter&lt;/a&gt; module. This means less clutter in your database compared to pure HTML and an easier syntax to learn for end-users. It also means that the user is encouraged to focus on semantic rather than aesthetic qualities when formatting the text.&lt;/p&gt;

&lt;p&gt;While Markdown is simple compared to HTML, you still need to learn a the syntax which can make it a hard sell when building a site for a non-technical client.&lt;/p&gt;

&lt;p&gt;We can alleviate this using a combination of modules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/project/bueditor&quot;&gt;BUEditor&lt;/a&gt; is an plain text editor with a customizable toolbar. By default BUEditor provides shortcut buttons for HTML.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/project/markdowneditor&quot;&gt;Markdown Editor for BUEditor&lt;/a&gt; is an add-on for BUEditor that provides a set of Markdown buttons.&lt;/li&gt;
&lt;li&gt;That covers the WYM of our &lt;a href=&quot;http://en.wikipedia.org/wiki/WYSIWYM&quot;&gt;WYSIWYM&lt;/a&gt;. For the WYS part, &lt;a href=&quot;http://drupal.org/project/markdownpreview&quot;&gt;Markdown Preview&lt;/a&gt; (by yours truly) inserts a pane below the &lt;code&gt;textarea&lt;/code&gt; field that displays a live preview of the HTML output as you type. This is accomplished using the &lt;a href=&quot;http://attacklab.net/showdown/&quot;&gt;Showdown&lt;/a&gt; JavaScript Markdown implementation by John Fraser (the end result of this combination of modules is actually very similar to Fraser's (&lt;a href=&quot;http://blog.stackoverflow.com/2008/12/reverse-engineering-the-wmd-editor/&quot;&gt;possibly abandoned&lt;/a&gt;) &lt;a href=&quot;http://wmd-editor.com/&quot;&gt;WMD editor&lt;/a&gt;).
Note that while Markdown filter and Markdown Editor for BUEditor support &lt;a href=&quot;http://michelf.com/projects/php-markdown/extra/&quot;&gt;Markdown Extra&lt;/a&gt;, Showdown and Markdown Preview only support original Markdown.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Check out the &lt;a href=&quot;http://markdownpreview.sixshooter.se&quot;&gt;demo&lt;/a&gt; to see it in action.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Spruce up your Drupal search box for Safari users (Updated for Drupal 6)</title>
      <link>http://henriksjokvist.net/archive/2008/8/spruce-up-your-drupal-search-box-for-safari-users-updated-for-drupal-6/</link>
      <pubDate>Fri, 29 Aug 2008 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2008/8/spruce-up-your-drupal-search-box-for-safari-users-updated-for-drupal-6</guid>
      <description>&lt;p&gt;My favourite browser Safari has support for a snazzy custom input field type called &quot;search&quot;. This gives the field a rounded look and the ability to remember search history (amongst other things). The major drawback is of course that the HTML will no longer validate since this feature isn't part of the official spec.&lt;/p&gt;

&lt;p&gt;In order get around this problem I whipped up a jQuery snippet that dynamically changes the Drupal search input field to a Safari search field if the visitor uses Safari. You can see it in action in the right sidebar on this site.&lt;/p&gt;

&lt;p&gt;This goes into &lt;code&gt;template.php&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;drupal_add_js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path_to_theme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/fancysearch.js&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;theme&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This goes into &lt;code&gt;fancysearch.js&lt;/code&gt; in your theme folder:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;Drupal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;behaviors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fancySearch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;browser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;safari&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// jQuery 1.2.x doesn&amp;#39;t support type alteration.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;edit-search-block-form-1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;search&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#edit-search-block-form-1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; 
              &lt;span class=&quot;nx&quot;&gt;autosave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;net.henriksjokvist.search&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#block-search-0 :submit&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You will probably need to change the ids &lt;code&gt;#block-search-0&lt;/code&gt; (the form's containing &lt;code&gt;div&lt;/code&gt;) and &lt;code&gt;#edit-search-block-form-1&lt;/code&gt; (the id of the &lt;code&gt;input&lt;/code&gt; field) to whatever ids your theme uses.
&lt;code&gt;autosave&lt;/code&gt; is the name under which the search history is stored and should be unique for your site, &lt;code&gt;results&lt;/code&gt; is the number of past searches to remember and &lt;code&gt;placeholder&lt;/code&gt; is the placeholder text inside the field.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Duplicate id attributes for submit buttons in Drupal 5.x</title>
      <link>http://henriksjokvist.net/archive/2008/7/duplicate-id-attributes-for-submit-buttons-in-drupal-5-x/</link>
      <pubDate>Thu, 31 Jul 2008 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2008/7/duplicate-id-attributes-for-submit-buttons-in-drupal-5-x</guid>
      <description>&lt;p&gt;Drupal 5 doesn't generate unique id attributes for form submit buttons. This means that if there's both a login form and a search box on the same page they will both use the same &lt;code&gt;edit-submit&lt;/code&gt; id causing the page to fail validation.&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;This has been &lt;a href=&quot;http://drupal.org/node/111719&quot;&gt;fixed in Drupal 6&lt;/a&gt;. You can solve it in Drupal 5 by inserting the following into &lt;code&gt;template.php&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
* Quick fix for the validation error: 'ID &quot;edit-submit&quot; already defined' or edit-name
* There is a solution in d6 core: http://drupal.org/node/111719
*/
function phptemplate_submit($element) {
   static $count_double_id=0;

  $tmp = str_replace('edit-submit', 'edit-submit-'. $count_double_id++, theme('button', $element));
  return str_replace('edit-name', 'edit-name-'. $count_double_id++, $tmp);
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Snippet by &lt;a href=&quot;http://drupal.org/node/111719#comment-712049&quot;&gt;stevenQ&lt;/a&gt;)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>edit-On Pro WYSYWYG module for Drupal (Updated)</title>
      <link>http://henriksjokvist.net/archive/2008/6/edit-on-pro-wysywyg-module-for-drupal-updated/</link>
      <pubDate>Mon, 09 Jun 2008 00:00:00 -0700</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2008/6/edit-on-pro-wysywyg-module-for-drupal-updated</guid>
      <description>&lt;p&gt;I've put together &lt;a href=&quot;http://drupal.org/project/editonpro/&quot;&gt;a module&lt;/a&gt; that integrates the &lt;a href=&quot;http://www.realobjects.com/edit-on-Pro.435+M5d9bfab1bf7.0.html&quot;&gt;edit-on Pro WYSIWYG editor&lt;/a&gt; with Drupal. edit-on Pro is a full-featured cross-platform (Java) editor that outputs clean accessible XHTML. Unfortunately it isn't free/open source. &lt;a href=&quot;http://www.realobjects.com/Pricing.564+M5d9bfab1bf7.0.html&quot;&gt;Pricing&lt;/a&gt; starts at €249 for a 10 seat license.&lt;/p&gt;

&lt;p&gt;There is still a fair bit of work to do. For instance the module currently lacks support for image uploads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; A permissions typo locked out everyone but user 1. I've also put up a &lt;a href=&quot;http://editonpro.sixshooter.se&quot;&gt;demo site&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>XStandard demo site now runs Drupal 6.0</title>
      <link>http://henriksjokvist.net/archive/2008/2/xstandard-demo-site-now-runs-drupal-6-0/</link>
      <pubDate>Sun, 24 Feb 2008 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2008/2/xstandard-demo-site-now-runs-drupal-6-0</guid>
      <description>&lt;p&gt;I just finished updating the &lt;a href=&quot;http://xstandard.sixshooter.se&quot;&gt;XStandard demo site&lt;/a&gt; for Drupal to version 6, making it my first live Drupal 6 site. The only modules I use on it are &lt;a href=&quot;http://drupal.org/project/xstandard&quot;&gt;XStandard&lt;/a&gt; (obviously), &lt;a href=&quot;http://drupal.org/project/demo&quot;&gt;Demonstration site (Sandbox)&lt;/a&gt; and &lt;a href=&quot;http://drupal.org/project/google_analytics&quot;&gt;Google Analytics&lt;/a&gt;, so it was as straightforward as it gets.
It went pretty smoothly, despite my complete disregard for the upgrade instructions.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Drupal 6.0 is out!</title>
      <link>http://henriksjokvist.net/archive/2008/2/drupal-6-0-is-out/</link>
      <pubDate>Wed, 13 Feb 2008 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2008/2/drupal-6-0-is-out</guid>
      <description>&lt;p&gt;Drupal 6.0 &lt;a href=&quot;http://drupal.org/drupal-6.0&quot;&gt;has been released&lt;/a&gt;! No 6.x versions of &lt;a href=&quot;http://drupal.org/project/views&quot;&gt;Views&lt;/a&gt; or &lt;a href=&quot;http://drupal.org/project/cck&quot;&gt;CCK&lt;/a&gt; are out yet, so I'll have to hold off upgrading my sites a while longer.&lt;/p&gt;

&lt;p&gt;I'm very exited about the new built-in multilanguage support. The old i18n contrib module didn't always work right with other modules since many module authors didn't take it into account.&lt;/p&gt;

&lt;p&gt;I'm also looking forward to sinking my teeth into the improved theming system with the new &lt;a href=&quot;http://drupal.org/project/devel&quot;&gt;Theme Developer module&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>XStandard module version 1.0 released</title>
      <link>http://henriksjokvist.net/archive/2007/12/xstandard-module-version-1-0-released/</link>
      <pubDate>Wed, 26 Dec 2007 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2007/12/xstandard-module-version-1-0-released</guid>
      <description>&lt;p&gt;I've finally decided to roll out version 1.0 of my &lt;a href=&quot;http://drupal.org/project/xstandard&quot;&gt;XStandard module for Drupal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So why choose XStandard over FCKeditor or TinyMCE?  Simply put, it produces valid markup. The pro version can actually filter material pasted from Word into semantic XHTML while retaining structure.
Here's a full &lt;a href=&quot;http://xstandard.com/en/documentation/xstandard-dev-guide/features/&quot;&gt;feature list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The blog &lt;a href=&quot;http://www.standards-schmandards.com/&quot;&gt;Standards Schmandards&lt;/a&gt; has an excellent &lt;a href=&quot;http://www.standards-schmandards.com/2007/wysiwyg-editor-test-2/&quot;&gt;comparison of WYSIWYG editors&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Setting up a Drupal development environment with lighttpd in Mac OS X</title>
      <link>http://henriksjokvist.net/archive/2007/12/setting-up-a-drupal-development-environment-with-lighttpd-in-mac-os-x/</link>
      <pubDate>Sat, 15 Dec 2007 00:00:00 -0800</pubDate>
      <author>henrik.sjokvist@gmail.com (Henrik Sjökvist)</author>
      <guid>http://henriksjokvist.net/archive/2007/12/setting-up-a-drupal-development-environment-with-lighttpd-in-mac-os-x</guid>
      <description>&lt;p&gt;After upgrading to Leopard I finally got fed up with MAMP. I've been using it for development for quite a while, but found it dog slow and I never got the GUI tools to work right under 10.5. I've been using &lt;a href=&quot;http://www.lighttpd.net&quot;&gt;lighttpd&lt;/a&gt; on servers and decided to give it a go on my MacBook Pro. It runs superbly.&lt;/p&gt;

&lt;p&gt;This setup requires MacPorts which is a Linux style package management system. Everything you install through MacPorts is contained in the folder &lt;code&gt;/opt&lt;/code&gt; and it doesn't tamper with your existing OS X installation.&lt;/p&gt;

&lt;!--break--&gt;


&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Install MacPorts&lt;/h2&gt;

&lt;p&gt;Download and install &lt;a href=&quot;http://www.macports.org/&quot;&gt;MacPorts&lt;/a&gt;. Note that MacPorts requires that Apple's &lt;a href=&quot;http://developer.apple.com/tools/xcode/&quot;&gt;Xcode Developer Tools&lt;/a&gt; package is installed.&lt;/p&gt;

&lt;p&gt;You can verify that you're using the latest version of MacPorts by firing up the Terminal and running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo port selfupdate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you don't already have a &lt;code&gt;~/.profile&lt;/code&gt; file, you may need to create it and add the paths for MacPorts (close and re-open your Terminal window for the changes to become active). Edit &lt;code&gt;~/.profile&lt;/code&gt; and insert:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export PATH=/opt/local/bin:/opt/local/sbin:$PATH
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Install and configure lighttpd and PHP&lt;/h2&gt;

&lt;p&gt;We're using the CML version of lighttpd for URL rewriting so we need Lua too. Run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo port install lua &amp;amp;&amp;amp; sudo port install lighttpd +cml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since it compiles the packages from source this takes a while.&lt;/p&gt;

&lt;h3&gt;Setting up lighttpd.conf&lt;/h3&gt;

&lt;p&gt;Make a copy of the config template that lighttpd comes with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd  /opt/local/etc/lighttpd/
sudo cp lighttpd.conf.default lighttpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;lighttpd.conf&lt;/code&gt; and enable &lt;code&gt;mod_magnet&lt;/code&gt; and &lt;code&gt;mod_fastcgi&lt;/code&gt; in the &lt;code&gt;server.modules&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;Enable PHP with FastCGI by adding this snippet somewhere below the &lt;code&gt;server.modules&lt;/code&gt; section:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fastcgi.server = (
    &quot;.php&quot; =&amp;gt; ((
        &quot;bin-path&quot; =&amp;gt; &quot;/opt/local/bin/php-cgi&quot;,
        &quot;socket&quot; =&amp;gt; &quot;/opt/local/var/run/php5/php.socket&quot;
    ))
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Set the primary site directory. I like to use my Sites folder:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server.document-root        = &quot;/Users/yourname/Sites/&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add your first virtual host:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$HTTP[&quot;host&quot;] == &quot;mydrupalsite&quot; {
  server.document-root = &quot;/Users/yourname/Sites/mydrupalsite/&quot;
  index-file.names = ( &quot;index.php&quot; )
  magnet.attract-physical-path-to = ( &quot;/opt/local/etc/lighttpd/drupal.lua&quot; )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Rewrite rules&lt;/h3&gt;

&lt;p&gt;lighttpd doesn't support Apache's esoteric mod_rewrite syntax, so the &lt;code&gt;.htaccess&lt;/code&gt; file that Drupal ships with doesn't do us any good. Instead we'll use a Lua script to handle clean URLs.&lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;/opt/local/etc/lighttpd/drupal.lua&lt;/code&gt; containg the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;attr = lighty.stat(lighty.env[&quot;physical.path&quot;])
if (not attr) then
lighty.env[&quot;uri.query&quot;] = &quot;q=&quot; .. string.gsub(lighty.env[&quot;request.uri&quot;], &quot;?&quot;, &quot;&amp;amp;&quot;)
lighty.env[&quot;uri.path&quot;] = &quot;/index.php&quot;
lighty.env[&quot;physical.rel-path&quot;] = lighty.env[&quot;uri.path&quot;]
lighty.env[&quot;physical.path&quot;] = lighty.env[&quot;physical.doc-root&quot;] .. lighty.env[&quot;physical.rel-path&quot;]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This a slightly updated version of &lt;a href=&quot;http://pixel.global-banlist.de/2007/2/6/drupal-on-lighttpd-with-clean-urls&quot;&gt;darix's script&lt;/a&gt;. The original version couldn't pass on GET variables appended to the clean URL (e.g. for exposed Views filters where the URL ends up looking something like: &lt;code&gt;/somepage?filter0=x&amp;amp;filter1=y&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;Add the new hostname&lt;/h3&gt;

&lt;p&gt;We need to add the hostname to &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1       mydrupalsite
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In the version I downloaded lighttpd's default log directory was set to &lt;code&gt;/var/log/lighttpd&lt;/code&gt;, but since that is outside of &lt;code&gt;/opt&lt;/code&gt; it isn't created. lighttpd &lt;strong&gt;will not start&lt;/strong&gt; if it can't write to that directory, so I created it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir /var/log/lighttpd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make lighttpd start at boot up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl load -w /Library/LaunchDaemons/org.macports.lighttpd.plist
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Start lighttpd:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl start org.macports.lighttpd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting tip:&lt;/strong&gt; If lighttpd fails to start (for example if you have a typo in your lighttpd.conf), you can get a more verbose output by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo lighttpd -D -f /opt/local/etc/lighttpd/lighttpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Installing MySQL&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;sudo port install mysql5 +server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install the MySQL system tables:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mysql_install_db5 --user=mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make it run at startup:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Fire it up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl start org.macports.mysql5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can log in and secure the initial user accounts (as described &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/default-privileges.html&quot;&gt;here&lt;/a&gt;), and create your Drupal database:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mysql5 -u root
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Install PHP&lt;/h2&gt;

&lt;p&gt;PHP 5 is pre-installed in Leopard, but the Apple built version lacks GD support and we need the FastCGI version too.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo port install php5 +fastcgi +mysql5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the socket directory for php-cgi (as defined in the &lt;code&gt;fastcgi.server&lt;/code&gt; section of &lt;code&gt;lighttpd.conf&lt;/code&gt; above):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir -p /opt/local/var/run/php5
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Install Drupal&lt;/h2&gt;

&lt;p&gt;Install Drupal in &lt;code&gt;/Users/yourname/Sites/mydrupalsite/&lt;/code&gt;.
Now open up your browser and go to http://mydrupalsite/. Voila!&lt;/p&gt;

&lt;p&gt;To add another virtual server, just duplicate the &lt;code&gt;$HTTP[&quot;host&quot;]&lt;/code&gt; entry in &lt;code&gt;lighttpd.conf&lt;/code&gt; and give it the new hostname and path. Don't forget to add the new hostname to &lt;code&gt;/etc/hosts&lt;/code&gt;. Easy as pie.&lt;/p&gt;

&lt;h2&gt;Install phpMyAdmin&lt;/h2&gt;

&lt;p&gt;phpMyAdmin is nice to have.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo port install phpmyadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/opt/local/etc/lighttpd.conf&lt;/code&gt; and add it as a virtual host (no need for the rewrite rules):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$HTTP[&quot;host&quot;] == &quot;phpmyadmin&quot; {
  server.document-root = &quot;/opt/local/www/phpmyadmin/&quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add the hostname to &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1       phpmyadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make a copy of the template configuration file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo cp /opt/local/www/phpmyadmin/config.sample.inc.php /opt/local/www/phpmyadmin/config.inc.php
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/opt/local/www/phpmyadmin/config.inc.php&lt;/code&gt; and enter something as the &lt;code&gt;$cfg['blowfish_secret']&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Restart lighttpd:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl stop org.macports.lighttpd
sudo launchctl start org.macports.lighttpd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Point your browser to &lt;a href=&quot;http://phpmyadmin/&quot;&gt;http://phpmyadmin/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Create an Apple Script for starting and stopping lighttpd and MySQL&lt;/h2&gt;

&lt;p&gt;I created a simple Apple Script that restarts lighttpd and MySQL. Fire up Script Editor and paste this in there:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;do shell script &quot;sudo launchctl stop org.macports.lighttpd &amp;amp;&amp;amp; sudo launchctl start org.macports.lighttpd &amp;amp;&amp;amp; sudo launchctl stop org.macports.mysql5 &amp;amp;&amp;amp; sudo launchctl start org.macports.mysql5&quot; with administrator privileges
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Save it as an application and add it to your dock. Now you can restart the server without having to do any typing in the Terminal.&lt;/p&gt;
</description>
    </item>
    

  </channel> 
</rss>
