<?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>Cloud Four &#187; Blogs and Social Media</title>
	<atom:link href="http://www.cloudfour.com/category/blogs-and-social-media/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cloudfour.com</link>
	<description>Expert Web and Mobile Design, Development and Strategy</description>
	<lastBuildDate>Tue, 31 Jan 2012 17:22:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>You Received a Hookup Badge: Why I Deleted My Foursquare Account</title>
		<link>http://www.cloudfour.com/you-received-a-hookup-badge-why-i-deleted-my-foursquare-account/</link>
		<comments>http://www.cloudfour.com/you-received-a-hookup-badge-why-i-deleted-my-foursquare-account/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 19:28:31 +0000</pubDate>
		<dc:creator>Jason Grigsby</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Emerging Technology]]></category>
		<category><![CDATA[foursquare]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=833</guid>
		<description><![CDATA[One of the recurring subjects of conversation at SXSW was the many competing location services. Attendees were using Foursquare and Gowalla extensively during the conference to help find their friends. I decided to give them a try during the conference. That is until Foursquare decided to give me a &#8220;Hookup Badge.&#8221; Apparently, the Hookup Badge [...]]]></description>
			<content:encoded><![CDATA[<p>One of the recurring subjects of conversation at SXSW was the many competing location services. Attendees were using Foursquare and Gowalla extensively during the conference to help find their friends.</p>
<p><img src="http://www.cloudfour.com/wp-content/uploads/2010/03/hookup.png" style="float:right;margin:0 0 10px 10px;" alt="Fourquare's Hookup Badge" />I decided to give them a try during the conference. That is until Foursquare decided to give me a &#8220;Hookup Badge.&#8221;</p>
<p>Apparently, the Hookup Badge is given to someone who checks in at two different hotels.</p>
<p>For anyone visiting Austin who doesn&#8217;t stay at the historic Driskill Hotel, there is a good chance you&#8217;re going to check in at two hotels during your trip. The Driskill is a must see and you will likely check in at the hotel you&#8217;re staying at.</p>
<p>That is what happened to me.</p>
<p>I checked in at the Driscoll Hotel when I met friends there. I purposely asked Foursquare not to tweet the check in because I feel like it is spam in my Twitter stream.</p>
<p>However, I didn&#8217;t remember that I had allowed Foursquare to post updates about badges that I won. Foursquare didn&#8217;t tweet the check in, but it did tweet about my &#8220;Hookup Badge.&#8221;</p>
<p>So part of the blame is mine. I shouldn&#8217;t have let Foursquare post to Twitter at all.</p>
<p>At the same time, I had no expectations that Foursquare would be posting inappropriate tweets. I&#8217;m a happily married man. Joking about hooking up while I&#8217;m on business travel is not funny.</p>
<p>Thankfully the damage was limited. A few months ago I disconnected Twitter from Facebook. Otherwise, my new &#8220;Hookup Badge&#8221; would have been shared with family members who would have no idea what Foursquare is nor understand Foursquare&#8217;s idea of a &#8220;funny&#8221; badge.</p>
<p>When I relayed this story with <a href="http://twitter/petegreen2">Péter Green</a> of Finnish Mobile Association, he told me how he had received the &#8220;Hangover Badge,&#8221; and received many comments from his friends back home.</p>
<p>Those comments were funny, but imagine how quickly they would have turned into concerned or panic if the Hangover Badge was handed out to a recovering alcoholic who was half a world away.</p>
<p>I like the idea of gaming mechanics to get people to participate in a location-based service, but Foursquare seems to be making some big mistakes here:</p>
<ul>
<li>The incentive structure in the game should be known instead of a surprise. For example, if you check-in more times than another person, you become mayor. That&#8217;s well known and easy to understand. The Hookup and Hangover badges use rule combinations that you don&#8217;t known until you unwittingly unlock a badge.</li>
<li>The badges indicate a lack of perspective on what issues they may cause for the people who receive them.</li>
<li>The overall impression of the service based on these badges is one that is designed for party-going twenty-somethings. It&#8217;s hard to take such a service seriously.</li>
</ul>
<p>We&#8217;ve heard a lot about location-based services and cell phone logs getting people in trouble for their infidelity. There&#8217;s no need for services like Foursquare to create problems where none exist.</p>
<p>As far as I&#8217;m concerned, this was inexcusable breach of trust. I deleted my Foursquare account and will not use their service again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/you-received-a-hookup-badge-why-i-deleted-my-foursquare-account/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Who Owns Your Retweet?</title>
		<link>http://www.cloudfour.com/who-owns-your-retweet/</link>
		<comments>http://www.cloudfour.com/who-owns-your-retweet/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 03:10:43 +0000</pubDate>
		<dc:creator>Jason Grigsby</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Emerging Technology]]></category>
		<category><![CDATA[retweet]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=719</guid>
		<description><![CDATA[When you retweet something, do you expect someone else to be able to delete it? Previously, if you retweeted something, your retweet was your own. Only you had the ability to delete it. But with Twitter&#8217;s new retweet feature, your retweet is tied to the original author&#8217;s tweet. And if the original author deletes the [...]]]></description>
			<content:encoded><![CDATA[<p>When you retweet something, do you expect someone else to be able to delete it?</p>
<p>Previously, if you retweeted something, your retweet was your own. Only you had the ability to delete it.</p>
<p>But with Twitter&#8217;s <a href="http://www.cloudfour.com/676/twitters-new-retweet-is-broken-and-how-to-fix-it/">new retweet feature</a>, your retweet is tied to the original author&#8217;s tweet. And <strong>if the original author deletes the tweet, your retweet is deleted from your timeline</strong>. </p>
<p>I&#8217;m not sure what the proper way to handle this is. </p>
<p>On the one hand, if the original author shared something they wished to retract, it would be nice to honor that. </p>
<p>On the other hand, the tweet didn&#8217;t happen in a vacuum. More importantly, the act of retweeting should be tied to the timeline of the person who retweeted it. Someone else shouldn&#8217;t be able to scrub that history.</p>
<p>What do you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/who-owns-your-retweet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter&#8217;s New Retweet is Broken and How to Fix it</title>
		<link>http://www.cloudfour.com/twitters-new-retweet-is-broken-and-how-to-fix-it/</link>
		<comments>http://www.cloudfour.com/twitters-new-retweet-is-broken-and-how-to-fix-it/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 16:57:27 +0000</pubDate>
		<dc:creator>Jason Grigsby</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Emerging Technology]]></category>
		<category><![CDATA[Mobile Web and Services]]></category>
		<category><![CDATA[retweets]]></category>
		<category><![CDATA[tweetie]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=676</guid>
		<description><![CDATA[When Twitter announced their new retweet feature, I read Twitter founder Ev William&#8217;s reasons for the design of the new feature with interest. I understood his points. I didn&#8217;t agree with the solution, but was comforted by his closing note that &#8220;there&#8217;s nothing stopping you from simply quoting another tweet if that&#8217;s what you want [...]]]></description>
			<content:encoded><![CDATA[<p>When Twitter announced their new retweet feature, I read Twitter founder <a href="http://evhead.com/2009/11/why-retweet-works-way-it-does.html">Ev William&#8217;s reasons for the design of the new feature</a> with interest. I understood his points. I didn&#8217;t agree with the solution, but was comforted by his closing note that &#8220;there&#8217;s nothing stopping you from simply quoting another tweet if that&#8217;s what you want to do. Also, old-school retweets are still allowed, as well.&#8221;</p>
<p>My plan was simply to ignore the new retweet feature until they fixed its shortcomings. However, <a href="http://twitter.com/atebits/">Loren Brichter</a> released a new version of my favorite Twitter client for the iPhone, <a href="http://www.atebits.com/tweetie-iphone/">Tweetie</a>, that incorporates the new retweet feature and <a href="http://twitter.com/tweetie/status/6182598734">&#8220;deprecates&#8221; the old way of retweeting</a>.</p>
<p>After spending some time with the new version of Tweetie, it became clear that the new retweet feature and all of its warts are here to stay. Instead of ignoring it, it was more important to document the ways it is broken and try to get Twitter and the developers of Twitter clients to fix it.</p>
<h3>What Ev Got Wrong</h3>
<p>Ev&#8217;s post does an excellent job of outlining the <a href="http://evhead.com/2009/11/why-retweet-works-way-it-does.html">perceived shortcomings of the old way of retweeting</a>. I&#8217;m grateful for his explanation. Not only is it helpful to understand the design decisions they made, but it also helps me understand where Ev missed important uses of retweets.</p>
<h4>Attribution Confusion vs. Credibility and Reputation</h4>
<p>One of the main things that Twitter was trying to solve with the new retweet feature is attribution confusion. &#8220;Most notably, the text of the tweet is not written by the person whose picture you&#8217;re seeing, nor the username that&#8217;s at the beginning.&#8221;</p>
<p>The solution to this in the new retweet feature is to show the name and picture of the original person who wrote the tweet and annotate below the tweet the name of the person you are following who retweeted the post.</p>
<p><img src="http://www.cloudfour.com/wp-content/uploads/2009/12/twitter-new-retweet-format.png" style="width:484px;height:95px;border:0;margin-left:auto;margin-right:auto;" /></p>
<p>The problem with this solution to attribution confusion is that it eliminates one of the main values of retweets: the credibility and reputation of the person who is retweeting.</p>
<p>By removing the picture of the person who retweeted and making the name much smaller, it becomes much harder to tell quickly which of the people you are following retweeted the post. </p>
<p>The person who retweeted a link to an article matters a lot. We place different value on the people we follow and the information they share. </p>
<p>In the example above, it is more important to me to know that <a href="http://twitter.com/davewiner">Dave Winer</a> was the source of the retweet than it is to know that jenny8lee—someone I don&#8217;t know—wrote the original tweet.</p>
<p><a href="http://twitter.com/timoreilly">Tim O&#8217;Reilly</a> is someone who I find to have very intelligent takes on technology. When I see his picture in my twitter stream, I stop scanning and pay closer attention. His <strong>credibility and reputation</strong> is what makes me pay attention to what he tweets or retweets.</p>
<p>This is something that the independent Twitter clients have done a better job of addressing than Twitter itself. Both Tweetie and <a href="http://www.tweetdeck.com/">Tweetdeck</a> have included both the picture of the person who originated the tweet as well as the person who retweeted.</p>
<p style="text-align:center;"><img src="http://www.cloudfour.com/wp-content/uploads/2009/12/tweetie-retweet.jpg" style="width:320px;height:101px;border:0;" /></p>
<p>I much prefer the way Tweetie handles the retweet in the screenshot above to the way Twitter handles it. I see both Dave Winer&#8217;s name and picture. My only complaint is that the picture of the person retweeting is often too small to recognize quickly.</p>
<h4>Redundancy vs. Dipping in the Stream</h4>
<p>Another point that Ev makes is that &#8220;if five people you follow retweet the same thing, you get five copies, which can be useful but is a lot of noise.&#8221;</p>
<p>Ev is right that if you are reading every single tweet having redundant retweets can be a bit of noise. That said, it isn&#8217;t something that has ever bothered me.</p>
<p>The multiple retweets has however been something that has alerted me to important information. When you think of Twitter as a stream that you dip your toes into when you have time, important information can be missed if it only shows up in your stream one time. However, the more people retweet it, the more likely you are to encounter it whenever you decide to dip your toes in your Twitter stream.</p>
<p>I have to look no further than this past weekend to see the importance of this. On Saturday, the City of Portland announced that <a href="http://www.oregonlive.com/politics/index.ssf/2009/11/water_bureau_issues_boil_water.html">e-coli had been found in some of its water supply</a>.</p>
<p>I happened to be out with the family in one of the affected areas. While waiting in line, I checked Twitter. By the time I checked, it had been several hours since the announcement. Yet, I saw one of the many retweets about the outbreak and was able to advise the people around me what water to avoid.</p>
<p>Let me repeat, the <strong>only reason I learned about the e-coli outbreak was because I received multiple retweets</strong>. </p>
<p>Another reason multiple retweets are valuable is because of reputation and credibility. A retweet from someone I follow whose opinion I value more highly than others is more likely to catch my eye.</p>
<p>There is value in multiple retweets. I&#8217;d love to have this be an option to see all retweets or only the first one.</p>
<h3>Problems with the Current Implementations</h3>
<p>Aside from the two viewpoints about credibility and the value of multiple retweets, there are things lacking in the current retweet implementations. As my friend Peter Whooly pointed out, <a href="http://twitter.com/peterwooley/status/6206404620">it&#8217;s hard to tell if these are problems with the Twitter clients or Twitter&#8217;s API</a>.</p>
<h4>No Way to See Who Has Retweeted Your Tweets</h4>
<p>In Tweetie, when you go under your profile and look at the retweets, there is no way to tell who retweeted your tweet. This is possible on Twitter&#8217;s web interface.</p>
<h4>No Notification of Retweets</h4>
<p>One of the nice aspects of the old style of retweeting was that retweets also contained the @reply syntax. This meant that you could not only could see the retweets easily, but if your Twitter client offered notifications for replies, you would be prompted when someone retweeted you.</p>
<p>Knowing when someone retweets you is important so that you can participate in the conversation.</p>
<h4>Retweets Don&#8217;t Show Up in Lists</h4>
<p>This again is an issue of credibility and reputation. Say you create a list of people whose opinions and thoughts you highly value. It is a very select list and you read every tweet these people write. When you look at that list, you will miss any retweets using the new feature.</p>
<p>Being able to see retweets in Twitter lists is a big deal.</p>
<h4>Ability to Annotate Retweets</h4>
<p>This is already on the Twitter team&#8217;s radar. Ev says they have some ideas on how they might implement it. This isn&#8217;t a show stopper for me, but it is for a lot of other people.</p>
<h3>Vocal Minority or Silent Majority?</h3>
<p>One of the things that got me worked up about this was seeing Loren Brichter&#8217;s take on the new retweet feature. He said, &#8220;<a href="http://twitter.com/atebits/status/6183141704">vocal minority have problem with change &#8211; no doubt once they try it they&#8217;ll realize how awesome it is</a>.&#8221;</p>
<p>Because Loren is the developer of Tweetie, the iPhone client I prefer to use, his opinion about the retweet feature matters. The fact that he thinks that:</p>
<ol>
<li>it is only a vocal minority that has problems with it and
<li>that we simply have a problem with change</li>
</ol>
<p>frustrated me. From the conversations I&#8217;ve had with other users, that isn&#8217;t an accurate description.</p>
<p>Many of the same people who have problems with the new retweet feature embraced the new lists feature. Discounting opinions by saying people simply have a problem with change is a way of marginalizing contrary opinions without having to address them. There are legitimate issues with the retweet feature as I&#8217;ve outlined above.</p>
<p>And I&#8217;m not convinced that it is a minority of people who have problems with the new retweet feature. So far, I haven&#8217;t seen a single person who thinks the new retweet feature is complete.</p>
<p>Unlike lists which a majority of people raved about and immediately started using, the new retweet feature is something that most people seem to be at best accepting with hopes that Twitter will address its issues and at worst, so strongly opposed to the new feature that they are taking actions like <a href="http://twitter.com/betsywhim/status/6191434706">refusing to upgrade Tweetie to avoid it</a>.</p>
<h3>How to Fix Retweets</h3>
<p>I don&#8217;t disagree with most of what Ev said were the reasons for the new retweet feature. I also think formalizing retweets can lead to some really interesting information and features. </p>
<p>That said, the new feature has significant shortcomings that need to be addressed before we should consider the old way of retweeting deprecated. </p>
<p>I&#8217;m thankful that Loren implemented the new feature in Tweetie. It made me recognize that the feature wasn&#8217;t going away and was already impacting me even if I choose to use the old style retweet because others may use the new feature and I won&#8217;t see their retweets.</p>
<p>Therefore, the most important thing we can do to fix the situation is provide feedback to Twitter and Twitter client developers.</p>
<p>My hope is that if enough people provide feedback to Twitter (they are asking for feedback on the feature) that we can have a new retweet feature that we embrace as enthusiastically as we did Twitter lists.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/twitters-new-retweet-is-broken-and-how-to-fix-it/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Freedom Time: Google Voice Letter to the FCC, iPhone App Store &amp; Mobile Gatekeepers</title>
		<link>http://www.cloudfour.com/freedom-time-google-voice-letter-fcc/</link>
		<comments>http://www.cloudfour.com/freedom-time-google-voice-letter-fcc/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 18:58:58 +0000</pubDate>
		<dc:creator>Jason Grigsby</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Cloud Four Stories]]></category>
		<category><![CDATA[Emerging Technology]]></category>
		<category><![CDATA[Mobile Web and Services]]></category>
		<category><![CDATA[Top Stories]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[appstore]]></category>
		<category><![CDATA[att]]></category>
		<category><![CDATA[fcc]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[googlevoice]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[mobileweb]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=625</guid>
		<description><![CDATA[Friday is the day to release news you want people to forget. No surprise then that Friday was when Google released the unredacted version of its letter to the FCC about Apple&#8217;s rejection of the Google Voice application. In case you missed it, the FCC sent letters to Apple, Google, and AT&#038;T asking them about [...]]]></description>
			<content:encoded><![CDATA[<p>Friday is the day to release news you want people to forget. No surprise then that Friday was when Google released the <a href="http://googlepublicpolicy.blogspot.com/2009/09/our-complete-letter-to-fcc-regarding.html">unredacted version of its letter to the FCC</a> about <a href="http://www.techcrunch.com/2009/07/27/apple-is-growing-rotten-to-the-core-and-its-likely-atts-fault/">Apple&#8217;s rejection of the Google Voice application</a>.</p>
<p>In case you missed it, the <a href="http://www.computerworld.com/s/article/9136164/FCC_probes_Apple_s_rejection_of_Google_Voice_for_iPhone">FCC sent letters to Apple, Google, and AT&#038;T</a> asking them about Apple&#8217;s rejection of the Google Voice for iPhone application and what role each company played.</p>
<p><a href="http://www.apple.com/hotnews/apple-answers-fcc-questions/">Apple</a> and <a href="http://www.techcrunch.com/2009/08/21/att-to-fcc-we-did-not-block-the-google-voice-app-on-the-iphone/">AT&#038;T</a> released the full content of their responses to the FCC. Google asked for portions of its response to be redacted. However, a Freedom of Information Act request prompted Google to divulge the full content of their response.</p>
<p>And yet despite this latest revelation, the <a href="http://news.cnet.com/8301-13579_3-10356462-37.html">he said, she said nature of the follow ups</a>, and word that <a href="http://www.techcrunch.com/2009/09/18/google-releases-a-nuke-apple-wont-win-this-fight/">Google may even have a screenshot proving that Apple is lying</a>, <strong>Google Voice is nowhere near the most important App Store rejection</strong>.</p>
<p>That distinction belongs to Freedom Time.</p>
<h3>Why Freedom Time Matters More than Google Voice</h3>
<p><img src="http://www.cloudfour.com/wp-content/uploads/2009/09/freedomtime1.jpg" style="float:right;width:216px;border:0;margin:0 0 10px 10px" alt="Freedom Application Screenshot" />Like many iPhone applications, Freedom Time was a frivolous application. The application displayed a cartoon character of George Bush with arms like a Mickey Mouse watch. But instead of telling time, the application counted down the days until Inauguration Day.</p>
<p>Freedom Time wasn&#8217;t one of the more high-profile iPhone App Store rejections. Unlike Google Voice, people barely noticed when the application was rejected.</p>
<p>What is important is the reason why Freedom Time was rejected. <a href="http://www.juggleware.com/blog/2008/09/freedomtime-rejected-by-apple-for-app-store/">Apple&#8217;s response</a> to the developer was:</p>
<blockquote><p>Upon review of your application, Freedom Time cannot be posted to the App Store because it contains content that does not comply with Community Standards.  Usage of such materials, as outlined in the iPhone SDK Agreement section 3.3.12, is prohibited:</p>
<p>“Applications must not contain any obscene, pornographic, offensive or defamatory content or materials of any kind (text, graphics, images, photographs, etc.), or other content or materials that in Apple’s reasonable judgement may be found objectionable by iPhone or iPod touch users.”</p>
<p><strong>Defaming, demeaning, or attacking political figures is not considered appropriate content for the App Store</strong>.</p></blockquote>
<p>Can you imagine political discourse of any significance that doesn&#8217;t include demeaning or attacking political figures? Like it or not, that&#8217;s part of the exchange of ideas that form a democracy.</p>
<p>This policy essentially bans any editorial cartoons&#8212;cartoons that have been part of America&#8217;s history since its inception.</p>
<p>The idea that political discourse might be rejected from the App Store as a matter of policy surely must be a mistake, right?</p>
<h3>Think Different? What&#8217;s the Point?</h3>
<p>Unfortunately, it isn&#8217;t a mistake. The developer of Freedom Time emailed Steve Jobs, and he actually got a reply. <a href="http://www.juggleware.com/blog/2008/09/steve-jobs-writes-back/">Steve wrote</a>:</p>
<blockquote><p>
 Even though my personal political leanings are democratic, I think this app will be offensive to roughly half our customers.  <strong>What’s the point?</strong></p>
<p>Steve</p></blockquote>
<p>I&#8217;ve often wondered what the Steve Jobs who attended Reed College during the early days of the Watergate scandal would think of that quote.</p>
<h3>Steve Jobs, George Bush, Richard Nixon, and Scott Ritter</h3>
<p>These four people&#8212;two that I admire and two that broke our trust&#8212;have become linked in my mind because of the Freedom Time rejection.</p>
<p>Freedom of speech is easy to defend when the speech is popular, but the real test comes when you have to defend unpopular speech or things that you don&#8217;t agree with.</p>
<p>In Fall 2008, George Bush had the <a href="http://www.gallup.com/poll/110980/Bush-Job-Approval-25-Lowest-Yet.aspx">worst approval ratings since Nixon</a>. <strong>At a time in which we had one of the most unpopular Presidents in American history, Apple didn&#8217;t have the courage to approve a simple, stupid application like Freedom Time.</strong></p>
<p>What is the likelihood that Apple would approve a truly controversial and unpopular application during a time when popular opinion makes it difficult to stand up for what&#8217;s right?</p>
<p>I find myself wondering what would have happened if former marine and U.N. Weapons Inspector <a href="http://en.wikipedia.org/wiki/Scott_Ritter">Scott Ritter</a> had tried to release an application in 2002 talking about how there were no weapons of mass destruction in Iraq.</p>
<p>When Ritter did speak up in 2002 and told the world that he had been in Iraq and that there were no weapons of mass destruction, popular opinion was so high in favor of Bush policies that despite being known as a patriot, conservative, and a hawk, Ritter was <a href="http://www.google.com/search?q=scott+ritter+traitor">called a traitor by some</a>.</p>
<p><strong>What if the only means Scott Ritter had to share what he knew with the rest of the world had been through an App Store?</strong></p>
<h3>Flickr Censorship Pales in Comparison</h3>
<p><a href="http://www.flickr.com/photos/thomashawk/3834570613/"><img src="http://farm4.static.flickr.com/3469/3834570613_69356550ef_m.jpg" style="float:left;margin:0 10px 10px 0;border:0;" alt="Censored Obama image"></a>Recently Flickr received a lot of scrutiny and pressure because of perceived <a href="http://thomashawk.com/2009/08/flickr-censors-political-image-critical-of-president-obama.html">censorship of a political image</a>. The image showed a modified version of Obama on the cover of Time Magazine where Obama was made to look like the Joker from the most recent Batman movie.</p>
<p>Yahoo, the parent company for Flickr, later explained that they removed the image from Flickr because they had received a <a href="http://www.techcrunch.com/2009/08/21/flickr-v-free-speech-where-is-the-courage/">copyright infringement claim</a>.</p>
<p>I don&#8217;t care to debate the Flickr censorship case. Instead, I want to ask simply why Flickr got a lot of grief for censoring a single image that they say they removed because of a copyright claim, but <strong>Apple has thus far escaped scrutiny for a standing policy that rejects any applications that attack political figures</strong>.</p>
<p>The image that Flickr removed would have never made it through the iPhone app review process in the first place.</p>
<h3>The Mobile Proposition: Trade Liberty for Security</h3>
<p>Apple has good reasons for why it has an App Store review process. It <a href="http://www.apple.com/hotnews/apple-answers-fcc-questions/">told the FCC that</a>:</p>
<blockquote><p>We created an approval process that reviews every application submitted to Apple for the App Store in order to protect consumer privacy, safeguard children from inappropriate content, and avoid applications that degrade the core experience of the iPhone.</p></blockquote>
<p>This is a very similar argument that carriers and handset manufacturers have been making for years now. The argument is that mobile phones contain so much personal, sensitive information that applications need to be vetted to ensure that consumers are protected.</p>
<p>This is the same argument that <a href="http://en.wikiquote.org/wiki/Benjamin_Franklin">Ben Franklin famously warned us about</a> when he said:</p>
<blockquote><p>Those who would give up Essential Liberty to purchase a little Temporary Safety, deserve neither Liberty nor Safety.</p></blockquote>
<p>And despite the fact that we would not accept similar arguments from our government, we seem willing to give up our freedoms to mobile companies for the sake of our own security.</p>
<h3>It&#8217;s Not About Apple. It&#8217;s About Gatekeepers</h3>
<p>While I&#8217;ve spent most of my time focusing on Apple, please don&#8217;t mistake this as a tirade against Apple. Apple just happens to be leading the way in this area of mobile as well.</p>
<p>The reality is that if mobile is going to live up to its promise, we need a future without gatekeepers.</p>
<p>It isn&#8217;t hard to conceive of a future where more people have smartphones than have PCs. In some countries, people get more news from their mobile phones than they do from their desktop computers.</p>
<p>Before we get to the point where mobile phones have become the primary way that people get their news and information, we need to ensure that we have the freedom to publish what we want without restrictions.</p>
<p>For these reasons, I&#8217;m encouraged by the work of organizations like the <a href="http://www.open-mobile.org/about-omc/why-open-mobile-consortium-needed">Open Mobile Consortium</a>. They are tackling the difficult work of providing truly open mobile solutions that allow people in repressive regimes to communicate freely.</p>
<h3>The Moral Imperative of the Mobile Web</h3>
<p>In addition to the Open Mobile Consortium, we need to make sure that there are alternatives to app stores and their gatekeepers. The best alternative is web technology.</p>
<p>This is why I&#8217;ve gone from thinking about mobile web technology as a <a href="http://www.cloudfour.com/459/the-five-most-common-arguments-for-native-iphone-development/">smart business decision</a> for some applications to thinking of it as a moral imperative.</p>
<p>Even if you are an Objective-C programmer who has had a lot of success on the iPhone App Store, it is in your best interest that the mobile web develop into a viable alternative to app stores. It is in society&#8217;s best interest.</p>
<p>To get to that point, we need to solve the short-coming of the mobile web. We need the technology to stabilize. We need real browsers on all phones. And we need a reliable and easy way to accept payment for our mobile web applications and services.</p>
<p>I cannot state this strongly enough: we need an <strong>open and free mobile web</strong> to be a viable alternative to the mobile gatekeepers to ensure that we have the <strong>freedom to say what must be said</strong> and the ability to have <strong>our voices heard by others</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/freedom-time-google-voice-letter-fcc/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JavaScript GZIP Compression in WordPress: What&#8217;s Possible and what Hurts</title>
		<link>http://www.cloudfour.com/javascript-gzip-compression-in-wordpress-whats-possible-and-what-hurts/</link>
		<comments>http://www.cloudfour.com/javascript-gzip-compression-in-wordpress-whats-possible-and-what-hurts/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 21:22:20 +0000</pubDate>
		<dc:creator>Lyza Gardner</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=609</guid>
		<description><![CDATA[WordPress 2.8 introduced some constants and bits and bots that nominally make certain kinds of compression of JavaScript and CSS possible. This post looks at JavaScript compression and explains what is possible, and what is very, very hard. In a nutshell, with a bit of tweaking, you can GZIP and concatenate the scripts that come [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress 2.8 introduced some constants and bits and bots that nominally make certain kinds of compression of JavaScript and CSS possible. This post looks at JavaScript compression and explains what is possible, and what is very, very hard.</p>
<p>In a nutshell, with a bit of tweaking, you can <strong>GZIP and concatenate the scripts that come packaged with WordPress</strong>. GZipping and concatenating anything else&#8211;plugin scripts or scripts in your own theme&#8211;is not currently supported in any obviously sane way (using WP&#8217;s WP_Scripts management class anyway).</p>
<p>I&#8217;m going to give away the ending to save you some time:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'wp_enqueue_scripts'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'lyza_force_compress'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">function</span> lyza_force_compress<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$compress_scripts</span><span style="color: #339933;">,</span> <span style="color: #000088;">$concatenate_scripts</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$compress_scripts</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$concatenate_scripts</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ENFORCE_GZIP'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
    <span style="color: #666666; font-style: italic;">/* enqueue your scripts here */</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Putting the above in your functions.php file <em>may</em> result in insanely good compression on your subsequently-enqueued JavaScript files. I say <em>may</em> because GZIP is one of those fidgety server-side things that varies from hosting provider to hosting provider. I tested this approach on two vastly different environments and had good success, but as always with these things, YMMV.</p>
<p>While this may look rather silly and simple, figuring out exactly which constants and globals to set and when to set them took me just about forever. </p>
<p>The most important thing to note is that <strong>this only works on scripts that come pre-packaged with WordPress and are listed in the wp_default_scripts() function in wp-includes/script-loader.php</strong>. This is slightly irritating.</p>
<h3>When it Does Work</h3>
<p>The above will concatenate and GZIP all of the applicable enqueued JavaScript into a single request, served out through the wp-admin/load-scripts.php script. </p>
<ul>
<li>By &#8220;applicable&#8221;, I mean scripts listed in wp-includes/script-loader.php in the wp_default_scripts() function.</li>
<li>If you have applicable JavaScript in both the head and the foot, you will end up with two script src tags. If everything is in the foot (or the head), you&#8217;ll get one tag. You not only get GZipping, you get fewer HTTP requests! Yay!</li>
<li>JavaScript in plugins and your own theme won&#8217;t get concatenated and GZipped in this approach, but it certainly doesn&#8217;t break it.</li>
</ul>
<p>In testing, the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'thickbox'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'scriptaculous'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'editor'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Went from:</p>
<p>10 requests, 310kB</p>
<p>to</p>
<p>2 requests, 90kB</p>
<p>with the activation of the above function. Nice! I got two requests because the above enqueueing puts stuff in both the head and the footer.</p>
<p><strong style="font-size:1.5 em; border: 1px solid #ccc; padding: 1em;width:100%">That&#8217;s a 340% improvement on filesize alone.</strong></p>
<h3>Why Won&#8217;t It Work for All JavaScript?</h3>
<p>Because there are no, nada, zilch, none hooks for making it do so without doing some deep surgery and writing a plugin. It boils down to a couple of places in code:</p>
<p>From wp-includes/class.wp-scripts.php in the do_item() function:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>100
101
102
103
104
105
106
107
108
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">in_default_dir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$srce</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">print_code</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">print_scripts_l10n</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">concat</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$handle</span>,&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">concat_version</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$handle</span><span style="color: #006699; font-weight: bold;">$ver</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ext_handles</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$handle</span>,&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ext_version</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$handle</span><span style="color: #006699; font-weight: bold;">$ver</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>To get the built-in concatenation and GZIPped delivery, it is necessary that the if statement here evaluate true. I won&#8217;t explain the nitty gritty unless you really want me to. </p>
<p>So, my first approach was to add paths to the $wp_scripts->default_dirs Array to add entries for my theme&#8217;s scripts and my plugin dir&#8217;s scripts. Big fat fail.</p>
<p>The reason is that the actual file &#8212; <strong>wp-admin/load-scripts.php</strong> &#8212; that serves up the concatenated, zipped JavaScript is a standalone script. I imagine that this is both for security and for performance. It does not have the complement of WordPress constants and hooks that we are accustomed to. In fact, it is <strong>completely and absolutely unpluggable</strong> (unless I missed something). It only includes the files that define the WP_Scripts and WP_Dependencies classes, and utility functions for those. It does not include any theme- or plugin-level items.</p>
<p>And it does something that completely shuts down the game. It instantiates a new, clean WP_Scripts object and then calls wp_default_scripts(). </p>
<p>If you&#8217;ll recall, the WP_Scripts object in a normal WordPress request is a global singleton that manages all of the enqueued scripts. By creating a new instantiation, the load-scripts.php script has obliterated any notion of any enqueued scripts. Further, the wp_default_scripts() function is a hard-coded list of the JavaScript files that WordPress comes packaged with. While this function nominally triggers the &#8216;wp_default_scripts&#8217; action, this is not usable here because no files are getting included in which I could take advantage of that hook. Further, it redefines do_action() and other API functions as blank functions that do nothing. </p>
<p>The load-scripts.php file then iterates through the requested JavaScript handles (comma-delimited GET) and sees if it recognizes them from the wp_default_scripts() list. As anything that&#8217;s in your own theme or in a plugin won&#8217;t be in this list, FAIL. </p>
<p>Though I see some possible options for me in the writing-a-plugin realm, I also sadly see that it would replicate functionality and am highly curious as to what the WordPress developers had in mind here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/javascript-gzip-compression-in-wordpress-whats-possible-and-what-hurts/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Getting all JavaScript into the Footer in WordPress? Not so fast, Buster!</title>
		<link>http://www.cloudfour.com/getting-all-javascript-into-the-footer-in-wordpress-not-so-fast-buster/</link>
		<comments>http://www.cloudfour.com/getting-all-javascript-into-the-footer-in-wordpress-not-so-fast-buster/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 20:26:02 +0000</pubDate>
		<dc:creator>Lyza Gardner</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=591</guid>
		<description><![CDATA[Warning: Technical WordPress post ahead! Overview: Really Getting JavaScript Into the Footer Quoth the WordPress Version 2.8 feature list: &#8211; Improvements to the script loader: allows plugins to queue scripts for the front end head and footer, adds hooks for server side caching of compressed scripts, adds support for ENFORCE_GZIP constant (deflate is used by [...]]]></description>
			<content:encoded><![CDATA[<p><br />
Warning: Technical WordPress post ahead!</p>
<h3>Overview: Really Getting JavaScript Into the Footer</h3>
<p><strong>Quoth the WordPress Version 2.8 feature list:</strong></p>
<blockquote><p> &#8211; Improvements to the script loader: <strong>allows plugins to queue scripts for the front end head and footer</strong>, adds hooks for server side caching of compressed scripts, adds support for ENFORCE_GZIP constant (deflate is used by default since it&#8217;s faster)
</p></blockquote>
<p>At the time, I thought <em>Wow, cool. When I have time, I&#8217;ll investigate that</em> and then immediately forgot about it for a few months. During RSS-coffee-breaks I read <a href="http://lesterchan.net/wordpress/2009/01/26/loading-javascript-in-footer-in-wordpress-28/">Lester Chan&#8217;s post</a> about how to put JavaScript in the footer (sounds easy enough!) and <a href="http://wpdevel.wordpress.com/2009/02/06/script-loader-updates/">Andrew Ozz&#8217;s post</a>, which left me coated with an intense and foolish optimism about compression.</p>
<p><strong>What I aim to do in this post</strong> &#8212; part one of a series of three if I find time to investigate the second and third pieces &#8212; is <strong>explain why it&#8217;s not as easy as you&#8217;d expect to get some scripts (specifically scripts that come with WordPress by default) into the footer, and how you can make it happen.</strong></p>
<p>If you&#8217;re <strong>in a hurry, you can skip to the Summary section at the end of the post</strong>.</p>
<h3>WP JavaScript Inclusion: Header vs. Footer</h3>
<p>What I read had me believe that it is falling-off-log easy to put all WordPress JavaScript in the footer. If you are trying to include a piece of JavaScript, say, in a plugin, that WP has not previously known about, it <em>is that easy</em>. But woe if you try this on certain scripts that come packaged with WordPress.</p>
<p>Let&#8217;s take a look at the functions that are involved in letting WordPress know that you want to use a given piece of JavaScript.</p>
<p>These are taken from wp-includes/functions.wp-scripts.php. </p>
<h4>wp_register_script() and wp_enqueue_script()</h4>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Register new JavaScript file.
 *
 * @since r16
 * @see WP_Dependencies::add() For parameter information.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> wp_register_script<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span><span style="color: #339933;">,</span> <span style="color: #000088;">$deps</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ver</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$in_footer</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">is_a</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'WP_Scripts'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #000088;">$wp_scripts</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WP_Scripts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span><span style="color: #339933;">,</span> <span style="color: #000088;">$deps</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ver</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$in_footer</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_data</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'group'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Enqueues script.
 *
 * Registers the script if src provided (does NOT overwrite) and enqueues.
 *
 * @since r16
 * @see WP_Script::add(), WP_Script::enqueue()
*/</span>
<span style="color: #000000; font-weight: bold;">function</span> wp_enqueue_script<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$deps</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ver</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$in_footer</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">is_a</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'WP_Scripts'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #000088;">$wp_scripts</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WP_Scripts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$src</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$_handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_handle</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span><span style="color: #339933;">,</span> <span style="color: #000088;">$deps</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ver</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$in_footer</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_data</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_handle</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'group'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enqueue</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>As a theme developer, you may only ever have encounters with wp_enqueue_script(). But let&#8217;s look at what each of these functions does so I can then explain the issue.</p>
<p><strong>wp_register_script()</strong> tells WordPress about a script, but does not actually cause it to be included in a given page request. By default, WordPress registers a gripload of scripts that are then available to you, the theme hacker, when or if you should need them. A list of these can be found in wp-includes/script-loader.php in the wp_defalut_scripts() function. Highlights include jQuery, prototype, scriptaculous, etc., as well as extensions to those frameworks (e.g. jQuery UI). WordPress (via the WP_Scripts class, itself extended from WP_Dependencies) handles dependencies and makes sure that jQuery UI doesn&#8217;t get included without its necessary jQuery, if you should forget to enqueue jQuery itself or it gets enqueued after jQuery UI.</p>
<p><strong>wp_enqueue_script()</strong> tells WordPress, hey, I actually need this script, in this request. You may have seen or done something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This spools up jQuery and spits out a script tag to include the requested script. </p>
<p>In a lot of cases, it seems easy and straightforward to do this simple enqueue request. jQuery comes packaged with WP and is automatically registered for you, so you just have to hand the wp_enqueue_script() function one argument: $handle. </p>
<p>As a clever theme hacker, you may have noticed that the signature for wp_enqueue_script() and wp_register_script() changed in version 2.8 and this seems exciting. <strong>An $in_footer parameter was added:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">wp_enqueue_script<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$deps</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ver</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$in_footer</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Totally psyched, you update your theme and use:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And wait for the magic. RELOAD! Wait, maybe something&#8217;s cached. RELOAD! Wait, what? RELOADRELOADRELOAD.</p>
<p><strong>jQuery is still in the head.</strong></p>
<p>So you get irritable and you quit trying, or like me you spend a few hours deactivating all of your plugins and trying to figure out where the problem is. You notice that the same thing happens with other scripts that WP already knows about (that is, the scripts in wp_default_scripts()). Stubbornly, they won&#8217;t get out of your page&#8217;s head element.</p>
<p>Here&#8217;s why.</p>
<h3>Why WordPress Default JavaScripts Won&#8217;t Move to the Footer</h3>
<p>The crux is: <strong>if the script you are enqueueing has anything defined as a dependency in WordPress&#8217; wp_default_scripts() function, it will ignore your request to put it in the footer</strong> (I&#8217;ll provide a workaround shortly). </p>
<p>The reason for this is twofold. </p>
<h4>Dependency Handling and &#8220;Groups&#8221;</h4>
<p>Part of WordPress&#8217; dependency handling for scripts involves &#8220;groups&#8221;, the ins and outs of which I&#8217;ll leave as an exercise for an intrigued reader. In an oversimplification, it put scripts with dependencies (e.g. jQuery, Scriptaculous) in groups[0]. It explicitly puts scripts that depend on other scripts in groups[1]. The default behavior of both wp_register_script()  is to put a script in groups[0] if the $in_footer argument != true.</p>
<h4>How Groups Handling does Something Possibly Confusing</h4>
<p>OK, now check out this snippet from class.wp-scripts.php (do_item() method):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>85
86
87
88
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$group</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">groups</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">in_footer</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$handle</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This piece of logic puts groups &gt; 0 into the footer. So <strong>that&#8217;s how WP decides to move things into the footer</strong>&#8211;it&#8217;s based on where the script is in the $wp_scripts->groups Array. </p>
<p>But here&#8217;s a potential pitfall in the wp_enqueue_script() function:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$src</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$_handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_handle</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span><span style="color: #339933;">,</span> <span style="color: #000088;">$deps</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ver</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$in_footer</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_data</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_handle</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'group'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$wp_scripts</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enqueue</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$handle</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>If you don&#8217;t give wp_enqueue_script() a $src (which you don&#8217;t have to provide do if the script has already been registered) for your $handle, it is going to enqueue it in whatever group it&#8217;s already registered in</strong>. So, when you do your little simple enqueue:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The entire part of the function where it would put it in the footer doesn&#8217;t execute because the if($src) test fails. And jQuery has already been registered&mdash;in groups[0].</p>
<h4>Possible Workaround</h4>
<p>I don&#8217;t like this but it works:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'/wp-includes/js/jquery/jquery.js'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>jQuery is now in the footer.</strong></p>
<p>This does still appear to handle dependencies correctly, but I haven&#8217;t deeply tested. <strong>Also, there are some valid reasons to have some scripts, and possibly jQuery, in the head</strong>. This was just a demo.</p>
<h3>Getting JS into the Footer: Quick Summary</h3>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// This will NOT put jquery in the footer</span>
wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
<span style="color: #666666; font-style: italic;">// But this will, if inelegant and circumventing abstraction</span>
wp_enqueue_script<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'/wp-includes/js/jquery/jquery.js'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>For My Next Trick&#8230;Compression</h3>
<p>Really, this post was a red herring. I tripped into this oddity while investigating the second part of the WordPress 2.8 feature claim: <strong><em>adds hooks for server side caching of compressed scripts, adds support for ENFORCE_GZIP constant (deflate is used by default since it&#8217;s faster)</em></strong>. We&#8217;ll talk about that next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/getting-all-javascript-into-the-footer-in-wordpress-not-so-fast-buster/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress: Taking the Hack out of Multiple Custom Loops</title>
		<link>http://www.cloudfour.com/wordpress-taking-the-hack-out-of-multiple-custom-loops/</link>
		<comments>http://www.cloudfour.com/wordpress-taking-the-hack-out-of-multiple-custom-loops/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 22:33:55 +0000</pubDate>
		<dc:creator>Lyza Gardner</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=533</guid>
		<description><![CDATA[Here's one approach to handling multiple custom loops in WordPress!]]></description>
			<content:encoded><![CDATA[
<h3>Overview</h3>
<p><em>Consider this a looking-forward-to <a href="http://www.wordcampportland.org/">WordCamp Portland</a> post! WordCamp is this weekend in Portland, Sept. 19-20. It is utterly sold out!</em></p>
<p><em>This post is aimed at those comfortable with WordPress hackery and PHP programming.</em></p>
<p>Making things work for our customers often&#8211;nay, <em>all the time</em>&#8211;ends up with the need for <strong>multiple WordPress loops on pages</strong></p>
<p>On a given day, one of our enterprise or otherwise-crafty-and-complex clients may request, say, the three most recent posts about <em>foo</em> in the right sidebar, &#8220;upcoming events&#8221; (e.g. date-sensitive posts in some events category) in another box, a couple of embedded and editable WordPress page components, a random post or two, and then the &#8220;traditional&#8221; post loop itself. Whew.</p>
<p><strong>I have long tried to find the best way to handle custom loops</strong>. For sake of definition, <em>custom loop</em> here means querying and displaying posts and/or pages within a page that are not that page&#8217;s &#8220;natural&#8221; queried posts (that is, the landing page of a WordPress blog by default &#8220;naturally&#8221; queries the most recent posts, and a category page &#8220;naturally&#8221; queries for posts in a given category). </p>
<p>There are a number of plugins and even entire themes keyed toward custom-loop-heavy development and modular formatting of posts in loops, including the <a href="http://carringtontheme.com/2009/02/carrington-jam-10/">Carrington JAM</a> theme. But I find that most solutions either are a bit too baked&#8211;the Carrington theme feels like it would require a lifestyle change and an adoption of a new outlook (not that I&#8217;m ragging on the Carrington stuff; I&#8217;ve actually heard good stuff about it)&#8211;or a little bit too under-baked and soggy in the middle (&#8220;Here&#8217;s a two-line code snippet to call query_posts! I think? I mean, this should work, probably.&#8221;). </p>
<h3>I&#8217;m Tired of Solving these things Ad Nauseum</h3>
<p>Problems I keep running into:</p>
<ul>
<li>The dreadful tendency to <strong>forget to restore the &#8220;natural&#8221;, appropriate global post and wp_query objects</strong> after one is done messing about. Those are sort of inviolate and should not be sullied, but it&#8217;s wretchedly easy to lose track.</li>
<li>Yet, if one does <em>not</em> pollute the global namespace with posts in the custom loop, <strong>one cannot access certain template tags</strong> and the like.</li>
<li>The <strong>mishmash of logic and formatting</strong> that often happens when one munges together a custom query in a page or post template is totally aesthetically unpleasing and betrays a certain lack of character/mettle.</li>
<li><strong>Duplicated markup</strong> across a site that would better be modular and re-used.</li>
</ul>
<p>It occurred to me recently that there is a straightforward way to deal with this. By <strong>creating a custom function (in a given theme&#8217;s functions.php file</strong>) of relatively low complexity, one can solve some of these problems once and for all. </p>
<h3>The function: lyzadotcom_custom_loop($args)</h3>
<p>It&#8217;s prefaced with lyzadotcom because I initially wrote it for <a href="http://www.lyza.com">my own site</a>, but you can call it whatever.</p>
<p>This is what it looks like, and we&#8217;ll talk about it more below:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * To use when a loop is needed in a page. Use $args to call query_posts and then 
 * use the template indicated to render the posts. The template gets included once
 * per post.
 * 
 * @param Array $args               Wordpress-style arguments; passed on to query_posts 
 *                                  'template' =&gt; name of post template to use for posts
 * @return Array of WP $post objs   Matching posts, if you should need them.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> lyzadotcom_custom_loop<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_query</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$post_template_dir</span>          <span style="color: #339933;">=</span> <span style="color: #0000ff;">'post_templates'</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">/* The 'template' element should be the name of the PHP template file
       to use for rendering the matching posts. It should be the name of file,
       without path and without '.php' extension. e.g. the default value 'default'
       is $post_template_dir/default.php
    */</span>
    <span style="color: #000088;">$defaults</span>                   <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'template'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'default'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
    <span style="color: #000088;">$opts</span> <span style="color: #339933;">=</span> wp_parse_args<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #339933;">,</span> <span style="color: #000088;">$defaults</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Bring arguments into local scope, vars prefixed with $loop_</span>
    <span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$opts</span><span style="color: #339933;">,</span> EXTR_PREFIX_ALL<span style="color: #339933;">,</span> <span style="color: #0000ff;">'loop'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Preserve the current query object and the current global post before messing around.</span>
    <span style="color: #000088;">$temp_query</span> <span style="color: #339933;">=</span> clone <span style="color: #000088;">$wp_query</span><span style="color: #339933;">;</span>                                  
    <span style="color: #000088;">$temp_post</span>  <span style="color: #339933;">=</span> clone <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$template_path</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%s/%s/%s.php'</span><span style="color: #339933;">,</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$post_template_dir</span><span style="color: #339933;">,</span> <span style="color: #000088;">$loop_template</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$template_path</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">printf</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&lt;p class=&quot;error&quot;&gt;Sorry, the template you are trying to use (&quot;%s&quot;)
            in %s() does not exist (%s).'</span><span style="color: #339933;">,</span>
            <span style="color: #000088;">$template</span><span style="color: #339933;">,</span> 
            <span style="color: #009900; font-weight: bold;">__FUNCTION__</span><span style="color: #339933;">,</span> 
            <span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">/* Allow for display of posts in order passed in post__in array
       [as the 'orderby' arg doesn't seem to work consistently without giving it some help]
       If 'post__in' is in args and 'orderby' is set to 'none', just grab those posts,
       in the order provided in the 'post__in' array.
    */</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_orderby</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$loop_orderby</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'none'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$loop_post__in</span><span style="color: #009900;">&#41;</span>     
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_post__in</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$post_id</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000088;">$loop_posts</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> get_post<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post_id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
        <span style="color: #000088;">$loop_posts</span> <span style="color: #339933;">=</span> query_posts<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Utility vars for the loop; in scope in included template */</span>
    <span style="color: #000088;">$loop_count</span>             <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> 
    <span style="color: #000088;">$loop_odd</span>               <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$loop_even</span>              <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$loop_first</span>             <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$loop_last</span>              <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$loop_css_class</span>         <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>                               <span style="color: #666666; font-style: italic;">// For convenience</span>
    <span style="color: #000088;">$loop_size</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_posts</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$loop_owner</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$temp_post</span><span style="color: #339933;">;</span>       <span style="color: #666666; font-style: italic;">/* The context from within this loop is called
                                       the global $post before we query */</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_posts</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$loop_count</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_count</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$loop_even</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$loop_even</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_count</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$loop_odd</span>  <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$loop_odd</span>  <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> ?     <span style="color: #000088;">$loop_first</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$loop_first</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_count</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$loop_size</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$loop_last</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$loop_last</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_even</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$loop_css_class</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'even'</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$loop_class</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'odd'</span><span style="color: #339933;">;</span>
        setup_postdata<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$template_path</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$wp_query</span> <span style="color: #339933;">=</span> clone <span style="color: #000088;">$temp_query</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// Put the displaced query and post back into global scope</span>
    <span style="color: #000088;">$post</span> <span style="color: #339933;">=</span> clone <span style="color: #000088;">$temp_post</span><span style="color: #339933;">;</span>       <span style="color: #666666; font-style: italic;">// And set up the post for use.</span>
    setup_postdata<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$loop_posts</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Loop Templates</h3>
<ul>
<li>By default, this function will look for loop templates in a directory called &#8216;post_templates&#8217; in your theme&#8217;s template directory. Also by default, it will look for a file called &#8216;default.php&#8217; in this directory. You can change the directory for templates if this bugs you.</li>
<li>Templates are PHP files and you can do what you will in them. All <a href="http://codex.wordpress.org/Template_Tags">template tags</a> are available.</li>
<li>You can create as many template files as you want and use them for different chunks of content.</li>
</ul>
<h4>Example Loop Template File</h4>
<p>For example, this might be your default.php template file.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;div class=&quot;post &lt;?php echo $loop_css_class ?&gt;&quot; id=&quot;post-&lt;?php the_ID(); ?&gt;&quot;&gt;
        &lt;h4&gt;&lt;?php echo $loop_count; ?&gt;&lt;a href=&quot;&lt;?php the_permalink(); ?&gt;&quot; title=&quot;&lt;?php the_title(); ?&gt;&quot;&gt;
            &lt;?php the_title(); ?&gt;
        &lt;/a&gt;&lt;/h4&gt;
        &lt;em&gt;&lt;?php the_date(); ?&gt;&lt;/em&gt;&lt;br /&gt;
        &lt;?php the_excerpt(); ?&gt;        
    &lt;/div&gt;</pre></div></div>

<p>You can see that, in addition to standard <a href="http://codex.wordpress.org/Template_Tags">&#8220;>WordPress template tags</a>, I&#8217;ve used a couple of the batching variables made available by the function.</p>
<h5>Batching Variables Available to Loop Templates</h5>
<p>Available variables in loop templates are:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$loop_count</span>                         <span style="color: #666666; font-style: italic;">// The count of the current post within the loop</span>
<span style="color: #000088;">$loop_odd</span>                           <span style="color: #666666; font-style: italic;">// True if we're on an odd item (e.g. $loop_count = 1, 3, 5...)</span>
<span style="color: #000088;">$loop_even</span>                          <span style="color: #666666; font-style: italic;">// True if we're on an even item (e.g. $loop_count = 2, 4, 6...)</span>
<span style="color: #000088;">$loop_first</span>                         <span style="color: #666666; font-style: italic;">// True if this is the first post/page in the loop</span>
<span style="color: #000088;">$loop_last</span>                          <span style="color: #666666; font-style: italic;">// True if this is the last post/page in the loop</span>
<span style="color: #000088;">$loop_css_class</span>                     <span style="color: #666666; font-style: italic;">// 'even' if $loop_even, 'odd' if $loop_odd</span>
<span style="color: #000088;">$loop_size</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$loop_posts</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Total number of posts/pages in loop</span>
<span style="color: #000088;">$loop_owner</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$temp_post</span><span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// The post in global scope before this loop was entered</span></pre></div></div>

<h3>How to Use this Thing</h3>
<h4>Requirements</h4>
<ul>
<li>The use of clone means you need to have PHP5.</li>
<li>I have not tested this on any versions of WordPress 2.8. I imagine it would be OK, but YMMV.</li>
</ul>
<h4>Usage</h4>
<ol>
<li>Edit your themes functions.php file and stick this function in it.</li>
<li>Create at least one loop template file. By default (unless you tell it otherwise, which likely you will) this function looks for a template in

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;template_directory&gt;/post_templates/default.php</pre></div></div>

<p>We&#8217;ll talk about templates shortly.</li>
<li>Call the function from any WordPress template file you might need it from. You talk to it with <a href="http://codex.wordpress.org/Template_Tags/How_to_Pass_Tag_Parameters#Tags_with_query-string-style_parameters">WordPress query-string-style arguments</a>. This function takes any argument that the <a href="http://codex.wordpress.org/Template_Tags/query_posts">query_posts()</a> function takes.</li>
<li>It also takes an additional argument, &#8216;template&#8217;. This is how you tell it which loop template to use.
</ol>
<h3>Usage Examples</h3>
<h4>Embed an editable Page into Content</h4>
<ol>
<li>In the desired WordPress template:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">&lt;?php</span>
        <span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'pagename'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'embed-this-page'</span><span style="color: #339933;">,</span>
                      <span style="color: #0000ff;">'template'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'embed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">?&gt;</span>  
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> lyzadotcom_custom_loop<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

</li>
<li>This is going to look for the template &#8216;embed.php&#8217; in your $post_templates directory. This template might look like this:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    &lt;div class=&quot;embedded&quot; id=&quot;embedded-page-<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_ID<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
        &lt;strong&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_title<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/strong&gt;&lt;br /&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> the_content<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> edit_post_link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;/div&gt;</pre></div></div>

</ol>
<h4>Display 5 Most Recent Posts from Several Categories, Titles Only</h4>
<ol>
<li>In the desired WordPress template:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    &lt;ul&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> 
        <span style="color: #666666; font-style: italic;">// This assumes you have category IDs. </span>
        <span style="color: #666666; font-style: italic;">// Getting them is beyond the scope of this pos</span>
        <span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'category__in'</span>        <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">6</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
                      <span style="color: #0000ff;">'showposts'</span>           <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span>
                      <span style="color: #0000ff;">'template'</span>            <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'list_with_link'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        lyzadotcom_custom_loop<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;/ul&gt;</pre></div></div>

</li>
<li>list_with_link.php might look like:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    &lt;li id=&quot;link-<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_ID<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; class=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$list_css_class</span><span style="color: #339933;">&gt;</span><span style="color: #0000ff;">&quot;&gt;
        &lt;a href=&quot;</span><span style="color: #000000; font-weight: bold;">&lt;?php</span> the_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #0000ff;">&quot; title=&quot;</span><span style="color: #000000; font-weight: bold;">&lt;?php</span> the_title<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_title<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;
    &lt;/li&gt;</pre></div></div>

</li>
</ol>
<h4>Display Your Posts Tagged &#8216;Banana&#8217; from March of 2009</h4>
<ol>
<li>In the desired WordPress template:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    &lt;h3&gt;March's Bananas&lt;/h3&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span>
        <span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tag'</span>              <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span>
                 <span style="color: #0000ff;">'showposts'</span>        <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//show all posts</span>
                 <span style="color: #0000ff;">'monthnum'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span>
                 <span style="color: #0000ff;">'year'</span>             <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2009</span><span style="color: #339933;">,</span>
                 <span style="color: #0000ff;">'template'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'month_archive_list'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$banana_posts</span> <span style="color: #339933;">=</span> lyzadotcom_custom_loop<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">/* Hint: You might used the returned $banana_posts to
           populate another call to lyzadotcom_custom_loop(), 
           e.g. 'post__not_in' =&gt; [ids from $banana_posts] 
           to avoid duplicating posts!
        */</span>
    <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

</li>
<li>month_archive_list.php might look like:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    &lt;div class=&quot;archive_post&quot; id=&quot;archive_post-<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_ID<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$loop_count</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> of <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$loop_size</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> Bananas:
        &lt;strong&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_title<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/strong&gt;&lt;br /&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> the_content<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> edit_post_link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;/div&gt;</pre></div></div>

</li>
</ol>
<h3>FAQ (In Which I Anticipate Questions)</h3>
<dl>
<dt>Will this work with pages as well as posts?</dt>
<dd>Yes. Sure. Just fine! Anything that query_posts() can do, I can do too!</dd>
<dt>Why isn&#8217;t this a plugin?</dt>
<dd>It took me hours just to write this post; I&#8217;ve got stuff to do! If there&#8217;s a lot of interest, maybe I&#8217;ll consider it.</dd>
<dt>I found a bug/horrible security hole/idiocy?</dt>
<dd>Please let me know! Gently! Comments to this post is a fine method to do so.</dd>
<dt>How is this bad boy licensed?</dt>
<dd>GPL. Do with it what you will!</dd>
<dt>OMG! Don&#8217;t you know about XYZ plugin? It totally does this, but better!</dt>
<dd>Nope! But I&#8217;d like to!</dd>
</dl>
<h3>Download, with Examples</h3>
<p>I&#8217;ve gone ahead and zipped up some stuff for you:</p>
<ul>
<li>a functions.php file with the function in it (add it to yours)</li>
<li>Several example files in a post_templates directory</li>
<li>Example.php with several calls to the function</li>
</ul>
<p><strong style="font-size:2em; padding: 2em; border: 1px solid #ccc; background-color:#f0f0f0; display:block; margin:20px;"><a href="http://www.cloudfour.com/wp-content/uploads/2009/09/custom_loop.zip">Download ZIP</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/wordpress-taking-the-hack-out-of-multiple-custom-loops/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Welcome, Megan!</title>
		<link>http://www.cloudfour.com/welcome-megan/</link>
		<comments>http://www.cloudfour.com/welcome-megan/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 17:32:11 +0000</pubDate>
		<dc:creator>Jason Grigsby</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Cloud Four Stories]]></category>
		<category><![CDATA[Emerging Technology]]></category>
		<category><![CDATA[Top Stories]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[megan]]></category>
		<category><![CDATA[portland]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=304</guid>
		<description><![CDATA[We're excited to welcome Megan Notarte (@megnotarte) to Cloud Four. We think she's going to contribute a lot to our company right away, but we also expect her to help shape what comes next for Cloud Four.]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re excited to welcome <a href="http://twitter.com/megnotarte">Megan Notarte</a> (@<a href="http://www.twitter.com/megnotarte">megnotarte</a>) to Cloud Four. Megan has extensive experience as both a project manager and developer, most recently as the IT Manager at Oregon Real Estate Forms.</p>
<p>Megan will be helping us mostly in a project management role, but we will be putting her development skills through the paces, too.</p>
<p>We feel fortunate to be growing during these challenging economic times&#8211;and we feel particularly lucky to have someone of Megan&#8217;s caliber joining us. We think she&#8217;s going to contribute a lot to our company right away, but we also expect her to help shape what comes next for Cloud Four.</p>
<p><strong>Cloud Five?</strong></p>
<p>During the hiring process, the most common question we got asked was whether or not we would change our name to Cloud Five.</p>
<p>The simple answer is no.</p>
<p>We picked Cloud Four not because of the four founders, but instead because we wanted a name that represented <a href="http://www.cloudfour.com/13/what-we-believe/">our values</a> and our roots.</p>
<p>We wanted a name that conveyed transparency and openness. A cloud has those characteristics while also being something with substance. And as Portlanders, we see our fair share of clouds.</p>
<p>Those values and characteristics are not changing as we grow. The qualities of the name that originally appealed to us remain true no matter how many people we have in the company.</p>
<p>We&#8217;re excited about what comes next and we&#8217;re very happy to have Megan as part of our team.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/welcome-megan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make Your Blog Faster &amp; Help Save the Environment</title>
		<link>http://www.cloudfour.com/make-your-blog-faster-help-save-the-environment/</link>
		<comments>http://www.cloudfour.com/make-your-blog-faster-help-save-the-environment/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 03:44:11 +0000</pubDate>
		<dc:creator>Jason Grigsby</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>
		<category><![CDATA[Cloud Four Stories]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Top Stories]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=43</guid>
		<description><![CDATA[Jason will be talking about how to help the environment by making your blog load faster at this Friday's Beer and Blog located at the Green Dragon from 4 to 6 pm.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.cloudfour.com/wp-content/uploads/2008/06/world.jpg" alt="" title="Earth" width="125" height="124" class="alignright size-full wp-image-49" style="float:right;" />For those in the Portland area, I&#8217;m going to be leading an informal session at this week&#8217;s <a href="http://www.beerandblog.com">Beer and Blog</a> on <strong>how to optimize your blog for performance</strong> and why doing so is <strong>good for the environment</strong>.</p>
<p>More on how performance is connected to the environment in a moment, but first, the details on when and where:</p>
<p style="margin-left:20px;"><a href="http://www.beerandblog.com/make-your-blog-load-fast-and-help-the-environment-at-the-same-time/#comments">Beer and Blog &#8211; Make Your Blog Load Fast &amp; Save the Environment</a><br />
Green Dragon Bistro &#038; Brewpub<br />
928 SE 9th Ave.<br />
Portland, Oregon 97214<br />
<a href="http://upcoming.yahoo.com/event/760191/">RSVP</a> | <a href="http://upcoming.yahoo.com/event/760191/export/">Add to Calendar</a> | <a href="http://maps.google.com/maps?f=q&#038;hl=en&#038;geocode=&#038;q=green+dragon,+portland,+oregon&#038;ie=UTF8&#038;ll=45.519338,-122.6651&#038;spn=0.033377,0.053215&#038;z=14&#038;iwloc=A">Map</a>
</p>
<h2>The Impact of Data Centers on the Environment</h2>
<p><a href="http://www.flickr.com/photos/grigs/1637750602/" title="HP Efficient Computing by grigs, on Flickr"><img src="http://farm3.static.flickr.com/2135/1637750602_e0d3cc953d_m.jpg" width="240" height="180" alt="HP Efficient Computing at SNW" style="float:right;margin:0 0 10px 10px;border:2px solid #919191;" /></a>Everyone is aware that our ability to reduce our energy consumption is a key component to reducing the impact we have on the environment.</p>
<p>However, it wasn&#8217;t until I was asked to speak to the <a href="http://www.snia.org/">Storage Networking Industry Association</a> (SNIA) at <a href="http://www.snwusa.com/">Storage Networking World</a> last fall that I realized how important this is for those who run data centers.</p>
<p>At the time, <a href="http://userfirstweb.com/103/saving-the-environment-one-server-at-a-time/">I observed</a>:</p>
<blockquote><p>Several businesses are now being told that <strong>they cannot bring any more power into their data centers</strong>. The power company is simply refusing to provide them with more capacity.</p>
<p>In many cases, the <strong>cost of powering and cooling a data center exceed the costs of the hardware within two years</strong>.</p></blockquote>
<p>The people in the storage industry get it. The SNIA has started the <a href="http://www.snia.org/forums/green/">Green Storage Initiative</a> to foster innovative ways of reducing power consumption in data centers.</p>
<p>The question is are those of us who are web developers doing our part? Sadly, no.</p>
<h2>Web Site Gluttons</h2>
<p>Web developers live insulated lives. We have broadband at our homes and our offices and it shows. We&#8217;ve stopped paying attention to the size of web pages.</p>
<p>Andrew King recently highlighted research showing that the <a href="http://www.websiteoptimization.com/speed/tweak/average-web-page/">average size of web pages has doubled since 2003</a>. &#8220;Longer term statistics show that since 1995 the size of the average web page has increased by 22 times, and the number of objects per page has grown by 21.7 times.&#8221; </p>
<p><a href="http://www.websiteoptimization.com/speed/tweak/average-web-page/"><img src="http://www.cloudfour.com/wp-content/uploads/2008/06/growth-average-web-page.png" alt="Growth of Average Web Page Size and Number of Objects" title="Growth of Web Pages" width="500" height="398" class="aligncenter size-full wp-image-50" style="border:none;" /></a></p>
<p style="font-size:xx-small;text-align:center;">Source: <a href="http://www.websiteoptimization.com/speed/tweak/average-web-page/">http://www.websiteoptimization.com/speed/tweak/average-web-page/</a></p>
<p>In addition to the size of web pages, few sites are optimized to ensure that browsers cache the files and don&#8217;t request the same files repeatedly.</p>
<p>Steve Souders recently conducted a thought experiment on how much <a href="http://www.stevesouders.com/blog/2008/03/06/how-green-is-your-web-page/">CO2 would be saved by optimizing</a> the Wikipedia home page. He used the <a href="http://www.co2stats.com/?rs=13730">CO2stats.com</a> estimate that &#8220;<a href="http://radar.oreilly.com/archives/2007/11/co2stats-measuring-a-sites-imp.html">three minutes on a Web site generates three grams of CO2</a> &#8211; roughly equal to the amount one person generates by breathing for 4.5 minutes.&#8221;</p>
<p>Steve estimated that the optimization could save &#8220;<strong>5,000 kilowatt-hours per year or approximately 500-1000 pounds of CO2 emissions</strong>.&#8221;</p>
<h2>Why Now?</h2>
<p>I&#8217;ve been interested in web optimization for ever since it saved my prior company tens of thousands of dollars a few years ago. I&#8217;ve been <a href="http://userfirstweb.com/70/speed-matters-presentation-files-and-resources/">speaking on the topic</a> whenever possible and trying to help web developers understand how much benefit they can get by optimizing their pages and how easy it is to do.</p>
<p>A couple of weeks ago, I finally watched <a href="http://www.climatecrisis.net/">An Inconvenient Truth</a>. At the conclusion of the film I started thinking about what more I could do. I&#8217;m getting a bike ready to use for my commute to work. I&#8217;m reducing the energy I use. I&#8217;m contemplating a vegetarian diet.</p>
<p>And I&#8217;ve redoubled my commitment to getting web developers to take site performance seriously. It saves money, improves the experience for your customers, and it&#8217;s easy to do.</p>
<p>Most importantly, <strong>if you care about global warming, optimizing your site is a moral imperative</strong>.</p>
<p>So come <a href="http://upcoming.yahoo.com/event/760191/">join us tomorrow at the Green Dragon</a> to make your blog faster and reduce the energy it consumes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/make-your-blog-faster-help-save-the-environment/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Akismet Numbers Paint Picture of Comment Spam</title>
		<link>http://www.cloudfour.com/akismet-numbers-paint-picture-of-comment-spam/</link>
		<comments>http://www.cloudfour.com/akismet-numbers-paint-picture-of-comment-spam/#comments</comments>
		<pubDate>Thu, 15 Nov 2007 19:20:06 +0000</pubDate>
		<dc:creator>Lyza Gardner</dc:creator>
				<category><![CDATA[Blogs and Social Media]]></category>

		<guid isPermaLink="false">http://www.cloudfour.com/?p=11</guid>
		<description><![CDATA[I knew comment spam on blogs was a problem, but I didn&#8217;t know quite how much of one until I happened across Akismet&#8217;s Zeitgeist page recently. Akismet is a comment spam protection service that is free to use for non-commercial use and integrated with popular blog software (e.g. WordPress, which we use at Cloud Four). [...]]]></description>
			<content:encoded><![CDATA[<p>I knew comment spam on blogs was a problem, but I didn&#8217;t know quite how much of one until I happened across <a href="http://akismet.com/stats/">Akismet&#8217;s Zeitgeist page</a> recently.</p>
<p>Akismet is a comment spam protection service that is free to use for non-commercial use and integrated with popular blog software (e.g. <a href="http://wordpress.com/">WordPress</a>, which we use at Cloud Four).</p>
<p>But I never knew the true numbers before: of the 3.67 billion comments Akismet has seen, only about 295 million are legitimate. That means <strong>only about 8% of all blog comments</strong> filtered through Akismet <strong>are legitimate.</strong> That&#8217;s kind of grim.</p>
<p>It makes me realize that having Akismet activated for my blog isn&#8217;t just a nice-to-have, but a must.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloudfour.com/akismet-numbers-paint-picture-of-comment-spam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

