<?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>David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞. &#187; APIs</title> <atom:link href="http://davidwalsh.name/tutorials/apis/feed" rel="self" type="application/rss+xml" /><link>http://davidwalsh.name</link> <description>Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</description> <lastBuildDate>Thu, 02 Sep 2010 03:13:15 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0.1</generator> <item><title>Create a Dynamic Flickr Image Search with the Dojo&#160;Toolkit</title><link>http://davidwalsh.name/dojo-flickr</link> <comments>http://davidwalsh.name/dojo-flickr#comments</comments> <pubDate>Tue, 24 Aug 2010 01:46:49 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[AJAX]]></category> <category><![CDATA[APIs]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[Markup]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5051</guid> <description><![CDATA[The Dojo Toolkit is a treasure chest of great JavaScript classes.  You can find basic JavaScript functionality classes for AJAX, node manipulation, animations, and the like within Dojo.  You can find elegant, functional UI widgets like DropDown Menus, tabbed interfaces, and form element replacements within Dijit.  In DojoX you can find charting libraries, special data [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/dojo-flickr">Create a Dynamic Flickr Image Search with the Dojo&nbsp;Toolkit</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/dojo-context-menu' rel='bookmark' title='Permanent Link: Create a Context Menu with Dojo and&nbsp;Dijit'>Create a Context Menu with Dojo and&nbsp;Dijit</a></li><li><a
href='http://davidwalsh.name/dojo-accordion' rel='bookmark' title='Permanent Link: Create a Simple Dojo&nbsp;Accordion'>Create a Simple Dojo&nbsp;Accordion</a></li><li><a
href='http://davidwalsh.name/dojo-dijit-charting' rel='bookmark' title='Permanent Link: Dive Into Dojo Series:  Dijit and&nbsp;Charting'>Dive Into Dojo Series:  Dijit and&nbsp;Charting</a></li><li><a
href='http://davidwalsh.name/dojo-digg' rel='bookmark' title='Permanent Link: Digg-Style Dynamic Share Widget Using the Dojo&nbsp;Toolkit'>Digg-Style Dynamic Share Widget Using the Dojo&nbsp;Toolkit</a></li><li><a
href='http://davidwalsh.name/dojo-tabs' rel='bookmark' title='Permanent Link: Dijit&#8217;s TabContainer Layout:  Easy Tabbed&nbsp;Content'>Dijit&#8217;s TabContainer Layout:  Easy Tabbed&nbsp;Content</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
href="http://davidwalsh.name/dw-content/dojo-flickr.php"><img
src="http://davidwalsh.name/dw-content/dojo-flickr.jpg" alt="Dojo Flickr" /></a></p><p>The Dojo Toolkit is a treasure chest of great JavaScript classes.  You can find basic JavaScript functionality classes for AJAX, node manipulation, animations, and the like within Dojo.  You can find elegant, functional UI widgets like DropDown Menus, tabbed interfaces, and form element replacements within Dijit.  In DojoX you can find charting libraries, special data stores, vector graphic helpers, and much more.</p><p>This post aims to mesh the three collections together.  We&#8217;ll be creating a tabbed interface for grabbing Flickr images using Dijit&#8217;s TabContainer, <a
href="http://www.dojotoolkit.org/reference-guide/dojox/data/FlickrStore.html#dojox-data-flickrstore" rel="nofollow">DojoX&#8217;s Flickr data store</a>, and basic Dojo code for event handling and node manipulation.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/dojo-flickr.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>Select a&nbsp;Theme</h2><p>There are two main steps in adding a theme to the page:  importing the theme stylesheet and adding the theme as a class name to the <code>BODY</code> element.</p><pre class="css">
&lt;style type="text/css"&gt;
	/* bring in the claro theme */
	@import "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/claro/claro.css";
	
	/* define styles per the images */
	a.thumb	{ display:inline-block; margin:0 20px 20px 0; }
	
&lt;/style&gt;
</pre><pre class="html">
&lt;body class="claro"&gt;
</pre><p>The claro theme is new in Dojo 1.5 and happens to be my favorite.</p><h2>Import Dojo From CDN,&nbsp;parseOnLoad:true</h2><p>Pulling from Google&#8217;s CDN makes Dojo load lightning-fast.  Adding a <code>djConfig</code> attribute with <code>parseOnLoad:true</code> instructs Dojo to scour the page looking for widgets.</p><pre class="html">
&lt;script src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js" type="text/javascript" djConfig="parseOnLoad:true"&gt;&lt;/script&gt;
</pre><p>Alternatively you could configure Dojo by using the <code>djConfig</code> JavaScript variable:</p><pre class=" js">
djConfig = {
	parseOnLoad: true
};
</pre><p>Either way will suffice.</p><h2>Create the HTML Structure: Tab Container and Search&nbsp;Form</h2><p>Setting up the form comes first.  The form is going to be very simple, containing only a search box and a submit button.  Each node (<code>FORM</code>, <code>INPUT</code>, and <code>BUTTON</code>) is converted to its Dijit widget equivalent to provide extra functionality and themed display.</p><pre class="html">
&lt;!-- search will be here --&gt;
&lt;form dojoType="dijit.form.Form" id="searchForm"&gt;
	&lt;input dojoType="dijit.form.ValidationTextBox" id="searchBox" missingMessage="Please provide a term to search" placeholder="search term..." required="true" /&gt;
	&lt;button type="submit" dojoType="dijit.form.Button" id="searchButton"&gt;Submit Search&lt;/button&gt;
&lt;/form&gt;
</pre><p>The search box becomes a <code>dijit.form.ValidationTextBox</code> which allows me to require a value and display an error message if no term is provided.  I&#8217;ve also used the <code>placeholder</code> attribute to display a message in the search box when there is no value.  Dojo&#8217;s internal awesomeness adds JavaScript support for the same functionality if the user&#8217;s browser doesn&#8217;t support <code>placeholder</code> yet.</p><p>The second piece is placing the <code>TabContainer</code> and its initial content pane in the page.  The initial <code>ContentPane</code> content will simply be a &#8220;welcome&#8221; tab so that there&#8217;s always one tab within the container:</p><pre class="html">
&lt;!-- will set the eventual dimensions for the tab container --&gt;
&lt;div style="width:675px;height:400px"&gt;
	&lt;!-- will host all tabs and their content panes --&gt;
	&lt;div dojoType="dijit.layout.TabContainer" id="tabContainer" style="width:100%;height:100%;"&gt;
		&lt;!-- welcome pane: title is tab name, make this tab selected --&gt;
		&lt;div dojoType="dijit.layout.ContentPane" title="Welcome Pane" selected="true"&gt;
			&lt;p&gt;
				Welcome to the Flickr Search data store and Tab Container example.  
				Submit your search and watch the tab load!
			&lt;/p&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre><p>Future tabs will be closable.</p><h2>Require Dojo/Dijit/DojoX&nbsp;Dependencies</h2><p>Before we can create our widgets and use Dojo classes, we need to load them:</p><pre class="js">
/* require necessary classes */
dojo.require('dijit.layout.TabContainer');
dojo.require('dijit.layout.ContentPane');
dojo.require('dijit.form.Button');
dojo.require('dijit.form.Form');
dojo.require('dijit.form.ValidationTextBox');
dojo.require('dojox.data.FlickrStore');
dojo.require('dijit.Tooltip');
</pre><p>Dojo&#8217;s internal functionality will also direct dependencies of dependencies to be loaded.  If you aren&#8217;t familiar with Dojo class loading, be sure to read <a
href="http://davidwalsh.name/dojo-require">The Beauty of dojo.require()</a>.</p><h2>Dojo, Dijit, DojoX:  Make It&nbsp;Happen</h2><p>Now that the theme is in place, HTML structure is there, and we&#8217;ve required the necessary classes, we can code our application-specific JavaScript.  There&#8217;s a decent amount of JavaScript need to make this work so let&#8217;s break it down.</p><p>Start by creating an object which will hold all of our open tabs and an instance of <code>dojox.data.FlickrStore</code> which will be used to query Flickr:</p><pre class="js">
/* settings */
var tabSubjects = {};
var flickrStore = new dojox.data.FlickrStore();
</pre><p>Then collect the form elements as well as the <code>TabContainer</code>:</p><pre class="js">
/* collect proper elements */
var searchForm = dijit.byId('searchForm');
var searchBox = dijit.byId('searchBox');
var searchButton = dijit.byId('searchButton');
var tabContainer = dijit.byId('tabContainer');
</pre><p>Add a &#8220;submit&#8221; event listener to the <code>TabContainer</code>&#8230;</p><pre class="js">
/* connect click event to search */
dojo.connect(searchForm,'onSubmit',function(e) {
</pre><p>&#8230;which stops the normal form submission:</p><pre class="js">
//stop!
dojo.stopEvent(e);
</pre><p>&#8230;grabs the value of the search box:</p><pre class="js">
//store value - set to lower case to save to caching object
var value = searchBox.get('value').toLowerCase();
</pre><p>If a value is present, make sure there isn&#8217;t currently a search tab open for that term.  If there is, focus on it.  If this is a new search term, direct the <code>dojox.data.FlickrStore</code> instance to search and return images for the given term.  Upon search, a new tab for this term is created with a default title and content string, added to the TabContainer, and this new tab is selected:</p><pre class="js">
//if a value exists...
if(value) {
	//if the tab isn't already there...
	if(!tabSubjects[value]) {
		//do the search...
		flickrStore.fetch({
			query: { tags: value },
			onBegin: function() {
				//create the tab
				tabSubjects[value] = new dijit.layout.ContentPane({ 
					title:value, 
					content:'Searching for ' + value + '...', 
					closable:true,
					onClose: function() {
						//remove this from our saved tabs when closed
						tabSubjects[value] = null;
						return true;
					}
				});
				//add to tabcontainer and select
				tabContainer.addChild(tabSubjects[value]);
				tabContainer.selectChild(tabSubjects[value]);
			},
</pre><p>When the search is complete, we clear the contents of the tab&#8217;s pane and loop through each returned image, injecting it into the content pane.  Lastly, we create a tooltip for the image which displays the image name when the user focuses on the image:</p><pre class="js">
	onComplete: function(items) {
		//if we got items...
		if(items.length) {
			//clear the tab's content'
			tabSubjects[value].set('content','');
			//cycle through each image returned, inject into new tab, add tooltip
			dojo.forEach(items,function(item,i) {
				//create the link's ID for the tooltip
				var id = new Date().getTime() + '_' + i;
				var a = dojo.create('a',{ 
					href: flickrStore.getValue(item,'link'),
					className: 'thumb',
					target: '_blank',
					id:  id,
					innerHTML: '&lt;img src="' + flickrStore.getValue(item,'imageUrlSmall') + '" alt="' + flickrStore.getValue(item,'title') +'" /&gt;'
				},tabSubjects[value].domNode);
				//tooltip!
				new dijit.Tooltip({ label: flickrStore.getValue(item,'title'), connectId: id });
			});
		}
		else {
			//provide "no images" content
			tabSubjects[value].set('content','There were no images available for this term.');
		}
		//empty the search box
		searchBox.set('value','');
		
	}
});
</pre><p>Here&#8217;s the complete JavaScript block for this app:</p><pre class="js">
/* require necessary classes */
dojo.require('dijit.layout.TabContainer');
dojo.require('dijit.layout.ContentPane');
dojo.require('dijit.form.Button');
dojo.require('dijit.form.Form');
dojo.require('dijit.form.ValidationTextBox');
dojo.require('dojox.data.FlickrStore');
dojo.require('dijit.Tooltip');

/* when all classes have loaded... */
dojo.ready(function() {
	
	/* settings */
	var tabSubjects = {};
	var flickrStore = new dojox.data.FlickrStore();
	
	/* collect proper elements */
	var searchForm = dijit.byId('searchForm');
	var searchBox = dijit.byId('searchBox');
	var searchButton = dijit.byId('searchButton');
	var tabContainer = dijit.byId('tabContainer');
	
	/* connect click event to search */
	dojo.connect(searchForm,'onSubmit',function(e) {
		//stop!
		dojo.stopEvent(e);
		//store value
		var value = searchBox.get('value').toLowerCase();
		//if a value exists...
		if(value) {
			//if the tab isn't already there...
			if(!tabSubjects[value]) {
				//do the search...
				flickrStore.fetch({
					query: { tags: value },
					onBegin: function() {
						//create the tab
						tabSubjects[value] = new dijit.layout.ContentPane({ 
							title:value, 
							content:'Searching for ' + value + '...', 
							closable:true,
							onClose: function() {
								//remove this from our saved tabs when closed
								tabSubjects[value] = null;
								return true;
							}
						});
						//add to tabcontainer and select
						tabContainer.addChild(tabSubjects[value]);
						tabContainer.selectChild(tabSubjects[value]);
					},
					onComplete: function(items) {
						//if we got items...
						if(items.length) {
							//clear the tab's content'
							tabSubjects[value].set('content','');
							//cycle through each image returned, inject into new tab, add tooltip
							dojo.forEach(items,function(item,i) {
								//create the link's ID for the tooltip
								var id = new Date().getTime() + '_' + i;
								var a = dojo.create('a',{ 
									href: flickrStore.getValue(item,'link'),
									className: 'thumb',
									target: '_blank',
									id:  id,
									innerHTML: '&lt;img src="' + flickrStore.getValue(item,'imageUrlSmall') + '" alt="' + flickrStore.getValue(item,'title') +'" /&gt;'
								},tabSubjects[value].domNode);
								//tooltip!
								if(flickrStore.getValue(item,'title')) { new dijit.Tooltip({ label: flickrStore.getValue(item,'title'), connectId: id }); }
							});
						}
						else {
							//provide "no images" content
							tabSubjects[value].set('content','There were no images available for this term.');
						}
						//empty the search box
						searchBox.set('value','');
						
					}
				});
			}
			//if it does exist, focus on it
			else {
				tabContainer.selectChild(tabSubjects[value]);
			}
		}
	});
});
</pre><p>How long would you say this took to write?  Half hour?  Hour? Three hours?  Nope.  This mini-application only took me about 15 minutes to write!  DojoX also features a class for pulling images from Picasa.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/dojo-flickr.php" class="demo">View Demo</a><div
class="clear"></div></div><p>Nice, huh?  Meshing Dojo, Dijit, and DojoX classes is a breeze thanks to Dojo&#8217;s tightly knit class system.  I challenge you to create a simple application and see what you can do in an hour.  Use <a
href="http://download.dojotoolkit.org/release-1.5.0/dojo-release-1.5.0/dijit/themes/themeTester.html">Theme Tester</a> as a helper should you need inspiration!  And always share what you&#8217;ve created when you&#8217;re done!</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/dojo-flickr">Create a Dynamic Flickr Image Search with the Dojo&nbsp;Toolkit</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/dojo-context-menu' rel='bookmark' title='Permanent Link: Create a Context Menu with Dojo and&nbsp;Dijit'>Create a Context Menu with Dojo and&nbsp;Dijit</a></li><li><a
href='http://davidwalsh.name/dojo-accordion' rel='bookmark' title='Permanent Link: Create a Simple Dojo&nbsp;Accordion'>Create a Simple Dojo&nbsp;Accordion</a></li><li><a
href='http://davidwalsh.name/dojo-dijit-charting' rel='bookmark' title='Permanent Link: Dive Into Dojo Series:  Dijit and&nbsp;Charting'>Dive Into Dojo Series:  Dijit and&nbsp;Charting</a></li><li><a
href='http://davidwalsh.name/dojo-digg' rel='bookmark' title='Permanent Link: Digg-Style Dynamic Share Widget Using the Dojo&nbsp;Toolkit'>Digg-Style Dynamic Share Widget Using the Dojo&nbsp;Toolkit</a></li><li><a
href='http://davidwalsh.name/dojo-tabs' rel='bookmark' title='Permanent Link: Dijit&#8217;s TabContainer Layout:  Easy Tabbed&nbsp;Content'>Dijit&#8217;s TabContainer Layout:  Easy Tabbed&nbsp;Content</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-flickr/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Change Category Slug within&#160;WordPress</title><link>http://davidwalsh.name/wordpress-category-slug</link> <comments>http://davidwalsh.name/wordpress-category-slug#comments</comments> <pubDate>Thu, 12 Aug 2010 14:16:04 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5037</guid> <description><![CDATA[When I first started this blog, I set the category &#8220;slug&#8221; to &#8220;sugar.&#8221;  Why sugar?  Because a lot of a good thing is candy;  thus, a bunch of MooTools tutorials is as sweet as sugar.  While I get a giggle out of calling my categories sugar, Google doesn&#8217;t find it nearly as funny, nor does [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/wordpress-category-slug">Change Category Slug within&nbsp;WordPress</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/php-wordpress-post-categories' rel='bookmark' title='Permanent Link: PHP: Get WordPress Post&nbsp;Categories'>PHP: Get WordPress Post&nbsp;Categories</a></li><li><a
href='http://davidwalsh.name/detect-ipad' rel='bookmark' title='Permanent Link: iPad Detection Using JavaScript or&nbsp;PHP'>iPad Detection Using JavaScript or&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/april-fools-change-php-pages-asp' rel='bookmark' title='Permanent Link: April Fools!  Change Your PHP Pages to ASP&#8230;Or&nbsp;Not'>April Fools!  Change Your PHP Pages to ASP&#8230;Or&nbsp;Not</a></li><li><a
href='http://davidwalsh.name/change-php-query-string-variable-separator-php-ini' rel='bookmark' title='Permanent Link: Change the PHP Query String Variable Separator Using&nbsp;php.ini'>Change the PHP Query String Variable Separator Using&nbsp;php.ini</a></li><li><a
href='http://davidwalsh.name/php-redirect-function' rel='bookmark' title='Permanent Link: PHP Redirect&nbsp;Function'>PHP Redirect&nbsp;Function</a></li></ol>]]></description> <content:encoded><![CDATA[<p>When I first started this blog, I set the category &#8220;slug&#8221; to &#8220;sugar.&#8221;  Why sugar?  Because a lot of a good thing is candy;  thus, a bunch of MooTools tutorials is as sweet as sugar.  While I get a giggle out of calling my categories sugar, Google doesn&#8217;t find it nearly as funny, nor does Yahoo or Bing.  In an effort to increase my SEO, I wanted to change my category slug to &#8220;tutorials.&#8221;  That&#8217;s where the awesome Redirection plugin and a simple regular expression comes into place.</p><h2>Changing the&nbsp;Slug</h2><p>You can very easily change the category slug within WordPress&#8217;s admin panel by navigating to Settings &gt;&gt; Permalinks:</p><img
src="http://davidwalsh.name/dw-content/wordpress-category-slug.jpg" alt="WordPress Category" /><p>I changed the slug from &#8220;sugar&#8221; to &#8220;tutorials.&#8221;</p><h2>WordPress&nbsp;Redirection</h2><p>So why do we need the <a
href="http://wordpress.org/extend/plugins/redirection/">Redirection plugin</a>?  Because search engines like Google and users who have bookmarked your site will try to reach the old address.  Thus, we need an appropriate redirect to push them to the new address.  Not only do we need a redirection plugin but we need it to be reliable.  I&#8217;ve been using Redirection for <em>years</em> so I knew this would be the best route.</p><p>While Redirection allows you to make a simple URL to URL redirection, I needed something a bit more powerful since almost anything could be after &#8220;/sugar/&#8221; in the URL.  What I did was use Redirection&#8217;s regular expression capabilities to create a wildcard search on the URL to redirect all &#8220;/sugar/&#8221; URLs to &#8220;/tutorials/&#8221; URLS:</p><img
src="http://davidwalsh.name/dw-content/wordpress-redirection.jpg" alt=" WordPress Redirection" /><p>And there I have it;  all category URLs are redirected as they should be!  The <code>(*)</code> in the source URL grabs the text after &#8220;/sugar/&#8221; in the URL and the <code>$1</code> in the Target URL places that text after the new category slug!</p><p>The Redirection plugin for WordPress is outstanding.  As I mentioned above, I&#8217;ve used it for years, have hundreds of redirections in place, and it&#8217;s always been one of my most trusted plugins.  Thanks to <a
href="http://profiles.wordpress.org/users/johnny5">John Godley</a> for his great plugin!</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/wordpress-category-slug">Change Category Slug within&nbsp;WordPress</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/php-wordpress-post-categories' rel='bookmark' title='Permanent Link: PHP: Get WordPress Post&nbsp;Categories'>PHP: Get WordPress Post&nbsp;Categories</a></li><li><a
href='http://davidwalsh.name/detect-ipad' rel='bookmark' title='Permanent Link: iPad Detection Using JavaScript or&nbsp;PHP'>iPad Detection Using JavaScript or&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/april-fools-change-php-pages-asp' rel='bookmark' title='Permanent Link: April Fools!  Change Your PHP Pages to ASP&#8230;Or&nbsp;Not'>April Fools!  Change Your PHP Pages to ASP&#8230;Or&nbsp;Not</a></li><li><a
href='http://davidwalsh.name/change-php-query-string-variable-separator-php-ini' rel='bookmark' title='Permanent Link: Change the PHP Query String Variable Separator Using&nbsp;php.ini'>Change the PHP Query String Variable Separator Using&nbsp;php.ini</a></li><li><a
href='http://davidwalsh.name/php-redirect-function' rel='bookmark' title='Permanent Link: PHP Redirect&nbsp;Function'>PHP Redirect&nbsp;Function</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/wordpress-category-slug/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Async Google&#160;Analytics</title><link>http://davidwalsh.name/async-google-analytics</link> <comments>http://davidwalsh.name/async-google-analytics#comments</comments> <pubDate>Fri, 22 Jan 2010 14:16:53 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Google]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4657</guid> <description><![CDATA[It seems like every website these days uses Google Analytics. And why not? It&#8217;s an outstanding tool that gives you any and every statistic you could ever want. The problem with Google Analytics is that it&#8217;s been, well, slow loading at times. That&#8217;s why I was so pumped when I saw Google was releasing an [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/async-google-analytics">Async Google&nbsp;Analytics</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/secure-ssl-google-analytics' rel='bookmark' title='Permanent Link: Secure (SSL) Google&nbsp;Analytics'>Secure (SSL) Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/track-file-downloads-google-analytics-mootools' rel='bookmark' title='Permanent Link: Track File Downloads in Google Analytics Using&nbsp;MooTools'>Track File Downloads in Google Analytics Using&nbsp;MooTools</a></li><li><a
href='http://davidwalsh.name/php-google-analytics' rel='bookmark' title='Permanent Link: Retrieve Google Analytics Visits and PageViews with&nbsp;PHP'>Retrieve Google Analytics Visits and PageViews with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/mootools-google-analytics-track-outbound-links' rel='bookmark' title='Permanent Link: Using MooTools to Instruct Google Analytics to Track Outbound&nbsp;Links'>Using MooTools to Instruct Google Analytics to Track Outbound&nbsp;Links</a></li><li><a
href='http://davidwalsh.name/track-ajax-link-clicks-google-analytics' rel='bookmark' title='Permanent Link: Track AJAX Link Clicks Using Google&nbsp;Analytics'>Track AJAX Link Clicks Using Google&nbsp;Analytics</a></li></ol>]]></description> <content:encoded><![CDATA[<p>It seems like every website these days uses Google Analytics.  And why not?  It&#8217;s an outstanding tool that gives you any and every statistic you could ever want.  The problem with Google Analytics is that it&#8217;s been, well, slow loading at times.  That&#8217;s why I was so pumped when I saw Google was releasing an async version of their script.</p><h2>Google Analytics&nbsp;JavaScript</h2><pre class="js">
&lt;script type=&quot;text/javascript&quot;&gt;
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-#######-#']); //your code here
    _gaq.push(['_trackPageview']);
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
(function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
  })();
&lt;/script&gt;
</pre><p>The one thing you&#8217;ll notice is the <span
class="attribute">async</span> attribute being set to <span
class="attribute">true</span>.  Obviously you&#8217;ll want to use your own Analytics code within the top portion of the JavaScript.  You&#8217;ll also want to put this at the top of the <span
class="tag">BODY</span>.  What a difference the async version can make &#8212; my website seems to load faster due to this upgrade!</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/async-google-analytics">Async Google&nbsp;Analytics</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/secure-ssl-google-analytics' rel='bookmark' title='Permanent Link: Secure (SSL) Google&nbsp;Analytics'>Secure (SSL) Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/track-file-downloads-google-analytics-mootools' rel='bookmark' title='Permanent Link: Track File Downloads in Google Analytics Using&nbsp;MooTools'>Track File Downloads in Google Analytics Using&nbsp;MooTools</a></li><li><a
href='http://davidwalsh.name/php-google-analytics' rel='bookmark' title='Permanent Link: Retrieve Google Analytics Visits and PageViews with&nbsp;PHP'>Retrieve Google Analytics Visits and PageViews with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/mootools-google-analytics-track-outbound-links' rel='bookmark' title='Permanent Link: Using MooTools to Instruct Google Analytics to Track Outbound&nbsp;Links'>Using MooTools to Instruct Google Analytics to Track Outbound&nbsp;Links</a></li><li><a
href='http://davidwalsh.name/track-ajax-link-clicks-google-analytics' rel='bookmark' title='Permanent Link: Track AJAX Link Clicks Using Google&nbsp;Analytics'>Track AJAX Link Clicks Using Google&nbsp;Analytics</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/async-google-analytics/feed</wfw:commentRss> <slash:comments>25</slash:comments> </item> <item><title>Using the GitHub API and PHP to Get Repository&#160;Information</title><link>http://davidwalsh.name/github-markdown</link> <comments>http://davidwalsh.name/github-markdown#comments</comments> <pubDate>Wed, 30 Dec 2009 14:10:17 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4526</guid> <description><![CDATA[GitHub is an awesome place to host your open source project code. MooTools, Prototype, and jQuery all use GitHub. As you probably know, the MooTools Forge requires your plugins be hosted on GitHub. The only problem with hosting all my MooTools plugins is that I lose traffic when I want people to see my code. [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/github-markdown">Using the GitHub API and PHP to Get Repository&nbsp;Information</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/mootools-forge-script' rel='bookmark' title='Permanent Link: MooTools Forge / GitHub Plugin Structure Shell&nbsp;Script'>MooTools Forge / GitHub Plugin Structure Shell&nbsp;Script</a></li><li><a
href='http://davidwalsh.name/mootools-plugins' rel='bookmark' title='Permanent Link: Forge:  MooTools Plugin&nbsp;Repository'>Forge:  MooTools Plugin&nbsp;Repository</a></li><li><a
href='http://davidwalsh.name/github-badge' rel='bookmark' title='Permanent Link: Represent Your Repositories Using the GitHub&nbsp;Badge!'>Represent Your Repositories Using the GitHub&nbsp;Badge!</a></li><li><a
href='http://davidwalsh.name/github-merge-batch' rel='bookmark' title='Permanent Link: Create a GitHub Merge Batch&nbsp;File'>Create a GitHub Merge Batch&nbsp;File</a></li><li><a
href='http://davidwalsh.name/mootools-github' rel='bookmark' title='Permanent Link: Follow MooTools on&nbsp;GitHub!'>Follow MooTools on&nbsp;GitHub!</a></li></ol>]]></description> <content:encoded><![CDATA[<p>GitHub is an awesome place to host your open source project code.  MooTools, Prototype, and jQuery all use GitHub.  As you probably know, the MooTools Forge requires your plugins be hosted on GitHub.  The only problem with hosting all my MooTools plugins is that I lose traffic when I want people to see my code.   Problem solved:  use PHP, the GitHub API, and PHP Markdown to display files of my choice on my website.</p><p>Our goals with this code will be to:</p><ul><li>Connect to GitHub via the API to retrieve repository information.</li><li>Retrieve the content of two files from the repository:  a source file and the README.md Markdown file.</li><li>Cache the information for a given period of time to reduce the load on GitHub.</li><li>Use PHP Markdown to output a formatted README.md file.</li></ul><p>I know that seems like a lot of work but you&#8217;ll be amazed at how easy the process is.</p><h2>PHP&nbsp;MarkDown</h2><p>You may download PHP Markdown at <a
href="http://michelf.com/projects/php-markdown/">Michel Fortin&#8217;s website</a>.  It&#8217;s simple and full of features.</p><h2>The&nbsp;PHP</h2><p>The first step is to build a PHP function that will connect to GitHub using cURL:</p><pre class="php">
/* gets url */
function get_content_from_github($url) {
	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,1);
	$content = curl_exec($ch);
	curl_close($ch);
	return $content;
}
</pre><p>Next we need to define a few settings:</p><pre class="php">
/* static settings */
$plugin = 'Overlay';
$cache_path = $_SERVER['DOCUMENT_ROOT'].'/plugin-cache/';
$cache_file = $plugin.'-github.txt';
$github_json = get_repo_json($cache_path.$cache_file,$plugin);
</pre><p>The next step is to create another PHP function that grabs the repository information (JSON-encoded, because I love JSON) &#8212; either fresh from GitHub (by first grabbing the most recent commit hash, then grabbing the contents of the two files) or our local cached information:</p><pre class="php">
/* gets the contents of a file if it exists, otherwise grabs and caches */
function get_repo_json($file,$plugin) {
	//vars
	$current_time = time(); $expire_time = 24 * 60 * 60; $file_time = filemtime($file);
	//decisions, decisions
	if(file_exists($file) &#038;&#038; ($current_time - $expire_time < $file_time)) {
		//echo 'returning from cached file';
		return json_decode(file_get_contents($file));
	}
	else {
		$json = array();
		$json['repo'] = json_decode(get_content_from_github('http://github.com/api/v2/json/repos/show/darkwing/'.$plugin),true);
		$json['commit'] = json_decode(get_content_from_github('http://github.com/api/v2/json/commits/list/darkwing/'.$plugin.'/master'),true);
		$json['readme'] = json_decode(get_content_from_github('http://github.com/api/v2/json/blob/show/darkwing/'.$plugin.'/'.$json['commit']['commits'][0]['parents'][0]['id'].'/Docs/'.$plugin.'.md'),true);
		$json['js'] = json_decode(get_content_from_github('http://github.com/api/v2/json/blob/show/darkwing/'.$plugin.'/'.$json['commit']['commits'][0]['parents'][0]['id'].'/Source/'.$plugin.'.js'),true);
		file_put_contents($file,json_encode($json));
		return $content;
	}
}
</pre><p>Once we've acquired the appropriate information, we output the information to screen:</p><pre class="php">
/* build json */
if($github_json) {
	
	//get markdown
	include($_SERVER['DOCUMENT_ROOT'].'/wp-content/themes/walshbook3/PHP-Markdown-Extra-1.2.4/markdown.php');
	
	//build content
	$content = '<p>'.$github_json['repo']['repository']['description'].'</p>';
	$content.= '<h2>MooTools JavaScript&nbsp;Class</h2><pre class="js">'.$github_json['js']['blob']['data'].'</pre><br
/>';
$content.= trim(str_replace(array('<code>','</code>'),'',Markdown($github_json['readme']['blob']['data'])));
} </pre><p>That's all!  Now I get the benefit of hosting my code on GitHub but displaying it on my own website.  I've created a special WordPress template page to do so and recommend you do too!</p><h2>Demo?</h2><p>Visit my <a
href="http://davidwalsh.name/js/">Projects page</a> and click on the "Docs" link for any project.  All of the information that comes up on individual project pages comes from GitHub.  No more manual page creation!</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/github-markdown">Using the GitHub API and PHP to Get Repository&nbsp;Information</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/mootools-forge-script' rel='bookmark' title='Permanent Link: MooTools Forge / GitHub Plugin Structure Shell&nbsp;Script'>MooTools Forge / GitHub Plugin Structure Shell&nbsp;Script</a></li><li><a
href='http://davidwalsh.name/mootools-plugins' rel='bookmark' title='Permanent Link: Forge:  MooTools Plugin&nbsp;Repository'>Forge:  MooTools Plugin&nbsp;Repository</a></li><li><a
href='http://davidwalsh.name/github-badge' rel='bookmark' title='Permanent Link: Represent Your Repositories Using the GitHub&nbsp;Badge!'>Represent Your Repositories Using the GitHub&nbsp;Badge!</a></li><li><a
href='http://davidwalsh.name/github-merge-batch' rel='bookmark' title='Permanent Link: Create a GitHub Merge Batch&nbsp;File'>Create a GitHub Merge Batch&nbsp;File</a></li><li><a
href='http://davidwalsh.name/mootools-github' rel='bookmark' title='Permanent Link: Follow MooTools on&nbsp;GitHub!'>Follow MooTools on&nbsp;GitHub!</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/github-markdown/feed</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Simple PHP Caching and Content Retrieval&#160;Function</title><link>http://davidwalsh.name/php-cache-function</link> <comments>http://davidwalsh.name/php-cache-function#comments</comments> <pubDate>Thu, 10 Dec 2009 17:52:58 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4270</guid> <description><![CDATA[One way to make your website exponentially faster is by caching both remote and internal requests. Why request your RSS subscriber count from FeedBurner more than once a day if that count is calculated once per day? Why hit your database on each page load if that content rarely changes? I&#8217;ve created a primitive request-and-cache [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/php-cache-function">Simple PHP Caching and Content Retrieval&nbsp;Function</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/cache-feedburner' rel='bookmark' title='Permanent Link: Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count'>Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count</a></li><li><a
href='http://davidwalsh.name/download-urls-content-php-curl' rel='bookmark' title='Permanent Link: Download a URL&#8217;s Content Using PHP&nbsp;cURL'>Download a URL&#8217;s Content Using PHP&nbsp;cURL</a></li><li><a
href='http://davidwalsh.name/download-google-ajax-libraries' rel='bookmark' title='Permanent Link: Remotely Download Google AJAX Libraries Using&nbsp;PHP'>Remotely Download Google AJAX Libraries Using&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/cache-ajax' rel='bookmark' title='Permanent Link: Caching AJAX Results in&nbsp;JavaScript'>Caching AJAX Results in&nbsp;JavaScript</a></li><li><a
href='http://davidwalsh.name/twitter-friendships' rel='bookmark' title='Permanent Link: Test Twitter Friendships with&nbsp;PHP'>Test Twitter Friendships with&nbsp;PHP</a></li></ol>]]></description> <content:encoded><![CDATA[<p>One way to make your website exponentially faster is by caching both remote and internal requests.  Why request your RSS subscriber count from FeedBurner more than once a day if that count is calculated once per day?  Why hit your database on each page load if that content rarely changes?  I&#8217;ve created a primitive request-and-cache function for PHP that checks for fresh content in the cache and retrieves content from a source if fresh content isn&#8217;t available.</p><h2>The PHP&nbsp;Function</h2><pre class="php">
/* gets the contents of a file if it exists, otherwise grabs and caches */
function get_content($file,$url,$hours = 24,$fn = '',$fn_args = '') {
	//vars
	$current_time = time(); $expire_time = $hours * 60 * 60; $file_time = filemtime($file);
	//decisions, decisions
	if(file_exists($file) &#038;&#038; ($current_time - $expire_time < $file_time)) {
		//echo 'returning from cached file';
		return file_get_contents($file);
	}
	else {
		$content = get_url($url);
		if($fn) { $content = $fn($content,$fn_args); }
		$content.= '';
		file_put_contents($file,$content);
		//echo 'retrieved fresh from '.$url.':: '.$content;
		return $content;
	}
}

/* gets content from a URL via curl */
function get_url($url) {
	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5);
	$content = curl_exec($ch);
	curl_close($ch);
	return $content;
}
</pre><p>My <span
class="function">get_content</span> function accepts four arguments:</p><ul><li>The file to grab content from.  If the file doesn&#8217;t exist, the file is created and content placed into.</li><li>The URL to get content from if cached content isn&#8217;t fresh.</li><li>A function name to pass the freshly received content to.</li><li>Arguments to pass to the third argument&#8217;s function.</li></ul><p>The function is, of course, very primitive.  I like that my function handles both retrieval and caching so that I don&#8217;t need to repeat code whenever I want cached content.</p><h2>Sample Usage&nbsp;1</h2><pre class="php">
/* usage */
$TWITTER_FOLLOWERS_FILE_NAME = 'twitter-followers.txt';
$TWITTER_FOLLOWERS_URL = 'http://twitter.com/users/show.json?screen_name=davidwalshblog';

$TWITTER_FOLLOWERS = get_content($TWITTER_FOLLOWERS_FILE_NAME,$TWITTER_FOLLOWERS_URL,3,'format_followers',array('file'=>$TWITTER_FOLLOWERS_FILE_NAME));
/* utility function */
function format_followers($content,$args) {
	$content = json_decode($content);
	$twitter_subscribers = $content->{'followers_count'};
	if($twitter_subscribers) {
		$twitter_subscribers = number_format($twitter_subscribers,0,'',',');
		file_put_contents($args['file'],$twitter_subscribers);
		return $twitter_subscribers;
	}
}
</pre><p>The above code retrieves my Twitter follower count, parses the code, and caches the content for three hours.</p><p>There are several more advanced PHP caching classes available but the simple function above covers most of my needs &#8212; hopefully it can help you out too!</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/php-cache-function">Simple PHP Caching and Content Retrieval&nbsp;Function</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/cache-feedburner' rel='bookmark' title='Permanent Link: Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count'>Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count</a></li><li><a
href='http://davidwalsh.name/download-urls-content-php-curl' rel='bookmark' title='Permanent Link: Download a URL&#8217;s Content Using PHP&nbsp;cURL'>Download a URL&#8217;s Content Using PHP&nbsp;cURL</a></li><li><a
href='http://davidwalsh.name/download-google-ajax-libraries' rel='bookmark' title='Permanent Link: Remotely Download Google AJAX Libraries Using&nbsp;PHP'>Remotely Download Google AJAX Libraries Using&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/cache-ajax' rel='bookmark' title='Permanent Link: Caching AJAX Results in&nbsp;JavaScript'>Caching AJAX Results in&nbsp;JavaScript</a></li><li><a
href='http://davidwalsh.name/twitter-friendships' rel='bookmark' title='Permanent Link: Test Twitter Friendships with&nbsp;PHP'>Test Twitter Friendships with&nbsp;PHP</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/php-cache-function/feed</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>Get a URL&#8217;s Reddit Score Using PHP and&#160;JSON</title><link>http://davidwalsh.name/get-reddit-score</link> <comments>http://davidwalsh.name/get-reddit-score#comments</comments> <pubDate>Wed, 11 Nov 2009 14:04:13 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4189</guid> <description><![CDATA[Since we can see Digg turning more into a funny-pic-and-vid site each day, I&#8217;ve turned my attention to Reddit. Reddit just seems more controlled and programmer-friendly. Since I have respect for Reddit I thought I&#8217;d put together a quick tutorial on how you can retrieve a URL&#8217;s Reddit score using PHP. The&#160;PHP &#60;?php /* settings [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/get-reddit-score">Get a URL&#8217;s Reddit Score Using PHP and&nbsp;JSON</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/web-service-php-mysql-xml-json' rel='bookmark' title='Permanent Link: Create a Basic Web Service Using PHP, MySQL, XML, and&nbsp;JSON'>Create a Basic Web Service Using PHP, MySQL, XML, and&nbsp;JSON</a></li><li><a
href='http://davidwalsh.name/cache-feedburner' rel='bookmark' title='Permanent Link: Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count'>Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count</a></li><li><a
href='http://davidwalsh.name/php-cache-function' rel='bookmark' title='Permanent Link: Simple PHP Caching and Content Retrieval&nbsp;Function'>Simple PHP Caching and Content Retrieval&nbsp;Function</a></li><li><a
href='http://davidwalsh.name/bitly-api-php' rel='bookmark' title='Permanent Link: Create Bit.ly Short URLs Using PHP: API Version&nbsp;3'>Create Bit.ly Short URLs Using PHP: API Version&nbsp;3</a></li><li><a
href='http://davidwalsh.name/create-tiny-url-php' rel='bookmark' title='Permanent Link: Create a TinyURL with&nbsp;PHP'>Create a TinyURL with&nbsp;PHP</a></li></ol>]]></description> <content:encoded><![CDATA[<img
class="image" src="http://davidwalsh.name/dw-content/reddit-larger.png" alt="Reddit Guy" /><p>Since we can see Digg turning more into a funny-pic-and-vid site each day, I&#8217;ve turned my attention to Reddit.  Reddit just seems more controlled and programmer-friendly.  Since I have respect for Reddit I thought I&#8217;d put together a quick tutorial on how you can retrieve a URL&#8217;s Reddit score using PHP.</p><h2>The&nbsp;PHP</h2><pre class="php">&lt;?php

	/* settings */
	$url = 'http://davidwalsh.name/9-signs-not-to-hire-that-web-guy';
	$reddit_url = 'http://www.reddit.com/api/info.{format}?url='.$url;
	$format = 'json'; //use XML if you'd like...JSON FTW!
	$score = $ups = $downs = 0; //initialize

	/* action */
	$content = get_url(str_replace('{format}',$format,$reddit_url)); //again, can be xml or json
	if($content) {
		if($format == 'json') {
			$json = json_decode($content,true);
			foreach($json['data']['children'] as $child) { // we want all children for this example
				$ups+= (int) $child['data']['ups'];
				$downs+= (int) $child['data']['downs'];
				//$score+= (int) $child['data']['score']; //if you just want to grab the score directly
			}
			$score = $ups - $downs;
		}
	}

	/* output */
	echo "Ups: $ups&lt;br /&gt;"; //21
	echo "Downs: $downs&lt;br /&gt;"; //8
	echo "Score:  $score&lt;br /&gt;"; //13

	/* utility function:  go get it! */
	function get_url($url) {
		$ch = curl_init();
		curl_setopt($ch,CURLOPT_URL,$url);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
		curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,1);
		$content = curl_exec($ch);
		curl_close($ch);
		return $content;
	}

?&gt;</pre><p>Parsing the JSON is simple using <span
class="function">json_encode</span> with the value of <span
class="var">true</span> to make turn the JSON into an associate array.  My example shows how you can grab the number of &#8220;ups&#8221; and &#8220;downs&#8221; &#8212; not just the score.  As with every API/web service, I highly recommend caching the result of your request.</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/get-reddit-score">Get a URL&#8217;s Reddit Score Using PHP and&nbsp;JSON</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/web-service-php-mysql-xml-json' rel='bookmark' title='Permanent Link: Create a Basic Web Service Using PHP, MySQL, XML, and&nbsp;JSON'>Create a Basic Web Service Using PHP, MySQL, XML, and&nbsp;JSON</a></li><li><a
href='http://davidwalsh.name/cache-feedburner' rel='bookmark' title='Permanent Link: Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count'>Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count</a></li><li><a
href='http://davidwalsh.name/php-cache-function' rel='bookmark' title='Permanent Link: Simple PHP Caching and Content Retrieval&nbsp;Function'>Simple PHP Caching and Content Retrieval&nbsp;Function</a></li><li><a
href='http://davidwalsh.name/bitly-api-php' rel='bookmark' title='Permanent Link: Create Bit.ly Short URLs Using PHP: API Version&nbsp;3'>Create Bit.ly Short URLs Using PHP: API Version&nbsp;3</a></li><li><a
href='http://davidwalsh.name/create-tiny-url-php' rel='bookmark' title='Permanent Link: Create a TinyURL with&nbsp;PHP'>Create a TinyURL with&nbsp;PHP</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/get-reddit-score/feed</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>Dynamically Create Charts Using jQuery Flot and Google&#160;Analytics</title><link>http://davidwalsh.name/jquery-flot</link> <comments>http://davidwalsh.name/jquery-flot#comments</comments> <pubDate>Thu, 22 Oct 2009 12:34:25 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Google]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[jQuery]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=4048</guid> <description><![CDATA[Earlier in the week I published a popular article titled Dynamically Create Charts Using MooTools MilkChart and Google Analytics. My post showed you how to use MooTools MilkChart and a splash of PHP to create beautiful charts of Google Analytics data. I was interested in seeing what jQuery had to offer in the charting department. [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/jquery-flot">Dynamically Create Charts Using jQuery Flot and Google&nbsp;Analytics</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/milkchart' rel='bookmark' title='Permanent Link: Dynamically Create Charts Using MooTools MilkChart and Google&nbsp;Analytics'>Dynamically Create Charts Using MooTools MilkChart and Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/php-google-analytics' rel='bookmark' title='Permanent Link: Retrieve Google Analytics Visits and PageViews with&nbsp;PHP'>Retrieve Google Analytics Visits and PageViews with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/secure-ssl-google-analytics' rel='bookmark' title='Permanent Link: Secure (SSL) Google&nbsp;Analytics'>Secure (SSL) Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/track-ajax-link-clicks-google-analytics' rel='bookmark' title='Permanent Link: Track AJAX Link Clicks Using Google&nbsp;Analytics'>Track AJAX Link Clicks Using Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/async-google-analytics' rel='bookmark' title='Permanent Link: Async Google&nbsp;Analytics'>Async Google&nbsp;Analytics</a></li></ol>]]></description> <content:encoded><![CDATA[<p><img
src="http://davidwalsh.name/dw-content/flot.png" alt="jQuery Flot" /></p><p>Earlier in the week I published a popular article titled <a
href="http://davidwalsh.name/milkchart">Dynamically Create Charts Using MooTools MilkChart and Google Analytics</a>.  My post showed you how to use MooTools MilkChart and a splash of PHP to create beautiful charts of Google Analytics data.  I was interested in seeing what jQuery had to offer in the charting department. <a
href="http://code.google.com/p/flot/">jQuery Flot</a> is what I found.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/flot.php?month=9&#038;year=2009" class="demo">View Demo</a><div
class="clear"></div></div><h2>The&nbsp;PHP</h2><pre class="php">
/* defaults */
$month = date('n');
$year = date('Y');

/* submission? */
if($_GET['month'] || $_GET['year']):
	/* cleanse lookups */
	$month = (int) $_GET['month']; if(!$month) { $month = 1; }
	$year = (int) $_GET['year']; if(!$year) { $year = date('Y'); }
	/* retrieve information from google analytics */
	require 'ga/analytics.class.php';
	$analytics = new analytics('&#121;ourac&#99;oun&#116;&#64;&#103;m&#97;&#105;l&#46;&#99;om', 'password');
	$analytics-&gt;setProfileByName('yourdomain.com');
	$analytics-&gt;setMonth($month,$year);
	$visits = $analytics-&gt;getVisitors();
	$views = $analytics-&gt;getPageviews();
	/* build tables */
	if(count($visits)) {
		foreach($visits as $day=&gt;$visit) { 
			$flot_datas_visits[] = '['.$day.','.$visit.']';
			$flot_datas_views[] = '['.$day.','.$views[$day].']';
		}
		$flot_data_visits = '['.implode(',',$flot_datas_visits).']';
		$flot_data_views = '['.implode(',',$flot_datas_views).']';
	}
endif;
</pre><p>The above code is the same as my MooTools post with the exception of the statistics output format.  jQuery flot prefers arrays instead of  a  HTML table.</p><h2>The jQuery Flot&nbsp;JavaScript</h2><pre class="js">
$(document).ready(function() {
	var visits = &lt;?php echo $flot_data_visits; ?&gt;;
	var views = &lt;?php echo $flot_data_views; ?&gt;;
	$('#placeholder').css({
		height: '400px',
		width: '600px'
	});
	$.plot($('#placeholder'),[
			{ label: 'Visits', data: visits },
			{ label: 'Pageviews', data: views }
		],{
	        lines: { show: true },
	        points: { show: true },
	        grid: { backgroundColor: '#fffaff' }
	});
});
</pre><p>The above is a simple example of using jQuery Flot&#8217;s plot method.  Simply provide the placeholder and statistical data from the PHP above.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/flot.php?month=9&#038;year=2009" class="demo">View Demo</a><div
class="clear"></div></div><h2>Comparison</h2><ul><li>jQuery Flot provides IE support via ExCanvas, which is great.</li><li>MilkChart allows for pie charts while Flot doesn&#8217;t.  I prefer pie charts to other chart types.</li><li>MilkChart allows for easy creation of charts from HTML tables (good for accessibility) while jQuery Flot requires an array syntax.</li></ul><p>What do you think?  Which method do you prefer?</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/jquery-flot">Dynamically Create Charts Using jQuery Flot and Google&nbsp;Analytics</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/milkchart' rel='bookmark' title='Permanent Link: Dynamically Create Charts Using MooTools MilkChart and Google&nbsp;Analytics'>Dynamically Create Charts Using MooTools MilkChart and Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/php-google-analytics' rel='bookmark' title='Permanent Link: Retrieve Google Analytics Visits and PageViews with&nbsp;PHP'>Retrieve Google Analytics Visits and PageViews with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/secure-ssl-google-analytics' rel='bookmark' title='Permanent Link: Secure (SSL) Google&nbsp;Analytics'>Secure (SSL) Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/track-ajax-link-clicks-google-analytics' rel='bookmark' title='Permanent Link: Track AJAX Link Clicks Using Google&nbsp;Analytics'>Track AJAX Link Clicks Using Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/async-google-analytics' rel='bookmark' title='Permanent Link: Async Google&nbsp;Analytics'>Async Google&nbsp;Analytics</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/jquery-flot/feed</wfw:commentRss> <slash:comments>17</slash:comments> </item> <item><title>Dynamically Create Charts Using MooTools MilkChart and Google&#160;Analytics</title><link>http://davidwalsh.name/milkchart</link> <comments>http://davidwalsh.name/milkchart#comments</comments> <pubDate>Tue, 20 Oct 2009 13:22:07 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Markup]]></category> <category><![CDATA[MooTools]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3943</guid> <description><![CDATA[The prospect of creating graphics charts with JavaScript is exciting. It&#8217;s also the perfect use of JavaScript &#8212; creating non-essential features with unobtrusive scripting. I&#8217;ve created a mix of PHP (the Analytics class), HTML, and MooTools JavaScript that will connect to Google Analytics, create an HTML table with the statistics for a given month, and [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/milkchart">Dynamically Create Charts Using MooTools MilkChart and Google&nbsp;Analytics</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/jquery-flot' rel='bookmark' title='Permanent Link: Dynamically Create Charts Using jQuery Flot and Google&nbsp;Analytics'>Dynamically Create Charts Using jQuery Flot and Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/php-calendar-controls' rel='bookmark' title='Permanent Link: Add Controls to the PHP&nbsp;Calendar'>Add Controls to the PHP&nbsp;Calendar</a></li><li><a
href='http://davidwalsh.name/php-google-analytics' rel='bookmark' title='Permanent Link: Retrieve Google Analytics Visits and PageViews with&nbsp;PHP'>Retrieve Google Analytics Visits and PageViews with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/php-event-calendar' rel='bookmark' title='Permanent Link: Add Events to the PHP&nbsp;Calendar'>Add Events to the PHP&nbsp;Calendar</a></li><li><a
href='http://davidwalsh.name/track-ajax-link-clicks-google-analytics' rel='bookmark' title='Permanent Link: Track AJAX Link Clicks Using Google&nbsp;Analytics'>Track AJAX Link Clicks Using Google&nbsp;Analytics</a></li></ol>]]></description> <content:encoded><![CDATA[<img
src="http://davidwalsh.name/dw-content/milkchart.jpg" alt="MilkChart" /><p>The prospect of creating graphics charts with JavaScript is exciting.  It&#8217;s also the perfect use of JavaScript &#8212; creating non-essential features with unobtrusive scripting.  I&#8217;ve created a mix of PHP (the <a
href="http://davidwalsh.name/php-google-analytics">Analytics class</a>), HTML, and MooTools JavaScript that will connect to Google Analytics, create an HTML table with the statistics for a given month, and use MooTools MilkChart to colorfully chart them out.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/milkchart-analytics.php?month=9&#038;year=2009&#038;type=Column" class="demo">View Demo</a><div
class="clear"></div></div><h2>The&nbsp;PHP</h2><pre class="php">
/* defaults */
$month = date('n');
$year = date('Y');
$type = 'Column';

/* submission? */
if($_GET['month'] || $_GET['year']):
	/* cleanse lookups */
	$month = (int) $_GET['month']; if(!$month) { $month = 1; }
	$year = (int) $_GET['year']; if(!$year) { $year = date('Y'); }
	/* retrieve information from google analytics */
	require 'ga/analytics.class.php';
	$analytics = new analytics('&#121;ou&#114;ac&#99;ount&#64;&#103;&#109;&#97;i&#108;.&#99;o&#109;', 'yourP@ss');
	$analytics-&gt;setProfileByName('yourdomain.com');
	$analytics-&gt;setMonth($month,$year);
	$visits = $analytics-&gt;getVisitors();
	$views = $analytics-&gt;getPageviews();
	/* build tables */
	if(count($visits)) {
		//visits - php
		$visits_table_data = '&lt;table id=&quot;data-table-visits&quot;&gt;';
		/* $visits_table_data.= '&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Unique Visits&lt;/th&gt;&lt;th&gt;PageViews&lt;/th&gt;&lt;/tr&gt;&lt;/head&gt;&lt;tbody&gt;'; */
		$visits_table_data.= '&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Unique Visits&lt;/th&gt;&lt;/tr&gt;&lt;/head&gt;&lt;tbody&gt;';
		foreach($visits as $day=&gt;$visit) { 
			/*
			$visits_table_data.= '&lt;tr&gt;&lt;td&gt;'.$visit.'&lt;/td&gt;&lt;td&gt;'.$views[$day].'&lt;/td&gt;&lt;/tr&gt;'.&quot;\n&quot;; 
			$visits_table_foot.= '&lt;td&gt;'.$day.'&lt;/td&gt;&lt;td&gt;'.$day.'&lt;/td&gt;'.&quot;\n&quot;;
			*/
			$visits_table_data.= '&lt;tr&gt;&lt;td&gt;'.$visit.'&lt;/td&gt;&lt;/tr&gt;'.&quot;\n&quot;; 
			$visits_table_foot.= '&lt;td&gt;'.$day.'&lt;/td&gt;'.&quot;\n&quot;;
		}
		$visits_table_data.= '&lt;/tbody&gt;';
		$visits_table_data.= '&lt;tfoot&gt;&lt;tr&gt;'.$visits_table_foot.'&lt;/tr&gt;&lt;/tfoot&gt;';
		$visits_table_data.= '&lt;/table&gt;';
	}
endif;
</pre><p>It all kicks off with grabbing the information from Google Analytics.  Simply provide the time frame you would like statistics for.  I usually choose to retrieve statistics by the month.</p><h2>The Generated HTML &amp; MooTools&nbsp;JavaScript</h2><pre class="html">
&lt;h2&gt;Select Your Month/Year&lt;/h2&gt;
&lt;form method=&quot;get&quot;&gt;
	&lt;select name=&quot;month&quot; id=&quot;month&quot;&gt;
		&lt;option value=&quot;&quot;&gt;-- Select Month --&lt;/option&gt;
		&lt;?php
			for($x = 1; $x &lt;= 12; $x++):
				echo '&lt;option value=&quot;',$x,'&quot;',($month == $x ? ' selected=&quot;selected&quot;' : ''),'&gt;',date('F',mktime(0,0,0,$x,1,2009)),'&lt;/option&gt;';
			endfor;
		?&gt;
	&lt;/select&gt;
	&lt;select name=&quot;year&quot; id=&quot;year&quot;&gt;
		&lt;option value=&quot;&quot;&gt;-- Select Year --&lt;/option&gt;
		&lt;?php
			for($x = 2008; $x &lt;= date('Y'); $x++):
				echo '&lt;option value=&quot;',$x,'&quot;',($year == $x ? ' selected=&quot;selected&quot;' : ''),'&gt;',$x,'&lt;/option&gt;';
			endfor;
		?&gt;
	&lt;/select&gt;
	&lt;select name=&quot;type&quot; id=&quot;type&quot;&gt;
		&lt;option value=&quot;&quot;&gt;-- Select Chart Type --&lt;/option&gt;
		&lt;?php
			$chart_types = array('Column','Bar','Line','Scatter','Pie');
			foreach($chart_types as $chart_type):
				echo '&lt;option value=&quot;',$chart_type,'&quot;',($type == $chart_type ? ' selected=&quot;selected&quot;' : ''),'&gt;',$chart_type,'&lt;/option&gt;';
			endforeach;
		?&gt;
	&lt;/select&gt;
	&lt;input type=&quot;submit&quot; name=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Get Statistics!&quot; /&gt;
&lt;/form&gt;

&lt;?php 
	//php time - echo tables
	if($visits_table_data) { echo '&lt;h3&gt;Visits&lt;/h3&gt;', $visits_table_data,'&lt;br /&gt;'; } 
?&gt;
&lt;?php if(count($visits)): ?&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
		var visits = new MilkChart.&lt;?php echo $_GET['type']; ?&gt;('data-table-visits',{
			width: 960,
			height: 550,
			font: 'tahoma',
			showValues: false,
			useFooter: true
		});
	&lt;/script&gt;
&lt;?php endif; ?&gt;
</pre><p>Using the THEAD, TBODY, and TFOOT elements is extremely important in the ensuring the correct labels are placed within the generated chart.  The data table itself is very simple.  MilkChart will take the above table and create a CANVAS element which will contain the chart.</p><p>There are five different chart types you may choose from:  Column, Bar, Pie, Line, Scatter.  MilkChart takes full advantage of MooTools&#8217; inheritance model as each type of chart&#8217;s class extends the base MilkChart class.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/milkchart-analytics.php?month=9&#038;year=2009&#038;type=Column" class="demo">View Demo</a><div
class="clear"></div></div><p>I love the way the MilkChart developer(s) utilized MooTools&#8217; OOP/inheritance model to perfection.  I also love that MilkChart requires the bare minimum of data for the HTML table.  MilkChart isn&#8217;t without its flaws though.  A few of the table types had a fit about including multiple dimensions (using both page views and visits within the same chart, for example) and value label placement has yet to be perfected.</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/milkchart">Dynamically Create Charts Using MooTools MilkChart and Google&nbsp;Analytics</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/jquery-flot' rel='bookmark' title='Permanent Link: Dynamically Create Charts Using jQuery Flot and Google&nbsp;Analytics'>Dynamically Create Charts Using jQuery Flot and Google&nbsp;Analytics</a></li><li><a
href='http://davidwalsh.name/php-calendar-controls' rel='bookmark' title='Permanent Link: Add Controls to the PHP&nbsp;Calendar'>Add Controls to the PHP&nbsp;Calendar</a></li><li><a
href='http://davidwalsh.name/php-google-analytics' rel='bookmark' title='Permanent Link: Retrieve Google Analytics Visits and PageViews with&nbsp;PHP'>Retrieve Google Analytics Visits and PageViews with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/php-event-calendar' rel='bookmark' title='Permanent Link: Add Events to the PHP&nbsp;Calendar'>Add Events to the PHP&nbsp;Calendar</a></li><li><a
href='http://davidwalsh.name/track-ajax-link-clicks-google-analytics' rel='bookmark' title='Permanent Link: Track AJAX Link Clicks Using Google&nbsp;Analytics'>Track AJAX Link Clicks Using Google&nbsp;Analytics</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/milkchart/feed</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Retrieve, Cache, and Display Your FeedBurner Subscriber&#160;Count</title><link>http://davidwalsh.name/cache-feedburner</link> <comments>http://davidwalsh.name/cache-feedburner#comments</comments> <pubDate>Fri, 09 Oct 2009 13:20:41 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3775</guid> <description><![CDATA[One way of significantly speeding up your website is by caching information you retrieve remotely from other websites or databases. Caching information is extremely simple and can save your users seconds of unnecessary waiting. Here&#8217;s how I cache my FeedBurner follower count on my site. The&#160;PHP /* settings */ $cache_path = '/cache/'; $rss_file_name = date('Y-m-d').'-rss.txt'; [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/cache-feedburner">Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/feedburner-reader-statistic-php-curl-feedburner-api' rel='bookmark' title='Permanent Link: Get Your FeedBurner Reader Statistic Using PHP cURL and the FeedBurner&nbsp;API'>Get Your FeedBurner Reader Statistic Using PHP cURL and the FeedBurner&nbsp;API</a></li><li><a
href='http://davidwalsh.name/php-cache-function' rel='bookmark' title='Permanent Link: Simple PHP Caching and Content Retrieval&nbsp;Function'>Simple PHP Caching and Content Retrieval&nbsp;Function</a></li><li><a
href='http://davidwalsh.name/technorati-rank-authority' rel='bookmark' title='Permanent Link: Technorati Grabber:  Get Your Technorati Rank and&nbsp;Authority'>Technorati Grabber:  Get Your Technorati Rank and&nbsp;Authority</a></li><li><a
href='http://davidwalsh.name/twitter-friendships' rel='bookmark' title='Permanent Link: Test Twitter Friendships with&nbsp;PHP'>Test Twitter Friendships with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/php-imdb-information-grabber' rel='bookmark' title='Permanent Link: PHP IMDB Information&nbsp;Grabber'>PHP IMDB Information&nbsp;Grabber</a></li></ol>]]></description> <content:encoded><![CDATA[<p>One way of significantly <a
href="http://davidwalsh.name/speeding-website">speeding up your website</a> is by caching information you retrieve remotely from other websites or databases.  Caching information is extremely simple and can save your users seconds of unnecessary waiting.  Here&#8217;s how I cache my FeedBurner follower count on my site.</p><h2>The&nbsp;PHP</h2><pre class="php">
/* settings */
$cache_path = '/cache/';
$rss_file_name = date('Y-m-d').'-rss.txt';

/* rss */
if(file_exists($cache_path.$rss_file_name)) {
	$rss_subcribers = file_get_contents($cache_path.$rss_file_name);
}
else {
	$rss_content = get_url('https://feedburner.google.com/api/awareness/1.0/GetFeedData?id=dfadajf324789fhSDFDf48');
	$subscribers = get_match('/circulation="(.*)"/isU',$rss_content);
	if($subscribers) {
		$subscribers = number_format($subscribers,0,'',',');
		file_put_contents($cache_path.$rss_file_name,$subscribers);
		$rss_subcribers = $subscribers;
	}
}

/* display */
echo 'My subscriber count is: ',$rss_subscribers;

/* connects to the URL, returns content */
function get_url($url) {
	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,1);
	$content = curl_exec($ch);
	curl_close($ch);
	return $content;
}

/* helper: does the regex */
function get_match($regex,$content) {
	preg_match($regex,$content,$matches);
	return $matches[1];
}

</pre><p>The first thing we do is check to see if our cached file exists.  If it does, we simply return its contents.  If the cache file doesn&#8217;t exist, we connect to our private FeedBurner URL, parse the content, and save the feed to a file named after the current day.  Note the way we can check if we had gotten the count for the current day is by naming the file in &#8220;year-month-day&#8221; format.</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/cache-feedburner">Retrieve, Cache, and Display Your FeedBurner Subscriber&nbsp;Count</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/feedburner-reader-statistic-php-curl-feedburner-api' rel='bookmark' title='Permanent Link: Get Your FeedBurner Reader Statistic Using PHP cURL and the FeedBurner&nbsp;API'>Get Your FeedBurner Reader Statistic Using PHP cURL and the FeedBurner&nbsp;API</a></li><li><a
href='http://davidwalsh.name/php-cache-function' rel='bookmark' title='Permanent Link: Simple PHP Caching and Content Retrieval&nbsp;Function'>Simple PHP Caching and Content Retrieval&nbsp;Function</a></li><li><a
href='http://davidwalsh.name/technorati-rank-authority' rel='bookmark' title='Permanent Link: Technorati Grabber:  Get Your Technorati Rank and&nbsp;Authority'>Technorati Grabber:  Get Your Technorati Rank and&nbsp;Authority</a></li><li><a
href='http://davidwalsh.name/twitter-friendships' rel='bookmark' title='Permanent Link: Test Twitter Friendships with&nbsp;PHP'>Test Twitter Friendships with&nbsp;PHP</a></li><li><a
href='http://davidwalsh.name/php-imdb-information-grabber' rel='bookmark' title='Permanent Link: PHP IMDB Information&nbsp;Grabber'>PHP IMDB Information&nbsp;Grabber</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/cache-feedburner/feed</wfw:commentRss> <slash:comments>12</slash:comments> </item> <item><title>Create WordPress Page Templates with Custom&#160;Queries</title><link>http://davidwalsh.name/wp_query</link> <comments>http://davidwalsh.name/wp_query#comments</comments> <pubDate>Tue, 06 Oct 2009 13:08:18 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=3674</guid> <description><![CDATA[One of my main goals with the redesign was to make it easier for visitors to find the information that was most popular on my site. Not to my surprise, posts about MooTools, jQuery, and CSS were at the top of the list. What do those three topics have in common? The fact that I [...]<p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/wp_query">Create WordPress Page Templates with Custom&nbsp;Queries</a></p>Related posts:<ol><li><a
href='http://davidwalsh.name/script-style-exclusive-add-custom-values-wordpress-rss-feed' rel='bookmark' title='Permanent Link: Script &#038; Style Exclusive: Add Custom Values To Your WordPress RSS&nbsp;Feed'>Script &#038; Style Exclusive: Add Custom Values To Your WordPress RSS&nbsp;Feed</a></li><li><a
href='http://davidwalsh.name/wordpress-recent-posts' rel='bookmark' title='Permanent Link: Create a &#8220;Recent Posts&#8221; Module Outside of&nbsp;WordPress'>Create a &#8220;Recent Posts&#8221; Module Outside of&nbsp;WordPress</a></li><li><a
href='http://davidwalsh.name/custom-404-page-tips' rel='bookmark' title='Permanent Link: Custom Error Page Tips &#8211; Designate The Pages You Hope No One&nbsp;Sees'>Custom Error Page Tips &#8211; Designate The Pages You Hope No One&nbsp;Sees</a></li><li><a
href='http://davidwalsh.name/mootools-custom-event' rel='bookmark' title='Permanent Link: Create Custom Events in MooTools&nbsp;1.2'>Create Custom Events in MooTools&nbsp;1.2</a></li><li><a
href='http://davidwalsh.name/create-custom-pseudo-selector-mootools-selected' rel='bookmark' title='Permanent Link: Create a Custom &#8220;:selected&#8221; Pseudo Selector in&nbsp;MooTools'>Create a Custom &#8220;:selected&#8221; Pseudo Selector in&nbsp;MooTools</a></li></ol>]]></description> <content:encoded><![CDATA[<p>One of my main goals with the redesign was to make it easier for visitors to find the information that was most popular on my site.  Not to my surprise, posts about MooTools, jQuery, and CSS were at the top of the list.  What do those three topics have in common?  The fact that I provide a sweet demo for each of them.  Thus I set out to create an easy way to check out all of my demos &#8212; the Demos &amp; Downloads page.</p><p>I could address my Demos and Downloads link to <span
class="file">&#8220;/index.php?s=view+demo&#8221;</span> but that&#8217;s ugly &#8212; not SEO friendly nor is it an address anyone will remember.  The solution was to create a new page template that would act similar to a search results page but afford me much more flexibility.</p><h2>The&nbsp;Strategy</h2><p>The first step was to identify posts that had a demo.  If I were starting my blog today I would add a custom field called &#8220;demo&#8221; and give all posts containing a demo a value of &#8220;1&#8243;.  The issue is that I have 2 years worth of posts and no desire to add a custom field to all of those posts that contain demos.  I do know, however, that the label of all of my demos is &#8220;View Demo&#8221;  so any post containing that string would likely contain a demo. <strong>Problem solved:  I will need a search parameter for my custom query that looks for the &#8220;view demo&#8221; string.</strong></p><h2>WP_Query</h2><p><span
class="function">WP_Query</span> is WordPress&#8217; awesome database interaction class. <a
href="http://codex.wordpress.org/Template_Tags/query_posts">WP_Query accepts dozens of helpful parameters</a> in the form of a request string or an array to grab the posts you need (writing raw MySQL statements sucks).  With my strategy mapped out and <span
class="function">WP_Query</span> researched, it was GO time.</p><h2>The Page Template&nbsp;PHP</h2><pre class="php">
&lt;?php
/*
Template Name: Demos and Downloads
*/

/* helper:  does regex */
function get_content_match($regex,$content) {
	preg_match($regex,$content,$matches);
	return $matches[1];
}

/* list of "view demo" posts */
$paged = (get_query_var('paged')) ? (int) get_query_var('paged') : 1;
$demoPosts = new WP_Query('s=view+demo&#038;showposts=10&#038;order=desc&#038;post_status=publish&#038;paged='.$paged);

?&gt;
&lt;?php get_header(); ?&gt;

&lt;h1&gt;Demos &amp; Downloads&lt;/h1&gt;

&lt;?php while ($demoPosts-&gt;have_posts()) : $demoPosts-&gt;the_post(); ?&gt;
&lt;?php 
	$content = get_the_content();
	if(strstr(strtolower($content),'href="http://davidwalsh.name/dw-content/')):
?&gt;
	&lt;h1&gt;&lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;&lt;?php the_title(''); ?&gt;&lt;/a&gt;&lt;/h1&gt;
	&lt;p style="padding-bottom:3px;padding-left:5px;"&gt;
	&lt;?php
		$intro = get_content_match('/&lt;p&gt;(.*)&lt;\/p&gt;/isU',$content);
		$image = get_content_match('/src="(.*)" class="image"/isU',$content);
		$link = strip_tags(get_content_match('/href="http:\/\/davidwalsh.name\/dw-content\/(.*)"&gt;/isU',$content));
		if($image) { echo '&lt;img src="'.$image.'" class="image" alt="Tutorial Demo" /&gt;'; }
		echo $intro;
	?&gt;
	&lt;/p&gt;
	&lt;div class="demo-actions"&gt;
		&lt;a href="&lt;?php the_permalink(); ?&gt;" class="conred"&gt;Continue Reading &raquo;&lt;/a&gt;
		&lt;a href="http://davidwalsh.name/dw-content/&lt;?php echo $link; ?&gt;" class="demo"&gt;View Demo&lt;/a&gt;
	&lt;/div&gt;
&lt;?php endif; ?&gt;
&lt;?php endwhile; ?&gt;

&lt;div class="next-prev-links no-print"&gt;
	&lt;div class="nav-left"&gt;
		&lt;a href="/demos/page/&lt;?php echo $paged + 1; ?&gt;"&gt;&laquo; Older Posts&lt;/a&gt;
	&lt;/div&gt;
	&lt;?php if($paged != 1): ?&gt;
	&lt;div class="nav-right"&gt;
		&lt;a href="/demos/page/&lt;?php echo $paged - 1; ?&gt;"&gt;Newer posts &raquo;&lt;/a&gt;
	&lt;/div&gt;
	&lt;?php endif; ?&gt;
	&lt;div class="clear"&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;!-- &lt;?php trackback_rdf(); ?&gt; --&gt;
&lt;?php get_footer(); ?&gt;
</pre><p>Notice that in order to use pagination within the demos section, I needed to set my own <span
class="var">$paged</span> variable and add it to the <span
class="function">WP_Query</span> parameters string.  The other parameters should be self explanatory.</p><p>Once I had the posts for the page,  I&#8217;d cycle throw each post and use some custom PHP (which you couldn&#8217;t easily do on the search page) to parse the post content to and pull out a supporting image and link to the demo.  The result is my <a
href="http://davidwalsh.name/demos">Demos and Downloads</a> page.</p><p>Beautiful!  Don&#8217;t be afraid to create custom page templates with content generated from your own custom queries.  Have any other pages that you think would make the site better?  Let me know!</p><p><strong>Follow Me!</strong> <a
href="http://twitter.com/davidwalshblog">Twitter</a> | <a
href="http://www.facebook.com/#!/pages/David-Walsh-Blog/186644584869">Facebook</a> | <a
href="http://www.linkedin.com/in/davidjameswalsh">LinkedIn</a> | <a
href="http://mootools.net/forge/profile/davidwalsh">MooTools Forge.</a><br/><br/>Full David Walsh Blog Post: <a
href="http://davidwalsh.name/wp_query">Create WordPress Page Templates with Custom&nbsp;Queries</a></p><p>Related posts:<ol><li><a
href='http://davidwalsh.name/script-style-exclusive-add-custom-values-wordpress-rss-feed' rel='bookmark' title='Permanent Link: Script &#038; Style Exclusive: Add Custom Values To Your WordPress RSS&nbsp;Feed'>Script &#038; Style Exclusive: Add Custom Values To Your WordPress RSS&nbsp;Feed</a></li><li><a
href='http://davidwalsh.name/wordpress-recent-posts' rel='bookmark' title='Permanent Link: Create a &#8220;Recent Posts&#8221; Module Outside of&nbsp;WordPress'>Create a &#8220;Recent Posts&#8221; Module Outside of&nbsp;WordPress</a></li><li><a
href='http://davidwalsh.name/custom-404-page-tips' rel='bookmark' title='Permanent Link: Custom Error Page Tips &#8211; Designate The Pages You Hope No One&nbsp;Sees'>Custom Error Page Tips &#8211; Designate The Pages You Hope No One&nbsp;Sees</a></li><li><a
href='http://davidwalsh.name/mootools-custom-event' rel='bookmark' title='Permanent Link: Create Custom Events in MooTools&nbsp;1.2'>Create Custom Events in MooTools&nbsp;1.2</a></li><li><a
href='http://davidwalsh.name/create-custom-pseudo-selector-mootools-selected' rel='bookmark' title='Permanent Link: Create a Custom &#8220;:selected&#8221; Pseudo Selector in&nbsp;MooTools'>Create a Custom &#8220;:selected&#8221; Pseudo Selector in&nbsp;MooTools</a></li></ol></p>]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/wp_query/feed</wfw:commentRss> <slash:comments>6</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced) (user agent is rejected)
Database Caching 105/332 queries in 4.323 seconds using disk

Served from: davidwalsh.name @ 2010-09-02 23:19:27 -->