<?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/"
xmlns:series="http://unfoldingneurons.com/"
><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>Sun, 20 May 2012 22:40:48 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>JavaScript CDN&#160;Fallbacks</title><link>http://davidwalsh.name/cdn-fallbacks</link> <comments>http://davidwalsh.name/cdn-fallbacks#comments</comments> <pubDate>Mon, 02 Jan 2012 01:23:26 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5389</guid> <description><![CDATA[CDNs are great for pulling shared resources from, especially JavaScript libraries. The advantage in the likelihood that a file is already cached before the user gets to our site is huge. The only problem with using a CDN is that it&#8217;s out of control; more specifically, what if the CDN server is down? What a [...]<p><a
href="http://davidwalsh.name/cdn-fallbacks">JavaScript CDN&nbsp;Fallbacks</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>CDNs are great for pulling shared resources from, especially JavaScript libraries.  The advantage in the likelihood that a file is already cached before the user gets to our site is huge.  The only problem with using a CDN is that it&#8217;s out of control;  more specifically, what if the CDN server is down?  What a nightmare!  Thousands if not millions of websites would be hurt&#8230;but not yours.  Nope, you added a CDN fallback so that a failed CDN wouldn&#8217;t hurt your site!</p><h2>The HTML /&nbsp;JavaScript</h2><p>The document.write method is one you generally want to avoid, but it works best in this case:</p><pre class="html">
&lt;!-- Use Google CDN for MooTools, local Moo as a callback --&gt;
&lt;script src="//ajax.googleapis.com/ajax/libs/mootools/1.4.1/mootools-yui-compressed.js"&gt;&lt;/script&gt;
&lt;script&gt;!window.MooTools &amp;&amp; document.write(unescape('%3Cscript src="/js/mootools-yui-compressed.js"%3E%3C/script%3E'))&lt;/script&gt;
</pre><p>In the event that the CDN fails, your local file is instead used.  Simple but clever fallback, yes?  The likelihood that Google or other CDNs is down is small, but since you don&#8217;t control the other server, there&#8217;s always that risk!  Play it safe!</p><p><a
href="http://davidwalsh.name/cdn-fallbacks">JavaScript CDN&nbsp;Fallbacks</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/cdn-fallbacks/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>XBox Live Gamer&#160;API</title><link>http://davidwalsh.name/xbox-api</link> <comments>http://davidwalsh.name/xbox-api#comments</comments> <pubDate>Tue, 22 Nov 2011 15:45:49 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Bookmarking / Social]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5334</guid> <description><![CDATA[I&#8217;ve thought long and hard about this, and I still can&#8217;t decide whether or not I should consider myself a &#8220;gamer.&#8221; During my lifetime, I&#8217;ve owned an original Nintendo, Sega Genesis, Nintendo64 (best controller of any console ever), wii, and XBox 360. I used to have a horrible habit of downloading pirating games, but that&#8217;s [...]<p><a
href="http://davidwalsh.name/xbox-api">XBox Live Gamer&nbsp;API</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p><a
href="http://davidwalsh.name/dw-content/xbox-api.php"><img
src="http://davidwalsh.name/dw-content/xbox.jpg" alt="XBox Live API" /></a></p><p>I&#8217;ve thought long and hard about this, and I still can&#8217;t decide whether or not I should consider myself a &#8220;gamer.&#8221;  During my lifetime, I&#8217;ve owned an original Nintendo, Sega Genesis, Nintendo64 (best controller of any console ever), wii, and XBox 360.  I used to have a horrible habit of downloading pirating games, but that&#8217;s long and over with.  Anyways, the only game I&#8217;ve played consistently over the past three years is Call of Duty.  Which one?  Whichever the latest Call of Duty has been most recently released.  I don&#8217;t even care to attempt the story mode;  I simply want to log on and shoot each and every one of you I encounter.</p><p>My sharpshooter status aside, I&#8217;ve always been <del>surprised</del> upset that Microsoft has never provided an API for the vast amount of information about users, the games they play, and statistics within the games.  Namely, I&#8217;d like to publicly shame every n00b I&#8217;ve baptized with my sniper rifle.  I recently found a great gamer API effort by XBoxLeaders.com.  While their API can&#8217;t tell me the titles and emblems I&#8217;ve earned in Modern Warfare 3, I can get some relevant information about my user, my status, and the games I&#8217;ve recently dominated.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/xbox-api.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>The&nbsp;PHP</h2><p>The API is incredibly simple to use: simply send the the gamertag and response type you desire:</p><pre class="php">
// Settings
$gamertag = 'dwalsh83';
$profileUrl = 'http://www.xboxleaders.com/api/profile/'.$gamertag.'.json';

// Get information about me
$info = file_get_contents($profileUrl);

// To JSON
$json = json_decode($info);
$user = $json-&gt;user;
</pre><p>The response will look like this:</p><pre class="javascript">
{
  "status": {
    "is_valid": "yes",
    "is_cheater": "no",
    "tier": "gold"
  },
  "profile": {
    "gamertag": "dwalsh83",
    "gamerscore": 300,
    "reputation": 20,
    "gender": "male",
    "motto": "Watch your head.",
    "name": "David Walsh",
    "location": "Madison, WI, US",
    "bio": "There is, and only can be, Call of Duty.",
    "url": "http:\/\/live.xbox.com\/en-US\/Profile?gamertag=dwalsh83",
    "avatar_tile": "http:\/\/image.xboxlive.com\/global\/t.fffe07d1\/tile\/0\/2000b",
    "avatar_small": "http:\/\/avatar.xboxlive.com\/avatar\/dwalsh83\/avatarpic-s.png",
    "avatar_large": "http:\/\/avatar.xboxlive.com\/avatar\/dwalsh83\/avatarpic-l.png",
    "avatar_body": "http:\/\/avatar.xboxlive.com\/avatar\/dwalsh83\/avatar-body.png",
    "launch_team_xbl": "no",
    "launch_team_nxe": "no",
    "launch_team_kin": "no"
  }
}
</pre><p>As you can see, you get basic account information (name, bio, etc) but also a bit of information about the games the user has been playing recently.  You also get links to images for the user and said games.  What you choose to do with this information is up to you;  you could put together a really basic gamercard:</p><pre class="php">
&lt;style&gt;
	
	.gamercard {
		border: 1px solid #bdbec1;
		padding: 10px;
		width: 600px;
		font-family: arial, sans-serif;
		font-size: 12px;
		color: #bdbec1;
		
		background-image: -webkit-linear-gradient(#ddd, #fff, #e9fdce);
		background-image: -moz-linear-gradient(top, #ddd, #fff, #e9fdce);
		background-image: -ms-linear-gradient(#ddd, #fff, #e9fdce);
		background-image: -o-linear-gradient(#ddd, #fff, #e9fdce);
		background-image: linear-gradient(#ddd, #fff, #e9fdce);
	}
	
	.gamercard img {
		display: block;
	}
	
	.gamercard .avatar {
		float: right;
		width: 150px;
		height: 300px;
		margin: -60px 0 0 50px;
	}
	
	.gamercard h1 {
		font-weight: normal;
	}
		
		.gamercard h1 img {
			display: inline-block; 
			padding-right: 10px;
			width: 24px; 
			height: 24px;
		}
		
		.gamercard h1 a {
			text-decoration: none;
		}
		
			.gamercard h1 a:hover {
				background: #bbe6a6;
				color: #333;
			}
			
	.gamercard h2 {
		color: #111;
		font-size: 16px;
		font-weight: normal;
		margin-top: 15px;
	}
	
	.gamercard ul {
		list-style-type: none;
	}
		.gamercard ul li {
			padding-top: 8px;
		}
			
			.gamercard ul li strong {
				color: #666;
			}
			
	.gamercard ul.games li {
		display: inline-block; 
		margin-right: 20px;
		text-align: center;
		font-weight: bold;
		width: 85px;
		vertical-align: top;
	}
		.gamercard ul.games li img {
			margin: 0 auto;
			width: 85px;
		}
	
	.gamercard a {
		color: #78bb58;
	}
	
	.gamercard .clear {
		clear: both;
	}
	
&lt;/style&gt;

&lt;!-- gamercard --&gt;
&lt;div class="gamercard"&gt;
	
	&lt;!-- profile image --&gt;
	&lt;img src="&lt;?php echo $profile-&gt;avatar_body; ?&gt;" alt="&lt;?php echo $profile-&gt;gamertag; ?&gt;" class="avatar" /&gt;

	&lt;!-- gamer name --&gt;
	&lt;h1&gt;&lt;img src="&lt;?php echo $profile-&gt;avatar_tile; ?&gt;" alt="&lt;?php echo $profile-&gt;gamertag; ?&gt;" /&gt;&lt;a href="&lt;?php echo $profile-&gt;profile_link; ?&gt;"&gt;&lt;?php echo $profile-&gt;gamertag; ?&gt;&lt;/a&gt;&lt;/h1&gt;

	&lt;!-- personal info --&gt;
	&lt;h2&gt;The Legend&lt;/h2&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;strong&gt;Name:&lt;/strong&gt; &lt;?php echo $profile-&gt;name; ?&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Bio:&lt;/strong&gt; &lt;?php echo $profile-&gt;bio; ?&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Location:&lt;/strong&gt; &lt;?php echo $profile-&gt;location; ?&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Gender:&lt;/strong&gt; &lt;?php echo $profile-&gt;gender; ?&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Motto:&lt;/strong&gt; &lt;?php echo $profile-&gt;motto; ?&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Online:&lt;/strong&gt; &lt;?php echo $profile-&gt;online ? "Online" : "Offline"; ?&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Status:&lt;/strong&gt; &lt;?php echo $profile-&gt;online ? $profile-&gt;online_status : "(none)"; ?&gt;&lt;/li&gt;
	&lt;/ul&gt;

	&lt;?php if($profile-&gt;recent_games): ?&gt;
	&lt;!-- recent games --&gt;
	&lt;h2&gt;Recent Games&lt;/h2&gt;
	&lt;ul class="games"&gt;
		&lt;?php foreach($profile-&gt;recent_games as $game): ?&gt;
			 &lt;li&gt;&lt;a href="&lt;?php echo $game-&gt;marketplace_url; ?&gt;"&gt;&lt;img src="&lt;?php echo $game-&gt;small_boxart; ?&gt;" alt="&lt;?php echo $game-&gt;title; ?&gt;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;?php echo $game-&gt;title; ?&gt;&lt;/li&gt; 
		&lt;?php endforeach; ?&gt;
	&lt;/ul&gt;
	&lt;?php endif; ?&gt;
	
	&lt;div class="clear"&gt;&lt;/div&gt;
&lt;/div&gt;
</pre><p>Don&#8217;t forget to cache the responses you get back from the API for faster performance!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/xbox-api.php" class="demo">View Demo</a><div
class="clear"></div></div><p>In the end, I&#8217;m not sure how feasible it would be to create a true API for XBox and its games.  I assume each game and online service stores its information on the game creator&#8217;s own servers, so the information you could get would be minimal and fragmented at best.  It would be nice if the creators of Call of Duty could put something out there for assassins like me, but they&#8217;re probably all trying to find a way to improve the horrible spawn positioning logic.  Awesome work by XBoxLeaders.com in this effort though &#8212; it&#8217;s given me a great start at a fun project.</p><p><a
href="http://davidwalsh.name/xbox-api">XBox Live Gamer&nbsp;API</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/xbox-api/feed</wfw:commentRss> <slash:comments>13</slash:comments> </item> <item><title>Facebook Tooltip HTML and&#160;CSS</title><link>http://davidwalsh.name/facebook-tooltip</link> <comments>http://davidwalsh.name/facebook-tooltip#comments</comments> <pubDate>Tue, 08 Nov 2011 14:46:23 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Markup]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5329</guid> <description><![CDATA[Facebook recently implemented a new, lighter tooltip. I say the tooltip is lighter because it seems a lot quicker and more elegant than their previous effort. I took a few moments to grab the HTML structure and CSS rules to see how they did it. The&#160;HTML The tooltip structure consists of five elements: {content here}{content [...]<p><a
href="http://davidwalsh.name/facebook-tooltip">Facebook Tooltip HTML and&nbsp;CSS</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<img
src="http://davidwalsh.name/dw-content/fb-tip.png" alt="Facebook Tooltip" class="image" /><p>Facebook recently implemented a new, lighter tooltip.  I say the tooltip is lighter because it seems a lot quicker and more elegant than their previous effort.  I took a few moments to grab the HTML structure and CSS rules to see how they did it.</p><h2>The&nbsp;HTML</h2><p>The tooltip structure consists of five elements:</p><pre class="html">
<div class="uiContextualDialogPositioner uiContextualDialogLeft" style="top: 20px; left: 600px;">
	<div class="uiOverlay uiContextualDialog uiOverlayArrowRight" style="width: 347px; top: 0px; ">
		<div class="uiOverlayContent">
			<div class="uiOverlayContentHolder">
				{content here}{content here}{content here}{content here}{content here}{content here}{content here}{content here}{content here}
			</div>
		</div>
		<div class="uiOverlayArrow" style="top: 15px; margin-top: 0px;"></div>
	</div>
</div>
</pre><p>The root element dictates the position of the tooltip (which is most likely injected to the body).  The sole child element controls the width of the tooltip.  That element contains two elements:  the content container and the and the arrow node (which I&#8217;ve changed from an I element to a DIV).  The last, innermost DIV element will hold the content and provide padding.</p><h2>The&nbsp;CSS</h2><p>The CSS to create the tooltip layout is actually very minimal:</p><pre class="css">
body {
	font-size: 11px;
	font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
	color: #333;
	line-height: 1.28; 
	text-align: left;
	direction: ltr;
}

.uiContextualDialogPositioner, .uiContextualDialogPositioner .uiContextualDialog {
	position: absolute;
	z-index: 200;
}

.uiContextualDialogLeft .uiContextualDialog {
	right: 0;
}

.uiOverlayArrowRight {
	padding-right: 10px;
}

.uiOverlay {
	position: relative;
	z-index: 200;
}

.uiContextualDialog, .uiContextualDialog:focus {
	outline: 0 solid transparent;
}

.uiOverlayContent {
	background: white;
	border: 1px solid #8C8C8C;
	border: 1px solid rgba(0, 0, 0, .45);
	border-bottom: 1px solid #666;
	-moz-box-shadow: 0 3px 8px rgba(0, 0, 0, .3);
	-webkit-box-shadow: 0 3px 8px rgba(0, 0, 0, .3);
	box-shadow: 0 3px 8px rgba(0, 0, 0, .3);
	position: relative;
}

.uiOverlayContentHolder {
	padding: 10px;
}

.uiOverlayArrow {
	position: absolute;
	overflow: hidden;
}

.uiOverlayArrowRight .uiOverlayArrow {
	background-image: url(sprite.png);
	background-repeat: no-repeat;
	background-position: -177px -309px;
	height: 16px;
	right: 2px;
	width: 9px;
}
</pre><p>The content pane contains the majority of the CSS rules, include the box-shadow and border, both of which use rgba color for a more detailed effect.  Showing and hiding of the tooltip may be done via CSS key-frames or JavaScript &#8212; the choice would be up to the individual implementing the tooltip.</p><h2>Why Show&nbsp;This?</h2><p>Two reasons.  The first is that I appreciate well-coded features like this.  The second, more important reason, is that I&#8217;ll be creating a JavaScript-powered version of this functionality which accounts for content size, position on page, stacking/z-index management, etc.  Do I create as a jQuery and MooTools plugin?  Do I create it as a standalone JavaScript project.  Let me know your thoughts!</p><p><a
href="http://davidwalsh.name/facebook-tooltip">Facebook Tooltip HTML and&nbsp;CSS</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/facebook-tooltip/feed</wfw:commentRss> <slash:comments>25</slash:comments> </item> <item><title>Add a Google+1 Badge to Your&#160;Website</title><link>http://davidwalsh.name/google-plus-badge</link> <comments>http://davidwalsh.name/google-plus-badge#comments</comments> <pubDate>Thu, 30 Jun 2011 22:47:17 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Google]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Markup]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5261</guid> <description><![CDATA[Google&#8217;s new Google+ service is taking the development world by storm, and why shouldn&#8217;t it?  It&#8217;s minimalistic UI, use of cutting edge web techniques, and overall usability make it Google+ one of the more impressive web applications I&#8217;ve seen in quite a while (I was going to say &#8220;since Google Wave&#8221;, but that one didn&#8217;t [...]<p><a
href="http://davidwalsh.name/google-plus-badge">Add a Google+1 Badge to Your&nbsp;Website</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<img
src="http://davidwalsh.name/dw-content/plusOneLogo.png" alt="Google+ Badge" class="image" /><p>Google&#8217;s new Google+ service is taking the development world by storm, and why shouldn&#8217;t it?  It&#8217;s minimalistic UI, use of cutting edge web techniques, and overall usability make it Google+ one of the more impressive web applications I&#8217;ve seen in quite a while <em>(I was going to say &#8220;since Google Wave&#8221;, but that one didn&#8217;t end up well, did it?)</em> Google+ allows you to share photos, links, statuses, and much more;  consider it a mesh between Twitter and Facebook.</p><p>Google+ will only gain more traction, meaning that the information we share will be pushed to more and more people.  This presents an excellent opportunity to promote our websites, much in the way that Twitter and Facebook have.  Let me show you a few different ways to add the new Google+1 badge to your website.</p><h2>The Simple&nbsp;HTML</h2><p>Adding a Google+1 badge is as easy as adding a few HTML tags:</p><pre class="html">
&lt;!-- one button, uses canonical link or current URL --&gt;
&lt;g:plusone&gt;&lt;/g:plusone&gt;

&lt;!-- customized for a specific address --&gt;
&lt;g:plusone href="http://davidwalsh.name/google-plus-badge"&gt;&lt;/g:plusone&gt;

&lt;!-- include the JS file --&gt;
&lt;script src="https://apis.google.com/js/plusone.js"&gt;&lt;/script&gt;
</pre><p>Provide the <code>g:plusone</code> tag the URL to share via the <code>HREF</code> attribute <em>(if none is provided, the page&#8217;s <a
href="http://davidwalsh.name/canonical-link-rel">canonical link</a> will be searched for and used, otherwise the current URL is used)</em> and the desired size of button via the size attribute.  This tag should be added wherever within the page that you&#8217;d like the button to appear;  the SCRIPT tag should be found at the bottom of the page.  If you&#8217;d prefer not to dabble with the HTML yourself, Google provides a <a
href="http://www.google.com/intl/en/webmasters/+1/button/index.html">Google+1 button builder</a> to do the dirty work for you.  Four button sizes are currently offered.</p><p>You could also use the following HTML5 code to render your button:</p><pre class="html">
&lt;div class="g-plusone" data-size="standard" data-count="true"&gt;&lt;/div&gt;
</pre><p>Your button must have the <code>g-plusone</code> CSS class and <code>data-</code> attributes for options.</p><h2>Deferring&nbsp;Loading</h2><p>The HTML code above will render with the rest of the page, but what if you want to render a button on your own schedule?  No worries &#8212; Google&#8217;s API allows you to render buttons whenever you&#8217;d like:</p><pre class="html">
&lt;!-- one button, uses canonical link or current URL --&gt;
&lt;g:plusone&gt;&lt;/g:plusone&gt;

&lt;!-- Place this tag in your head or just before your close body tag --&gt;
&lt;script src="https://apis.google.com/js/plusone.js"&gt;
  {parsetags: 'explicit'}
&lt;/script&gt;

&lt;!-- Now render! --&gt;
&lt;script&gt;
	gapi.plusone.go();
&lt;/script&gt;
</pre><p>Using <code>{parsetags: 'explicit'}</code> and <code>gapi.plusone.go()</code> will turn your <code>g:plusone</code> tags into badges whenever you&#8217;d like.  You can also render a specific button with the following JavaScript code:</p><pre class="js">
&lt;script type="text/javascript" src="https://apis.google.com/js/plusone.js"&gt;
	{"parsetags": "explicit"}
&lt;/script&gt;
&lt;script type="text/javascript"&gt;
	function renderPlusone() {
		gapi.plusone.render("plusone-div");
	}
&lt;/script&gt;
&lt;body&gt;
	&lt;a href="#" onClick="renderPlusone();"&gt;Render the +1 button&lt;/a&gt;
	&lt;div id="plusone-div"&gt;&lt;/div&gt;
&lt;/body&gt;
</pre><p>Full API information as well as an introductory video is <a
href="http://code.google.com/apis/+1button/">available here</a>.  There are a few more small customization options available so check them out if you&#8217;re looking to specify language or play with custom rendering.</p><p>Don&#8217;t miss out on another avenue for sharing your awesome web content with everyone!  Implementing Twitter, Facebook, and Google+1 sharing buttons takes 5 minutes but the amount of traffic you can gain via these referral avenues is tremendous!</p><p><a
href="http://davidwalsh.name/google-plus-badge">Add a Google+1 Badge to Your&nbsp;Website</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/google-plus-badge/feed</wfw:commentRss> <slash:comments>26</slash:comments> </item> <item><title>Facebook Open Graph META&#160;Tags</title><link>http://davidwalsh.name/facebook-meta-tags</link> <comments>http://davidwalsh.name/facebook-meta-tags#comments</comments> <pubDate>Mon, 25 Apr 2011 14:24:28 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Bookmarking / Social]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5208</guid> <description><![CDATA[It&#8217;s no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook &#8220;Like&#8221; and &#8220;Recommend&#8221; widgets on every website.  One problem I&#8217;ve always found with sharing URLs on Facebook [...]<p><a
href="http://davidwalsh.name/facebook-meta-tags">Facebook Open Graph META&nbsp;Tags</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<img
src="http://davidwalsh.name/dw-content/facebook-developers-logo.png" alt="Facebook META Tags Open Graph" class="image" /><p>It&#8217;s no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook &#8220;Like&#8221; and &#8220;Recommend&#8221; widgets on every website.  One problem I&#8217;ve always found with sharing URLs on Facebook is that you often have no control over the image and description text that accompany the URL.  Had I known about Facebook Open Graph API, I would&#8217;ve known the solution to that problem.</p><p>Facebook&#8217;s Open Graph protocol allows for web developers to turn their websites into Facebook &#8220;graph&#8221; objects, allowing a certain level of customization over how information is carried over from a non-Facebook website to Facebook when a page is &#8220;recommended&#8221;, &#8220;liked&#8221;, or just generally shared.  The information is set via custom META tags on the source page.  Let&#8217;s take a look at the different META tags Facebook uses to allow you to customize how your website is shared.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/facebook-metas.php" class="demo">View Demo</a><div
class="clear"></div></div><p>All of Facebook&#8217;s Open Graph META tags are prefixed with <code>og:</code>, then continued with more specific the specific property to be set.  The data relative to the property set goes within the <code>content</code> attribute:</p><pre class="html">
&lt;meta property="og:{tagName}" content="{tagValue}"/&gt; 
</pre><p>Using this simple META tag strategy, you can tell Facebook what images, text, and more to use when sharing your webpage.  Let&#8217;s review a few key META tags!</p><h2>Facebook Open Graph Meta&nbsp;Tags</h2><h3>image</h3><p>The image META tag directs Facebook to use the specified image when the page is shared:</p><pre class="html">
&lt;meta property="og:image" content="http://davidwalsh.name/wp-content/themes/klass/img/facebooklogo.png"/&gt;
</pre><p>It&#8217;s best to use a square image, as Facebook displays them in that matter. That image should be at least 50&#215;50 in any of the usually supported image forms (JPG, PNG, etc.)</p><h3>title</h3><p>The title to accompany the URL:</p><pre class="html">
&lt;meta property="og:title" content="Facebook Open Graph META Tags"/&gt;
</pre><p>In most cases, this should be the article or page title.</p><h3>url</h3><p>The URL should be the <a
href="http://davidwalsh.name/canonical-link-rel">canonical address</a> for the given page:</p><pre class="html">
&lt;meta property="og:url" content="http://davidwalsh.name/facebook-meta-tags"/&gt;
</pre><p>Familiarize yourself with the <a
href="http://davidwalsh.name/canonical-link-rel">canonical LINK</a> type if you aren&#8217;t aware of its purpose &#8212; it could help your SEO out greatly!</p><h3>site_name</h3><p>Provides Facebook the name that you would like your website to be recognized by:</p><pre class="html">
&lt;meta property="og:site_name" content="David Walsh Blog"/&gt;
</pre><p>This is very useful as Facebook may have no way of knowing outside of this META tag.</p><h3>type</h3><p>Provides Facebook the type of website that you would like your website to be categorized by:</p><pre class="html">
&lt;meta property="og:type" content="blog"/&gt;
</pre><p>Read the <a
href="http://developers.facebook.com/docs/opengraph/#types" rel="nofollow">complete list of website types</a> to best categorize your website.</p><p
style="text-align:center;"> <img
src="http://davidwalsh.name/dw-content/david-facebook-share.png" alt="Facebook Open Graph" style="border:1px solid #ccc;padding:5px;margin:10px auto;display:block;" /></p><h2>More Facebook Open Graph META&nbsp;Tags</h2><p>The META tags provided above are just a few of the special Open Graph META tags sniffed by Facebook.  Open Graph also specified META tags for:</p><ul><li>Facebook Application-specific settings, if your website also has a Facebook app</li><li>Activities</li><li>Businesses</li><li>Groups</li><li>Locations</li></ul><p>Visit the <a
href="http://developers.facebook.com/docs/opengraph/" rel="nofollow">Facebook Open Graph page</a> to retrieve more details about each META tag and its intended information.  Facebook also provides a <a
href="http://developers.facebook.com/tools/lint" rel="nofollow">Lint tool</a> to help you validate what you&#8217;re sending!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/facebook-metas.php" class="demo">View Demo</a><div
class="clear"></div></div><p>The Open Graph protocol is a great way to not only share a page&#8217;s information but to also control how your site&#8217;s information is shared.  Using these META tags could be the difference in attracting just a few visitors from Facebook or attracting loads of visitors because your shared links provide useful keywords and imagery!</p><p><a
href="http://davidwalsh.name/facebook-meta-tags">Facebook Open Graph META&nbsp;Tags</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/facebook-meta-tags/feed</wfw:commentRss> <slash:comments>29</slash:comments> </item> <item><title>Dojo Toolkit API&#160;Bookmarklet</title><link>http://davidwalsh.name/dojo-bookmarklet</link> <comments>http://davidwalsh.name/dojo-bookmarklet#comments</comments> <pubDate>Thu, 03 Mar 2011 14:47:24 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5183</guid> <description><![CDATA[You probably know by know that I enjoy using JavaScript-powered bookmarklets to retrieve information.  I create a jQuery documentation bookmarklet, a MooTools class sniffer bookmarklet, and a  even a bookmarklet to allow you to submit articles to Script &#38; Style.  I work extensively with Dojo on a day to day basis so I end up needing [...]<p><a
href="http://davidwalsh.name/dojo-bookmarklet">Dojo Toolkit API&nbsp;Bookmarklet</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>You probably know by know that I enjoy using JavaScript-powered bookmarklets to retrieve information.  I create a <a
href="http://davidwalsh.name/jquery-favelet-documentation">jQuery documentation bookmarklet</a>, a <a
href="http://davidwalsh.name/mootools-documentation">MooTools class sniffer bookmarklet</a>, and a  even a bookmarklet to allow you to submit articles to <a
href="http://scriptandstyle.com">Script &amp; Style</a>.  I work extensively with Dojo on a day to day basis so I end up needing to review documentation often.  I got tired of using the API&#8217;s search methods and instead chose to create a bookmarklet to get quick access to what I want.</p><div
class="actions"><a
href="javascript:(function()%7Bvar%20d=document,w=window,ds=d.getSelection,ws=w.getSelection,ss=d.selection;t=(ws)%3Fws():(ds)%3Fds():(ss)%3Fss.createRange().text:'';t=(t.toString().length)%3Ft:prompt('Please select the Dojo resource you would like to research.','');if(t)%7Ba='http://dojotoolkit.org/api/';u=a+t.split('.').join('/');f=function()%7Bx=w.open(u,'dwin','scrollbars=1,toolbar=0,resizable=1,status=1,width=600,height=600');if(!x)w.location.href=u;%7D;if(/Firefox/.test(navigator.userAgent))setTimeout(f,0);else%20f();%7D%7D)();" class="demo">Bookmarklet</a><div
class="clear"></div></div><h2>The&nbsp;JavaScript</h2><pre class="js">
(function()%7Bvar%20d=document,w=window,ds=d.getSelection,ws=w.getSelection,ss=d.selection;t=(ws)%3Fws():(ds)%3Fds():(ss)%3Fss.createRange().text:'';t=(t.toString().length)%3Ft:prompt('Please select the Dojo resource you would like to research.','');if(t)%7Ba='http://dojotoolkit.org/api/';u=a+t.split('.').join('/');f=function()%7Bx=w.open(u,'dwin','scrollbars=1,toolbar=0,resizable=1,status=1,width=600,height=600');if(!x)w.location.href=u;%7D;if(/Firefox/.test(navigator.userAgent))setTimeout(f,0);else%20f();%7D%7D)();
</pre><p>What a mess!  Don&#8217;t worry about it &#8212; it&#8217;s compact because your browsers want it that way.  You may simply click the bookmarklet and type in the class name you want to find (ex: dijit.layout.TabContainer), or highlight a class name in the page and click the bookmarklet.</p><div
class="actions"><a
href="javascript:(function()%7Bvar%20d=document,w=window,ds=d.getSelection,ws=w.getSelection,ss=d.selection;t=(ws)%3Fws():(ds)%3Fds():(ss)%3Fss.createRange().text:'';t=(t.toString().length)%3Ft:prompt('Please select the Dojo resource you would like to research.','');if(t)%7Ba='http://dojotoolkit.org/api/';u=a+t.split('.').join('/');f=function()%7Bx=w.open(u,'dwin','scrollbars=1,toolbar=0,resizable=1,status=1,width=600,height=600');if(!x)w.location.href=u;%7D;if(/Firefox/.test(navigator.userAgent))setTimeout(f,0);else%20f();%7D%7D)();" class="demo">Bookmarklet</a><div
class="clear"></div></div><p>Have fun with this bookmarklet &#8212; it may save you some time.</p><p><a
href="http://davidwalsh.name/dojo-bookmarklet">Dojo Toolkit API&nbsp;Bookmarklet</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-bookmarklet/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>JSONP with jQuery, MooTools, and&#160;Dojo</title><link>http://davidwalsh.name/jsonp</link> <comments>http://davidwalsh.name/jsonp#comments</comments> <pubDate>Mon, 28 Feb 2011 15:09:42 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[MooTools]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5181</guid> <description><![CDATA[We all know that the big limitation of AJAX is that cross-domain requests aren&#8217;t allowed.  We also know, however, that we skirt around that rule a bit by using JSONP.  JSONP is the process of SCRIPT tag injection, referencing a cross-domain URL and providing a callback function (on your page) that the provider will call [...]<p><a
href="http://davidwalsh.name/jsonp">JSONP with jQuery, MooTools, and&nbsp;Dojo</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<img
src="http://davidwalsh.name/dw-content/jsonp.png" alt="JSONP MooTools jQuery" class="image" /><p>We all know that the big limitation of AJAX is that cross-domain requests aren&#8217;t allowed.  We also know, however, that we skirt around that rule a bit by using JSONP.  JSONP is the process of SCRIPT tag injection, referencing a cross-domain URL and providing a callback function (on your page) that the provider will call so that you can handle the result.  Let&#8217;s take a look at how JSONP is handled with jQuery, MooTools, and the Dojo Toolkit.  For our examples, we&#8217;ll pull tweets from Twitter with the term &#8220;Arsenal&#8221; in them.</p><h2>jQuery&nbsp;JSONP</h2><p>jQuery uses the same method for JSONP as it does for regular JSON &#8212; the <a
href="http://api.jquery.com/jQuery.getJSON/">jQuery.getJSON</a> method:</p><pre class="js">
jQuery.getJSON("http://search.twitter.com/search.json?callback=?",{
	q: "Arsenal"
},function(tweets) {
	// Handle response here
	console.info("Twitter returned: ",tweets);
});
</pre><p>As long as a callback parameter is provided to the getJSON method, jQuery will consider the request JSONP.</p><h2>MooTools&nbsp;JSONP</h2><p>MooTools requires the <a
href="http://mootools.net/docs/more/Request/Request.JSONP">Request.JSONP Class</a> available in <a
href="http://mootools.net/more/">MooTools More</a>.  Armed with Request.JSONP, fetching JSON from another domain is a piece of cake:</p><pre class="js">
new Request.JSONP({
	url: "http://search.twitter.com/search.json",
	data: {
		q: "Arsenal"
	},
	onComplete: function(tweets) {
		// Log the result to console for inspection
		console.info("Twitter returned: ",tweets);
	}
}).send();
</pre><p>Request.JSONP is a super compact class too!</p><h2>Dojo&nbsp;JSONP</h2><p>JSONP with the Dojo Toolkit requires the <a
href="http://dojotoolkit.org/reference-guide/dojo/io/script.html">dojo.io.script</a> resource and its get method:</p><pre class="js">
// dojo.io.script is an external dependency, so it must be required
dojo.require("dojo.io.script");

// When the resource is ready
dojo.ready(function() {
	
	// Use the get method
	dojo.io.script.get({
		// The URL to get JSON from Twitter
		url: "http://search.twitter.com/search.json",
		// The callback paramater
		callbackParamName: "callback", // Twitter requires "callback"
		// The content to send
		content: {
			q: "Arsenal"
		},
		// The success callback
		load: function(tweetsJson) {  // Twitter sent us information!
			// Log the result to console for inspection
			console.info("Twitter returned: ",tweetsJson);
		}
	});
});
</pre><p>Retrieving JSON with Dojo is usually done with the dojo.xhrGet method, but JSONP request this special method.  The arguments for dojo.io.script.get are the same as dojo.xhrGet with the exception of the callback parameter.</p><p>JSONP is a hugely effective, reliable, and easy to implement.  JSONP strategies also allow developers to avoid cumbersome server-side proxy writing to retrieve data.  Each of the JavaScript libraries above have battle-tested methods for retrieving JSON data across domains &#8212; it&#8217;s up to you to implement them to suit your needs!</p><p><a
href="http://davidwalsh.name/jsonp">JSONP with jQuery, MooTools, and&nbsp;Dojo</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/jsonp/feed</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>RealTime Stock Quotes with MooTools Request.Stocks and&#160;YQL</title><link>http://davidwalsh.name/javascript-stock-quotes</link> <comments>http://davidwalsh.name/javascript-stock-quotes#comments</comments> <pubDate>Wed, 23 Feb 2011 14:18:23 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[AJAX]]></category> <category><![CDATA[APIs]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Markup]]></category> <category><![CDATA[MooTools]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5174</guid> <description><![CDATA[It goes without saying but MooTools&#8217; inheritance pattern allows for creation of small, simple classes that possess immense power.  One example of that power is a class that inherits from Request, Request.JSON, and Request.JSONP:  Request.Stocks.  Created by Enrique Erne, this great MooTools class acts as a wrapper for Request.JSON and Yahoo!&#8217;s YQL service.  Let me [...]<p><a
href="http://davidwalsh.name/javascript-stock-quotes">RealTime Stock Quotes with MooTools Request.Stocks and&nbsp;YQL</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>It goes without saying but MooTools&#8217; inheritance pattern allows for creation of small, simple classes that possess immense power.  One example of that power is a class that inherits from Request, Request.JSON, and Request.JSONP:  <a
href="http://mootools.net/forge/p/request_stocks">Request.Stocks</a>.  Created by Enrique Erne, this great MooTools class acts as a wrapper for Request.JSON and Yahoo!&#8217;s YQL service.  Let me show you how to user Enrique&#8217;s awesome MooTools JavaScript class!</p><div
class="actions"> <a
href="http://davidwalsh.name/dw-content/request-stocks.php" class="demo">View Demo</a> <a
href="http://mootools.net/forge/p/request_stocks" class="demo">Download Request.Stocks</a><div
class="clear"></div></div><h2>The&nbsp;HTML</h2><p>The stock content will be built by javascript but we will have two DIVS created within the page:</p><pre class="html">
&lt;div id="stockIndicator"&gt;Retrieving stock information....&lt;/div&gt;
&lt;div id="stockContainer"&gt;&lt;/div&gt;
</pre><p>One DIV is an indicator which fades in an out during data fetch, the other is the container which will hold the stock information.</p><h2>The&nbsp;CSS</h2><p>As always, the styling of elements is subject to however you&#8217;d like them to look, but here&#8217;s a really basic style set:</p><pre class="css">
#stockContainer, #stockIndicator { width:500px; }
#stockContainer		{ background:#343434; padding:10px; }
#stockIndicator		{ text-align:right; visibility:hidden; padding:5px; }
.stockRow			{ padding:5px 10px; clear:both; margin-bottom:5px; }
	.stockName		{ font-size:14px; font-weight:normal; float:left; }
	.stockData		{ font-size:11px; float:right; width:200px; text-align:right; }

/* stock differential */`
.stockSame			{  }
.stockUp			{ background:lightgreen; }
	.stockUp .stockName	{ color:green; }
.stockDown			{ background:pink; }
	.stockDown .stockName { color:red; }
</pre><p>Stocks that are above for the day are green, below are red.  Stocks which have stayed the same are black.  Style however you&#8217;d like though.</p><h2>The MooTools&nbsp;JavaScript</h2><p>Before attacking an example usage, let&#8217;s talk about about Request.Stocks.  This class is an extension of JSONP, setting numerous defaults that correspond to using Yahoo&#8217;s YQL service, and adding additional options to customize the data you want to receive from Yahoo.  A few of the custom options include:</p><ul><li>stocks: An array of symbols to retrieve stocks for</li><li>sortBy: The data field to sort by</li><li>display: The data fields to retrieve from Yahoo.  A few of the fields you can retrieve include:  Ask, AverageDailyVolume, Bid, AskRealtime, BidRealtime, BookValue, Change&amp;PercentChange, Change, Commission, ChangeRealtime, AfterHoursChangeRealtime, DividendShare, LastTradeDate, TradeDate, and more!</li></ul><p>More detail on all of the custom options, some of which are not listed on this blog, <a
href="http://2011.mild.ch/projects/request-stocks.html">can be found here</a>.</p><p>So now to the class usage.  The sample code looks long but that&#8217;s due to my commenting:</p><pre class="js">
// When the dom is ready...
window.addEvent("domready",function() {
	// Get the stock container and indicator
	var container = document.id("stockContainer");
	var indicator = document.id("stockIndicator");
	// Create the instance
	var request = new Request.Stocks({
		// Stocks to retrieve
		stocks: ["AAPL","GOOG","MSFT"],
		// Formatter upon result
		onComplete: function(result) {
			// Log out the result to see the structure
			console.warn(result);
			// Hide the indicator
			indicator.fade(0);
			// Create a template with which to display the information
			var template = ' \
				&lt;div class="stockRow stock{UpDown}"&gt; \
					&lt;div class="stockName"&gt;({symbol}) {Name}&lt;/div&gt;\
					&lt;div class="stockData"&gt;{Ask} {Change} {ChangeinPercent}&lt;/div&gt; \
					&lt;br class="clear" /&gt; \
				&lt;/div&gt; \
			';
			// For every stock , display its information in the template
			var html ="";
			Array.from(result.query.results.quote).each(function(quote) {
				// Add an "UpDown" property to the quote object
				var change = Number.from(quote.Change);
				quote.UpDown =  change == 0 ? "Same" : change &gt; 0 ? "Up" : "Down";
				// Update running contnet
				html += template.substitute(quote);
			});
			// Update the content
			container.set("html",html);
		},
		// Show the indicator upon request
		onRequest: function () {
			indicator.fade(1);
		}
	});
	// Send the request every 20 seconds
	(function() {
		request.send();
	}).periodical(20 * 1000);
	// Send right away
	request.send();
</pre><p>Request.Stocks&#8217; onComplete method provides a method to handle the result from Yahoo.  Notice how I build the content string (using MooTools&#8217; string.substitute) and then set the element&#8217;s HTML, instead of appending to the element&#8217;s innerHTML property &#8212; that&#8217;s the more efficient way to change a node&#8217;s content.  Also, remember that this class contains every method that Request, Request.JSON, and Request.JSONP have.</p><div
class="actions"> <a
href="http://davidwalsh.name/dw-content/request-stocks.php" class="demo">View Demo</a> <a
href="http://mootools.net/forge/p/request_stocks" class="demo">Download Request.Stocks</a><div
class="clear"></div></div><p>Request.Stocks is an outstanding utility class for developers looking to create applications based on stock market data.  The mix of flexibility and simplicity are real strong points of this class.  If I had one criticism of this class, it would be that it doesn&#8217;t provide a method to add or remove stocks on the fly.  This functionality would allow the developer to create applications which allow users to add their own portfolio stocks without needing them all defined immediately.  Other than that, this class rock solid and I look forward to seeing where it goes in the future!</p><p><a
href="http://davidwalsh.name/javascript-stock-quotes">RealTime Stock Quotes with MooTools Request.Stocks and&nbsp;YQL</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/javascript-stock-quotes/feed</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Translate Content with the Google Translate API and&#160;JavaScript</title><link>http://davidwalsh.name/google-translate-api</link> <comments>http://davidwalsh.name/google-translate-api#comments</comments> <pubDate>Mon, 07 Feb 2011 15:28:49 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Google]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[MooTools]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5165</guid> <description><![CDATA[Note:  For this tutorial, I&#8217;m using version1 of the Google Translate API.  A newer REST-based version is available. In an ideal world, all websites would have a feature that allowed the user to translate a website into their native language (or even more ideally, translation would be done before the user sees anything on the [...]<p><a
href="http://davidwalsh.name/google-translate-api">Translate Content with the Google Translate API and&nbsp;JavaScript</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p><em>Note:  For this tutorial, I&#8217;m using version1 of the Google Translate API.  A newer REST-based version is available.</em></p><p>In an ideal world, all websites would have a feature that allowed the user to translate a website into their native language (or even more ideally, translation would be done before the user sees anything on the page).  In the real world, most small businesses can&#8217;t afford to invest money into website translation.   Luckily a small startup named &#8220;Google&#8221; provides an outstanding <a
href="http://code.google.com/apis/language/translate/overview.html">Translate API</a> to translate simple text from one language to another!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/google-language-api.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>Sample&nbsp;HTML</h2><p>Google&#8217;s awesome Translate API allows you to send HTML &#8212; you don&#8217;t need to extract the text yourself! That&#8217;s a huge feature because parsing HTML and putting it all back again would be a nightmare!  Let&#8217;s put together some sample content:</p><pre class="html">
&lt;script src="https://www.google.com/jsapi?key=YOUR_GOOGLE_KEY"&gt;&lt;/script&gt;
&lt;div id="languages"&gt;&lt;p&gt;
	&lt;a href="?lang=en" rel="en"&gt;English&lt;/a&gt; / &lt;a href="?lang=es" rel="es"&gt;Spanish&lt;/a&gt; / &lt;a href="?lang=it" rel="it"&gt;Italian&lt;/a&gt; /
	&lt;a href="?lang=fr" rel="fr"&gt;French&lt;/a&gt;
&lt;/p&gt;&lt;/div&gt;

&lt;div id="languageBlock"&gt;
	&lt;p&gt;Lights go out and I can't be saved &lt;br /&gt;
	Tides that I tried to swim against  &lt;br /&gt;
	Brought me down upon my knees  &lt;br /&gt;
	Oh I beg, I beg and plead &lt;/p&gt;

	&lt;p&gt;Singin', come out if things aren't said  &lt;br /&gt;
	Shoot an apple off my head  &lt;br /&gt;
	And a, trouble that can't be named  &lt;br /&gt;
	Tigers waitin' to be tamed &lt;/p&gt;

	&lt;p&gt;Singing, yooooooooooooo ohhhhhh  &lt;br /&gt;
	Yoooooooooooo ohhhhhh &lt;/p&gt;

	&lt;p&gt;Home, home, where I wanted to go &lt;br /&gt; 
	Home, home, where I wanted to go  &lt;br /&gt;
	Home, home, where I wanted to go  &lt;br /&gt;
	Home, home, where I wanted to go&lt;/p&gt;
&lt;/div&gt;
</pre><p>We will use this #languageBlock element to send to Google for translation.  Note that each link has a rel attribute which holds the code for the language to switch to.</p><h2>Google Translate API&nbsp;JavaScript</h2><p><em>For the sake of keeping the code short, I&#8217;m using MooTools to access elements and add DOM events.  Feel free to stick to simple JavaScript or your framework of choice.</em></p><pre class="js">
// Set the original/default language
var lang = "en";
var currentClass = "currentLang";

// Load the language lib
google.load("language",1);

// When the DOM is ready....
window.addEvent("domready",function(){
	// Retrieve the DIV to be translated.
	var translateDiv = document.id("languageBlock");
	// Define a function to switch from the currentlanguage to another
	var callback = function(result) {
		if(result.translation) {
			translateDiv.set("html",result.translation);
		}
	};
	// Add a click listener to update the DIV
	$$("#languages a").addEvent("click",function(e) {
		// Stop the event
		if(e) e.stop();
		// Get the "to" language
		var toLang = this.get("rel");
		// Set the translation into motion
		google.language.translate(translateDiv.get("html"),lang,toLang,callback);
		// Set the new language
		lang = toLang;
		// Add class to current
		this.getSiblings().removeClass(currentClass);
		this.addClass(currentClass);
	});
});
</pre><p>The first step in the process is using google.load to load the Translate API.  When the the API is loaded, we grab the DIV to be translated.  We then define a callback for when the translation returns from Google.  This callback simply updates the content of the DIV.  The last step is adding a click event handler to each language link.  A google.language.translate call sends the content to Google for translation.  When the translated content returns, the content is updated by our callback!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/google-language-api.php" class="demo">View Demo</a><div
class="clear"></div></div><p>Thanks to Google&#8217;s Translate API, we can effortlessly translate data!  It&#8217;s important that I note that Google&#8217;s content size limit is quite small so you shouldn&#8217;t rely on the Translate API to completely translate your a page.  It is, however, an excellent way to translate an alert or status message in a give language!</p><p><a
href="http://davidwalsh.name/google-translate-api">Translate Content with the Google Translate API and&nbsp;JavaScript</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/google-translate-api/feed</wfw:commentRss> <slash:comments>25</slash:comments> </item> <item><title>Google URL Shortener PHP&#160;Class</title><link>http://davidwalsh.name/google-url</link> <comments>http://davidwalsh.name/google-url#comments</comments> <pubDate>Wed, 02 Feb 2011 15:25:30 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Google]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5162</guid> <description><![CDATA[Google has had a URL shortening domain for quite a while now but it wasn&#8217;t until recently that Google exposed the URL shortening API to the public.  I took a few minutes to review their API and created a very basic GoogleUrlApi class that will shorten long URLs and expand shortened URLs. The&#160;PHP The class [...]<p><a
href="http://davidwalsh.name/google-url">Google URL Shortener PHP&nbsp;Class</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Google has had a URL shortening domain for quite a while now but it wasn&#8217;t until recently that Google exposed the <a
href="http://code.google.com/apis/urlshortener/" rel="nofollow">URL shortening API</a> to the public.  I took a few minutes to review their API and created a very basic <code>GoogleUrlApi</code> class that will shorten long URLs and expand shortened URLs.</p><h2>The&nbsp;PHP</h2><p>The class itself is quite compact and the code should be easy to read:</p><pre class="php">
// Declare the class
class GoogleUrlApi {
	
	// Constructor
	function GoogleURLAPI($key,$apiURL = 'https://www.googleapis.com/urlshortener/v1/url') {
		// Keep the API Url
		$this-&gt;apiURL = $apiURL.'?key='.$key;
	}
	
	// Shorten a URL
	function shorten($url) {
		// Send information along
		$response = $this-&gt;send($url);
		// Return the result
		return isset($response['id']) ? $response['id'] : false;
	}
	
	// Expand a URL
	function expand($url) {
		// Send information along
		$response = $this-&gt;send($url,false);
		// Return the result
		return isset($response['longUrl']) ? $response['longUrl'] : false;
	}
	
	// Send information to Google
	function send($url,$shorten = true) {
		// Create cURL
		$ch = curl_init();
		// If we're shortening a URL...
		if($shorten) {
			curl_setopt($ch,CURLOPT_URL,$this-&gt;apiURL);
			curl_setopt($ch,CURLOPT_POST,1);
			curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode(array("longUrl"=&gt;$url)));
			curl_setopt($ch,CURLOPT_HTTPHEADER,array("Content-Type: application/json"));
		}
		else {
			curl_setopt($ch,CURLOPT_URL,$this-&gt;apiURL.'&amp;shortUrl='.$url);
		}
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
		// Execute the post
		$result = curl_exec($ch);
		// Close the connection
		curl_close($ch);
		// Return the result
		return json_decode($result,true);
	}		
}
</pre><p>The constructor requires your <a
href="https://code.google.com/apis/console/" rel="nofollow">Google API key</a>.  A second argument may be provided to the URL of the Google API.  As the API is currently in version 1, changing this URL would be more harmful than useful.  The class features two main methods:  shorten and expand.  Each method takes the long or short URL, contacts Google, and returns its counterpart.  If no counterpart is found, or the Google URL Shortener API is down, a result of false is returned, so please be sure to use your own error handling.</p><p>Now let&#8217;s create an instance of <code>GoogleUrlApi</code> to shorten and then expand a URL:</p><pre class="php">
// Create instance with key
$key = 'xhjkhzkhfuh38934hfsdajkjaf';
$googer = new GoogleURLAPI($key);

// Test: Shorten a URL
$shortDWName = $googer-&gt;shorten("http://davidwalsh.name");
echo $shortDWName; // returns http://goo.gl/i002

// Test: Expand a URL
$longDWName = $googer-&gt;expand($shortDWName);
echo $longDWName; // returns http://davidwalsh.name

</pre><p>The <code>shorten()</code> and <code>expand()</code> methods return their counterparts, as expected.  Quite painless, no?</p><p>The Google URL Shortener API provides much more than what my class provides, including user URL listing and usage tracking.  My class provides only the basics;  I&#8217;m assuming that 90%+ care only about getting the URL shortened so I&#8217;ve catered to that audience.  I had also thought about adding a caching mechanism to the class but since most everyone has their own method of caching information, I thought it best to leave that out.  Hopefully this class has some use for you all!</p><p><a
href="http://davidwalsh.name/google-url">Google URL Shortener PHP&nbsp;Class</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/google-url/feed</wfw:commentRss> <slash:comments>30</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (User agent is rejected)
Database Caching 1/59 queries in 0.043 seconds using disk: basic
Object Caching 1452/1557 objects using disk: basic

Served from: davidwalsh.name @ 2012-05-23 22:06:25 -->
