<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns: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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Janrain | Technology Blog</title>
	
	<link>http://janrain.com</link>
	<description>Developers talk nerdy about our products.</description>
	<lastBuildDate>Fri, 24 May 2013 22:32:55 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JanrainTechnology" /><feedburner:info uri="janraintechnology" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://janrain.com/category/technology/</link><url>http://janrain.com/wp-content/uploads/2012/04/janrain-rss-logo.png</url><title>Janrain</title></image><feedburner:emailServiceId>JanrainTechnology</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Food Carts and the UNIX Philosophy</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/Zpz9IPHi2wk/</link>
		<comments>http://janrain.com/blog/food-carts-and-the-unix-philosophy/#comments</comments>
		<pubDate>Fri, 10 May 2013 16:24:11 +0000</pubDate>
		<dc:creator>Luc Perkins</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=22610</guid>
		<description><![CDATA[For as long as I can remember growing up here, Portland has been known for a small handful of things: beer, coffee, mopey indie rock, bikes, soul-crushing weather. Added to that list in the past few years have been Portlandia, the Timbers Army, Voodoo Doughnut, and, most importantly (IMHO), food carts. Food carts have become [...]]]></description>
				<content:encoded><![CDATA[<p>For as long as I can remember growing up here, Portland has been known for a small handful of things: <a href="http://www.portlandbeer.org/breweries/">beer</a>, <a href="http://pdx.eater.com/archives/2012/09/05/portlands-20-best-coffeehouses-and-roasters.php">coffee</a>, <a href="http://www.sweetadeline.net/">mopey indie rock</a>, bikes, soul-crushing weather. Added to that list in the past few years have been <em>Portlandia</em>, the <a href="http://timbersarmy.org/">Timbers Army</a>, <a href="http://voodoodoughnut.com/">Voodoo Doughnut</a>, and, most importantly (IMHO), <a href="http://www.foodcartsportland.com/">food carts</a>.</p>
<p>Food carts have become a key component of our culinary culture here in PDX. We love that we can get phenomenal food all over town without paying for the overhead associated with brick-and-mortar establishments. It also doesn&#8217;t hurt that we can then eat wherever we please—on a park bench, at the office, or, here at Janrain, on the rooftop of the <a href="http://en.wikipedia.org/wiki/Dekum_Building">Dekum building</a>, which is a magisterial thing on the 12 or so nice days we have in a calendar year.</p>
<p>There are lots of phenomenal food carts, but <a href="http://khaomangai.com/">Nong&#8217;s Khao Man Gai</a> is considered by <a href="http://www.yelp.com/biz/nongs-khao-man-gai-portland#query:nong%27s%20khao%20man%20gai">many</a> to be one of a very small handful of the best PDX food carts if not <em>the</em> absolute, undisputed best.</p>
<p>So what does Nong&#8217;s serve that makes it so special? Many would assume that Nong&#8217;s serves a broad, continuously shifting array of dishes. I mean, if this place is one of the best of Portland&#8217;s <a href="http://www.foodcartsportland.com/maps/">over 500</a> carts, then surely they must have earned this reputation through a diversity of offerings, right? That&#8217;s what <em>I</em> would have thought. And this is indeed the approach that the vast majority of food carts take, sometimes offering <em>dozens</em> of menu options.</p>
<p>But Nong&#8217;s seems to succeed because it offers you shockingly <em>little</em> choice. In the picture below you&#8217;ll see the only thing that you can get at Nong&#8217;s (excluding beverages, of course):</p>
<div class="figure">
<p><img alt="Yum" src="http://imonlyhereforthefood.com/images/Food/NongsKhaoManGai/NongsKhaoManGai004.jpg" /></p>
<p class="caption">Have a look at its <a href="http://www.foodcartsportland.com/maps/">online menu</a> to see what I mean (see the &#8220;Downtown/Alder&#8221; column on the left). Yes, that&#8217;s right: <strong>two menu items</strong>. Menu item #1 is chicken and rice. Menu item #2 is chicken and rice &#8220;Big Size.&#8221; That barely counts as a separate item! That&#8217;s like 1.27 menu items! Vegetarian or vegan? Too bad. Go somewhere else. Looking for other common Thai items like Pad Thai or fried rice? Too bad. Deal with it. There are plenty of other Thai carts out there.</p>
</div>
<p>But far from alienating their potential clientele, Nong&#8217;s thrives in a major way. They continuously win culinary awards of all sorts. They&#8217;re frequently featured in publications about Portland&#8217;s food culture. And, most tellingly, the lunchtime line is almost always exasperatingly long. And when you do make it through the line and bring your chicken and rice back to the office, your response is almost invariably the following: &#8220;That was barely a wait at all. I would have waited an hour or more for the fermented bean curd sauce alone.&#8221;</p>
<h3 id="the-unix-philosophy">The UNIX Philosophy</h3>
<p>So what on Earth does this have to do with UNIX? Well, it&#8217;s simple: Nong&#8217;s and UNIX have the same core philosophy. There are a variety of formulations of the UNIX philosophy, but I&#8217;ll do something super hacky and deprecated and consult the UNIX philosophy <a href="http://en.wikipedia.org/wiki/Unix_philosophy">Wikipedia page</a> and try to distill the philosophy into a few core tenets:</p>
<ul>
<li>Small is beautiful</li>
<li>Make each program do <em>one thing</em> * and one thing well</li>
<li>Favor simplicity and portability over feature completeness</li>
<li>Write programs to work together</li>
</ul>
<p>The antithesis of the UNIX philosophy in computing consists, then, of the following:</p>
<ul>
<li>Big is beautiful</li>
<li>Make programs do a whole variety of things</li>
<li>Favor comprehensiveness of function over simplicity</li>
<li>Write programs to work autonomously</li>
</ul>
<p>Yes, this is an extremely rough expression of the UNIX philosophy, but I do think that it elucidates some crucial points. According to this worldview, complex processes should almost always be broken up into smaller processes in the name of transparency (e.g. teasing out problems and speeding the application of solutions); it&#8217;s always better to have a toolbelt with a lot of small tools with clear purposes than to have a toolbelt with one big tool that does everything; and larger systems should be carefully woven out of these smaller pieces.</p>
<h3 id="the-unix-philosophy-in-action-at-nongs">The UNIX Philosophy in Action at Nong&#8217;s</h3>
<p>The UNIX philosophy is typically associated with computing—unsurprisingly—but I see no reason why it can&#8217;t be applied to organizational theory. Nong&#8217;s makes one thing—chicken and rice—and does it extremely well. In this, it is a spiritual devotee of the UNIX philosophy, even if an inadvertent one. Nong&#8217;s menu has no aspirations whatsoever to be comprehensive, and they seem to have no plans to change their menu. It might be fair to say that limited ambition is another core component of the UNIX philosophy.</p>
<p>Going down this path has benefited the organization in a variety of ways:</p>
<ul>
<li><strong>Efficiency</strong>: when the line gets long—as it very often does—doing one thing and doing it well helps Nong&#8217;s with queue efficiency in a drastic and immediately apparent way. No one dilly-dallies figuring out what to order, and the cashier doesn&#8217;t have to navigate a sophisticated user interface in taking orders.</li>
<li><strong>Friendlier learning curve</strong>: new personnel are quickly brought up to speed. Instead of learning how to cook 50 dishes, they learn how to make one. Now, Nong&#8217;s chicken and rice is deceptively complex, and there&#8217;s a lot of careful work that goes into it. Nonetheless, less conceptual overhead means quicker turnaround times for new employees.</li>
<li><strong>Competitive advantage</strong>: whereas other carts always face the possibility that another Thai or Indonesian or Lebanese or Ethiopian or whatever cart is going to cut into their profits, Nong&#8217;s absolutely <em>owns</em> chicken and rice. If anyone came along and tried to do exactly what they do, they would be seen as a cheap knock-off.</li>
</ul>
<p>With all of this going for it, is it any surprise that Nong&#8217;s succeeds?</p>
<h3 id="toward-a-unix-flavored-federation-of-processes">Toward a UNIX-Flavored Federation of Processes?</h3>
<p>If the UNIX philosophy can work for Nong&#8217;s, it can probably benefit all kinds of organizations and processes. Modularity and learning curves and feature completeness are not just concepts for IT departments. They also have a place in any and all discussion of organizational competency and success more broadly.</p>
<p>I long for the day when <em>all</em> of Portland&#8217;s food carts adopt the UNIX philosophy and drastically limit their scope. The result would be fewer total menu options but a far higher quotient of out-of-this-world menu options. The food cart ecosystem would be transformed from an assemblage of redundant menu offerings and reinvented wheels into a thriving federation of lean operations. So next you&#8217;re at a food cart, talk with the owner and share this vision. Urge them to consider seeking the Nong&#8217;s path.</p>
<p>What do you think, Dear Reader? Should modularity trump completeness? Are limited feature sets usually a good thing? Am I crazy for thinking that the UNIX philosophy has real-world relevance?</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/Zpz9IPHi2wk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/food-carts-and-the-unix-philosophy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/food-carts-and-the-unix-philosophy/</feedburner:origLink></item>
		<item>
		<title>Technology Association of Oregon Honors Tech Companies of the Year</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/EFB81xoxcc0/</link>
		<comments>http://janrain.com/blog/technology-association-of-oregon-honors-tech-companies-of-the-year/#comments</comments>
		<pubDate>Fri, 26 Apr 2013 18:14:11 +0000</pubDate>
		<dc:creator>Gina Rau</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[janrain happenings]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=22378</guid>
		<description><![CDATA[In a metropolitan city where our GDP growth rate is outpacing our population growth primarily thanks to our tech sector and the continual birth and growth of rock star startups, one might assume that it’s a dog-eat-dog world of fighting over talent, resources and the spotlight. But not so, in Portland. Our technology community is [...]]]></description>
				<content:encoded><![CDATA[<p dir="ltr"><img class="alignright size-medium wp-image-22382" alt="raising star award" src="http://janrain.com/wp-content/uploads/2013/04/Screen-Shot-2013-04-26-at-9.27.34-AM-300x268.png" width="300" height="268" />In a metropolitan city where our <a title="Business Week on Portland' GDP Growth" href="http://www.businessweek.com/articles/2013-03-21/which-u-dot-s-dot-cities-boomed-which-went-bust" target="_blank">GDP growth rate is outpacing our population growth</a> primarily thanks to our tech sector and the continual birth and growth of rock star startups, one might assume that it’s a dog-eat-dog world of fighting over talent, resources and the spotlight. But not so, in Portland. Our technology community is one that comes together (often) to inspire, share and support each other with the common goal of bringing the very best technology to the world.</p>
<p dir="ltr">Last night, the<a title="Oregon TAO Honors Tech Company of the Year 2013" href="http://www.oregonlive.com/silicon-forest/index.ssf/2013/04/oregon_tech_awards_honor_cloud.html?" target="_blank"> Technology Association of Oregon honored</a> some of those companies who are putting Oregon on the map with their technology and mission. It can’t be easy to choose just four to put a spotlight on, because Portland has an abundance of technology companies who have or are on the verge of success.</p>
<p dir="ltr">For all of us at Janrain, just to be in the company with the likes of <a title="Iovation" href="https://www.iovation.com" target="_blank">Iovation</a>, <a title="Puppet Labs" href="www.puppetlabs.com" target="_blank">Puppet Labs</a>, <a title="FEI" href="http://www.fei.com" target="_blank">FEI</a>, <a title="Digimarc" href="www.digimarc.com" target="_blank">Digimarc</a>, <a title="Vendscreen" href="http://vendscreen.com" target="_blank">Vendscreen</a> and the other nominees for Technology Company of the Year is such a compliment to all that we’ve achieved. And to be selected as the Rising Star Technology Company of the Year is a huge and humbling honor that reflects the smart, dedicated people who bring their talent and passion everyday to the important work we’re doing on behalf of our customers.</p>
<p dir="ltr">Congratulations to all the nominees, winners and those who devote themselves to this incredible technology community. Thanks to the Technology Association of Oregon for acknowledging the great work we, and the entire community, are doing.</p>
<p dir="ltr">By the way, the Portland tech community would likely edit that common goal mentioned above to read: bring the very best technology to the world, and put Portland, Oregon’s Silicon Forest on the global map as the premier community for starting and growing world-class technology companies.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/EFB81xoxcc0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/technology-association-of-oregon-honors-tech-companies-of-the-year/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/technology-association-of-oregon-honors-tech-companies-of-the-year/</feedburner:origLink></item>
		<item>
		<title>Tutorial: Building a Sample Application with Haskell Snap, PostgreSQL, and the PostgreSQL Simple Snaplet</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/0oXV1brdcDM/</link>
		<comments>http://janrain.com/blog/tutorial-building-a-sample-application-with-haskell-snap-postgresql-and-the-postgresql-simple-snaplet/#comments</comments>
		<pubDate>Thu, 25 Apr 2013 16:22:03 +0000</pubDate>
		<dc:creator>Luc Perkins</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[snap]]></category>
		<category><![CDATA[snaplet]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=22086</guid>
		<description><![CDATA[If you&#8217;re reading this, you probably don&#8217;t need to be sold on using Haskell or Postgres, so I&#8217;ll cut to the chase. Instead of telling you why both are astonishingly and almost painfully amazing—and here at Janrain we use Haskell, the Snap web framework, and PostgreSQL (as well as the PostgreSQL Simple module itself) to [...]]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;re reading this, you probably don&#8217;t need to be sold on using <a href="http://www.haskell.org/haskellwiki/Haskell" target="_blank">Haskell</a> <em>or</em> <a href="http://www.postgresql.org/" target="_blank">Postgres</a>, so I&#8217;ll cut to the chase. Instead of telling you why both are astonishingly and almost painfully amazing—and here at Janrain we use <a href="http://download.fpcomplete.com/janrain-fp-complete-study.pdf" target="_blank">Haskell</a>, the <a href="http://snapframework.com/" target="_blank">Snap</a> web framework, and PostgreSQL (as well as the <a href="http://hackage.haskell.org/package/postgresql-simple" target="_blank">PostgreSQL Simple</a> module itself) to power our <a href="http://janrain.com/products/capture/">Janrain Capture</a> product, so we can vouch for that—I&#8217;ll skip straight to the tutorial.</p>
<p>What you&#8217;ll find below is more of a streamlined presentation of a lot of disparate sources (for example <a href="http://hackage.haskell.org/package/postgresql-simple" target="_blank">here</a> and <a href="http://ocharles.org.uk/blog/posts/2012-12-03-postgresql-simple.html" target="_blank">here</a>) than a 100% new tutorial, but I hope that it serves to put in easily digestible narrative form a lot of the currently existing information. I&#8217;ll be putting together an extremely simple product management tool (basically the most barebones and useful <a href="http://basecamp.com/" target="_blank">Basecamp</a> clone out there). I will do nothing on the UI level and will interact with the server only via <a href="https://httpkit.com/resources/HTTP-from-the-Command-Line/" target="_blank">cURL</a>. I&#8217;ll save views and fancy aesthetics for another day.</p>
<h3 id="get-a-snap-application-up-and-going">Get a Snap Application Up and Going</h3>
<p>Since this tutorial also serves as a rudimentary introduction to Snap for the uninitated, I&#8217;ll briefly walk through starting a new Snap application. If you&#8217;ve installed <a href="http://www.haskell.org/platform/" target="_blank">Haskell</a>, <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall" target="_blank">cabal</a>, and <a href="http://snapframework.com/download" target="_blank">Snap</a>, simply create a new project directory (we&#8217;ll call our project <code>projectomatic</code>), navigate to the directory, and initiate a new Snap application:</p>
<pre class="brush: bash; title: ; notranslate">
mkdir projectomatic
cd projectomatic
snap init
</pre>
<p>Once we&#8217;ve done that, if we run <code>ll</code> or <code>ls</code> or whatever, we&#8217;ll see that a variety of files and directories have been created. I won&#8217;t delve too deeply into that here, so I recommend reading up <a href="http://snapframework.com/docs/quickstart" target="_blank">here</a> if you want to learn more about the anatomy of a Snap application. I could have run <code>snap init barebones</code> to begin with a much more stripped-down application, but I&#8217;m going to go for a full installation so that we can more quickly get up to speed on using <a href="http://snapframework.com/snaplets" target="_blank">Snaplets</a>.</p>
<h3 id="setting-up-our-application-to-use-postgresql-simple">Setting up Our Application to Use PostgreSQL simple</h3>
<p>Snaplets are somewhat difficult to explain, but I&#8217;ll try to encapsulate it briefly. Snaplets are sort of a portal to the outside world from within a Snap application. Snaplets enable you to access state—database transactions being a perfect example of that—in a relatively painless fashion. Setting up our application to use PostgreSQL Simple involves using the very handy <a href="https://github.com/mightybyte/snaplet-postgresql-simple/" target="_blank">PostgreSQL Simple Snaplet</a>. First, install that using cabal (<code>cabal install snaplet-postgresql-simple</code>), then add that to your dependencies in your <code>projectomatic.cabal</code> file, run <code>cabal install</code>, then modify your <code>src/Application.hs</code> file like so:</p>
<pre class="brush: haskell; title: ; notranslate">
{-# LANGUAGE FlexibleInstances #-}

import Control.Lens
import Snap (get)
import Snap.Snaplet
import Snap.Snaplet.PostgresqlSimple

data App = App
    { _pg :: Snaplet Postgres }

makeLenses ''App

instance HasPostgres (Handler b App) where
    getPostgresState = with pg get
</pre>
<p>With the normal <code>snap init</code> install, your application is set up to use a few other Snaplets out of the box. Feel free to leave those in. I will remove them for the sake of brevity in this tutorial. What you see above is that I&#8217;ve embedded our Postgres Snaplet within our <code>App</code> data type and then used the <code>makeLenses ''App</code> function to generate an accessor <code>pg</code> that we can use elsewhere. Lastly, I&#8217;ll define the instance <code>HasPostgres (Handler b App)</code>, which will enable the application to have access to Postgres-related state.</p>
<p>Now that we have our handy <code>pg</code> accessor, we need to go over to our <code>src/Site.hs</code> file and do some additional setup. First, add the PostgreSQL Snaplet to the imports:</p>
<pre class="brush: haskell; title: ; notranslate">
import Snap.Snaplet.PostgresqlSimple
</pre>
<p>Now, we need to add our <code>pg</code> constructor to the core of the application. Let&#8217;s modify the definition of the <code>app</code> function to include our Postgres Snaplet:</p>
<pre class="brush: haskell; title: ; notranslate">
app :: SnapletInit App App
app = makeSnaplet &quot;app&quot; &quot;My stunningly advanced Snap application.&quot; Nothing $ do
    pg &lt;- nestSnaplet &quot;pg&quot; pg pgsInit
    addRoutes routes
    return $ App pg
</pre>
<p>We&#8217;re almost ready. All we have to do now is configure our Postgres connection. When we ran <code>cabal install</code> after adding the <code>snaplet-postgresql-simple</code> module to our dependencies, Snap created a <code>snaplets/postgresql-simple</code> directory on its own (wasn&#8217;t that sweet?). In that directory, there&#8217;s a file called <code>devel.cfg</code> where we specify our database connection. Here&#8217;s what mine will look like (yours will vary, of course!):</p>
<pre class="brush: bash; title: ; notranslate">
host = &quot;localhost&quot;
port = 5432
user = &quot;luc&quot;
pass = &quot;&quot;
db = &quot;projectomatic&quot;
</pre>
<p>There are other configuration possibilities, but this will be enough to get me up and going. Once this is done, try running <code>cabal install</code> and see if you get any compiler errors. If so, see if you can debug on your own. If not, then let&#8217;s move on to the next section.</p>
<h3 id="our-project-data-type">Our <code>Project</code> Data Type</h3>
<p>Haskell is a real stickler for data types, so we now have to start being both explicit and careful about everything we do. Let&#8217;s define our <code>Project</code> data type in our <code>src/Site.hs</code> file. We could do it in a separate file if we wanted to, but let&#8217;s keep it simple. I&#8217;ll be using the <code>Text</code> data type here—as use of strings is widely considered to be deprecated in Haskell)—so I&#8217;ll make sure and add <a href="http://hackage.haskell.org/packages/archive/text/0.11.2.0/doc/html/Data-Text.html"><code>Data.Text</code></a> to my imports:</p>
<pre class="brush: haskell; title: ; notranslate">
import qualified Data.Text as T
</pre>
<p>We&#8217;ll keep our data type simple:</p>
<pre class="brush: haskell; title: ; notranslate">
data Project = Project
  { title       :: T.Text
  , description :: T.Text
  }
</pre>
<h3 id="setting-up-postgres-to-handle-our-data">Setting up Postgres to Handle Our Data</h3>
<p>Postgres is a traditional columnar database (though with a of sugar on top), so we can&#8217;t simply start throwing a bunch of key/value pairs at it and expect it to start storing things. We&#8217;ll need to create tables that are ready to do our bidding. Oh, and our database. We should make one of those, too. Let&#8217;s start with that. In a *nix environment, chances are strong that you can create a new database from the command line (presuming that you have Postgres installed):</p>
<pre class="brush: bash; title: ; notranslate">
createdb projectomatic
</pre>
<p>If that doesn&#8217;t work, either consult one of many Postgres installation tutorials or cut to the chase and download <a href="http://postgresapp.com/" target="_blank">Postgres.app</a> for <em>real</em> ease of use. If that did work, then let&#8217;s write a <code>projectomatic.sql</code> file and place it in our main project directory. Here&#8217;s what it will need to look like:</p>
<pre class="brush: sql; title: ; notranslate">
CREATE TABLE projects (
  title TEXT NOT NULL,
  description TEXT NOT NULL,
);
</pre>
<p>Each project will simply have an integer identifier, a title, a description, and a set of users involved with the project. For sake of simplicity, we&#8217;ll set things up so that each user will simply have a username and a set of projects that they&#8217;re associated with, and none of the values we&#8217;re working with can be <code>NULL</code>.</p>
<p>Let&#8217;s open up our database using <code>psql projectomatic</code> in the command line and run our SQL script when we get there:</p>
<pre class="brush: bash; title: ; notranslate">
\i /path/to/application/dir/projectomatic.sql
</pre>
<p>If we get <code>CREATE TABLE</code> as a response, then we&#8217;re probably good to go. It&#8217;s a good idea to double check by running <code>\dt</code> and making sure that <code>projects</code> and <code>users</code> tables currently exist and are properly constructed. Once they do, we should be good to go within Postgres itself.</p>
<h3 id="making-our-data-types-ready-for-postgres">Making Our Data Types Ready for Postgres</h3>
<p>Like I said before, dealing with data types in Haskell is <em>tough</em>. While I would never assert that dealing with data types in <em>any</em> programming language is &#8220;easy&#8221; per se, Haskell really does present a pretty formidable learning curve. Fortunately, it&#8217;s not too bad if you&#8217;re doing fairly basic things.</p>
<p>Previously, we specified our <code>Project</code> data type, but that&#8217;s not yet enough to get them to actually interact with Postgres. Putting data <em>into</em> Postgres would likely work fine at this stage, but taking data <em>out of</em> Postgres and transforming it into something that Haskell can use within the application is going to take some work.</p>
<p>So in our <code>Site.hs</code> file, we need to set up a <code>FromRow</code> instance of both of our main data type. This will require the <code>Control.Applicative</code> module as well as a special submodule of PostgreSQL Simple, namely <code>FromRow</code>. Here&#8217;s what needs to be added to our <code>Site.hs</code> file:</p>
<pre class="brush: haskell; title: ; notranslate">
import Control.Applicative
import Database.PostgreSQL.Simple.FromRow

instance FromRow Project where
    fromRow = Project &lt;$&gt; field &lt;*&gt; field
</pre>
<p>The funny <code>&lt;$&gt;</code> and <code>&lt;*&gt;</code> operators come from the <code>Control.Applicative</code> module. The most important thing is that the number of <code>field</code>s that you use when constructing the instances matches the number of fields in the database, or else you&#8217;ll get all kinds of nasty compiler errors, just as you will if there&#8217;s a type mismatch (as when you try, for example, to put a Haskell integer into a Postgres field that takes only a <code>varchar</code> or <code>text</code>).</p>
<p>Setting up these <code>FromRow</code> instance constructors enables us to take data from Postgres (for example the results of a <code>SELECT * FROM projects</code>-style query) and use it in our pure, pristine Haskell application. One thing we should also do is to define a <code>Show</code> instance for our data type. This is necessary because when we make an HTTP request to see a <code>Project</code> (or a list thereof), we want to specify what that will actually <em>look like</em> in the command line. If we don&#8217;t specify a <code>Show</code> instance, that means that we won&#8217;t actually see anything, <em>even if we&#8217;ve done everything else right</em>. I&#8217;ll keep it basic:</p>
<pre class="brush: haskell; title: ; notranslate">
instance Show Project where
    show (Project title description) =
      &quot;Project { title: &quot; ++ T.unpack title ++ &quot;, description: &quot; ++ T.unpack description ++ &quot; }\n&quot;
</pre>
<p>Note that we need to use the <code>T.unpack</code> function, taken from the <code>Data.Text</code> module, to convert text into strings (else we get a compiler error).</p>
<h3 id="time-to-get-back-to-our-application">Time to Get Back to Our Application</h3>
<p>So that was a lot of setup, no doubt about it. Now it&#8217;s time to actually convert HTTP requests into PostgreSQL queries and consequently data. I&#8217;m going to set up our server to take requests that do the following things:</p>
<ol>
<li>Create a new project</li>
<li>Return a list of all projects</li>
<li>Delete a project</li>
</ol>
<p>Basically, we&#8217;re running simple CRUD operations on the <code>Project</code> data type.</p>
<p>Let&#8217;s start with creating a new project. First, our route:</p>
<pre class="brush: haskell; title: ; notranslate">
(&quot;/project/new&quot;, method POST createNewProject)
</pre>
<p>Here&#8217;s our corresponding function:</p>
<pre class="brush: haskell; title: ; notranslate">
createNewProject :: Handler App App ()
createNewProject = do
  title &lt;- getPostParam &quot;title&quot;
  description &lt;- getPostParam &quot;description&quot;
  newProject &lt;- execute &quot;INSERT INTO projects VALUES (?, ?)&quot; (title, description)
  redirect &quot;/&quot;
</pre>
<p>Let&#8217;s unpack this a bit. First, notice that this is embedded in a <code>do</code> block, which often (though certainly not always) means that you&#8217;ll be dealing with I/O. The first thing that this function does is extract the <code>title</code> of our new project out of the form data passed to the server with the <code>getPostParam</code> function (the same goes for our <code>description</code>). Now, we&#8217;ll use the <code>execute</code> function to actually interact with Postgres. In contrast to the <code>query_</code> function that we will encounter later, <code>execute</code> is typically used in situations where you don&#8217;t expect a return value (as when you write to a table).</p>
<p>The dual <code>?</code>s that you see are places in our SQL bytestring where we will insert values. Immediately after the bytestring, we specify which values we want inserted (in this case the <code>title</code> and the <code>description</code> that we derived from the URL).</p>
<p>Now, let&#8217;s work on using the <code>query_</code> function instead of <code>execute</code>. This is a bit trickier because it involves getting data back from Postgres that then needs to be processed and handled on the application side (whereas with the <code>execute</code> function we passed already-formed data on to Postgres). We&#8217;ll start with setting up a route that displays all projects. The route:</p>
<pre class="brush: haskell; title: ; notranslate">
(&quot;/projects&quot;, method GET getAllProjects)
</pre>
<p>And the handling function:</p>
<pre class="brush: haskell; title: ; notranslate">
getAllProjects :: Handler App App ()
getAllProjects = do
  allProjects &lt;- query_ &quot;SELECT * FROM projects&quot;
  liftIO $ print (allProjects :: [Project])
</pre>
<p>A few things to notice here. First, we store the results of the query in the <code>allProjects</code> variable. That&#8217;s pretty straightforward. What&#8217;s more difficult, however, is actually <em>displaying</em> those projects. First, have a look at the <code>print</code> function. What is being printed? The <code>allProjects</code> variable is going to be printed as a list of projects. But we can&#8217;t just use <code>print</code> on its own because <code>print</code> produces IO (which is always tricky in Haskell).</p>
<p>This is where the <a href="http://hackage.haskell.org/packages/archive/transformers/0.2.2.0/doc/html/Control-Monad-IO-Class.html#v:liftIO"><code>liftIO</code></a> function comes in handy. This function gives us access to the I/O in which the application is engaging, and in our case it will convert the type <code>IO ()</code> into the type <code>Handler App App ()</code>. And so <code>print</code> is producing IO which is then brought into the application context. Because we haven&#8217;t set up any views or anything fancy for displaying the data, the <code>print</code> function will make the results of our <code>GET</code> request show up in the console.</p>
<p>So now we can create a project and get all projects. Let&#8217;s add a route and a function for deleting specific projects. First, let&#8217;s set up a route to delete a project based on the project&#8217;s title:</p>
<pre class="brush: haskell; title: ; notranslate">
(&quot;/project&quot;, method DELETE deleteProjectByTitle)
</pre>
<p>In a serious project, you would probably want to delete on the basis of an integer project ID or something of the sort, but we&#8217;ll keep it simple. Now, our corresponding function:</p>
<pre class="brush: haskell; title: ; notranslate">
deleteProjectByTitle :: Handler App App ()
deleteProjectByTitle = do
  title &lt;- getPostParam &quot;title&quot;
  deleteProject &lt;- execute &quot;DELETE FROM projects WHERE title = ?&quot; (Only title)
  redirect &quot;/&quot;
</pre>
<p>Notice here that we&#8217;re only passing <em>one</em> value into our SQL bytestring, hence our reliance on the <code>Only</code> instance. Also notice that we&#8217;re not passing the project title via URL, but rather by way of form data.</p>
<p>So now we have some routes that interact with Postgres and do some really basic things. Let&#8217;s put our server to the test.</p>
<h3 id="curling-our-way-to-victory">cURLing Our Way to Victory</h3>
<p>As mentioned before, I&#8217;ve said nothing about views or HTML rendering or any of the sort. At the moment, our application has <strong>zero</strong> views. I&#8217;ll cover Snap&#8217;s default templating system, <a href="http://hackage.haskell.org/package/heist" target="_blank">Heist</a> in a future tutorial. For now, though, we&#8217;ll interact with our server the old-fashioned way: via cURL (my favorite tutorial can be found <a href="https://httpkit.com/resources/HTTP-from-the-Command-Line/" target="_blank">here</a>).</p>
<p>Let&#8217;s go through a set of examples involving each of the routes that I set up earlier. First, let&#8217;s fire up our server.</p>
<pre class="brush: bash; title: ; notranslate">
cabal install
projectomatic -p 3000
</pre>
<p>Now, let&#8217;s get a list of all of our projects:</p>
<pre class="brush: bash; title: ; notranslate">
curl -X GET http://localhost:3000/projects
</pre>
<p>At first, this should return an empty list (no surprises there). So let&#8217;s create a project. Let&#8217;s create a project called &#8220;Getting in shape&#8221; and give it the description &#8220;Daily exercise:&#8221;</p>
<pre class="brush: bash; title: ; notranslate">
curl -X POST http://localhost:3000/project/new \
-d 'title=Getting in shape' \
-d 'description=Daily exercise'
</pre>
<p>Now, when we run a <code>GET</code> request on <code>/projects</code> again, we should get the following in the CLI:</p>
<pre class="brush: bash; title: ; notranslate">
[Project { title: Getting in shape, description: Daily exercise}
]
</pre>
<p>This means that our server works. *whew*</p>
<p>Now, let&#8217;s delete the project that we just added to the database. Remember from above that the URL takes the form <code>/project</code>, while our <code>title</code> is passed in via form data. Our cURL request should look like this:</p>
<pre class="brush: bash; title: ; notranslate">
curl -X DELETE http://localhost:3000/project \
-d 'title=Getting in shape'
</pre>
<p>If we have more than one project in the database with the title &#8220;Get in shape,&#8221; then all projects with this title will be deleted. This is yet another reason why working with integer IDs for important data types is much better than working in terms of attributes like this. In a future tutorial, I&#8217;ll do a deeper dive into Snap and Postgres that does precisely this.</p>
<h3>Just a Basic Intro</h3>
<p>Like I said before, this application has no views or rendering, no error handling, no authentication. It&#8217;s just an HTTP server talking to Postgres. I&#8217;ve also only covered a minimal smattering of what the PostgreSQL Simple Snaplet <a href="http://hackage.haskell.org/packages/archive/snaplet-postgresql-simple/0.1/doc/html/Snap-Snaplet-PostgresqlSimple.html" target="_blank">has on offer</a>. But I hope that it has at least served to show that using Postgres and Haskell in a web development context is not as intimidating as it may seem at first. There are some conceptual leaps (at least for a previously OOP-oriented person like myself), but patience pays off.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/0oXV1brdcDM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/tutorial-building-a-sample-application-with-haskell-snap-postgresql-and-the-postgresql-simple-snaplet/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/tutorial-building-a-sample-application-with-haskell-snap-postgresql-and-the-postgresql-simple-snaplet/</feedburner:origLink></item>
		<item>
		<title>The Real Reason Gartner Calls Janrain Cool</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/CRk5zRhNbgU/</link>
		<comments>http://janrain.com/blog/the-real-reason-gartner-calls-janrain-cool/#comments</comments>
		<pubDate>Thu, 18 Apr 2013 16:03:17 +0000</pubDate>
		<dc:creator>Larry Drebes</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[janrain happenings]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=22060</guid>
		<description><![CDATA[When one of the best and most respected research firms in the world says that a company is cool, people listen. And this week, Gartner included Janrain in their 2013 Cool Vendors in Social Marketing report. How cool is that? We’re thrilled to be honored with membership into Gartner’s “cool social technology” club (our words, [...]]]></description>
				<content:encoded><![CDATA[<p>When one of the best and most respected research firms in the world says that a company is cool, people listen. And this week, Gartner included Janrain in their <a href="http://www.gartner.com/id=2415017" target="_blank">2013 Cool Vendors in Social Marketing report</a>.</p>
<p><img alt="Janrain is Cool" src="http://janrain.com/wp-content/uploads/2013/04/Janrain-is-cool.png" width="600" height="565" /></p>
<h3>How cool is that?</h3>
<p>We’re thrilled to be honored with membership into Gartner’s “cool social technology” club (our words, not theirs) along with 140 Proof, Influitive, Woobox and Zuberance. The report’s focus is around the opportunity that exists for digital marketers in leveraging the social web to reach their online goals, and goes on to recommend these cool vendors for organizations to call upon.</p>
<p>Our motivation at Janrain isn’t necessarily to “be cool” but we think it’s pretty darn awesome to work with brands we all like, know and buy from such as Universal Music Group, Fox, Dr Pepper, Samsung, AMC, Guitar Center and Pac12. In our book, it’s our customers that we find pretty cool because they understand exactly what Gartner analyst Julie Hopkins means when she writes:</p>
<blockquote><p>Janrain simplifies the process of managing multiple online identities to remove the “digital hassle” often associated with the user’s broad social participation.</p></blockquote>
<p>In other words: our customers know that <a href="http://janrain.com/about/newsroom/press-releases/online-americans-fatigued-by-password-overload-janrain-study-finds/">password fatigue is a real problem</a> and leverage our social login technology to remove the obstacles that stand in the way of allowing their website visitors to quickly log in to their site.</p>
<p>So, while we’re humbled to be called a “cool vendor” and thank Gartner for the recognition, we really want to thank <a title="Janrain Customers" href="http://janrain.com/customer-success/">our customers</a> who make us who we are by choosing Janrain in the first place and relying on us to earn their trust everyday.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/CRk5zRhNbgU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/the-real-reason-gartner-calls-janrain-cool/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/the-real-reason-gartner-calls-janrain-cool/</feedburner:origLink></item>
		<item>
		<title>Disqus Partners with Janrain to Help Publishers Authenticate and Engage Audiences Online</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/gT5AY3OVTd0/</link>
		<comments>http://janrain.com/blog/disqus-partners-with-janrain-to-help-publishers-authenticate-and-engage-audiences-online/#comments</comments>
		<pubDate>Wed, 10 Apr 2013 16:02:45 +0000</pubDate>
		<dc:creator>Jeff Mills</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[partner]]></category>
		<category><![CDATA[social login]]></category>
		<category><![CDATA[social profile data]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=21946</guid>
		<description><![CDATA[Disqus refers to itself as the web’s “community of communities” and the largest discussion platform of its kind.  The company’s massive and distributed network enables users to create a single login profile to join discussions on millions of sites that have installed Disqus. Disqus was looking for a technology partner to help publishers collect and [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.disqus.com"><img class="alignright size-medium wp-image-3780" alt="disqus-t-blue-1" src="http://janrain.com/wp-content/uploads/2012/03/disqus-t-blue-11-300x58.png" width="300" height="58" />Disqus</a> refers to itself as the web’s “community of communities” and the largest discussion platform of its kind.  The company’s massive and distributed network enables users to create a single login profile to join discussions on millions of sites that have installed Disqus.</p>
<p>Disqus was looking for a technology partner to help publishers collect and organize valuable user profile information to enhance and develop their registered audience base.  The company joined the <a href="http://janrain.com/fusion">Janrain Fusion Partner Program</a> to make it easier for publishers to create personalized and targeted content for visitors based on a user’s declared interests and demographics.</p>
<p>Ro Gupta, vice president of business development for Disqus, believes that this integration is extremely compelling for publishers who want to develop deep relationships with their most engaged audience &#8211; those that consume content and participate in discussions. It allows the publisher to verify the user and gather key information about preferences, which in turn gives the user a better, more personalized experience on the publisher site.</p>
<p><img class="size-full wp-image-21947 alignnone" alt="social-login-btn" src="http://janrain.com/wp-content/uploads/2013/04/social-login-btn.png" width="606" height="155" /></p>
<p>Gupta knew Janrain specialized in user management, which Disqus wanted to enrich based on keen publisher interest to capture and verify more user data.  He views this partnership as a great example of two industry leaders working together to tangibly increase the value of online engagement.</p>
<p>For more information on Fusion Partners and the program, check out our <a href="http://www.janrain.com/fusion">partner section</a>.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/gT5AY3OVTd0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/disqus-partners-with-janrain-to-help-publishers-authenticate-and-engage-audiences-online/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/disqus-partners-with-janrain-to-help-publishers-authenticate-and-engage-audiences-online/</feedburner:origLink></item>
		<item>
		<title>Social Login Trends Across the Web for Q1 2013</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/ll4B5XOjO7M/</link>
		<comments>http://janrain.com/blog/social-login-trends-across-the-web-for-q1-2013/#comments</comments>
		<pubDate>Mon, 08 Apr 2013 16:00:14 +0000</pubDate>
		<dc:creator>Michael Olson</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[recommended reading]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[social login]]></category>
		<category><![CDATA[trends]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=21914</guid>
		<description><![CDATA[If you’re like 87% of people, you have likely come across the option to register at a website using one of your existing social network or email identities.  This is known as social login, a technology that Janrain pioneered to solve the challenge websites have faced when acquiring users online via traditional registration processes.  As [...]]]></description>
				<content:encoded><![CDATA[<p>If you’re like <a href="http://janrain.com/resources/industry-research/2013-consumer-research-value-of-social-login/">87% of people</a>, you have likely come across the option to register at a website using one of your existing social network or email identities.  This is known as social login, a technology that Janrain pioneered to solve the challenge websites have faced when acquiring users online via traditional registration processes.  As web users, we don’t like filling out registration forms from scratch.  Nor do we enjoy maintaining dozens of distinct usernames and passwords on each site that we frequently visit.</p>
<p>The advent of social media has emboldened us to foster personas for ourselves online.  But the social media landscape is fragmented.  We tend to use Facebook to interact with friends and family, Twitter to follow influencers and share opinions, LinkedIn as our professional network, and Gmail, Yahoo! or Hotmail to communicate directly with our important contacts.  Combined, more than 2.5 billion of us maintain accounts with these services, and social login solves the registration challenge by making it possible to use those identities to easily sign up and log in on sites across the web.</p>
<p>But which identity providers are the most popular choices?  Each quarter, we seek to answer this question by analyzing social login preferences for online consumers across all websites using <a href="http://www.janrain.com/products/engage">Janrain</a>.  Why do these trends matter for digital marketer?  Social login preferences are a leading indicator of consumer trust in the different online identity providers.  If I use my Google account to login and participate on sites across the web, for example, that choice serves as an indication of the trust and affinity felt toward Google’s service.</p>
<p>__________</p>
<p>When it comes to social login, our data shows that people want choice. Facebook currently leads as the most popular identity provider for social login.  During Q1, Facebook did lose ground to Google for the second consecutive quarter, dropping in popularity from 49% during Q4 2012 to 46% in Q1 2013, while Google’s share of social logins ascended from 31% to 34% during the same period.</p>
<p><img class="alignnone size-full wp-image-21920" alt="Q1 2013 Social Login Preferences" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Preferences.png" width="600" height="400" /> <img class="alignnone size-full wp-image-21921" alt="Q1 2013 Social Login Trends" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Trend.png" width="600" height="400" /></p>
<p>Despite the moderate decrease in share of social logins during Q4, Facebook still remains the most popular choice for the ninth consecutive quarter.  After reaching an all-time quarterly high during Q3, Twitter’s share also decreased moderately during each of the last two quarters.</p>
<p>LinkedIn enjoys substantial popularity on sites that cater toward business professionals, with as many as 80% of business professionals choosing to log in with their LinkedIn identity on some B2B websites.  A <a href="http://socialtimes.com/the-linkedin-profile-infographic_b97649">majority of us maintain our professional online identity on LinkedIn</a>. When using this identity to register on B2B sites, consumers can choose to grant the website access to their LinkedIn profile information, including a verified email address, first and last name, company name, job title and industry. The site can then use this information to conveniently pre-populate a sign-up form, which eliminates the need for consumers to fill out the form from scratch or enter lots of redundant details about themselves.</p>
<p>We also have observed disparate preferences across geographic regions.  For example, Hyves contends with Facebook as the most popular social network in the Netherlands, and social login preferences on Dutch websites substantiate that notion.  In Brazil and India, Orkut is a popular identity provider for social login, while in China, Sina Weibo and Renren maintain popularity.  Mixi is a common social login choice in Japan, while VK is preferred in Russia.</p>
<p>As with prior analyses, we have taken a sampling of sites in four industry verticals to measure trends in consumer login preferences.  While the overall story arc is similar, there are disparate preferences within each vertical that merit attention.</p>
<p>Despite its decreased share across all Janrain customer websites, Facebook still leads other social networks and email providers across prominent industry verticals including media, retail, entertainment and gaming, consumer brands, and music-related sites.  Its popularity is especially pronounced on entertainment, gaming, retail and consumer brand websites.</p>
<p><img alt="Q1 2013 Social Login Trends for Entertainment Brands" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Trend-entertainment.png" width="600" height="400" /></p>
<p><img alt="Q1 2013 Social Login Trends for Media Brands" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Trend-Media.png" width="600" height="400" /><img class="alignnone size-full wp-image-21919" alt="Q1 2013 Social Login Trends for Retail Brands" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Trend-Retail.png" width="600" height="400" /> <img class="alignnone size-large wp-image-21918" alt="Q1 2013 Social Login Trends for Music Brands" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Trend-Music.png" width="600" height="400" /> <img class="alignnone size-full wp-image-21915" alt="Q1 2013 Social Login Trends for Consumer Brands" src="http://janrain.com/wp-content/uploads/2013/04/Q1-2013-Social-Login-Trend-Consumer-Brands.png" width="600" height="400" /></p>
<p>Google is performing well as the second most favored portable identity provider across each of these verticals, but its popularity is most evident on retail and consumer brand sites, which could perhaps be a reflection of the trust that people place in Google as a secure provider of their online identity. With Janrain’s <a href="http://janrain.com/blog/janrain-launches-support-for-google-sign-in/">recent launch of Google+ as a sign-in provider</a>, we expect the propensity for consumers to choose a Google identity for social login to increase throughout 2013.</p>
<p>What do these findings mean for your business?  As you work to add a social layer to your site to improve engagement and drive conversions, social login and sharing should be fully integrated.  We hope these findings provide a useful benchmark as you optimize your on-site social media strategy.</p>
<p><strong>For Digital Marketers:</strong></p>
<p>Social login helps solve the challenge of how to collect more accurate data on your users while increasing registration conversion rates at the same time. Social login shortens the registration process to a single click and gives you instant permission-based access to rich demographic, psychographic and social graph data on your users. This social profile data can be leveraged for content personalization or product recommendations and more tailored segmentation and targeting. Social sharing enables your users to broadcast content and activities from your site to their social networks, increasing brand advocacy and creating an effective source of qualified referral traffic back to your site.</p>
<p><strong>For Developers and Technologists:</strong></p>
<p>It can be a big headache to implement the plumbing to each social network API on your own.  These networks use different protocols under the hood, such as OpenID, OAuth, hybrids and proprietary technologies. As a result, coding social login on your own requires a significant investment of time, engineering expertise and ongoing maintenance as the networks change their APIs, often without advanced notice. Your social login and sharing solution should allow you to easily <em>connect to all the social networks by writing once to a single API</em>. By cutting deployment times from weeks or months to a couple days, you can focus on your core competency while trusting that the social and user management tools on your site just work.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/ll4B5XOjO7M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/social-login-trends-across-the-web-for-q1-2013/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/social-login-trends-across-the-web-for-q1-2013/</feedburner:origLink></item>
		<item>
		<title>Why Building Trust Through Transparency is Key to Customer Success</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/U2UljSxwMfI/</link>
		<comments>http://janrain.com/blog/why-building-trust-through-transparency-is-key/#comments</comments>
		<pubDate>Fri, 05 Apr 2013 18:28:31 +0000</pubDate>
		<dc:creator>Angie Fallows</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[janrain happenings]]></category>
		<category><![CDATA[privacy]]></category>
		<category><![CDATA[recommended reading]]></category>

		<guid isPermaLink="false">http://janrain.com/?p=21896</guid>
		<description><![CDATA[If you were to take a stroll down the bright and vivacious hallways at Janrain to ask any of our employees to share their perspective about the chief priority for our company, the answer would be universally consistent. At Janrain, the success of our customers is our top priority. Success is determined by our ability [...]]]></description>
				<content:encoded><![CDATA[<p>If you were to take a stroll down the bright and vivacious hallways at Janrain to ask any of our employees to share their perspective about the chief priority for our company, the answer would be universally consistent. At Janrain, the success of our customers is our top priority.</p>
<p>Success is determined by our ability to deliver exceptional products and services that delight our customers, and it also requires a high degree of trust. We believe that trust starts with openness and transparency. That’s why, as part of our ongoing commitment to promote transparency with our customers, we have introduced a new site to proactively communicate the status and availability of Janrain’s services &#8211; <a href="http://trust.janrain.com"><b>trust.janrain.com</b></a>.</p>
<p>This site will be the primary resource for Janrain customers seeking to monitor the availability of the Janrain service as well as learn about our infrastructure, security and compliance. The <a href="http://trust.janrain.com"><b>trust.janrain.com</b></a> site includes:</p>
<ul>
<li>Real-time and historical data on system performance</li>
<li>Incident reports and notification of planned maintenance</li>
<li>Information about how we safeguard and protect the privacy of your data</li>
<li>Information on Janrain’s product infrastructure</li>
</ul>
<p><img class="alignnone size-large wp-image-21899" alt="trust-dashboard" src="http://janrain.com/wp-content/uploads/2013/04/trust-dashboard-670x329.png" width="670" height="329" /></p>
<p><b><a href="http://trust.janrain.com">Trust.janrain.com</a></b> was inspired by conversations directly with our customers. We know that our customers hold us to a high quality standard, and we strive to provide you with the tools you need to hold us accountable to our commitments.</p>
<p>Please check out the site and bookmark it for future reference. And as always, don’t be shy about <a href="http://janrain.com/about/contact-us/">dropping us a line</a> to let us know if you have any feedback.<a href="#_msocom_1"><br />
</a></p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/U2UljSxwMfI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/why-building-trust-through-transparency-is-key/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/why-building-trust-through-transparency-is-key/</feedburner:origLink></item>
		<item>
		<title>How and Why We Use Dependency-Free JavaScript at Janrain</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/-mWi-Aj_lDo/</link>
		<comments>http://janrain.com/blog/how-and-why-we-use-dependency-free-javascript-at-janrain/#comments</comments>
		<pubDate>Fri, 05 Apr 2013 16:00:19 +0000</pubDate>
		<dc:creator>Luc Perkins</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://staging.janrain.com/?p=21677</guid>
		<description><![CDATA[Now, don&#8217;t get me wrong: I&#8217;m a huge fan of hefty, all-in-one JavaScript frameworks. Like a lot of other folks, jQuery was my first brush with real front-end development, and since I began learning jQuery back in the day, I’ve since come to harbor something between admiration (Backbone) and unrestrained adulation (AngularJS, jQuery Mobile) for [...]]]></description>
				<content:encoded><![CDATA[<p>Now, don&#8217;t get me wrong: I&#8217;m a huge fan of hefty, all-in-one JavaScript frameworks. Like a lot of other folks, <a href="http://jquery.com/">jQuery</a> was my first brush with real front-end development, and since I began learning jQuery back in the day, I’ve since come to harbor something between admiration (<a href="http://backbonejs.org/">Backbone</a>) and unrestrained adulation (<a href="http://angularjs.org/">AngularJS</a>, <a href="http://jquerymobile.com/">jQuery Mobile</a>) for some of the major JavaScript frameworks on offer nowadays.</p>
<p>It&#8217;s scarcely believable just how powerful and comprehensive these tools have become given the state of JavaScript just a half-decade ago. If I were building any kind of heavily event-driven client-side application with a lot of fancy UI elements and a structured data model–essentially what we now call the &#8220;thick client&#8221;–I would still opt to build it on top of a big MVC (or MVVM or MOVE or whatever) framework. The thought of building a thick client using the naked <a href="http://krook.org/jsdom/">DOM API</a> by itself is, to put it mildly, a slightly less than pleasant one.</p>
<h3 id="another-path">Another path</h3>
<p>Yet in spite of the wonders of contemporary JavaScript, there are times when clearing away the underbrush and getting back to the DOM API–the closest thing to bare metal that you&#8217;ll get in JavaScriptLand–is absolutely the <em>only</em> way of doing things.</p>
<p>When the original Janrain development team started making heavy use of JavaScript some years go, this was precisely the conclusion to which they came. For our use case–which involves allowing developers to simply copy and paste a JavaScript widget into their application that then enables <a href="http://janrain.com/products/engage/social-login/">social login</a> and/or <a href="http://janrain.com/products/capture/">user registration and data storage</a>–reliance on jQuery or <a href="http://underscorejs.org/">Underscore</a> or anything beyond native JavaScript was simply a non-starter.</p>
<p>Why? Because we have to write JavaScript that plays nicely with <em>anything and everything with which it interacts</em>. We can&#8217;t afford namespace or dependency clashes. Organizations that want to use <a href="http://janrain.com/products/engage/">Janrain Engage</a> or <a href="http://janrain.com/products/capture/">Capture</a> need to be able to drop a small snippet of JavaScript into their application (a snippet like the one included below) and to have it work unproblematically and without any additional work on their part…<em>ever</em>. Both the drop-in widget <em>and</em> the JavaScript that gets piped through the widget (more on that in a minute) have to demand <em>nothing</em> from the developers using Janrain. Our entire business model depends on it.</p>
<p>Another core reason: <strong>performance</strong>. The JavaScript that we compose that ends up in others&#8217; applications has to be blazingly fast, and it has to work on as many devices and for as many use cases as humanly possible. It has to be as close to 100% agnostic toward its end destination as the DOM API allows for.</p>
<p>If we had chosen to use framework-heavy JavaScript, it would have meant two things for us:</p>
<ol>
<li><strong>The good</strong>: it would have made our lives a lot less complicated because it&#8217;s far easier to find and then hire people to write jQuery or Backbone with most of the guts of JavaScript abstracted away.</li>
<li><strong>The bad</strong>: it would have made our lives vastly more <em>difficult</em> because we would have to require customers to go back and re-code all of their front-end JavaScript to ensure that it plays nicely with their supposed &#8220;drop-in&#8221; social login widget.</li>
</ol>
<p>For customer-facing JS, this path was unacceptable, and so we decided to go all in on all-native JS.</p>
<h3 id="dependency-free-js-example-drop-in-widget">Dependency-free JS example: drop-in widget</h3>
<p>While Janrain uses a lot of libraries like <a href="http://knockoutjs.com/">Knockout</a>, jQuery, and others in building <a href="http://developers.janrain.com/documentation/engage/getting-started/janrain-dashboard/">dashboards</a> and other thick client-style applications, all of the JS that we write for customers is dependency free (although we <em>do</em> offer widgets that depend on jQuery, but only if our customers ask for it). I could give hundreds of code examples here, but I&#8217;ll stick with the most stripped-down widget that we offer, simply in the name of offering a taste of the mechanics of low-level JS to the uninitiated.</p>
<p>This widget basically acts as a portal into the DOM for the more feature-rich JavaScript that powers a <a href="http://janrain.com/products/engage/social-login/">social login interface</a>. Let’s have a look at what such a widget might look like in its entirety and go from there:</p>
<pre class="brush: jscript; title: ; notranslate">&lt;script type=&quot;text/javascript&quot;&gt;

  (function() {
    if (typeof window.janrain !== 'object') window.janrain = {};
    if (typeof window.janrain.settings !== 'object') window.janrain.settings = {};

    janrain.settings.tokenUrl = 'http://www.your_site.com';

    function isReady() { janrain.ready = true; };
    if (document.addEventListener) {
        document.addEventListener(DOMContentLoaded, isReady, false);
    } else {
        window.attachEvent('onload', isReady);
    }

    var e = document.createElement('script');
    e.type = 'text/javascript';
    e.id = 'janrainAuthWidget';

    if (document.location.protocol === 'https:') {
        e.src = 'https://rpxnow.com/js/lib/luc/engage.js';
    } else {
        e.src = 'http://widget-cdn.rpxnow.com/js/lib/luc/engage.js';
    }

    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(e, s);
  })();
&lt;/script&gt;</pre>
<p>&nbsp;<br />
First off, notice that this is a self-executing snippet of JavaScript. Any time you&#8217;re working in JavaScript and you see something of the form</p>
<pre class="brush: jscript; title: ; notranslate">(function() {
    ...do stuff here…
})();</pre>
<p>&nbsp;<br />
you know that you&#8217;re dealing with something that isn&#8217;t going to need to be called from outside of the function. So this sets up the widget to execute itself as soon as its loaded.</p>
<p>Now, let&#8217;s see what&#8217;s actually going on in this self-executing function. In the first line, we see</p>
<pre class="brush: jscript; title: ; notranslate">if (typeof window.janrain !== 'object') window.janrain = {};</pre>
<p>&nbsp;<br />
This is essentially a kind of guard to check if there&#8217;s already a <code>window.janrain</code> something-or-other floating around in the DOM. If there is, and it isn&#8217;t an object, it needs to become one. And so whatever that <code>window.janrain</code> is will immediately be converted into an empty hash (i.e. a JavaScript object). After that, the widget does the same check regarding any <code>window.janrain.settings</code>. In these first two lines, the widget basically ensures that we&#8217;re starting from the right place with an object of this form:</p>
<pre class="brush: jscript; title: ; notranslate">{
  window: {
    janrain: {
      settings: {}
    }
  }
}</pre>
<p>&nbsp;</p>
<h3 id="working-with-our-empty-window-object">Working with our empty <code>window</code> object</h3>
<p>Now, we can begin populating this somewhat barren object. First, we need to fetch the <code>tokenUrl</code> from the application-specific URL (a URL that we provide you when a new Janrain-powered application is created). This URL is used not by the widget but rather by the JavaScript that will arrive in the application a few milliseconds later.</p>
<p>Next, we define an <code>isReady()</code> function to be used later. This function, when invoked, declares that the document is ready to go, so to speak. It should remind you immediately of the <code>$(document).ready()</code> function from jQuery. What that means in jQuery is that anything that happens inside of <code>.ready( … )</code> happens as soon as possible and doesn&#8217;t wait for the page to load.</p>
<p>In the next line, we&#8217;ll see why this is important:</p>
<pre class="brush: jscript; title: ; notranslate">if (document.addEventListener) {
  document.addEventListener(DOMContentLoaded, isReady, false);
} else {
  window.attachEvent('onload', isReady);
}</pre>
<p>&nbsp;<br />
This is here to ensure cross-browser compatibility. It says that if the <code>addEventListener</code> function is invoked, it will take the form either of the <code>addEventListener</code> function understood directly by Chrome, Firefox, Safari, and newer versions of Opera and Internet Explorer, <em>or</em> of the <code>attachEvent</code> function understood by older browsers. And so no matter what the browser, an event listener will be added to the document at large that basically waits until all of the DOM content is loaded (the <code>onReady</code> event for older and <code>DOMContentLoaded</code> for newer browsers) and then declares the <code>janrain</code> object ready (<code>janrain.ready = true</code>).</p>
<h3 id="piping-javascript-into-the-dom-from-outside">Piping JavaScript into the DOM from outside</h3>
<p>So far, the widget hasn&#8217;t really done anything to modify the DOM in any significant way. In the next code block, that all begins to change:</p>
<pre class="brush: jscript; title: ; notranslate">var e = document.createElement('script');
e.type = 'text/javascript';
e.id = 'janrainAuthWidget';</pre>
<p>&nbsp;<br />
Here, the widget is inserting a new <code>&lt;script type='text/javascript' id='janrainAuthWidget'&gt;</code> element. Next, a source for the script is found. In the next block, the widget checks to see if the application in which it&#8217;s embedded is currently using HTTPS or HTTP and then acts accordingly:</p>
<pre class="brush: jscript; title: ; notranslate">if (document.location.protocol === 'https:') {
    e.src = 'https://rpxnow.com/js/lib/luc/engage.js';
} else {
    e.src = 'http://widget-cdn.rpxnow.com/js/lib/luc/engage.js';
}</pre>
<p>&nbsp;<br />
Clearly, the URL used as the source of the script is specific to the application that I created in <a href="https://rpxnow.com/">RPX</a>. So now our <code>&lt;script&gt;</code> tag is complete and ready to be inserted into the DOM:</p>
<pre class="brush: jscript; title: ; notranslate">var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(e, s);</pre>
<p>&nbsp;<br />
The first line simply locates the first <code>&lt;script&gt;</code> block in the DOM. The second line ensures that our new <code>&lt;script&gt;</code> is placed before it.</p>
<p>And that&#8217;s it. On the basis of this self-executing widget, the DOM will now be populated with an application-specific <code>engage.js</code> file (itself dependency-free, unless the customer wishes otherwise) that will be loaded in an asynchronous, non-blocking fashion, which means that other JavaScript that needs to be loaded won&#8217;t compete with it and can load at the same time.</p>
<h3 id="going-dependency-free-not-for-everyone">Going dependency-free: not for everyone</h3>
<p>This is a pretty basic example that involves only a small handful of functionality available through the DOM API, but I hope that it shows that dependency-free JavaScript really isn&#8217;t as scary as you might think.</p>
<p>As I said before, I&#8217;m not necessarily arguing for a &#8220;return to roots&#8221;-style movement in the JavaScript community, in which we all toss aside all the frameworks we&#8217;ve been using these past few glorious, framework-enabled years. I do think, though, that dependency-free JavaScript is very much worthy of consideration in a larger variety of cases than you may think.</p>
<p>Our Janrain <a href="http://janrain.com/products/engage/">Engage</a> widgets are textbook use cases for ditching frameworks and getting back in touch with the DOM API, as motley and inelegant as it may sometimes be. We think that developers that want to use Janrain have enough to worry about; there&#8217;s no reason to make them worry about delicately tiptoeing around our widgets.</p>
<p>So if you think that you might have a good use case for weaning yourself off of JS dependencies, give it a shot. There may be less to lose than you&#8217;ve been brought to think.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/-mWi-Aj_lDo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/how-and-why-we-use-dependency-free-javascript-at-janrain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/how-and-why-we-use-dependency-free-javascript-at-janrain/</feedburner:origLink></item>
		<item>
		<title>Automattic and Janrain Partnership Helps Largest Publishers Personalize Brand Experience</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/KrqULgwetdc/</link>
		<comments>http://janrain.com/blog/automattic-and-janrain-partnership-helps-largest-publishers-personalize-brand-experience/#comments</comments>
		<pubDate>Wed, 03 Apr 2013 16:11:10 +0000</pubDate>
		<dc:creator>Jeff Mills</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[partner]]></category>

		<guid isPermaLink="false">http://staging.janrain.com/?p=21725</guid>
		<description><![CDATA[You may not recognize the name Automattic, but you’re certainly familiar with the WordPress.com platform, the most popular content management system (CMS) on the web. Automattic manages the enterprise arm, WordPress.com VIP, which powers some of the largest publisher and media sites, including CNN, New York Times, CBS and Forbes. These media executives have been [...]]]></description>
				<content:encoded><![CDATA[<p><img class="size-full wp-image-20204 alignnone" alt="automattic" src="http://staging.janrain.com/wp-content/uploads/2013/01/automattic.png" width="553" height="97" /></p>
<p>You may not recognize the name <a href="http://www.automattic.com">Automattic</a>, but you’re certainly familiar with the WordPress.com platform, the most popular content management system (CMS) on the web. Automattic manages the enterprise arm, WordPress.com VIP, which powers some of the largest publisher and media sites, including CNN, New York Times, CBS and Forbes.</p>
<p>These media executives have been trying to find a technology solution to personalize their brand experience. The solution had to be easy to integrate, scalable and secure.</p>
<p>Automattic has joined the <a href="http://janrain.com/partners">Janrain Fusion Partner Program</a> to provide VIP sites a technology solution to better understand and engage their audiences. The JUMP integration provides turnkey registration, social profile storage and user insight solutions so WordPress.com VIP customers can acquire more users and provide better, more engaging experiences.</p>
<p>Vice-president of platform services for Automattic, Inc., Paul Maiorana, is looking forward to offering their customers the ability to streamline the traditional registration process for their end users, thus helping website owners better understand visitors to their site. He says this key partnership with Janrain allows his customers to easily enable these additional services and features on their site with just one click. Paul notes it also provides confidence that the functionality is well integrated and supported by both teams.</p>
<p><strong>For more information on Fusion Partners and the program check out our <a href="http://www.janrain.com/fusion">partner section</a>.</strong></p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/KrqULgwetdc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/automattic-and-janrain-partnership-helps-largest-publishers-personalize-brand-experience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/automattic-and-janrain-partnership-helps-largest-publishers-personalize-brand-experience/</feedburner:origLink></item>
		<item>
		<title>Janrain Launches Support for Google+ Sign-In</title>
		<link>http://feedproxy.google.com/~r/JanrainTechnology/~3/kkhrsYiw23I/</link>
		<comments>http://janrain.com/blog/janrain-launches-support-for-google-sign-in/#comments</comments>
		<pubDate>Tue, 02 Apr 2013 18:01:14 +0000</pubDate>
		<dc:creator>Michael Olson</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[recommended reading]]></category>
		<category><![CDATA[social graph]]></category>
		<category><![CDATA[social login]]></category>

		<guid isPermaLink="false">http://staging.janrain.com/?p=21664</guid>
		<description><![CDATA[The introduction of Google+ in 2011 has amplified a diverse and rapidly evolving social networking landscape. With more than 500 million members and a seamless integration with popular Google services such as Gmail, Android, Google Calendar, YouTube, Google+ has rapidly become one of the leading social networks on the web. That’s why we’re excited today to launch [...]]]></description>
				<content:encoded><![CDATA[<p>The introduction of <a href="http://plus.google.com" target="_blank">Google+</a> in 2011 has amplified a diverse and rapidly evolving social networking landscape. With more than 500 million members and a seamless integration with popular Google services such as Gmail, Android, Google Calendar, YouTube, Google+ has rapidly become one of the leading social networks on the web.</p>
<p>That’s why we’re excited today to launch a new integration with <a href="http://googleplusplatform.blogspot.com/2013/04/more-ways-to-add-google-plus-sign-in.html" target="_blank">Google+ Sign-In</a>.  With this product launch, Janrain customers can streamline the registration process for Google users, and gather additional profile data to better engage with and improve their experience.</p>
<p>Here is a run down of what’s new:</p>
<h3>Simple, secure login</h3>
<p>Google+ Sign-In helps improve registration conversion rates by offering a convenient and secure way for visitors to sign up on your site. We’ve made it really easy for websites to get up and running with Google+ Sign-In via <a href="http://www.janrain.com/products/engage/social-login">Janrain Engage Social Login</a>.</p>
<p><img class="alignnone size-full wp-image-21670" alt="NPR-Janrain-Google+-Sign-in-670x289" src="http://janrain.com/wp-content/uploads/2013/04/NPR-Janrain-Google+-Sign-in-670x289.png" width="670" height="289" /></p>
<h3>Gather Additional Public Demographic Information</h3>
<p><img class="size-full wp-image-21669 alignright" alt="NPR-Google+-Permission-Screen-259x300" src="http://janrain.com/wp-content/uploads/2013/04/NPR-Google+-Permission-Screen-259x300.png" width="259" height="300" /></p>
<p>In addition to a verified email address and a first and last name, users can now choose to share additional information from their Google+ profile when they log in to your site. Collect demographic and psychographic data such as gender, location, birthdate, interests, work history, education history, relationship status, profile photo and any other information made public within the user’s Google+ profile.</p>
<h3>Access Google+ Social Graphs</h3>
<p>Google+ Sign-In enables users to provide access to their Google+ circles of friends. Utilize this social graph information to let users discover what their friends are up to on your site, interact with friends, and surface content recommended by friends.</p>
<h3>Drive Adoption of Android Apps</h3>
<p>Let your website users instantly download and install your mobile or tablet app to their Android device.  Your users with Android devices don’t need to visit the Google Play store to install your Android app – instead, you can easily prompt them to do so in a single click when they sign in to your site with their Google identity.</p>
<p><img class="alignnone size-large wp-image-21723" alt="NPR-OTA-Android-App-Install" src="http://janrain.com/wp-content/uploads/2013/04/NPR-OTA-Android-App-Install-670x457.png" width="670" height="457" /></p>
<p>You are invited to check out Google+ Sign-in on <a href="http://www.npr.org">NPR</a>, <a href="http://www.hsn.com">HSN</a> and several <a href="http://www.universalmusic.com/">Universal Music Group</a> artist websites, including <a href="http://www.ladygaga.com">LadyGaga.com</a>, <a href="http://www.eminem.com">Eminem.com</a> and <a href="http://www.justinbiebermusic.com">JustinBieberMusic.com</a>.</p>
<p>The team at Janrain has been hard at work, and we are excited to offer the benefits of Google+ Sign-In to you. As always, your feedback is welcome.</p>
<img src="http://feeds.feedburner.com/~r/JanrainTechnology/~4/kkhrsYiw23I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://janrain.com/blog/janrain-launches-support-for-google-sign-in/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://janrain.com/blog/janrain-launches-support-for-google-sign-in/</feedburner:origLink></item>
	</channel>
</rss>
