Blog
As a youth, you tend to think price is in some way related to cost.
It is not.
It's easy to be taught this in your MBA course, it's easy to think this is evil from your Marxism course, but I have found it really is the way of things. The answer to "how much is that doggy in the window?" is at best "what's he worth to ya?" and at worse, "how much you got?" How much time, care and energy went into raising the bitch and birthing the puppy have nothing to do with it. (yes I choose that metaphor to create a credible excuse to curse. son-of-bitch-shit!)
I've never been a huge fan of the corporate training week. In my experience going to them as a employee, it's kinda a paid vacation, yet a boring. It's great to learn all at once and whatnot, but having someone read a manual to you in front of a computer seems like a horrible way to spend your day when you're visiting a fun big city.
It's not all strategic crap and programming around the office.. in fact an awful lot of time gets wasted with stuff like this fantastically amusing video:
http://www.cracked.com/video_16019_video-game-pitch-meeting-1979.html
Tasty dim sum today, fresh shrimp yum.
Figured the revenue model out for Concrete 5 today at lunch. We knew we were gonna give the source away, but hadn't quite figured out how to offer a hosted one for a price. We wanted to make it easy for tired old developers like me to setup a site quickly, as you would a blog and take the opportunity to make some money on the hosting side. We also think the elegant ‘demo turns into your install' approach of so many web2.0 apps is nice.
Well the challenge with that for us is unlike Wordpress or Basecamp, we need to give people a fair amount of personalization and space. A website isn't much good without a email, our CMS shines most when one starts to mess with the presentation layer, you just have to deliver a non-centralized traditional hosting environment for it to be useful and stable in the big picture.
That becoming clear helped settle the details around our how to price hosting. The demo simply isn't gonna happen without a credit card. You're welcome to download the source, see examples, etc.. but if you want to "1-2-3 it's just that easy" on our servers, we're gonna need a credit card and real info. Keep yer l33t warez off my boxes.
Nothing shocking here, just reality. There are a lot of unique problems in the world and we don't have time to solve them all perfectly. I'll be the first to aknowlege that a Content Management company using something like WordPress to blog about their adventures is somewhat ironic. We do have a blog component in Concrete today, and it works well if you need to incorporate a blog into a larger more design centric site. For this problem, I did not. I just needed something I could setup quickly and use well from anywhere without having to take my developers away from building a CMS that serves our client's needs So in addition to WordPress, here are some other 3rd party tools we enjoy around the office
UPDATE: We moved all this content into our own concrete5.org site with a nice blog UI on the top end. So while aspects of this post remain true (blogs are about writing, concrete5 is about managing) the bulk of it is way out of date.
Hello world.
I've been making websites since there was a web to make ‘em on.
I've run my own show for almost the whole time, with a two year dabble in corporate IT at the height of the bubble.
I'm an entrepreneur who has big ideas, works hard, and wants to provide for his family. My shop wins awards, our clients generally love us, I do everything that a good mid-sized webshop should do, yet I find myself unsatisfied.
I grew up with computers in the family. My Dad worked on punch cards and tape, so I can say with as much credibility as anyone that it "runs in the blood." I was programming my Apple ][e at 6, I was building Heathkits in the electronics lab in our basement. I ran BBS's, I got busted for bringing a Virus to school as a kid, you name it. Think War Games, that was me. I still have an acoustic coupler in the basement somewhere. My friends all played D&D and I know what a blue box is from using one, not reading about em.
I got excited about the web for bigger reasons than a paycheck though. Yes, growing up a programmer with a passion for visual arts pretty much forces you into web design these days, but in 95 when I dropped out of college to make websites that wasn't quite so that clear to everyone. What got me excited was the idea of the web as universal expression for everyone. I believed in the power of "myPetCat.com" when you could actually buy that domain and build the site yourself. I remember telling entrepreneurs that "you can look as good as IBM on a shoestring budget using the web!".. which as we all know, turned out to be more of an ideal than a reality.
I worked my way through the bubble, I've built working solutions for some of the most bizarre ideas and clients known to man, with a smile and a voice in the back of my head saying "well this might not be the printing press for the masses that the idealistic 21-year-old Franz wanted, but I am doing a great job being a voice of reason in this sea of madness."
Well now I'm 32. I've got a 2 year old daughter and another on the way. I'm responsible for a dozen bright people who love to make great websites, and I'm asking myself hard questions about if this is where I wanted to be in life. Frankly, I planned on being dead by 27 or a millionaire by 30. Neither happened. The last 5 years have been a blur of extra-credit confusion. As I grow up and realize I might very well be coming up with interesting ideas for a long time, I look at the business I've built by being flexible and bright and I wonder if, why, and how I truly love it.
I am a plumber. (shit, sorry Plumbers Association of America) but I get paid by the hour. Like any IT services company, we want recurring income, and we've historically thought the best way to do that was license a product. It is tiresome to get paid by the hour. There's no dependability in it unless you're willing to get tied to a vertical. We certainly have dabbled with the idea, why not be the company that just bangs out lawyer websites. The reality is this strategy seems to both miss the point of making the world a better place through free communication on an uncontrollable medium, and also the fun adventure of random consulting. Given the choice of Han Solo or Luke's Uncle tending the farm Well call me Franzolo.
So we make Our products...small products in Flash and JavaScript for niches we stumble upon, and we've got our own proprietary CMS that we've developed through years of working together and licensed as we saw fit.
We do a lot of work for bright entrepreneurs who are starting an online business, but we're constantly building ourselves out of a job. Just this spring we ended up losing a huge client from last year lemonade.com because they decided they needed to build out their own IT department as part of their rev 2 launch. I can't say I blame them, sure we built everything they've got from the ground up last year, and obviously I wish I was getting that check instead of ADP in some ways, but if I were in their shoes I'd do the same thing. They need an IT department and my shop's not it, nor do we want to be in the big picture.
We're in Portland, Oregon.. where the beer flows and the creative folk grow like the moss on roofs. I learned many years ago that competing for local web development work is a tough, gossipy, battle. There's not a lot of business outside of lumber and microchips, and while everyone in this town seems to get a hard-on for doing something for HP, Intel, or Nike I can't say I do.
So how do I support my growing family & crew in a way that I have some clue as to where money is coming from more than 6 weeks out and I'm not competing with the client's neighbor kid? How do I do something with my life that I can point to and say "that was worth while, the world is now a better place?"
Well, I could quit it all and go start some new dot com that makes virtualized widgets for gizmogingers in the social media space. Frankly, I've built enough of those ideas over the years that it's hard for me to commit my success or failure to just one idea. These days that comes down to a competitive "who do you know" battle that holds little interest for an idea guy like myself. Frankly, I want to do a lot of stuff. I want to be more involved in music and fashion than I am. I want to have the shop I have, but have a dash of downtime so we can pursue fun internal projects that we used to when it was just me and Andy in the basement. I'm sure I'm absolutely the first person you've ever heard express this dream.
Okay, so there's my self-serving blog dribble is there a point?
Yes.
It is time for us to make a new strategic play. We've had a CMS we've been selling since 2003 quite effectively. We built it before "blogs" were the big deal they are today and we made it because we were tired of our bosses spending 6 figures on some license fee for what amounted to a publishing system. It's called Concrete CMS and it works. It's flexible to work with, easy for office workers to use, and robust enough to handle real sites. We made it because we had an AdCouncil project with an insane deadline and too many stakeholders. We knew they would never agree to a fixed scope, so we needed a modular way to deal with content and functionality where we could re-arrange things in real-time and look like heroes. We did.
It grew. For the last 5 years we've done major and minor edits to it and basically sold it as the market allowed. As a production guy turned bizdev guy, I gotta say its really interesting to see the market change. I remember when people thought we were cheap because we wanted 15k instead of 30k for a perpetual license of our app. Shit I remember when TeamSite cost 300k. The price has come down year after year. As the guy in me who cuts paychecks cries, the Anarchist industrial punk kid who dropped out of college to help the underdog take on the man is getting excited though.
So here it is.
We've been working on the next HUUUGE version update of Concrete for over a year now. It's mad web2.0. It's hella AJAXy. It's dead fucking sexy and you're going to love it. It's my job to figure out who we're going to sell it to, and how we're going to price it. There's been a lot of debate. We could tweak it around to serve a particular vertical. We could add some more eCommerce loving to it and take on Magenta and the array of OsCommerce killers that are about to come out. We could come up with all sorts of money grubbing bullshit plans that we'd implement to some degree and keep making cash off of.. but frankly.. I grow weary of the battle & bullshit.
I want two things.
1) I want financial security for my family and creative crew. I want to be able to spend time with my daughters and know that I'll be able to send them through school.
2) I want to do fun, creative, world improving things. Five figure license fees to corporate America, for software that only kinda meets the core promise behind the stated need, isn't gonna put a smile on my face.
So, oh faithful new reader Take it.
Take it for free.
Yes, I'm drinking beer, and I'm gonna buy you free beer too.
I saw Dirty Jobs the other day where a born and bread fisherman in Oregon looked at his trade, and decided to sell everything and buy into the Cranberry business for his family and personal sanity stake. Sadly the Cranberry market tanked for 3 years immediately after he got started, but he lasted through and amazingly built a successful business at something he barely knew.
I feel like I'm making the same type of decision here. My Father certainly would not give away intellectual property, his manufacturing software shop had the same core license plus time and materials model that my current webshop, and so many others had. I've certainly loved and benefited from many open source solutions over the years, but personally have always most identified with the older Shareware movement: "have a taste, but the meal ain't free." The fact that we're giving away Concrete CMS under the MIT license, more open than ‘public domain', is a true step out of the water for me, and I'm excited about what I'm gonna learn.
Of course, I hope it will be wildly successful, we'll live comfortable and creative lives while making the world a better place from our little wet corner of the world. I can promise you, oh dedicated reader, one thing.. We will embrace this full force. We will blog on our blog as openly and blatantly as our minds take us. We may end up being seen as asses or heroes, maybe both but we'll certainly do everything we can to go big. Welcome to the internal dialog at Concrete the Studio, you're going to hear it all.
http://www.thebigwordproject.com/
I can not lie, this is a good idea that we simply didn't have first.
If someone could please explain to me how concepts like this go from 2 users to 2,000 I've got some work for ya.
-frz
To anyone in Portland who's interested: I'll be doing a demo of concrete5 and a Q&A targeted at developers at pdxphp tonight. It's at 6:30, at cubespace.
For more information:
Andrew Embler CTO Concrete CMS
On November 2nd, Google announced its OpenSocial initiative. Amidst the breathless hyperbole there came a prevailing sense of confusion from the world's web developers (including those around our office). What exactly was this "OpenSocial?" Was it an API? A framework for building web applications? A social network? Was Google invading the Facebook space? All of the above? And perhaps most importantly just what the heck are we supposed to learn, exactly?
It turns out that OpenSocial is all of those, and a bit more. It's also a bit loosely defined, and complete documentation is still a bit scarce. So I'm going to try and fill this understanding gap.
While some good write-ups of OpenSocial have been circulating the web since the announcement (Marc Andreesen's is particularly fine) none of them really offer a full picture of the OpenSocial initiative, including how it extends current concepts of widgets and the social web. Moreover, none of them really speak to engaged, active web developers about how to "get on track" with it. If you happen to be one of those developers smart, passionate, and perhaps a little bit late to the party this should get you going, and quick.
A First Look at OpenSocial: Background
OpenSocial extends out of the rise in popularity of widgets on the web. How am I defining widgets? In the context of the web, widgets are typically HTML, JavaScript and/or Flash, bundled together, into a self-contained mini-applications. Stock tickers, clocks, mini news readers and weather displays are some example of popular types of widgets.
Widgets are not a new concept. The original Macintosh operating system embraced the concept of "desk accessories" tiny, omnipresent applications, uniquely styled to be recognized at a glance. This continues today in Mac OS X, in the form of the Dashboard. Software programs like Yahoo Desktop Engine (formerly Konfabulator), Google Gadgets (when paired with an environment like Google Desktop) and the Windows Vista sidebar are other examples of widgets at work in the personal computing space.
While these types of widgets are used as productivity enhancers, other types began to gain popularity with the rise of social networking sites like MySpace. Typically built in flash for easy portability, widgets like slideshows, mini games, movie players and scoreboards were meant to be installed in social websites, and to be viewed not by the person installing them, but by others. They are meant to impart information or a sense of style. They are social.
While definitely popular, these widgets are still self-contained. This aspect of widgets makes them portable and easy to install it's not difficult for a person to cut and paste a two-line flash embed code it does limit their utility. Widgets for the web either completely lack customization, or they require a large amount of overhead on the part of the widget creator, to support things like data persistence. Furthermore, widgets don't know anything about where they're placed. Finally, not all social websites support the various ways a widget can be delivered (straight HTML, JavaScript, Flash, etc)
2007: Facebook Applications Up the Ante
In May of 2007, Facebook changed all that, when it officially launched its Facebook Platform: with this, there was one spot in which all Facebook widgets could be listed, and easily added to profiles. Furthermore, the Facebook platform introduced the concept of a "Canvas" page, which gives applications an entire, user-unique view to offer additional functionality, simply when they're installed by a user. Finally, Facebook applications (in both the widget and canvas view) can access user profile information, interact with the user's friends, and provide mechanisms for application promotion.
Problems Still Remain
Boy do they ever. While Facebook's development platform exposes a lot of power, it's fairly complex, with its own markup language, API and even an abstracted query language to search the Facebook database. Needless to say, these options are completely specific to Facebook, as is 90% of pretty much any application you write for the platform. At this point, developers who want to embrace MySpace, Facebook and traditional websites are stuck writing, at the very least, three completely separate applications. They also must market those applications separately.
Enter OpenSocial
It is against this landscape that OpenSocial arrives. Consumers, web developers and clients all recognize the market for widgets and customizable mini-applications and their spaces. But with a multitude of social networks, how is it feasible for the average developer or development shop to support more than the biggest networks? The best case scenario? Facebook users get the most full-featured application; their app has a fully realized widget, a canvas space with extra full-page functionality, and the ability to tie in to users who also use Facebook. Other websites get a simple widget with little to make it specifically compelling to members of said website. Big win for Facebook. Mixed results for everybody else.
In theory, OpenSocial should change that. According to the OpenSocial initiative: "OpenSocial provides a common set of APIs for social applications across multiple websites. With standard JavaScript and HTML, developers can create apps that access a social network's friends and update feeds."
Clearly, Google is positioning OpenSocial as the answer to the Facebook platform, but one in which any widget or application developer can write once, deploy everywhere. That's the hype. Does OpenSocial deliver? Let's answer the questions.
Questions about OpenSocialAnswered
What are the components of an OpenSocial application? What are they made out of?
When comparing OpenSocial applications to widgets for MySpace or other social networks, the answer to this is simple: OpenSocial widgets are essentially Google Gadgets. Google Gadgets are Google's own implementation of widgets, built in HTML and JavaScript, and served in an iframe. A public API for Google Gadgets already exists, separate from OpenSocial. Up until now, however, these widgets have faced the same problems as widgets on MySpace.com: they're self-contained, and know little about the environment in which they've been embedded.
OpenSocial adds a new API and JavaScript namespace for use inside Google Gadgets. Since Google Gadgets already use JavaScript, using OpenSocial's JavaScript API is really a simple way to allow your widget to access friends list and some simple information about those viewing it. For example, the following JavaScript, when added to a Google Gadget, gets information about the friends of the person viewing the Gadget:
function getData() {
// Creates an Open Social request object.
var req = opensocial.newDataRequest();
// Adds a new request to this object - let's get information about the person viewing
// this widget, and store it mapped to the "viewer" attribute in the response object
req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
// Let's request some more information. Let's get information about the viewer's friends, and store it
// mapped to the "viewerFriends" attribute in the response object.
req.add( req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'viewerFriends');
// Let's send the request to the container website, which will load the "onLoadFriends" function when
// data is available
req.send(onLoadFriends);
}
// this function loads with information from any Open Social requests.
function onLoadFriends(response) {
// viewer and viewerFriends are available in the get() method below because that's
// what I named them in the req.add() call above
var viewer = response.get('viewer');
var viewerFriends = response.get('viewerFriends');
var data = viewerFriends.getData();
}
While the API documentation explains additional data types available to OpenSocial widgets, at their core they're just that simple. More adventurous developers can perhaps dispense with the JavaScript API entirely, and use OpenSocial's REST-based API for getting data about people, activities and data persistence, but for most the simpler JavaScript API will be sufficient.
Where do the assets for these applications live?
OpenSocial widgets can use assets hosted anywhere on the web, and linked to through simple HTML. Additionally, Google will host your assets on its domain gmodules.com; just upload your images and external stylesheets through a menu option in the Google Gadget Editor, and Google will store them and provide you a URL to link to them.
How do customers find these applications is there a directory?
Google currently hosts a Google Gadgets directory. Since OpenSocial is simply an API that can be included in Google Gadgets, they will likely appear in this directory without much fuss. Unfortunately, there is currently no list in the directory of which sites support OpenSocial, and to be truly effective and compete with Facebook OpenSocial will need to allow these applications to be added directly from within their container websites. There currently isn't any documentation on this, although to check out what is known, jump to our section on how a social network might include OpenSocial widgets.
Can I store data in them? How much and at what cost?
Yes, you can store data in social gadgets. The Google Gadgets API has support for saving preferences, meaning that when you add that ESPN Scoreboard widget to your profile, you'll be able to specify it as having a red background with white text; this instance of the ESPN Scoreboard widget the one tied to your profile page will continue to exist with these settings until you change them or remove the widget. Everyone who views the widget will also see it with a red background and white text.
Instances of widgets (like the example above) can also have additional data stored against them for those who might view them. For example, the ESPN Scoreboard widget might not only provide the ability for the person embedding it to set its background and foreground text, but might also offer viewers of the widget the ability to override those settings. These are "viewer"-specific settings, just like cookies on a web page. The settings saved for each instance of a widget are bound to the viewer's profile, by using the OpenSocial Persistent Data API.
How would we implement this in OpenSocial? Let's say a widget developer wanted to make it so that a person viewing the widget could save their city and state, so that the next time they viewed the widget they wouldn't have to re-enter them. This information obviously differs from viewer to viewer, so it couldn't be saved in the widget's global preferences. The developer would need to bind this data to the profile of the person viewing the widget. Here's how he or she would do it:
function saveCityAndState(city, state) {
var req = opensocial.newDataRequest();
// we use newUpdatePersonAppDataRequest to specify that we're updating data the data saved is
// bound to the person viewing the widget
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppCity", city));
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppState", state));
// we pass the function that's run automatically when the request completes
req.send(function() { alert('Data Saved!') });
}
Reading that data back programmatically is similarly simple:
function getViewerInformation() {
var req = opensocial.newDataRequest();
// define the fields that we're retrieving for the viewer of the widget
var fields = ["AppCity", "AppState"];
// define the request for the fields above, which uses the fetch person data request
req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewerData");
// send the request to OpenSocial API
req.send(function(data) {
// on completion, this function is run automatically passing the data object to it
// "viewerData" is populated because that's what we bound these fields to above
var viewerData = data.get("viewerData");
});
}
While this example stores strings, I imagine it isn't too difficult to store complex objects, if you serialize them to JSON first. For more information on how the data returned is structured, check out the Social Google Gadget API documentation.
Do these applications have access to user data?
Short answer, yes. The OpenSocial API gives developers access to a small amount of fixed data (a "display name," a thumbnail image, a user ID and a profile URL) and a varying amount of data which can be filtered by type, including "BASIC," "CONTACT," "FULL," "MATCHING" and "PERSONAL." The actual mechanics of using the JavaScript API to retrieve this information are somewhat up in the air, with few examples of applications actually using extended profile data, and no examples of programmatically determining what data is actually available on a container by container basis. Check back soon or voice your displeasure at incomplete documentation in the Google Group for Open Social.
How does OpenSocial deal with different networks' design limitations?
This is still a bit of an unknown; while many networks have pledged to support OpenSocial, only a few like Google's Orkut, Hi5 and Ning actually have environments in which it can be tested, and even in these OpenSocial is only available in the developer sandbox. At a glance it appears that OpenSocial has attempted to gather up some of the most prevalent functionality in the social networking space an activity stream, basic user information, friends and people in general and provide access to them. It is up to the container website to determine how much of the OpenSocial API it wants to implement, meaning that the onus is still on the application developer to provide error checking and graceful failure if certain aspects of the OpenSocial API aren't available. This is too bad, although probably unavoidable.
How does view/edit work?
OpenSocial at its core is really about widgets. In this way, it's not really concerned about the difference between viewing and editing, beyond giving application developers the ability to save state, and giving the developer a way to specify preferences, which can be exposed and edited easily (this is part of the Google Gadgets framework.)
For these widgets, only one view is ever defined; it is up to the developer to include all necessary view logic within this one context. A widget could present two distinct interfaces view and edit to only the owner of the widget, with all other viewers only getting the "View" interface, but this capability must be explicitly included by the developer, including any permissions checks to determine whether certain controls ought to be displayed to someone viewing the widget.
How does Yet Another Social Network (YASN™) take advantage of these widgets?
First, one must become a Google Gadget container, a process which is reasonably well documented, and has been used by many of websites. This, however, is nothing new. To actually make your widgets aware of their container website, and implement the OpenSocial API, a site must implement the OpenSocial Service Provider Interface. As of this writing an official development kit to add these capabilities and expose them via the necessary JavaScript framework is still forthcoming from Google, but they have just released an OpenSocial Container sample.
Do I need to get my applications "blessed" by Google in order to run OpenSocial?
Nope. Although you need to submit your applications for review in order to get them to be included in the official Google Gadgets directory, you may host your gadgets from anywhere and need only a provide a URL to end users who wish to install it.
Why is Google doing this?
There are probably a few reasons.
- Their motto, "Do No Evil." I suppose this would qualify.
- In the minds of some, this is a warning shot fired at Facebook. If Google is indeed in talks with acquiring Facebook, this might be a bargaining tactic.
- Since OpenSocial gadgets are, by their very definition, Google Gadgets, this increases the profile and number of Google Gadgets available to consumers. This will also increase the number of websites looking to become Google Gadget containers, which promotes their widget platform further.
With millions of mini-applications installed across a multitude of social networks, Google gets increasing access to more data definitely a win for a company whose business is data mining.
Have any "gotchas" been discovered? Anything that us developers might like to know?
There always are. One of the most useful tips I've discovered has been this one:
While developing the Hello World widget described below, I found that Orkut would frequently cache my Gadget output, making active development of widgets a painful, painful process. However, if you append "&bpc=1″ to your Orkut application URL, the site will stop doing this. For example, if you're viewing your in-development widget at
https://sandbox.orkut.com/Application.aspx?uid=x&appId=x
You can keep from ever seeing a cached version of the gadget by making the URL
https://sandbox.orkut.com/Application.aspx?uid=x&appId=x&bpc=1
Another tip? Double-check the data you get back. While checking the Google Group for OpenSocial, I found that certain details of the API haven't exactly been normalized across service providers. Attempting to retrieve a profile URL for a user record on Orkut returned the following:
/Profile.aspx?uid=xxxxxx
Grabbing the same data on Hi5 returned a fully qualified URL:
https://sandbox.hi5.com/friend/profile/displayProfile.do?userid=xxxxx
Clearly, this is a problem on Orkut's part, but keep this in mind this platform is far from stable.
Building Your First OpenSocial Widget
As mentioned before, OpenSocial widgets are really just Google Gadgets that add an extra API, which allows them to get some information from their container websites. So, to build an OpenSocial widget, we really need to start by building a Google Gadget. And Google Gadgets, at their simplest, are self-contained XML files. To give you the simplest example, here's a "Hello World" Google Gadget I created, using the Google Gadget
Editor, an inline, JavaScript-powered editor:
The code for this widget is very, very simple:
- <?xml version="1.0" encoding="UTF-8"?>
- <Module>
- <ModulePrefs title="Hello World" />
- <Content type="html"><![CDATA[
- <div>
- <div style="text-align: center">
- <img src="/url/to/logo.gif" /></div>
- <div>Hello World!</div>
- </div>
- ]]></Content>
- </Module>
(Note: I omitted some miscellaneous style information to make this example easier to read.)
While the Google Gadgets API offers many features for widget creators (including dynamic, styled tab creation, drag and drop, localization, and more) as well as the ability to store information about widgets like their title, author and a link to a thumbnail image, at their core Google Gadgets are really as simple and self-contained as the example above.
Let's take a look at my widget; sure, it's fantastic, but it's a bit static. What if we were to socialize the widget by making it say hello directly to the person viewing it. Wouldn't that be something? Well, that's the kind of stuff that OpenSocial can provide.
First, we'll need to make the Google Gadget include the OpenSocial API. We do this with a simple XML declaration inside the ModulePrefs tag:
- <ModulePrefs title="Hello World">
- <Require feature="opensocial-0.5"/>
- </ModulePrefs>
Next we replace "Hello World!" in our application with "Hello ," using the DIV as a placeholder that will eventually be populated by our call to the OpenSocial API. Finally, we add in the necessary JavaScript:
The code should be pretty easy to read. First, we initiate a callback function through the use of Google's _IG_RegisterOnloadHandler function; this function automatically runs and causes its function argument to run when the gadget is finished loading. The getData() function then instantiates a new request object to the OpenSocial API, adds a request for information about the viewer, and then sets up the loadViewer() callback, which is run automatically when information returns from the API. This information is then parsed for the viewer attribute (which was set in the req.add() method), and the viewer's display name is inserted into the contents of the viewer-name placeholder DIV.
Limitations of OpenSocial
While the "Hello World" example above should give you an idea of how to build a social gadget, it wasn't my first choice for a widget. Around our office, while brainstorming ideas for this article, and still somewhat confused about OpenSocial's exact capabilities, we conceived of a different type of widget. We wanted one that, when placed on someone's profile page, was able to learn and store that it was placed on a
particular social network. That's not that compelling obviously an instance of a social gadget on a profile page is able to tell what container website it's on, whether through the API itself or even inspecting variables like the profile URLs available. However, in addition to this, we wanted every instance of this widget for a particular user, spread across multiple social networks, to be able to share this data. This would create a "My Social Networks" widget, which would list all of a user's profiles around the web, without the user ever having to modify the widget or tell the widget that they had an account on Flickr, MySpace, Hi5, etc
On each website, the user would add the "My Social Network" widget, which would then communicate with every other instance of the widget spread across multiple social networks. We had hoped that OpenSocial, in addition to specifying common hooks for widgets to interact socially within a container website, would focus on people with multiple profiles, across multiple websites.
Unfortunately, OpenSocial doesn't do this. Each instance of a widget on a container website knows only about the profile to which its linked, and that profile's friends. My profile on LinkedIn and my profile on MySpace are too completely separate profiles, and OpenSocial provides no ability for widgets to actually understand that these profiles belong to the same person. We had hoped that it would. Yes, OpenSocial allows the developers of the ESPN Scoreboard widget to build them once for Orkut.com and once for MySpace.com, and still hook into each site's social functionality, but that is the extent of its benefits.
Conclusions
When Google first announced its OpenSocial initiative, about the only thing anyone really knew about it was the type of reactions it would provoke. Yes, we would see the initial outpouring of support; the hyperbole over Google's massive foray into the social space; its shot against the Facebook ship. Almost as predictable as the praise was the
condemnation: OpenSocial was not that impressive, not that interesting, and really not even worth talking about.
But as always, the truth is much less polarized, and quite a bit more mundane. Actually, OpenSocial is pretty interesting, and does showcase a new, standardized
approach toward building social-website-aware widgets. In a world where every social network joins the OpenSocial initiative, web developers will have to do less work, and be able to support more customers than before. Furthermore, OpenSocial helps Google reassert its presence in the widget space which, honestly I must admit, I'd completely forgotten about. Checking out the OpenSocial API has reminded me of their mature, pretty full-featured Google Gadget offering.
Of course, it's not perfect. These widgets are really only "social" within their container website; this isn't an inter-site communication API. Also, while Orkut appears to support different views for its various applications (like Facebook does), this is a decision each social network must make for itself; there's nothing built into the OpenSocial API to really support or encourage innovations like the Facebook canvas view, which is too bad: our Lemonade Facebook application is fun and informative in widget view, but it really shines when you bring in Facebook platform-specific code, like the ability to invite other users to the application, or the ability to show large-format information in a separate canvas view. Yes, some websites will support these types of
views, but unless they're built into the API, and the API itself is built in such a way that all of its functionality must be enabled on each container website, developers are still stuck writing website-specific code.
I think these are valid criticisms, but I don't want to let them overshadow the entire initiative; it's easy to get hung up on what OpenSocial doesn't do, and miss out on what it it does. No, you won't be able to stop writing Facebook-specific widgets yet, but the next widget you make will at least be able to say hello to you by name, on multiple
websites. While application underpinnings won't become completely website-agnostic any time soon, developers will be able to write less code. So take the time to explore OpenSocial, and voice concerns about its shortcomings; the more we do this, the more likely OpenSocial 2.0 will really be something to write home about.
Andrew Embler has written multiple Facebook applications. These days, he finds concrete5 web development more exciting. He can be found on twitter.
// sets getData() as the function that automatically gets called when the gadget is loaded
_IG_RegisterOnloadHandler(getData);
function getData() {
// Creates an OpenSocial request object.
var req = opensocial.newDataRequest();
// Adds a new request to this object - let's get information about the person viewing
// and store it mapped to the "viewer" attribute in the response object
req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
// Let's send the request to the container website, which will load the "onLoadFriends"
// function when data is available
req.send(loadViewer);
}
function loadViewer(response) {
var viewer = response.get('viewer').getData();
Lemonade.com lets people create a widget that contains different products for sale from companies like Appleand EBGames and easily place this "lemonade stand" on social networking sites and blogs. People then earn referral fees when people buy products via their stand.