<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BarneyBlog &#187; wordpress</title>
	<atom:link href="http://www.barneyb.com/barneyblog/category/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.barneyb.com/barneyblog</link>
	<description>Thoughts, rants, and even some code from the mind of Barney Boisvert.</description>
	<lastBuildDate>Mon, 02 Mar 2020 13:20:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>I&#039;m WPTouch Enabled</title>
		<link>https://www.barneyb.com/barneyblog/2010/04/07/i-am-wptouch-enabled/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/04/07/i-am-wptouch-enabled/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 23:02:45 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1470</guid>
		<description><![CDATA[Over lunch I installed the WPTouch plugin to provide a iPhone OS-like interface for those of you who want to read site on your phone but not with the full layout.Â  Mmobile devices will still see the normal layout by default; you must enable the new interface using the toggle in the footer.Â  Once toggled, [...]]]></description>
			<content:encoded><![CDATA[<p>Over lunch I installed the <a href="http://www.bravenewcode.com/products/wptouch/">WPTouch</a> plugin to provide a iPhone OS-like interface for those of you who want to read site on your phone but not with the full layout.Â  Mmobile devices will still see the normal layout by default; you must enable the new interface using the toggle in the footer.Â  Once toggled, subsequent visits will continue to use the mobile interface.Â  The plugin works by intercepting requests and completely subverting the configured theme and replacing it with a mobile-specific layout.</p>
<p>When I did the real layout for the site I considered mobile devices, picking a font size and column width that I thought reasonable to read in landscape mode on an iPhone-sized screen.Â  As well as meaning less work and providing a more consistent interface, PRE-formatted code renders without being sliced off to the right, which is a big win over the mobile interface.</p>
<p>No question, neither one is perfect, but the choice is now yours.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/04/07/i-am-wptouch-enabled/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Shortcodes in CFML</title>
		<link>https://www.barneyb.com/barneyblog/2010/03/13/wordpress-shortcodes-in-cfml/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/03/13/wordpress-shortcodes-in-cfml/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 18:27:53 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1375</guid>
		<description><![CDATA[If you've used WordPress, you may have run across shortcodes.Â  They're little directives you type into the editor box which then evaluate dynamically when the content is rendered on the outside of you site.Â  Plugins can register new shortcode handlers, which are implemented as a simple function callback.Â  It's a really simple way to expose [...]]]></description>
			<content:encoded><![CDATA[<p>If you've used WordPress, you may have run across shortcodes.Â  They're little directives you type into the editor box which then evaluate dynamically when the content is rendered on the outside of you site.Â  Plugins can register new shortcode handlers, which are implemented as a simple function callback.Â  It's a really simple way to expose psuedo-programming constructs to content authors in a safe manner (because you as the admin/developer can control which shortcodes are available), and without requiring any PHP knowledge and/or server access.</p>
<p>I needed this sort of functionality in CFML, so after playing with a few different syntaxes and parsers for them, I decided that a direct port of the WordPress shortcodes implementation was the best choice.Â  The code is pretty small (the grammar is context free and the parser is RegEx-based), and the port (including unit tests) took perhaps an hour and a half.Â  I had to roll my own <a href="http://www.barneyb.com/barneyblog/2010/03/10/rereplacecallback-udf/">REReplaceCallback UDF</a> to match one of the PHP builtins, as well as change the callback API slightly to deal with CFML idoms, but it's a pretty direct port.</p>
<p>So what can you do with shortcodes?Â  Here's a <a href="http://www.barneyb.com/r/shortcodes/">little demo</a>, both of the front side (the content) and the backside (the handlers and processing).Â  There is also a link to <a href="https://ssl.barneyb.com/svn/barneyb/shortcodes/trunk">the source</a>, of course.Â  And like all my projects, there is a <a href="http://www.barneyb.com/barneyblog/shortcodes/">project page</a> where current project information will always be available.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/03/13/wordpress-shortcodes-in-cfml/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>REReplaceCallback UDF</title>
		<link>https://www.barneyb.com/barneyblog/2010/03/10/rereplacecallback-udf/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/03/10/rereplacecallback-udf/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 08:35:35 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1333</guid>
		<description><![CDATA[If you've used pretty much any modern language, you know all about callback functions.Â  Unfortunately CFML is capable of doing it, but the language itself doesn't leverage the feature anywhere.Â  In particular, a callback for the replace operation is of great value.Â  Ben Nadel has blogged about such things a couple times, and now I'm [...]]]></description>
			<content:encoded><![CDATA[<p>If you've used pretty much any modern language, you know all about callback functions.Â  Unfortunately CFML is capable of doing it, but the language itself doesn't leverage the feature anywhere.Â  In particular, a callback for the replace operation is of great value.Â  Ben Nadel has blogged about such things a <a href="http://www.bennadel.com/blog/191-REReplace-Java-Function-Pointers-Freakin-Sexy-.htm">couple</a> <a href="http://www.bennadel.com/blog/1479-REReplace-ColdFusion-Custom-Tag-Another-Regular-Expression-Experiment.htm">times</a>, and now I'm doing the same.Â  First, here's how you use it:</p>
<pre>&lt;cfscript&gt;
string = "The catapult bifurcated the bearcat.";
fancyString = REReplaceCallback(string, "(\w*)(cat)(\w*)", doit, "all");
function doit(match) {
  if (match[2] EQ "") {
    return '#match[2]#&lt;b&gt;&lt;i&gt;#match[3]#&lt;/i&gt;&lt;/b&gt;#match[4]#';
  } else {
    return '&lt;u&gt;#match[2]#&lt;b&gt;&lt;i&gt;#match[3]#&lt;/i&gt;&lt;/b&gt;#match[4]#&lt;/u&gt;';
  }
}
&lt;/cfscript&gt;</pre>
<p>As you'd imagine, the 'doit' function is invoked for each match of the regular expression (in this case looking for a literal "cat" surrounded by any number of word characters).Â  It then does a check on match[2] (the leading word characters) to see if it's empty and then forks based on that result (either underlining or not).Â  The 'match' array, as you might surmise, contains the matched expressions.Â  The first index is the entire expression, and an additional index is added for each subexpression in the regular expression.Â  In this case, there are three subexpressions, so the 'match' array will have length <img src='http://s.wordpress.com/latex.php?latex=3%20%2B%201%20%3D%204&#038;bg=T&#038;fg=000000&#038;s=0' alt='3 + 1 = 4' title='3 + 1 = 4' class='latex' />.</p>
<p>This particular conditional can be performed without a callback.Â  Here are a pair of REReplace calls that do it:</p>
<pre>&lt;cfscript&gt;
string = "The catapult bifurcated the bearcat.";
fancyString = REReplace(string, "(\W|^)(cat)", "\1&lt;b&gt;&lt;i&gt;\2&lt;/i&gt;&lt;/b&gt;", "all");
fancyString = REReplace(fancyString, "(\w+)(cat)\w*", "&lt;u&gt;\1&lt;b&gt;&lt;i&gt;\2&lt;/i&gt;&lt;/b&gt;\3&lt;/u&gt;", "all");
&lt;/cfscript&gt;
</pre>
<p>The first one takes care of words starting with 'cat', the second words with 'cat' inside or at the end.Â  Note that this only works because the result of the first replace does NOT put word characters next to 'cat' in the replacement string.Â  If it did that, we'd be screwed, because the two replaces happen sequentially, not in parallel.</p>
<p>In this particular case, neither one of them is very readable.Â  :)Â  With a little cleanup and a well-named temp variable, I'd say the callback version has the potential to be more readable, but the pair of REReplaces is pretty much stuck as-is.Â  As things get more complicated, however, the callback approach becomes dramatically clearer.</p>
<p>The big win, of course, has nothing to do with conditional replaces.Â  Rather, it's the ability to execute arbitrary CFML code to generate the replace string <em>based on the matched string</em>.Â  Your callback can do anything you want: go hit the database, shell out to a web service, go grab a dynamically selected bean from ColdSpring and get a value from it, etc.Â  The sky's the limit.</p>
<p>Here's the REReplaceCallback UDF itself:</p>
<pre>&lt;cffunction name="REReplaceCallback" access="private" output="false" returntype="string"&gt;
  &lt;cfargument name="string" type="string" required="true" /&gt;
  &lt;cfargument name="pattern" type="string" required="true" /&gt;
  &lt;cfargument name="callback" type="any" required="true" /&gt;
  &lt;cfargument name="scope" type="string" default="one" /&gt;
  &lt;cfscript&gt;
  var start = 0;
  var match = "";
  var parts = "";
  var replace = "";
  var i = "";
  var l = "";
  while (true) {
    match = REFind(pattern, string, start, true);
    if (match.pos[1] EQ 0) {
      break;
    }
    parts = [];
    l = arrayLen(match.pos);
    for (i = 1; i LTE l; i++) {
      if (match.pos[i] EQ 0) {
        arrayAppend(parts, "");
      } else {
        arrayAppend(parts, mid(string, match.pos[i], match.len[i]));
      }
    }
    replace = callback(parts);
    start = start + len(replace);
    string = mid(string, 1, match.pos[1] - 1) &amp; replace &amp; removeChars(string, 1, match.pos[1] + match.len[1] - 1);
    if (scope EQ "one") {
      break;
    }
  }
  return string;
  &lt;/cfscript&gt;
&lt;/cffunction&gt;
</pre>
<p>Lots of stuff going on in there, but it's basically just doing a REFind with returnsubexpressions=true, ripping apart the string to pass the pieces to the callback function, and then reassembling the string afterwards.Â  It'd be trivially easy to make a REReplaceNoCaseCallback function, but I haven't done.Â  I've implemented the function with CFFUNCTION/CFARGUMENT tags so that I can have an optional fourth parameter on CF8, but the body as CFSCRIPT so that if you want to use the UDF in pure CFSCRIPT on CF9, you only have to rewrap the body (not reimplement).</p>
<p>This particular implementation differs from what you might expect in that the callback gets substrings instead of position/length tuples (i.e., the way REFind works).Â  I opted for this approach for two reasons: first it removes the need for the callback to have access to the raw string, and secondly all you do with the len/pos is rip the string apart to get the characters so why make every callback do it.</p>
<p>Why did I write this?Â  Just for fun?Â  No, not at all.Â  I needed a way of doing rich inline markup with tags that could be implemented via plugging for a project (you get one guess), and after playing with a couple formats I concluded that porting WordPress's shortcodes was as close to an optimal solution as I was going to get.Â  The shortcode implementation requires this sort of conditional replace operations, so I built this UDF.Â  If you do PHP, it's basically equivalent to preg_replace_callback but with CFML argument ordering.</p>
<p>Yes, I'll be sharing the CFC that implements shortcodes (complete with a port of the WordPress unit tests from PHPUnit to MXUnit), but not right this second.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 261px; width: 1px; height: 1px;">&lt;cffunction name="REReplaceCallback" output="false" returntype="string"&gt;<br />
&lt;cfargument name="string" type="string" required="true" /&gt;<br />
&lt;cfargument name="pattern" type="string" required="true" /&gt;<br />
&lt;cfargument name="callback" type="any" required="true" /&gt;<br />
&lt;cfargument name="scope" type="string" default="one" /&gt;<br />
&lt;cfset var start = 0 /&gt;<br />
&lt;cfset var match = "" /&gt;<br />
&lt;cfset var parts = "" /&gt;<br />
&lt;cfset var replace = "" /&gt;<br />
&lt;cfset var i = "" /&gt;<br />
&lt;cfloop condition="true"&gt;<br />
&lt;cfset match = REFind(pattern, string, start, true) /&gt;<br />
&lt;cfif match.pos[1] EQ 0&gt;<br />
&lt;cfbreak /&gt;<br />
&lt;/cfif&gt;<br />
&lt;cfset parts = [] /&gt;<br />
&lt;cfloop from="1&#8243; to="#arrayLen(match.pos)#" index="i"&gt;<br />
&lt;cfif match.pos[i] EQ 0&gt;<br />
&lt;cfset arrayAppend(parts, "") /&gt;<br />
&lt;cfelse&gt;<br />
&lt;cfset arrayAppend(parts, mid(string, match.pos[i], match.len[i])) /&gt;<br />
&lt;/cfif&gt;<br />
&lt;/cfloop&gt;<br />
&lt;cfset replace = callback(parts) /&gt;<br />
&lt;cfset start = start + len(replace) /&gt;<br />
&lt;cfset string = mid(string, 1, match.pos[1] &#8211; 1) &amp; replace &amp; removeChars(string, 1, match.pos[1] + match.len[1] &#8211; 1) /&gt;<br />
&lt;/cfloop&gt;<br />
&lt;cfreturn string /&gt;<br />
&lt;/cffunction&gt;</div>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/03/10/rereplacecallback-udf/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WordPress 3.0</title>
		<link>https://www.barneyb.com/barneyblog/2010/01/27/wordpress-30/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/01/27/wordpress-30/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 23:06:02 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1200</guid>
		<description><![CDATA[I just pulled down the latest and greatest from WordPress's SVN repository to give the new 3.0 code a whirl.Â  Specifically, I wanted to see what was happening around the WP.org and WPMU merge that is one of the big features of 3.0, since I run a bunch of WP.org blogs that I'd love to [...]]]></description>
			<content:encoded><![CDATA[<p>I just pulled down the latest and greatest from <a href="http://core.svn.wordpress.org/">WordPress's SVN repository</a> to give the new 3.0 code a whirl.Â  Specifically, I wanted to see what was happening around the WP.org and WPMU merge that is one of the big features of 3.0, since I run a bunch of WP.org blogs that I'd love to have multihosted, and at work we run an WPMU installation and are in the works of three more.Â  Having a single way to do everything is quite compelling, especially if there's a way to transparently "upgrade" from a standalone site to a multihosted one.</p>
<p>I was initially disappointed when I looked at the source, because the MU bits seemed to be missing, but a little more digging showed telltale signs that it was at least partially integrated.Â  After setting up the installation, I found a mysterious "Network" option in my "Tools" menu, clicked it, and was presented with basically the MU installer UI.Â  Sweet!</p>
<p>Submitting that resulted in a page with three simple instructions: create the blogs.dir directory, install this new wp-config.php script (in a TEXTAREA), and update .htaccess with this new config (also in a TEXTAREA).Â  My suspicion is that if PHP had write access it would've done all three automatically.</p>
<p>After following instructions and clearing my cookies (not explicitly mentioned), I had a fully functional multihosted WordPress install with the normal MU site administrator menu and everything.Â  This is awesome.Â  And just in case that was unclear, it's awesome.Â  The database, of course, was refactored behind the scenes.Â  Unfortunately it still uses the tableset-per-blog paradigm (just minus the "_1&#8243; infix for the root blog) rather than a single tableset with foreign keys, but there's no way they could change that without having all kinds of upgrade issues for existing WPMU installations.</p>
<p>There are still a pile of things to update (like the per-blog permalink config shouldn't attempt to write .htaccess) to get the WP.org functionality to morph into the WPMU functionality, but for the "normal" authoring tasks it appears to be as solid as ever.Â  I suspect a careful administrator could, with a bit of patience, produce a security setup that would let authors have the run of their site without breaking anything even before the actual restrictions are put in place by Automattic.</p>
<p>In any case, very exciting to see this integration project already so far along.Â  WordPress.org says 3.0 is slated for March, which is crazy soon, but I'm all for it.Â  I've been waiting to upgrade a pile of WP.org blogs to a WPMU instance for a while now, and this is going to make it much easier.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/01/27/wordpress-30/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>NaturallyCarolicious.com Is Live</title>
		<link>https://www.barneyb.com/barneyblog/2009/05/11/naturallycaroliciouscom-is-live/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/05/11/naturallycaroliciouscom-is-live/#comments</comments>
		<pubDate>Mon, 11 May 2009 23:11:11 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[personal]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=908</guid>
		<description><![CDATA[One of my WordPress projects was helping a friend move her blog from TypePad over to a self-hosted WordPress with a shiny new domain name: naturallycarolicious.com.Â  As of today she's made the official "welcome" post, and the new site is running like a champ.Â  She's still some design stuff, but that's just icing on the [...]]]></description>
			<content:encoded><![CDATA[<p>One of my WordPress projects was helping a friend move her blog from TypePad over to a self-hosted <a href="http://www.wordpress.org/">WordPress</a> with a shiny new domain name: <a href="http://www.naturallycarolicious.com/">naturallycarolicious.com</a>.Â  As of today she's made the official "welcome" post, and the new site is running like a champ.Â  She's still some design stuff, but that's just icing on the cake.</p>
<p>Biggest problem was that she was using a TypePad subdomain instead of a custom domain, which precluded any sort of transparent switch-over via DNS.Â  TypePad also doesn't have a half-way between drag'n'drop themes and roll-your-own, which meant that changing the site header to include a redirect was out.Â  So I had to resort to JS, which is hardly elegant, but it works well enough.Â  I was really hoping for .htaccess support, but pushing one up there had no effect, so they don't have it enabled in their Apache (or whatever) config.Â  Oh well.Â  Unfortunately this means search engines have to organically rebuild their indexes (since I can't give them a 301), but a robots.txt will at least ensure the old stuff drops out.</p>
<p>Once all that was sorted, however, things went pretty smoothly.Â  Found a great <a href="http://urbangiraffe.com/plugins/search-regex/">WordPress plugin for doing search and replace</a> within your content, which made updating internal links a breeze.Â  It also happens to output search results in a fashion that was really easy to rip with jQuery into a list of files (pics, movies, etc) to grab with wget and then bulk upload into WordPress.Â  And let me tell you, bulk uploading into WordPress is kickass; Flash for the win!</p>
<p>Did a little minor theme work, changed permalinks to only use year/month/slug (to match TypePad), and that's about it.Â  Smooth as butter.</p>
<p>Welcome home, Carole.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/05/11/naturallycaroliciouscom-is-live/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What the Hell is Wrong With Me?</title>
		<link>https://www.barneyb.com/barneyblog/2009/05/07/what-the-hell-is-wrong-with-me/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/05/07/what-the-hell-is-wrong-with-me/#comments</comments>
		<pubDate>Fri, 08 May 2009 05:21:18 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=903</guid>
		<description><![CDATA[For the past month or so I've written more PHP than every other language combined.Â  That's including English.Â  Really.Â  Four separate WordPress projects (two standalone, two MU), one of which is a blogging platform for Mentor Graphics, and I'm up to my neck.Â  I'm a CFML developer by profession; I think I got off at [...]]]></description>
			<content:encoded><![CDATA[<p>For the past month or so I've written more PHP than every other language combined.Â  That's including English.Â  Really.Â  Four separate WordPress projects (two standalone, two MU), one of which is a blogging platform for Mentor Graphics, and I'm up to my neck.Â  I'm a CFML developer by profession; I think I got off at the wrong stop.</p>
<p>What I have learned?</p>
<ol>
<li>PHP's function libraries are insane.Â  I thought ColdFusion's (now CFML's) libraries had plenty of wonkiness, but PHP makes them look like the friggin' Pope.Â  Latest example: there is a 'sort' function that sorts an array.Â  It has an optional second parameter for controlling the type of sort.Â  But it's a whole separate function with identical parameters (called 'rsort') to sort descending.Â  Where's the optional third parameter for direction?Â  Or how implode accepts arguments in either order, but explode (it's inverse) does not.</li>
<li>Dollar signs are harder to type than hashes.Â  Not sure why, especially with my big hands, but whatever.</li>
<li>PHP's operators are lunacy.Â  Arrays are declared with "=&gt;" for keys, by dereferenced with "['key']" syntax.Â  Object members are accessed with the "-&gt;" operator, and "." is for string concatenation.Â  And you can't combine the middle two in arbitrary ways (though some ways do work).</li>
<li>WordPress was designed by really smart people.Â  A little too smart, I think.Â  And even aside from the choice of language, the code style confirms without a doubt that they're PHP developers to the bone.</li>
<li>Implicit invocation is great, but while it fosters decoupling, overuse can create a developer's nightmare.Â  With too much indirection the code can't be easily read, so you have to simply memorize huge amounts of information in order to effectively work on an application.</li>
</ol>
<p>Now before you go assuming I'm a PHP hater&#8230;</p>
<ol>
<li>I largely put myself in this situation.Â  I was in charge of selecting WordPress MU for Mentor's infrastructure, knowing I was brining PHP into an 85% CFML / 10% Groovy / 5% Java shop.Â  Five people (of nine) on the team swear by it for our personal blogs, though I was the only one with any substantial experience hacking the engine itself.Â  Despite initial reservations from the boss, and others (including myself), time has shown that it was clearly a good choice.</li>
<li>PHP is friggin' fast.Â  Dear god is it fast.Â  With no concept of in-memory sharing across requests, everything has to reload on every request and it still <em>screams</em>.</li>
<li>WordPress is a really flexible platform.Â  It's provides a solid foundation, a kickass application framework built atop it, and a great blogging engine on top of that.Â  And if you get the right theme(s), you've got presentation and CSS as well.Â  It's not a CMS out of the box, but for what it's designed to do it's fantastic.</li>
<li>PHP's function types and higher order functions are kind of a mess, but at least they have them, and they support object methods.Â  You wouldn't believe how often this bites me in CFML.</li>
</ol>
<p>Am I gonna drop CFML for PHP?Â  Hell no.Â  But despite PHP's and WordPress's warts, there's a lot of stuff worth of emulation.Â  Definitely reenforced my belief that CFML is an inherently iffy language for "down-n-dirty" development, even though it excels at templating and simplifying complex tasks.</p>
<p>On the surface, CFML is no where near as warty as PHP, but looking deeper and the story isn't so clear.Â  It seems like every couple weeks I discover or learn about some utterly bizarre behaviour that ColdFusion exhibits, and unlike PHP's weird function libraries, they're internal weirdnesses.Â  Functions can be stupid, but at least they're in your face.Â  You get a hard fail if you type one wrong.</p>
<p>Long post, and again, no real point.Â  Whatever.Â  It's Thursday, and better for my liver than drinking.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/05/07/what-the-hell-is-wrong-with-me/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress MU &#8211; No Longer a Bare-Domain Nazi</title>
		<link>https://www.barneyb.com/barneyblog/2009/05/04/wordpress-mu-no-longer-a-bare-domain-nazi/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/05/04/wordpress-mu-no-longer-a-bare-domain-nazi/#comments</comments>
		<pubDate>Tue, 05 May 2009 04:28:56 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=896</guid>
		<description><![CDATA[A week or three ago I learned that WordPress MU was explicitly coded to refuse to run on a 'www' subdomain, instead forcing you to run it on the bare domain.Â  While running your website on the bare domain is certainly a reasonable thing to do, forcing users of your software to do it seemed, [...]]]></description>
			<content:encoded><![CDATA[<p>A week or three ago I learned that <a href="http://www.barneyb.com/barneyblog/2009/04/17/screw-you-wordpress/">WordPress MU was explicitly coded to refuse to run on a 'www' subdomain</a>, instead forcing you to run it on the bare domain.Â  While running your website on the bare domain is certainly a reasonable thing to do, forcing users of your software to do it seemed, well, idiotic.Â  I happen to think that the 'www' subdomain is the proper place to run your website, though since the bare domain is widely used, I ensure that if you visit 'barneyb.com' you'll have exactly the same experience as if you visit 'www.barneyb.com'.</p>
<p>Being the good (if opinionated and occasionally obnoxious) open source aficionado that I am, after my initial reaction of outrage, I've revisted the issue and "fixed" the problem.Â  Aside from the install script (index-install.php), there was only one place that needed changing (in wpmu-settings.php).Â  The patch is below, made against WordPress mU 2.7.1:</p>
<pre>Index: index-install.php
===================================================================
--- index-install.php   (revision 5342)
+++ index-install.php   (revision 5343)
@@ -362,8 +362,6 @@
        $weblog_title = ucfirst( $_SERVER[ 'HTTP_HOST' ] ) . ' Blogs';
        $email = '';
        $hostname = $_SERVER[ 'HTTP_HOST' ];
-       if( substr( $_SERVER[ 'HTTP_HOST' ], 0, 4 ) == 'www.' )
-               $hostname = str_replace( "www.", "", $_SERVER[ 'HTTP_HOST' ] );
        ?&gt;
        &lt;form method='post' action='index.php'&gt;
                &lt;input type='hidden' name='action' value='step2' /&gt;
@@ -511,8 +509,6 @@
        global $wpdb;
        $domain =   $wpdb-&gt;escape( $_POST[ 'basedomain' ] );
        $domain = str_replace( 'http://', '', $domain );
-       if( substr( $domain, 0, 4 ) == 'www.' )
-               $domain = substr( $domain, 4 );
        if( strpos( $domain, '/' ) )
                $domain = substr( $domain, 0, strpos( $domain, '/' ) );
        return $domain;
@@ -649,12 +645,6 @@
 $action = isset($_POST[ 'action' ]) ? $_POST[ 'action' ] : null;
 switch($action) {
        case "step2":
-               if( substr( $_POST[ 'basedomain' ], 0, 4 ) == 'www.' ) {
-                       printheader();
-                       nowww();
-                       continue;
-               }
-
                // get blog username, create wp-config.php
                step2();

@@ -662,7 +652,6 @@
                include_once('./wp-config.php');
                include_once('./wp-admin/includes/upgrade.php');

-               $_SERVER[ 'HTTP_HOST' ] = str_replace( 'www.', '', $_SERVER[ 'HTTP_HOST' ] ); // normalise hostname - no www.
                make_db_current_silent();
                populate_options();
                global $base;
Index: wpmu-settings.php
===================================================================
--- wpmu-settings.php   (revision 5342)
+++ wpmu-settings.php   (revision 5343)
@@ -6,8 +6,6 @@
 $wpmuBaseTablePrefix = $table_prefix;

 $domain = addslashes( $_SERVER['HTTP_HOST'] );
-if( substr( $domain, 0, 4 ) == 'www.' )
-       $domain = substr( $domain, 4 );
 if( strpos( $domain, ':' ) ) {
        if( substr( $domain, -3 ) == ':80' ) {
                $domain = substr( $domain, 0, -3 );</pre>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/05/04/wordpress-mu-no-longer-a-bare-domain-nazi/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unindex Search Plugin</title>
		<link>https://www.barneyb.com/barneyblog/2009/04/22/unindex-search-plugin/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/04/22/unindex-search-plugin/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 19:54:24 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=864</guid>
		<description><![CDATA[Even though I use Google Custom Search for my blog, I get a lot of WordPress's internal search results pages indexed by robots.Â  Didn't want that to happen anymore, so I wrote a simple plugin to address the issue.Â  Maybe someone will find it useful:
&#60;?php
/*
Plugin Name: Unindex Search
Plugin URI: http://www.barneyb.com/
Description: Addes a NOINDEX meta tag [...]]]></description>
			<content:encoded><![CDATA[<p>Even though I use Google Custom Search for my blog, I get a lot of WordPress's internal search results pages indexed by robots.Â  Didn't want that to happen anymore, so I wrote a simple plugin to address the issue.Â  Maybe someone will find it useful:</p>
<pre>&lt;?php
/*
Plugin Name: Unindex Search
Plugin URI: http://www.barneyb.com/
Description: Addes a NOINDEX meta tag for search result pages
Author: Barney Boisvert
Version: 0.1
*/
add_action('wp_head', 'unindexsearch_head');
function unindexsearch_head() {
  if (is_search()) {
    ?&gt;&lt;meta name="robots" content="NOINDEX" /&gt;
    &lt;?php
  }
}
?&gt;</pre>
<p>Simply checks if it's a search page and if so writes out the META tag.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/04/22/unindex-search-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Æ’ÂµÂ©Òœ You WordPress</title>
		<link>https://www.barneyb.com/barneyblog/2009/04/17/screw-you-wordpress/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/04/17/screw-you-wordpress/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 03:42:54 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=848</guid>
		<description><![CDATA[In my WordPress MU migration, I made the delightful discovery that it will not serve on a 'www' subdomain. Â Period. Â It will answer, but it will never regard a 'www' subdomain as canonical, and always assume the bare domain is the right spot to serve from.
Fuck You, WordPress.
While I certainly agree that the behaviour of [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://mu.wordpress.org/">WordPress MU</a> migration, I made the delightful discovery that it <strong>will not</strong> serve on a 'www' subdomain. Â Period. Â It will answer, but it will never regard a 'www' subdomain as canonical, and always assume the bare domain is the right spot to serve from.</p>
<p>Fuck You, WordPress.</p>
<p>While I certainly agree that the behaviour of typing '<a href="http://www.barneyb.com/">www.barneyb.com</a>' and '<a href="http://barneyb.com/">barneyb.com</a>' into a browser should be the same in nearly all cases (and it is in mine), using the bare domain as the canonical name is absurd. Â If I'm hitting a website, it's canonical address should be the 'www' subdomain. Â Exactly the same as every other protocol significant enough to warrant a globally accepted "standard" subdomain. Â Setting up the bare domain to forward to the proper canonical subdomain is good manners, but the bare domain is <strong>not</strong> the web host.</p>
<p>WordPress MU, on the other hand, <em>requires</em> exactly the opposite.</p>
<p>My web site is located at <a href="http://www.barneyb.com/">www.barneyb.com</a>. Â Period. Â End of story. Â If you're lazy and type in '<a href="http://barneyb.com/">barneyb.com</a>', it'll happily forward you to the right location, because I'm a courteous administrator, but you'll not stay on '<a href="http://barneyb.com/">barneyb.com</a>'. Â I'm lazy in most of my one-off demo apps and don't enforce canonicalization, so in those cases you can see either one in the address bar, but for my "official" web presence it's <a href="http://www.barneyb.com/">www.barneyb.com</a> and only <a href="http://www.barneyb.com/">www.barneyb.com</a>.</p>
<p>Perhaps worth mentioning is that my OpenID lives at <a href="http://barneyb.com/">http://barneyb.com/</a>;Â it does <strong>not</strong> live at <a href="http://www.barneyb.com/">http://www.barneyb.com/</a>. Â Why? Â Because while OpenID is HTTP-based, it's not part of my web site, and so doesn't belong on the 'www' subdomain.</p>
<p>I also split my HTTPS traffic to a separate subdomain (<a href="http://ssl.barneyb.com/">ssl.barneyb.com</a>), though if you go there you'll be redirected back to <a href="http://www.barneyb.com/">www.barneyb.com</a> unless you enter a specific application's path. Â All those applications are not part of my "official" website; they're things like EventLog, Pic of the Day, timecard/invoicing, financial tracking, etc.</p>
<p>I'm going to intentionallyÂ not Â dwell on this any more this evening. Â My gut reaction is to say "you're stupid, I'm not going to use you" and stick to my Ant-based solution. Â I'm not sure a bit of time to "cool down" will change that decision, but I'm going to give WPMU the benefit of the doubt and delay the decision until I'm not quite as pissed off. Â It doesn't deserve it (software is supposed to serve the user, not the other way around), but I'm a courteous administrator after all.</p>
<p><strong>Update (2009-05-04):</strong> I've come back and <a href="http://www.barneyb.com/barneyblog/2009/05/04/wordpress-mu-no-longer-a-bare-domain-nazi/">patched WordPress MU to allow the use of a 'www' subdomain</a>.Â  Hopefully the change will eventually make it back to the main codebase, but I'm not holding my breath.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/04/17/screw-you-wordpress/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Server Stories</title>
		<link>https://www.barneyb.com/barneyblog/2009/04/16/server-stories/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/04/16/server-stories/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 06:19:54 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=844</guid>
		<description><![CDATA[Got a whole bunch of work done on my new box this evening.Â  Still lots to do, but well on my way.Â  Pluggable on-box backups for MySQL, pluggable S3 backups for arbitrary files, a WordPress MU skeleton, a few Tomcats, base HTTPD config, even a ColdFusion instance.Â  Unfortunately, the majority of my stuff runs on [...]]]></description>
			<content:encoded><![CDATA[<p>Got a whole bunch of work done on my new box this evening.Â  Still lots to do, but well on my way.Â  Pluggable on-box backups for MySQL, pluggable S3 backups for arbitrary files, a WordPress MU skeleton, a few Tomcats, base HTTPD config, even a ColdFusion instance.Â  Unfortunately, the majority of my stuff runs on either www.barneyb.com or ssl.barneyb.com, which means moving those domains is an all-or-nothing arrangement.Â  It'll be a while before those move, but I did move one site (a nearly codeless Magnolia-managed site) over to the new box, so it's not a complete deadweight.</p>
<p>The WordPress stuff is going to be the biggest mess, I think.Â  I've been running a home-grown multiblogging app based on WordPress for the past several years and I'm doing away with it.Â  It's built with Ant and while you treat it as a single copy of the code, in reality you end up with a separate WordPress installation for each blog (with appropriate customizations, themes, etc.).Â  It gets the job done, but it's rather of cumbersome in various ways (no shared users, can't serve from a working copy, complex directory structure, etc.), so I'm going to bite the bullet and "upgrade" to MU.Â  Should make my life enormously easier in the long run, but in the short term I'm going to have to do some pretty invasive surgery to some plugins I cut corners on when I wrote them originally.Â  Also going to have to figure out how to migrate all the data into the slightly different MU schema.</p>
<p>Second to that will be Pic of the Day, simply because it has so many moving pieces, but I've done a lot of organizational work on it over the past year so it'll be a lot easier now than it would have been last summer when I was considering migrating to a new box.Â  I was hoping to switch to Railo to get it in an isolated JVM, but there are some issues preventing that, both with Railo and my code.Â  I don't have the RAM to run multiple copies of ColdFusion, nor the money to buy more, so it'll stay on a shared instance for now.Â  Fortunately, despite the fact that it's constantly churning it's gears, most of it can be taken offline for a day or three with no user-visible effect.Â  The user-visible portion of the app is a very narrow slice of the whole picture.</p>
<p>Finally, I'm trying <em>really</em> hard to ditch JRun for Tomcat everywhere.Â  The JRun connector is truly amazing in how it lets you virtualize your webroot, so it's not easy.Â  However, now that I've got Apache 2.2, I can bring mod_proxy_ajp and mod_rewrite to bear and hopefully get equivalent functionality.Â  I'm willing to sacrifice little bit of filesystem cleanliness for having a single web container for all my sites, but not much.Â  Fortunately, that's something I should be able to continuously refine and optimize over time, even after stuff is live.</p>
<p>I'm hoping to be all moved over within the month.Â  Long time, I know, but there's a lot of stuff to do, and this isÂ  a "free time" project.Â  With the inability to effectively test and migrate individual pieces, I have to be really careful and that always takes longer.Â  Wish me luck!</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/04/16/server-stories/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
