<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0" xml:base="http://engineeredweb.com">
<channel>
 <title>Engineered Web</title>
 <link>http://engineeredweb.com</link>
 <description />
 <language>en</language>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/EngineeredWeb" /><feedburner:info uri="engineeredweb" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>EngineeredWeb</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
 <title>Protocol Relative URLs in Drupal 7</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/5NlmqJjIZnY/protocol-relative-urls-drupal-7</link>
 <description>&lt;p&gt;When I first started tackling &lt;a href="http://engineeredweb.com/blog/11/12/drupal-does-not-respect-https-when-caching" title="Drupal Does Not Respect https:// When Caching"&gt;the problem of https and Drupal caching&lt;/a&gt; I wanted an interim solution and started by &lt;a href="http://drupal.org/sandbox/mfer/1386376"&gt;making the database caching layer smarter&lt;/a&gt;. &lt;a href="http://drupal.org/node/1377840#comment-5404064"&gt;Neil Drumm had the idea to use protocol-relative (a.k.a, schemeless) URLs&lt;/a&gt;. This turns out to be a great idea and thanks to some hooks in Drupal it's something we can implement fairly easily.&lt;/p&gt;
&lt;!--break--&gt;&lt;!--break--&gt;&lt;h2&gt;Protocol-Relative URL&lt;/h2&gt;
&lt;p&gt;Protocol relative URLs don't contain the protocol. For example, &lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;http://example.com/foo/bar&lt;/code&gt;&lt;/span&gt; would be &lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;//example.com/foo/bar&lt;/code&gt;&lt;/span&gt;. Browsers will use the protocol for the page it's on when the protocol is absent. For a page that could be displayed under https or http this is a nice solution and can help us avoid caching for both situations.&lt;/p&gt;
&lt;p&gt;Protocol-Relative URLs aren't new or novel. For example, Google has been using them for some time. Just take a look at the source of a Google Plus page (or many others).&lt;/p&gt;
&lt;h2&gt;The Setup&lt;/h2&gt;
&lt;p&gt;You first need to make sure your server is capable of serving both http and https requests. For URLs to not have a protocol it makes sense to serve with multiple protocols. There is also the case where your content could be served out of http on RSS then viewed in an RSS reader under https. You don't want problems to pop up in cases like this.&lt;/p&gt;
&lt;h2&gt;IE 7/8 and CSS&lt;/h2&gt;
&lt;p&gt;Yeah, so older versions of IE have a bug. &lt;a href="http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/" title="Missing schema double download"&gt;IE 7 and 8 will download stylesheets twice when the protocol is missing&lt;/a&gt;. You can either code around this, not use this technique, or let those users suffer with slightly slower performance.&lt;/p&gt;
&lt;h2&gt;Implementation Options&lt;/h2&gt;
&lt;p&gt;What follows are two different implementation options depending on what you want to do and your scenario. You can pick the case you think works best for you or tweak to your hearts delight.&lt;/p&gt;
&lt;h3&gt;Images Only&lt;/h3&gt;
&lt;p&gt;Many of the images inside Drupal (e.g., those handled by image styles) have a full URLs. If you want to alter these it's possible through the use of &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;hook_preprocess_image&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #009933; font-style: italic;"&gt;/**
 * Implementation of hook_preprocess_image().
 *
 * Make images that use a full url be protocol relative.
 */&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;function&lt;/span&gt; custom_preprocess_image&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$variables&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color: #666666; font-style: italic;"&gt;// If the image URL starts with a protocol remove it and use a&lt;/span&gt;
  &lt;span style="color: #666666; font-style: italic;"&gt;// relative protocol.&lt;/span&gt;
  &lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; file_uri_scheme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$variables&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'path'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #000088;"&gt;$protocols&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/array"&gt;&lt;span style="color: #990000;"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'http'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'https'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;a href="http://www.php.net/in_array"&gt;&lt;span style="color: #990000;"&gt;in_array&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #000088;"&gt;$protocols&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000088;"&gt;$variables&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'path'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'//'&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; file_uri_target&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$variables&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'path'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;em&gt;This code is available as a gist at &lt;a href="https://gist.github.com/1523736" title="https://gist.github.com/1523736"&gt;https://gist.github.com/1523736&lt;/a&gt; &lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;All File URLs Generated By Drupal&lt;/h3&gt;
&lt;p&gt;In Drupal &lt;a href="http://api.drupal.org/api/drupal/includes--file.inc/function/file_create_url/7"&gt;file_create_url()&lt;/a&gt; is used to create the full URLs for everything from image to CSS and JavaScript. It handles public and private files, internal paths (which it turns into full URLs), and making sure everything is tidy. To accommodate CDNs there is &lt;a href="http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_file_url_alter/7"&gt;hook_file_url_alter()&lt;/a&gt; which we can plug into in order to make protocol-relative URLs.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #009933; font-style: italic;"&gt;/**
 * Implements hook_file_url_alter().
 *
 * Make all URLs be protocol relative.
 * Note: protocol relatice URLs will cause IE7/8 to download stylesheets twice.
 */&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;function&lt;/span&gt; custom_file_url_alter&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
  &lt;a href="http://www.php.net/global"&gt;&lt;span style="color: #990000;"&gt;global&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #000088;"&gt;$base_url&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;a href="http://www.php.net/static"&gt;&lt;span style="color: #990000;"&gt;static&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #000088;"&gt;$relative_base_url&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;NULL&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #000088;"&gt;$relative_base_length&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;NULL&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; file_uri_scheme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color: #666666; font-style: italic;"&gt;// For some things (e.g., images) hook_file_url_alter can be called multiple&lt;/span&gt;
  &lt;span style="color: #666666; font-style: italic;"&gt;// times. So, we have to be sure not to alter it multiple times. If we already&lt;/span&gt;
  &lt;span style="color: #666666; font-style: italic;"&gt;// are relative protocol we can just return.&lt;/span&gt;
  &lt;span style="color: #666666; font-style: italic;"&gt;// Only setup the and parse this stuff once.&lt;/span&gt;
  &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;!&lt;/span&gt;&lt;span style="color: #000088;"&gt;$relative_base_url&lt;/span&gt; &lt;span style="color: #339933;"&gt;||&lt;/span&gt; &lt;span style="color: #339933;"&gt;!&lt;/span&gt;&lt;span style="color: #000088;"&gt;$relative_base_length&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000088;"&gt;$relative_base_url&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'//'&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; file_uri_target&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$base_url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #000088;"&gt;$relative_base_length&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/strlen"&gt;&lt;span style="color: #990000;"&gt;strlen&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$relative_base_url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
  &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;!&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;a href="http://www.php.net/substr"&gt;&lt;span style="color: #990000;"&gt;substr&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #000088;"&gt;$relative_base_length&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;==&lt;/span&gt; &lt;span style="color: #000088;"&gt;$relative_base_url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;return&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color: #666666; font-style: italic;"&gt;// Handle the case where we have public files with the scheme public:// or&lt;/span&gt;
  &lt;span style="color: #666666; font-style: italic;"&gt;// the case the relative path doesn't start with a /. Internal relative urls&lt;/span&gt;
  &lt;span style="color: #666666; font-style: italic;"&gt;// have the base url prepended to them.&lt;/span&gt;
  &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;!&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;||&lt;/span&gt; &lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;==&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'public'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #666666; font-style: italic;"&gt;// Internal Drupal paths.&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;!&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      &lt;span style="color: #000088;"&gt;$path&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;else&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      &lt;span style="color: #000088;"&gt;$wrapper&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; file_stream_wrapper_get_instance_by_scheme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
      &lt;span style="color: #000088;"&gt;$path&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000088;"&gt;$wrapper&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #004000;"&gt;getDirectoryPath&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'/'&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; file_uri_target&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #666666; font-style: italic;"&gt;// Clean up Windows paths.&lt;/span&gt;
    &lt;span style="color: #000088;"&gt;$path&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/str_replace"&gt;&lt;span style="color: #990000;"&gt;str_replace&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'\\'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'/'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #000088;"&gt;$path&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #000088;"&gt;$url&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000088;"&gt;$base_url&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'/'&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; &lt;span style="color: #000088;"&gt;$path&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color: #666666; font-style: italic;"&gt;// Convert full URLs to relative protocol.&lt;/span&gt;
  &lt;span style="color: #000088;"&gt;$protocols&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/array"&gt;&lt;span style="color: #990000;"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'http'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'https'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; file_uri_scheme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;a href="http://www.php.net/in_array"&gt;&lt;span style="color: #990000;"&gt;in_array&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$scheme&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #000088;"&gt;$protocols&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000088;"&gt;$url&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'//'&lt;/span&gt; &lt;span style="color: #339933;"&gt;.&lt;/span&gt; file_uri_target&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$url&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;em&gt;This code is available as a gist at &lt;a href="https://gist.github.com/1524135" title="https://gist.github.com/1524135"&gt;https://gist.github.com/1524135&lt;/a&gt; &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Be careful with this option as it will cause CSS to be downloaded twice in IE 7 and 8.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8DRy8vjr0cetvpOu3f0m8HqtCGM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8DRy8vjr0cetvpOu3f0m8HqtCGM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8DRy8vjr0cetvpOu3f0m8HqtCGM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8DRy8vjr0cetvpOu3f0m8HqtCGM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/5NlmqJjIZnY" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/12/protocol-relative-urls-drupal-7#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <pubDate>Tue, 27 Dec 2011 16:09:50 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">111 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/12/protocol-relative-urls-drupal-7</feedburner:origLink></item>
<item>
 <title>Drupal Does Not Respect https:// When Caching</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/h5iKK58yK6U/drupal-does-not-respect-https-when-caching</link>
 <description>&lt;p&gt;One of the problems I recently discovered with the Drupal cache is that it doesn't properly handle https transactions when caching happens. Let's take a look at understanding the problem, an interim solution for the database cache, and finding a long term solution.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;&lt;img src="http://engineeredweb.com/sites/engineeredweb.com/files/images/page-cache-https-issue.png" width="585" height="565" alt="page-cache-https-issue.png" /&gt;&lt;/p&gt;
&lt;p&gt;The page cache properly respects https because it uses a full url including the protocol when generating a cache id. But, Drupal uses multiple layers of caching with the html in a page. For example, the content of blocks can be cached. What if the html for a block has absolute URLs pointing back to the site and those are generated on the http version of the site. Then this is cached. Then this cache is used to create the https version of the page. Then those cached absolute URLs are not using https.&lt;/p&gt;
&lt;h3&gt;Media Module, Where I Found The Problem&lt;/h3&gt;
&lt;p&gt;The example that caused me to understand this problem was the media module. With the media module you can embed images and video into a text area (like the body of an article). Media tags are converted to html by the filter system and the results are cached. Images, for example, use absolute URLs (this is part of core and is a good thing for some use cases). If the cache for this text was generated on the http version of the site the path to the image on the https version of the page will use http as the protocol.&lt;/p&gt;
&lt;p&gt;This opens up all kids of possible issues. Just imagine someone in a coffee shop thinking they are on https only to have cookies sent back to the server for that image in plain text. Or maybe you have a better imagination than me and can think of something more sinister.&lt;/p&gt;
&lt;h3&gt;Nested Caching&lt;/h3&gt;
&lt;p&gt;The issues is nested caching of html and how many of the nested caches don't respect the protocol like the page cache does. This can apply to any html that's cached across any modules.&lt;/p&gt;
&lt;h2&gt;Fixing Database Caching In The Short Term&lt;/h2&gt;
&lt;p&gt;To work around this problem I've started a &lt;a href="http://drupal.org/sandbox/mfer/1386376"&gt;database caching layer that works around this problem by respecting https for most caches&lt;/a&gt;. I don't really like this solution and there are some definite hacks in how it works. The real solution should be to have the code saving and retrieving from the html caches be smart enough to include the protocol in the caches. Unfortunately, a cache backend can't fix the places the cache is used.&lt;/p&gt;
&lt;h2&gt;A Long Term Solution&lt;/h2&gt;
&lt;p&gt;An &lt;a href="http://drupal.org/node/1377840"&gt;issue for a long term solution&lt;/a&gt; is already open. If you have any experience in this area, it impacts your sites, or you want to help out please head over there so we can fix this moving forward.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JiQ8H5OQQintKgqjzxu8VIPvpwg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JiQ8H5OQQintKgqjzxu8VIPvpwg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JiQ8H5OQQintKgqjzxu8VIPvpwg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JiQ8H5OQQintKgqjzxu8VIPvpwg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/h5iKK58yK6U" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/12/drupal-does-not-respect-https-when-caching#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <pubDate>Mon, 26 Dec 2011 21:20:33 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">110 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/12/drupal-does-not-respect-https-when-caching</feedburner:origLink></item>
<item>
 <title>DrupalCamp Michigan Registration Re-Opened</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/nGjq-ePAXg0/drupalcamp-michigan-registration-re-opened</link>
 <description>&lt;p&gt;&lt;img src="http://engineeredweb.com/sites/engineeredweb.com/files/images/logos/DrupalCampMI-2011.png" width="144" height="144" alt="DrupalCampMI-2011.png" align="left" class="float-left" /&gt;When we first started planning &lt;a href="http://drupalcampmi.org"&gt;DrupalCamp Michigan&lt;/a&gt; we didn't have high expectations for turnout. Southeast Michigan, where the camp is being held, is not known for a large or active Drupal community. When we sold out less than 3 weeks after we had the idea for the camp it was a very present surprise. But, we knew there were more people who wanted to come and an opportunity to reach more people. So, we've added more space and re-opened registration.&lt;/p&gt;
&lt;p&gt;Special thanks to &lt;a href="http://bluedrop.me/"&gt;Jason Savino&lt;/a&gt; for jumping all over this, coordinating with others in the local community (especially &lt;a href="http://www.commerceguys.com/"&gt;Mike O'Connor from the Commerce Guys&lt;/a&gt; who was also working on this), and making the extra space happen quickly.&lt;/p&gt;
&lt;!--break--&gt;&lt;!--break--&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rHOSqvSgw7Xm2pxoEaJxdoHLhxQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rHOSqvSgw7Xm2pxoEaJxdoHLhxQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rHOSqvSgw7Xm2pxoEaJxdoHLhxQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rHOSqvSgw7Xm2pxoEaJxdoHLhxQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/nGjq-ePAXg0" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/10/drupalcamp-michigan-registration-re-opened#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <pubDate>Mon, 17 Oct 2011 11:41:54 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">109 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/10/drupalcamp-michigan-registration-re-opened</feedburner:origLink></item>
<item>
 <title>The First DrupalCamp Michigan</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/JNwuqRrd-OA/first-drupalcamp-michigan</link>
 <description>&lt;p&gt;&lt;a href="http://drupalcampmi.org" title="DrupalCamp Michigan"&gt;&lt;img src="http://engineeredweb.com/sites/engineeredweb.com/files/images/logos/DrupalCampMI-2011.png" width="144" height="144" alt="DrupalCampMI-2011.png" class="float-left" align="left" /&gt;&lt;/a&gt;&lt;strong&gt;This December 3rd will be the very first &lt;a href="http://drupalcampmi.org/"&gt;DrupalCamp Michigan&lt;/a&gt;.&lt;/strong&gt; Our initial go at a DrupalCamp will be a one day event at the &lt;a href="http://g.co/maps/uzajh"&gt;Crowne Plaza in Novi&lt;/a&gt;. The event is being sponsored and attended by the local Drupal shops of &lt;a href="http://www.commerceguys.com"&gt;Commerce Guys&lt;/a&gt;, &lt;a href="http://mustardseedmedia.com"&gt;Mustardseed Media&lt;/a&gt;, &lt;a href="http://switchbackcms.com/"&gt;Switchback&lt;/a&gt;, and &lt;a href="http://www.commercialprogression.com"&gt;Commercial Progression&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you're interested in attending head on over to &lt;a href="http://drupalcampmi.org" title="http://drupalcampmi.org"&gt;http://drupalcampmi.org&lt;/a&gt; for more details and to register. Space is limited.&lt;/p&gt;
&lt;!--break--&gt;&lt;!--break--&gt;&lt;p&gt;Our hope is to bring out many of the local Drupalers so we can better get to know each other. While there are a number of prominent Drupal developers in the area and some prominent shops, the community has yet to extensively connect with each other. We hope this DrupalCamp will be a great opportunity to build connections in the local community.&lt;/p&gt;
&lt;p&gt;If you're interested in connecting with other Michigan based Drupal developer in IRC, head over to &lt;a href="irc://irc.freenode.net#drupal-michigan"&gt;#drupal-michigan&lt;/a&gt; on freenode.&lt;/p&gt;
&lt;p&gt;Michiganders, it's time to connect. If you're a local Drupal developer come checkout the first DrupalCamp Michigan.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/34wtBVN4rFj1-nKp7BnTqM5rKKY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/34wtBVN4rFj1-nKp7BnTqM5rKKY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/34wtBVN4rFj1-nKp7BnTqM5rKKY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/34wtBVN4rFj1-nKp7BnTqM5rKKY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/JNwuqRrd-OA" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/10/first-drupalcamp-michigan#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <pubDate>Mon, 03 Oct 2011 12:37:28 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">108 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/10/first-drupalcamp-michigan</feedburner:origLink></item>
<item>
 <title>The Drupal Community and Front End Performance</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/z1BufMLIWAg/drupal-community-and-front-end-performance</link>
 <description>&lt;p&gt;&lt;strong&gt;&lt;a href="http://drupal.org"&gt;Drupal&lt;/a&gt; has a presence problem when it comes to front end performance. Drupal has for the most part ignored front end performance.&lt;/strong&gt; According to a &lt;a href="http://www.readwriteweb.com/hack/2011/06/mobile-page-response.php"&gt;study by Strangeloop&lt;/a&gt;, 97% of the time it takes a mobile page to render is in the front end. For desktop browser the front end makes up 85% of the time. These numbers may feel high. But, when pages take 500ms to render in Drupal but 6 seconds to display in an end users browser you can see where this comes from.&lt;/p&gt;
&lt;p&gt;The presence problem for Drupal can be seen in several places:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A the past few DrupalCons how many sessions have touched on front end performance? I can only recall one of them while there have been many covering memcache, apc, and other server side technologies.&lt;/li&gt;
&lt;li&gt;Take a look at the documentation pages on &lt;a href="http://drupal.org/node/79237"&gt;profiling&lt;/a&gt; &lt;a href="http://drupal.org/node/282862"&gt;Drupal&lt;/a&gt;. Or, search for documentation pages on performance. You'll find discussions about apache benchmark, learn about varnish, etc. You won't learn about font end performance.&lt;/li&gt;
&lt;li&gt;Drupal doesn't provide minified JavaScript. For production environments this is considered a standard practice.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://groups.drupal.org/node/166704"&gt;Drupal 8 development "gates" RFC&lt;/a&gt; gives 1 of 6 performance items to font end performance. The other 5 are tips/gates in detail for back end issues we've commonly run into. The front end one is a basic one liner.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Front end performance is a big deal. This is more so true as we enter into the dominance of mobile where mobile devices are low powered and on high latency networks.&lt;/p&gt;
&lt;h2&gt;What We Can Do About It&lt;/h2&gt;
&lt;p&gt;Pointing out problems is no good without solutions. The problem is in the amount of face time front end performance gets. So, lets get it some face time.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At DrupalCamps let's start presenting on it.&lt;/li&gt;
&lt;li&gt;Drupal companies could benefit from having someone knowledge in house. Come up with ways to add it to your expertise. Maybe hold a book club and discuss &lt;a href="http://www.amazon.com/Steve-Souders/e/B001I9TVJS/ref=ntt_athr_dp_pel_1"&gt;a Steve Souders book&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;When we learn about useful tools like &lt;a href="http://imageoptim.pornel.net/"&gt;ImageOptim&lt;/a&gt; or &lt;a href="http://www.spritecow.com/"&gt;Sprite Cow&lt;/a&gt; lets share them.&lt;/li&gt;
&lt;li&gt;If you see a contrib module serving JavaScript up that has not been minified file a patch. You can &lt;a href="http://marijnhaverbeke.nl/uglifyjs"&gt;use UglifyJS easily through the web&lt;/a&gt;. UglifyJS is what jQuery uses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Front end performance is a big deal. It's the largest part of the performance equation an end user experiences. Companies have done studies showing the financial and usage impact of end user performance. Let's elevate front end performance to the place it needs to be in the Drupal community.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/T2dnMb6iv3BNTrHUUDe914ZyJ9k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T2dnMb6iv3BNTrHUUDe914ZyJ9k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/T2dnMb6iv3BNTrHUUDe914ZyJ9k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T2dnMb6iv3BNTrHUUDe914ZyJ9k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/z1BufMLIWAg" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/9/drupal-community-and-front-end-performance#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <category domain="http://engineeredweb.com/blog/tags/performance">Performance</category>
 <pubDate>Tue, 20 Sep 2011 14:10:32 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">107 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/9/drupal-community-and-front-end-performance</feedburner:origLink></item>
<item>
 <title>PHP Needs A New Package Manager</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/mWismdGsjvA/php-needs-new-package-manager</link>
 <description>&lt;p&gt;After working with &lt;a href="http://pear.php.net"&gt;Pear&lt;/a&gt;, the &lt;a href="http://php.net"&gt;PHP&lt;/a&gt; package manager, recently one thing has become apparent. PHP needs a new package manager. Over the last couple years I've worked with &lt;a href="http://npmjs.org"&gt;npm&lt;/a&gt;, &lt;a href="http://mxcl.github.com/homebrew/"&gt;homebrew&lt;/a&gt;, and &lt;a href="http://rubygems.org/"&gt;gem&lt;/a&gt; which are great package managers for other languages and systems. Using Pear requires extra thought and work as a user, pain for creating packages, and suffering for those handling deployment outside a standard workflow. So, let's start a conversation about what would be better.&lt;/p&gt;
&lt;h2&gt;The Problem With Pear&lt;/h2&gt;
&lt;p&gt;Pear has been around since 1999. The web was an entirely different place. This is back in the day when dial-up internet was common place. After all this time and change in the developer community did Pear become antiquated?&lt;/p&gt;
&lt;p&gt;From my perspective I have 3 problems and see dozens of places for small potential improvements.&lt;/p&gt;
&lt;h3&gt;Decentralization&lt;/h3&gt;
&lt;p&gt;Pear was also built on decentralization. That means something like:&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;$ pear install symfony&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Pear doesn't know what symfony is or where to get it. Before you can install it you need to know where to get it from and add the channel. For example:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;$ pear channel-discover pear.symfony-project.com&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;If there were just a handful of sites providing packages this wouldn't be an issue. If you use packages from more than a handful of pear channels you could end up needing a manager just for your pear channels much less your PHP packages.&lt;/p&gt;
&lt;p&gt;Don't get me wrong, decentralization is nice in theory. But, in practice it's lowering my user experience and is a pain point.&lt;/p&gt;
&lt;h3&gt;The Pain Of Creating Packages&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;I don't update my projects often in part because of the pain in creating updates to my pear channel.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;While I was lamenting over Pear recently a developer shared this with me. That's when I realized there were others experiencing pain in creating packages. The few times I considered creating a pear channel and packages I started diving into the documentation and walked away after a short bit of screaming. To hear someone who had gone through with creating packages complain about it was new.&lt;/p&gt;
&lt;p&gt;Sure, there are tools like &lt;a href="http://pirum.sensiolabs.org/"&gt;Pirum&lt;/a&gt; that make it easier. But, creating pear packages is not something many people want to do.&lt;/p&gt;
&lt;h3&gt;What About Firewalls and Intranets?&lt;/h3&gt;
&lt;p&gt;Some companies and projects have firewall and packaging restrictions. Sure these can drive developers nuts sometimes but there are often (though not always) good reasons behind them. How do you handle this with Pear?&lt;/p&gt;
&lt;p&gt;Well, you could create your own Pear channel and put all the packages you want in there. If you look at the &lt;a href="http://pear.php.net/manual/en/guide.developers.package2.intro.php"&gt;package.xml&lt;/a&gt; that comes with each package you'll notice it calls out information like the pear channel it's associated with. So, you need to update each of the packages before moving them to your internal channel?&lt;/p&gt;
&lt;p&gt;Let's just say this setup is not one I personally want to work in.&lt;/p&gt;
&lt;h2&gt;A Picture Of What People (Mostly Myself) Want&lt;/h2&gt;
&lt;p&gt;Putting the justification for why I'm writing this all to long post aside lets focus on what would be great in a PHP package manager. To put it in a single word, &lt;em&gt;simplicity&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Can you imagine it being as simple for a user as:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;$ foo install bar
$ foo info bar
$ foo self-update
$ foo uninstall bar
$ foo pay bar tab&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;As an end user I want something simple and easy to use. No channel discovering (yes, I want a central repository). If it's going to pull from a corporate repository that could be a command line switch or in a system wide config file.&lt;/p&gt;
&lt;p&gt;From a developers standpoint simplicity should come first. Imagine the case where creating a new package worked like this.&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;$ cd /to/package/root
$ foo create bar&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
At this point a utility asked you a bunch of questions about the package and built the package.xml file for you. Then to publish it you do something like:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;$ foo publish bar&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This is the type of tool I would want to use. It might even help PHP in the popularity arena.&lt;/p&gt;
&lt;h2&gt;A Short List Of Requirements&lt;/h2&gt;
&lt;p&gt;Now that I've painted a picture of what it should look like here's a short list of requirements that should be covered.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The ability to create my own distribution site (like the central repo) and easily move packages into it. This will help those secure network types.&lt;/li&gt;
&lt;li&gt;The ability to import packages into an app. For example:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;\Foo\&lt;span style="color: #b1b100;"&gt;Require&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'bar'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
This may even include a specific version, for example.&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;\Foo\&lt;span style="color: #b1b100;"&gt;Require&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;'bar'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'1.1.1'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'&amp;gt;'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;The ability to get apps as well as install them on the system. For example:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;$ foo get wordpress&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
This would go get and download the latest release of wordpress and put it in the directory I'm currently in. Not everything is a package to be installed on a system.
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;What Do You Think?&lt;/h2&gt;
&lt;p&gt;I would find a tool like this to be incredibly useful and I've talked to a handful of others who feel the same way. But, nothing has been created in the years and years of PHP so maybe I'm off my rocker. What do you think? Is something like this something you'd want to use? What additional requirements would you like to see? Or, is there something out there that already does all of this that just isn't getting the attention it deserves?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lFMpR5jcdqO9W4JJtFpz6UCVviA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lFMpR5jcdqO9W4JJtFpz6UCVviA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lFMpR5jcdqO9W4JJtFpz6UCVviA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lFMpR5jcdqO9W4JJtFpz6UCVviA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/mWismdGsjvA" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/9/php-needs-new-package-manager#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/php">PHP</category>
 <category domain="http://engineeredweb.com/blog/tags/rant">Rant</category>
 <pubDate>Tue, 13 Sep 2011 14:14:28 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">106 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/9/php-needs-new-package-manager</feedburner:origLink></item>
<item>
 <title>SplFixedArray, An Underutilized PHP Gem</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/s9ABCVEbqJQ/splfixedarray-underutilized-php-gem</link>
 <description>&lt;p&gt;Arrays in PHP are not arrays per the typical &lt;a href="http://en.wikipedia.org/wiki/Array_data_type" title="Wikipedia: Array data type"&gt;array data type&lt;/a&gt;. Instead, as Matt Butcher recently pointed out &lt;a href="http://technosophos.com/content/php-arrays-are-not-arrays" title="PHP Arrays are NOT Arrays"&gt;arrays in PHP are similar to hashes in other languages&lt;/a&gt;. This can be a very important point to know when tracking down bugs in code and to programmers coming to PHP from other languages. But, what if we wanted something like a traditional array data type? Maybe something that preserved numeric order. Enter &lt;a href="splfixedarray" title="PHP: SplFixedArray"&gt;SplFixedArray&lt;/a&gt;.&lt;/p&gt;
&lt;!--break--&gt;&lt;!--break--&gt;&lt;h2&gt;An Example Problem&lt;/h2&gt;
&lt;p&gt;A simple example of a problem PHP arrays don't handle well is ordering by number. Let's look at a simple example.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/array"&gt;&lt;span style="color: #990000;"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'a'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'b'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'c'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #666666; font-style: italic;"&gt;// Remove and replace index 1 with something new.&lt;/span&gt;
&lt;a href="http://www.php.net/unset"&gt;&lt;span style="color: #990000;"&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'what?'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;a href="http://www.php.net/print"&gt;&lt;span style="color: #990000;"&gt;print&lt;/span&gt;&lt;/a&gt; &lt;a href="http://www.php.net/implode"&gt;&lt;span style="color: #990000;"&gt;implode&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;// prints &amp;quot;acwhat?&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;As you can see numeric order on an array is not preserved. What if we wanted to use something that preserved numeric order? Enter SplFixedArray.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;// SplFixedArray is fixed in size but it can be altered. 3 is initial size.&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; SplFixedArray&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'a'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'b'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'c'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #666666; font-style: italic;"&gt;// Remove and replace index 1 with something new.&lt;/span&gt;
&lt;a href="http://www.php.net/unset"&gt;&lt;span style="color: #990000;"&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'what?'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;a href="http://www.php.net/print"&gt;&lt;span style="color: #990000;"&gt;print&lt;/span&gt;&lt;/a&gt; &lt;a href="http://www.php.net/implode"&gt;&lt;span style="color: #990000;"&gt;implode&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #004000;"&gt;toArray&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;// prints &amp;quot;awhat?c&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;The numeric ordering of elements is preserved. SplFixedArray has the ability to be generated from an array and to have an array be generated from it allowing for interoperability.&lt;/p&gt;
&lt;h2&gt;The Performance and Memory Impact&lt;/h2&gt;
&lt;p&gt;Something I didn't expect was for SplFixedArray to be faster and use less memory than an array.&lt;/p&gt;
&lt;p&gt;Memory usage is does not scale the same for these two. An array with less than 6 items in it will use less or about equal memory than a comparable SplFixedArray object. Once you pass about 6 items SplFixedArray uses less memory. The memory growth rate SplFixedArray is much lower and you can quickly get to the case in large sets where it uses half the memory. This is of course dependent on what's being stored in the array.&lt;/p&gt;
&lt;p&gt;Also note, when you use calls like:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #000088;"&gt;$bar&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #004000;"&gt;toArray&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This case has both an array ($bar) and an object ($foo) in memory.&lt;/p&gt;
&lt;p&gt;SplFixedArray is faster at getting and setting information. In some basic testing I found it to be better than 25% faster.&lt;/p&gt;
&lt;h2&gt;Some Catches&lt;/h2&gt;
&lt;p&gt;There is a catch with SplFixedArray. It's an object not a primitive data type in PHP. Array specific functions like &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;&lt;a href="http://www.php.net/implode"&gt;&lt;span style="color: #990000;"&gt;implode&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; don't work on SplFixedArray. SplFixedArray does implement the Iterator, ArrayAccess, and Countable interfaces making it useful in a lot of situations. But, it's no drop in replacement. Rather SplFixedArray is another useful tool in our quest for better development.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/N4vditkJMY1o59M6xBLGI3N4BZk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N4vditkJMY1o59M6xBLGI3N4BZk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/N4vditkJMY1o59M6xBLGI3N4BZk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N4vditkJMY1o59M6xBLGI3N4BZk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/s9ABCVEbqJQ" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/9/splfixedarray-underutilized-php-gem#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <category domain="http://engineeredweb.com/blog/tags/php">PHP</category>
 <pubDate>Thu, 08 Sep 2011 13:55:45 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">104 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/9/splfixedarray-underutilized-php-gem</feedburner:origLink></item>
<item>
 <title>PHP 5.3 Performance: __toString() vs. A Method</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/EOrPicA4KHQ/php-53-performance-tostring-vs-method</link>
 <description>&lt;p&gt;Ever since &lt;a href="http://www.garfieldtech.com/blog/php-magic-call"&gt;Larry Garfield wrote about PHP magic calls and their slow performance&lt;/a&gt; I've been hesitant to use them. In the time since his post was written in 2007, &lt;a href="http://us.php.net/manual/en/language.oop5.magic.php"&gt;magic methods&lt;/a&gt; have seen improvements and I've started taking a look at them again. The first one I've started to explore using in the &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;__toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; method on objects. &lt;strong&gt;It turns out, as of PHP 5.3 using the &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;__toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; magic method can be faster than using regular method calls.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Understanding &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;__toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;When an object is treated as a string the &lt;a href="http://us.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring"&gt;&lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;__toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; method is called. It gives a class the ability to decide how it will react. For example:&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #009933; font-style: italic;"&gt;/**
 * A class named foo with a magic __toString method.
 */&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; Foo &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
  &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;function&lt;/span&gt; __toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;'foo'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #666666; font-style: italic;"&gt;// $foo is an instance of class Foo.&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; Foo&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #666666; font-style: italic;"&gt;// $foo is a class being treated like a string. When it is treated like a&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;// string the __toString method is called.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;// Outputs: foo&lt;/span&gt;
&lt;a href="http://www.php.net/print"&gt;&lt;span style="color: #990000;"&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h2&gt;Testing &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;__toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; vs a &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;render&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; method&lt;/h2&gt;
&lt;p&gt;In versions of PHP prior to PHP 5.3 there have been tests showing magic methods can be slow. I was warned not to use them for anything that requires performance, like working on a framework or CMS where there will be a lot of users. Recently I had heard magic method performance had improved so I decided to test some of them out and see what happens.&lt;/p&gt;
&lt;h3&gt;The setup&lt;/h3&gt;
&lt;p&gt;The code I used to perform the tests is:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="php geshifilter-php" style="font-family:monospace;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;?php&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; Foo &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
  &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;function&lt;/span&gt; render&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;''&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
  &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;function&lt;/span&gt; __toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;''&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
  &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000088;"&gt;$foo&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; Foo&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000088;"&gt;$iterations&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1000000&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000088;"&gt;$start1&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/microtime"&gt;&lt;span style="color: #990000;"&gt;microtime&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$i&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #000088;"&gt;$i&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #000088;"&gt;$iterations&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #000088;"&gt;$i&lt;/span&gt;&lt;span style="color: #339933;"&gt;++&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
  &lt;a href="http://www.php.net/print"&gt;&lt;span style="color: #990000;"&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #004000;"&gt;render&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$end1&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/microtime"&gt;&lt;span style="color: #990000;"&gt;microtime&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000088;"&gt;$start2&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/microtime"&gt;&lt;span style="color: #990000;"&gt;microtime&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$i&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #000088;"&gt;$i&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #000088;"&gt;$iterations&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #000088;"&gt;$i&lt;/span&gt;&lt;span style="color: #339933;"&gt;++&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
  &lt;a href="http://www.php.net/print"&gt;&lt;span style="color: #990000;"&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #000088;"&gt;$foo&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #000088;"&gt;$end2&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;a href="http://www.php.net/microtime"&gt;&lt;span style="color: #990000;"&gt;microtime&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;a href="http://www.php.net/printf"&gt;&lt;span style="color: #990000;"&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;Render Time: &lt;span style="color: #009933; font-weight: bold;"&gt;%0.2d&lt;/span&gt;&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$end1&lt;/span&gt; &lt;span style="color: #339933;"&gt;-&lt;/span&gt; &lt;span style="color: #000088;"&gt;$start1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;*&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1000&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;a href="http://www.php.net/printf"&gt;&lt;span style="color: #990000;"&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;toString Time: &lt;span style="color: #009933; font-weight: bold;"&gt;%0.2d&lt;/span&gt;&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000088;"&gt;$end2&lt;/span&gt; &lt;span style="color: #339933;"&gt;-&lt;/span&gt; &lt;span style="color: #000088;"&gt;$start2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;*&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1000&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This fairly simple code tries to be as minimal as possible to highlight the time to call these methods.&lt;/p&gt;
&lt;h3&gt;The results&lt;/h3&gt;
&lt;p&gt;What we care about is the results and how they compare to each other, not so much the amount of time they actually take.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;Render Time: 273
toString Time: 253&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Using &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;__toString&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; is faster than calling a method on the object to turn it into a string. Here we have a magic method performing quite nicely.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/r6k5ziN7yV6mljgc9k9eBVfK-sA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/r6k5ziN7yV6mljgc9k9eBVfK-sA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/r6k5ziN7yV6mljgc9k9eBVfK-sA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/r6k5ziN7yV6mljgc9k9eBVfK-sA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/EOrPicA4KHQ" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/7/php-53-performance-tostring-vs-method#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/php">PHP</category>
 <pubDate>Wed, 20 Jul 2011 13:45:51 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">102 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/7/php-53-performance-tostring-vs-method</feedburner:origLink></item>
<item>
 <title>JavaScript Theme Functions in Drupal</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/kb_WU5qC0Ww/javascript-theme-functions-drupal</link>
 <description>&lt;p&gt;&lt;a href="http://drupal.org"&gt;Drupal&lt;/a&gt; has an extensive theming system which includes theme functions that can be overridden and an extensible template system. There is an expectation that all markup go through the theme system and it is considered a bug when that doesn't happen. Most of the talk surrounding this system focuses on the server side system and what we can do in PHP. But, that's not all there is to the theme system. &lt;strong&gt;Drupal provides a theme system for JavaScript as well.&lt;/strong&gt; One with callbacks that can be overridden by themes, just like on the PHP side.&lt;/p&gt;
&lt;h2&gt;Theme Functions&lt;/h2&gt;
&lt;p&gt;The central function to the theme system is &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;. It is the JavaScript counterpart to &lt;a href="http://api.drupal.org/theme"&gt;&lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;theme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; and works in a similar manner to what &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;theme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; did in Drupal 6.&lt;/p&gt;
&lt;p&gt;The first step is to define a JavaScript theme function within a modules JavaScript file, then &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; can use it. To define a theme function simply create a new function in the Drupal theme prototype namespace like:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="javascript geshifilter-javascript" style="font-family:monospace;"&gt;Dupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;.&lt;span style="color: #660066;"&gt;prototype&lt;/span&gt;.&lt;span style="color: #660066;"&gt;displayName&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; url&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
  &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'&amp;lt;a href=&amp;quot;'&lt;/span&gt; &lt;span style="color: #339933;"&gt;+&lt;/span&gt; url &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'&amp;quot;&amp;gt;'&lt;/span&gt; &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt; &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Once this is done the function can be used like:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="javascript geshifilter-javascript" style="font-family:monospace;"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;&amp;quot;John Doe&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; url &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; display &lt;span style="color: #339933;"&gt;=&lt;/span&gt; Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'displayName'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; url&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Just like the Drupal 6 &lt;span class="geshifilter"&gt;&lt;code class="php geshifilter-php"&gt;theme&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; function usage, the arguments minus the first one are passed to the theme function itself. The first argument is the name of the function in the &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;.&lt;span style="color: #660066;"&gt;prototype&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; namespace.&lt;/p&gt;
&lt;h2&gt;Overriding Theme Functions in Themes&lt;/h2&gt;
&lt;p&gt;Not only does this system allow us to reuse theme functions as templates, it provides a mechanism for themes to override these theme functions. For example, a module defines a theme function like the one above and uses it. But, a theme wants to change the markup. The theme can define an override function like:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="javascript geshifilter-javascript" style="font-family:monospace;"&gt;Dupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;.&lt;span style="color: #660066;"&gt;displayName&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; url&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
  &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'&amp;lt;a href=&amp;quot;'&lt;/span&gt; &lt;span style="color: #339933;"&gt;+&lt;/span&gt; url &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'&amp;quot;&amp;gt;&amp;lt;em&amp;gt;'&lt;/span&gt; &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt; &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'&amp;lt;/em&amp;gt;&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This theme function has a slightly different name. &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; is the namespace instead of &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;.&lt;span style="color: #660066;"&gt;prototype&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;. The function name is the same as is the function argument signature.&lt;/p&gt;
&lt;p&gt;When &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;theme&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; sees this override function it uses it instead of the one defined by the module.&lt;/p&gt;
&lt;h2&gt;What Should Go Through Theme Functions?&lt;/h2&gt;
&lt;p&gt;The obvious answer is that all markup should go through theme functions. But, there is more to front end presentation than CSS and markup. For example, animations. It's not uncommon for JavaScript to cause something to display. What if a theme wanted that to slide in rather than just show up in the page? This is not something you can accomplish via markup and CSS changes.&lt;/p&gt;
&lt;p&gt;So, instead of thinking of these theme functions as a place for markup consider putting from end presentation in them. All of it. Drupal JavaScript theme functions are something we need to use more. It is the system we currently have and one we should embrace.&lt;/p&gt;
&lt;p&gt;For more information on the topic please see the &lt;a href="http://drupal.org/node/171213"&gt;Drupal.org handbook page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/STuYpGkees5gthdKJfiP4OpcH6I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/STuYpGkees5gthdKJfiP4OpcH6I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/STuYpGkees5gthdKJfiP4OpcH6I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/STuYpGkees5gthdKJfiP4OpcH6I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/kb_WU5qC0Ww" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/5/javascript-theme-functions-drupal#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <category domain="http://engineeredweb.com/blog/tags/javascript">JavaScript</category>
 <pubDate>Mon, 16 May 2011 11:06:28 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">101 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/5/javascript-theme-functions-drupal</feedburner:origLink></item>
<item>
 <title>Translatable Strings In Drupal JavaScript</title>
 <link>http://feedproxy.google.com/~r/EngineeredWeb/~3/-E7Obzn_-Ic/translatable-strings-drupal-javascript</link>
 <description>&lt;p&gt;&lt;a href="http://drupal.org" title="Drupal - Content Management Platform"&gt;Drupal&lt;/a&gt; is known for being highly translatable. The localization team has done a fantastic job building out tools to make Drupal translatable and it's rare to find a module that doesn't properly wrap its strings in the &lt;a href="http://api.drupal.org/t"&gt;&lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;t()&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; function or the lesser known &lt;a href="http://api.drupal.org/format_plural"&gt;&lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;format_plural()&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; function. While the Drupal community is doing fairly well on the PHP side, many people don't know there is a translation system for Drupal JavaScript as well through the use of the &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;t&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; and &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;formatPlural&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; functions.&lt;/p&gt;
&lt;!--break--&gt;&lt;!--break--&gt;&lt;h2&gt;Drupal.t()&lt;/h2&gt;
&lt;p&gt;&lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;t&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; is a counterpart to the &lt;a href="http://api.drupal.org/t"&gt;&lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;t()&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; function in PHP. Unfortunately there is no great API documentation site for the JavaScript included in Drupal. Luckily, the usage is almost identical to what we see in PHP.&lt;/p&gt;
&lt;p&gt;For example, to make a simple string translatable you could do something like:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="javascript geshifilter-javascript" style="font-family:monospace;"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; foo &lt;span style="color: #339933;"&gt;=&lt;/span&gt; Drupal.&lt;span style="color: #660066;"&gt;t&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'A translatable string.'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Passing replacements into &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;t&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; works just like the  &lt;a href="http://api.drupal.org/t"&gt;&lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;t()&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; function. The replacement keys act based on the first character of the key.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variables that start with ! will be passed in as is.&lt;/li&gt;
&lt;li&gt;When a variable begins with @ it is passed through &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;checkPlain&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;, the JavaScript counterpart to &lt;a href="http://api.drupal.org/check_plain"&gt;&lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;check_plain()&lt;/code&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Variables that start with % will be escaped and passed trough the placeholder JavaScript theme function.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="javascript geshifilter-javascript" style="font-family:monospace;"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; args &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
args&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'!url'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'http://example.com'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
args&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'%name'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'John Doe'&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; foo &lt;span style="color: #339933;"&gt;=&lt;/span&gt; Drupal.&lt;span style="color: #660066;"&gt;t&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'%name is the owner of !url'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; args&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h2&gt;Drupal.formatPlural()&lt;/h2&gt;
&lt;p&gt;Formatting plural strings is not something we often think about when it comes to translations. But, plural forms is part of translations and something we need to consider. The JavaScript counterpart to the PHP &lt;a href="http://api.drupal.org/t"&gt;&lt;span class="geshifilter"&gt;&lt;code class="text geshifilter-text"&gt;format_plural()&lt;/code&gt;&lt;/span&gt;&lt;/a&gt; function is &lt;span class="geshifilter"&gt;&lt;code class="javascript geshifilter-javascript"&gt;Drupal.&lt;span style="color: #660066;"&gt;formatPlural&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;. The API for using the function is the same. For example:&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="javascript geshifilter-javascript" style="font-family:monospace;"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; bar &lt;span style="color: #339933;"&gt;=&lt;/span&gt; Drupal.&lt;span style="color: #660066;"&gt;formatPlural&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;count&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'@name has 1 site.'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #3366CC;"&gt;'@name has @count sites.'&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'@name'&lt;/span&gt;&lt;span style="color: #339933;"&gt;:&lt;/span&gt; personName&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Drupal has the tools to make our JavaScript translatable. Lets put them to good use. For more details see the &lt;a href="http://drupal.org/node/323109"&gt;Drupal Handbook on translations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lAsH-kUxu7Mhyxg9SaL9CjSpubY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lAsH-kUxu7Mhyxg9SaL9CjSpubY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lAsH-kUxu7Mhyxg9SaL9CjSpubY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lAsH-kUxu7Mhyxg9SaL9CjSpubY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/-E7Obzn_-Ic" height="1" width="1"/&gt;</description>
 <comments>http://engineeredweb.com/blog/11/5/translatable-strings-drupal-javascript#comments</comments>
 <category domain="http://engineeredweb.com/blog/tags/drupal">Drupal</category>
 <category domain="http://engineeredweb.com/blog/tags/drupal-planet">Drupal Planet</category>
 <category domain="http://engineeredweb.com/blog/tags/javascript">JavaScript</category>
 <pubDate>Mon, 02 May 2011 02:01:50 +0000</pubDate>
 <dc:creator>Matt</dc:creator>
 <guid isPermaLink="false">100 at http://engineeredweb.com</guid>
<feedburner:origLink>http://engineeredweb.com/blog/11/5/translatable-strings-drupal-javascript</feedburner:origLink></item>
</channel>
</rss>

