My 2012 conference schedule is shaping up nicely. I will visiting a series of conferences, code camps and user groups this year. Last year I didn't do this nearly as much as I was building a failed product. So back to my love of badges and beer. If you have the opportunity to be at any of these great events, do it. I love them all. (Also, if you see me at an event, please stop by and say hello. As many can attest, I don't bite much.)
Here's the current slate (in chronological order):

May 19th, 2012 - Atlanta, GA
- Mobile Web Development: Learn to use Responsive Design and Mobile Pages in MVC4 to create great mobile experiences.
- Debugging the Web: Using the Browser Tools to achieve greatness.
June 15-16, 2012 - Knoxville, TN
- Modern Web Development: Learn the new ecosystem of technologies that make web development sane again.
- Building Mobile Websites with ASP.NET and HTML5: Learn to use MVC4's Mobile Pages to detect and deliver great mobile pages.

August 29-31, 2012 - Chattanooga, TN
- A Better CSS: Learn to use LESS and SASS to build CSS easier than ever!
September 17-21, 2012 - Mainz, Germany
- Modern Web Development: Learn the new ecosystem of technologies that make web development sane again.
- A Better CSS: Learn to use LESS and SASS to build CSS easier than ever!
October 22-24, 2012 - San Francisco, CA
- Getting Started with Windows Phone Development: A workshop that will take you from none to fun in WP development.
- Top 10 Mistakes Windows Phone Developers Make: I'll go through my least favorite mistakes in app development.
- Background Agents: Best Practices: Learn how to use background agents without hurting the phone experience.
If you have a conference or code camp you want me to speak about, reach out on the contact page!
This is another in my series about (hopefully) interesting JavaScript constructs that might surprise most C# developers. You can see others here: JavaScript for the C# Guy.
Back in the day I was doing some scripting in classic ASP sites (no, not classic ASP.NET) and we screamed and yelled about putting too much in the global scope. We wanted encapsulation and such and that is true today. In my C# work pretty much everything is in a class (static or otherwise) so I don't have to concern myself with it much. But in JavaScript I know there is an easily accessible global object...but it occurred to me that I don't see the "Global" object accessed much; even though it is used a bit (to hold other containers that have encapsulated code). "Why not?" I wondered.
In JavaScript you can certainly create things in the global space. In fact, in my Architecting JavaScript post from my Modern Web Development series, I show that using an 'app' object for your site can simplify a lot of things. But the app object needs to be in the global space (e.g. in the "Global" object) so everyone can get to it:
// app.js
(function (a, $) {
a.setStatusMessage = function (message) {
$('#status-message').text(message);
};
} (window.app = window.app || {}, jQuery));
This code is creating a function that passes in a global object called 'app'. This 'app' object is going to be a singleton that all scripts can add to so it is a canonical example of use of a global object since lots of code will interact with it. Great...but...in this case the code doesn't put the object in the global scope, but attaches it to 'window' object.
What does that imply? While reading up on it in the great book "Professional JavaScript for Web Developers", I found the answer. It seems that the JavaScript language supports a global object, but the spec that the web browsers use (ECMA-262) doesn't tell them how to allow access to the 'Global' object. It seems that the web browsers implement this by making "window' implement the access to the Global object. This means anything in the global space is accessible on the 'window' object. (The "window" object has a bunch of other responsibilities too, not just a alias for the Global object).
While this is true in our example, it also means that objects created in the global scope are also on window. For example:
// Some.js
var name = "foo";
function whatIsFoo() {
return name;
}
var result = window.whatIsFoo(); // works
In this example both 'whatIsFoo' and 'name' are both accessible from the window property. Makes sense (though an odd place for it IMO).
Have you run into this peculiarity?
I got into a longish, public discussion last night about XAML versus the HTML/CSS stack last night. I think they both have merit and pros and cons but it made me decide to add a short series of posts that highlight some of the CSS things that surprised me most (like my JavaScript for the C# Guy posts - and yes, more of those are coming too).
The first topic I am covering is some subtleties of the selector syntax. CSS selectors allow you to pick children, descendants and adjacent siblings. I found that I used descendant selector quite a lot:
#main h1 /* descendant */
{
color: Red;
}
This syntax effectively says, any h1 inside an element named "main". I see people assume this actually means, *directly* inside the "main" element. So if you had some HTML like this, all h1's inside "main" would be colored red:
<!DOCTYPE html>
<html>
<body>
<h1>Top</h1>
<section id="main">
<h1>Main Level</h1>
<section id="article">
<h1>Second Level</h1>
<p>Yup</p>
</section>
</section>
</body>
</html>
Note that it applies to all the descendants. But but if you did want just the h1's directly inside (or...ahem a child) of "main"? That's child selector syntax:
#main > h1 /* child */
{
font-size: 24px;
}
Then only the h1 containing "Main Level" will have the rule applied. I've seem some CSS with tons of "!important" to override the descendant syntax because they didn't seem to know about child selector.
The last one is the adjacent sibling selector. This selector looks for elements that are directly next to each other (or...ahem...adjacent):
h1 + p /* adjacent siblings */
{
border-bottom: black 2px solid;
}
In this case, the p (not the h1) will have a border under it. The other h1's will be left unmolested. Here's a complete example if you want to play:
"If you're not careful, you just mind learn something..."
This is the ninth of ten parts of this blog post.
The topics will be:
Why do users complicate our lives by trying to view our content on their phone and tablets? It's even an issue for smaller sized desktop screens too. Since this is simply a reality for today's web developer I was glad to see there were real strides in working with mobile.
Ways to Handle the Mobile Web
In general there are three techniques for dealing with mobile device browsers:
- Mobile Site: Write a version of your site specifically for mobile browsers/phones.
- Mobile Pages: Write mobile specific pages for individual pages in your site.
- Responsive Design: Adapt pages to work with mobile devices.
Which should you choose? Well, that depends...
While building a mobile site is been a standard way of doing business for a while (ahem m.foo.com is the pattern, right?), it involves more work and occasionally separate engineering efforts. This is still an option, but I think it should become more uncommon.
Building mobile pages is closer to what an software guy might suggest, but that can be a lot of engineering effort too. Imagine building every page twice (or more). But you don't have to. The last technique is to use "Responsive Design". Let's dig into how that works, then we'll add Mobile Pages to fill in the gaps (this is my take on the right approach).
Responsive Design
The basic tact of responsive design is to design your pages (and site) to react to changes in browser size. This means on different devices, you can have your site *respond* to the change. Instead of complex logic to sniff the type of device and a database screen sizes, you can use CSS specify changes to your design based on screen size.
A CSS media query is the key to getting this to work. A media query device type (in our case, screen) and size help you create exceptional case CSS for specific device types. A typical example in responsive design is defining that you want a 'screen' and a specific range of widths:
@media only screen and (min-width: 960px) {
}
This allows you to have rules that apply to only certain widths of an app. This works well to allow you to change formatting for desktop, then tablet, then phone.
/* fallback */
#main
{
width: 989px;
}
/* Tablet Portrait size to standard 960 (devices and browsers) */
@media only screen and (min-width: 768px) and (max-width: 959px)
{
#main
{
width: 760px;
}
}
/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
@media only screen and (min-width: 480px) and (max-width: 767px)
{
#main
{
width: 472px;
}
}
/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
@media only screen and (max-width: 479px) {
#main
{
width: 400px;
}
}
The idea behind this is to define rules that apply everywhere (and most of your rules will not be inside of media rules) and then for specific screen sizes, create rules that override the default rules. For example, the 1024px width for #main works in the browser, but when you resize your window to be < 960px(or open it on a device with the right resolution), the size of #main changes to 755px. This is to ensure it fix on smaller resolution devices. This continues for the different size screens all the way down.
Note that in the browser tools, you won't see the media rules, they'll just be applied. So on my laptop, when I look at the matching rules for #main I get:

Because the page size is > 960px at this time, I only see the first #main definition that defines the width. But if I reduce the size of the window to be smaller than 960px, the rules change as the media rule kicks in:

In this case we see both the original #main rule and then the #main added in the media query section and since the media query happened after the first declaration, it takes precedence.
If there are elements of the page (e.g. ".centered") that aren't different for the screen size variations, I don't need to duplicate them since their in the main CSS scope.
For example, I've created a simple design with a container and a way to float boxes next to each other when the screen is wide:

When the screen is large (e.g. 1024px wide as shown), it looks great. The menu items are floated to the right top, and the three columns are just floated sections. When I go down below 960px I simply change the sizes of the columns:

But you can completely change the rules to change the look, like when we're below 768px:

In this case, I am keeping the columns to be farily wide, but no longer floating them as on a small screen (like a phone) floating makes them too small to be useful. In addition, you can change other elements (like the menu is stacked below the logo instead of floated to the right. You can make design decisions about what looks best on the right size device.
In all of these cases, these changes are made in the design artifacts (e.g. CSS) and not in code. So that you still have a single code block for a particular page, even very complex ones. But sometimes even that isn't enough.
Mobile Pages
There are times when you want a completely different experience for mobile users than typical web users. This may not be a solution for the entirety of a site, but only applicable on special pages (e.g. data entry screens). For those times when you need special mobile pages, ASP.NET MVC4 has a great way to handle this (though there are hacks to work with MVC3 and get this behavior). The trick is to simply create a new view and name it {page}.mobile.??html (e.g. Contact.Mobile.cshtml). By default, it will find the mobile page (if it exists) for mobile devices. For example:

Why a specific page for mobile? One big reason is to use mobile frameworks (e.g. KendoUI Mobile or jQuery Mobile). My non-mobile version of my contact page looks like you might expect (using a _layout page):
@* Contact.cshmtl *@
@model ModernWebDev.Models.SomeFormModel
@{
ViewBag.Title = "Contact Us!";
}
@section Stylesheets
{
<link rel="stylesheet" href="~/Content/Home.Contact.less" />
}
<h2>
Contact</h2>
<section class="big-form">
@using (Html.BeginForm())
{
@Html.ValidationSummary()
@Html.EditorFor(m => m)
<input type="submit" value="Send" />
}
</section>
But for the mobile page, I could use jQuery Mobile to show off the page:
@* Contact.mobile.cshmtl *@
@model ModernWebDev.Models.SomeFormModel
@{
Layout = null;
ViewBag.Title = "Contact Us!";
}
<!DOCTYPE html>
<html>
<head>
<title>Modern Web Dev - Contact</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="~/Content/jquery.mobile-1.1.0.min.css" />
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Modern Web Dev</h1>
</div>
<!-- /header -->
<div data-role="content">
<h2>Contact (Mobile Version)</h2>
<section class="big-form">
@using (Html.BeginForm())
{
@Html.ValidationSummary()
@Html.EditorFor(m => m)
<input type="submit" value="Send" />
}
</section>
</div>
<!-- /content -->
</div>
<!-- /page -->
<script src="~/Scripts/jquery-1.7.2.min.js"></script>
<script src="~/Scripts/jquery.mobile-1.1.0.min.js"></script>
</body>
</html>
Note that I am setting the Layout to null to prevent using the Layout page as my 'master page' but doing it all in this page. But since this page is relying on sniffing the browser to detect a site, how do I trigger it? Magic? Nope, Safari!
The trick is to use Safari as it has the ability to send iPhone, iPad and iPod request headers. How does it work? Let me show you.
If you have Safari installed, you'll need to enable the developer menus by opening preferences:

Then on the Advanced Tab, show the Developer menu:

Once you have that you can enable them in the User Agent menu:

This will trigger the mobile versions. The contact page with the default User Agent:

And the jQuery Mobile version once I change the User Agent to "iPHone":

Using Mobile Pages allows you to have specific parts of your site use these mobile frameworks but not requiring whole separate sites.
Combining the two efforts (Responsive Design and Mobile Pages) I think is the best of both worlds. I don't see a realistic place for creating separate sites.
Here's an example of using these two techniques together:
What do you think?
So I've done it again. I survived another 30 minutes with Woody and Keith. Whew. We had a good conversation about the current state of Web Development and the future of XAML development.
I also got to discuss fried foods and make fun of Keith. Couldn't have been a better time. Go listen now:
As many of you have known for a while, I've been running my AgiliTrain training company focusing on technologies like Silverlight, WPF and the Web. My interest in training isn't going away, but I've yearned to work with a small group of thought leaders to help companies in more innovative ways. With this goal in mind, I am launching Wilder Minds.
The vision for Wilder Minds is to be a complete solution for companies who are trying to move to new technologies (like Windows 8, HTML5/JS, Mobile Development, node.js, etc.) Instead of just doing training, we're expanding to help in three primary ways:
- Training (like we've always done)
- Development
- Coaching
Training
Wilder Minds is still focused on training. We are still building and teaching our courseware as we did as AgiliTrain. This hasn't changed. We have adapted to the changing way people are taking training and suspending our publically-held courses. We won't be doing our "Tours" any longer, but we will continue to teach our courses (and custom courseware) as clients request them. In addition, we're continuing to build courses for PluralSight and do some remote classes. Training is still a major focus of this new venture.
Development
This might sound like a similar story to a lot of other companies, but our focus is to improve development teams, not replace them. Improving the skill sets of developers is what we've always done, but the development and coaching are new. Our goal is to help companies build projects where it helps the existing teams. This may be building proof-of-concepts or exemplars. It also means building the first version of a product that the company doesn't have time to wait for the team to get up to speed. It is imperative to us to make sure every line of code we deliver is of exceptional quality. This is of particular importance to use as we think even our development work is an opportunity for teaching. We know the best way to improve developers is to get them to work with exemplarity code. In our opinion, that's the best way to mentor coders.
Coaching
Coaching, on the other hand, is our answer to traditional consulting. The problem with the word 'consulting' is that it's become synonymous with contracting or being a head-count shop. When we talk about coaching, it's an opportunity to work directly with clients to help them with planning, architectural and code reviews as well as question and answer sessions. It's a way for us to take our expertise to clients directly for short stints to help them over key technical hurdles.
What about AgiliTrain?
Well, AgiliTrain is morphing into Wilder Minds. All the old AgiliTrain urls now forward directly to the new company. If you're an existing AgiliTrain client or student, nothing changes...except for the name.
If you have questions, please don't hesitate to contact me via our contact page:
http://www.wilderminds.com/contact
A lot has been made since a report from Microsoft late last week (http://shawnw.me/HPEh0R) that seemed to say that Silverlight on the phone was going away in Windows Phone 8 (Apollo). I liked a lot of what this article had to say (from e-week):
http://shawnw.me/IwMgR2
So it got me thinking that much of the Silverlight community would be jumping out of windows (lower case and not TM) this week due to the news. But of course, if that's the case for you, I'd urge you not to panic. Why? Let me tell you.
CAVEAT: I am guessing and have no inside knowledge on what Windows Phone 8 is going to do. Really!
Silverlight and Me
I came into Silverlight because of my prior work with WPF. But it's more complicated than that. I came to WPF at a time when I was primarily known as a database guy (my old moniker was "The ADO Guy"). So why would I care about WPF? Data binding.
I am not a UI/UX guy. I can barely match my own socks. But I came to XAML because I saw the potential of building apps using a smart markup language that has the possibility of a real data binding framework (unlike MFC, VB5/6, WinForms, ASP.NET WebForms before it).
I got into Silverlight because I lucked into being there at the ground floor (I taught a WPF/E course at Microsoft to MS employees and partners before it was publically named). But even in the early days of XAML + JS, I saw the potential of building apps (not sites) with XAML. The fact that Silverlight was originally to build them in the browser was tangential. In fact, I liked Silverlight (v2 and beyond especially) because it learned from the lessons of WPF (which in my opinion is over engineered somewhat) and simplified the XAML so that it was consumable in a short period. The lack of features like Triggers and a simplified text stack meant that people could get up to speed fairly quickly.
Windows Phone 8 and XAML
What the Microsoft folks said was that Windows Phone 8 development would be much more like Windows 8 XAML development. That meant that Windows Phone 8 would probably have the underpinnings of WinRT. Should anyone panic? Nope. Here is why.
The WinRT XAML stack is based on Silverlight 4. What losing Silverlight does is say that the XAML (and data binding stacks) are going to be unmanaged. That's a good thing. In Silverlight (especially on the phone) the managed part of the XAML stack (data binding et al.) got in the way of a great touch experience. In Mango, the Windows Phone team built several ways of keeping the experience smooth by doing a lot of tricks, but it is still pretty easy to screw it up as a developer. WinRT works differently. The entire XAML stack is in unmanaged code and the entire WinRT framework is built with async in mind. It makes it easier to build fluid, touch-enabled applications (or it should).
The other benefit is that it brings together the Metro-style application development on tablets and the phone. This is a big win for developers. This is likely not going to result in a single app working on both devices, but it should allow many of the assets to be more sharable. We have no details or promises yet, but if some of the features of WinRT come to the phone, we're all in luck. I am especially looking forward to Contracts.
WinRT XAML Development
I've been digging into the Windows 8 XAML stack and as of the Consumer Preview I am really enjoying the experience. The Consumer Preview build is pretty close to Silverlight's implementation IMO. There are likely some missing pieces, but all the big pieces are there. Adding to that, the great Visual Studio 11 XAML editing experience (powered by Blend) and I think you'll find the development experience is really good right now.
If you're a Windows Phone developer already, the experience of developing for Windows 8 (and Windows Phone 8 probably) will be pretty similar. App.xaml holds the application level events. Navigation to individual XAML files and support for a back-stack. Adding to the benefits here are things like Live storing of settings in the cloud (instead of inventing this yourself) as well as smoother touch APIs mean that the transition to WinRT should be smooth for Windows Phone developers.
If you're a WPF or Silverlight developer, there are pieces to learn (like Navigation and touch) but the XAML design experience should very familiar. If you're not digging into WinRT yet, it's time to dip your toes into the water!
I saw a tip by Tim Heuer on a StackOverflow question about how to show binding errors in the Output window of managed WinRT (e.g. Metro-style) XAML projects. Tim mentioned that:
You get this automatically for C++ applications and for managed applications you have to turn on unmanaged debugging to see them.
Since I had a hard time finding it, I thought I'd drop a quick image to help you find it. You have to go to your project properties and look at the Debug tab:

With this, you get the tried and true binding failures that you might already be used to in Silverlight or WPF. Wahoo!
Nearly a week ago I installed Windows 8 as my main laptop operating system. I could finally do this once the Windows Phone 7.1.1 SDK update was released (making the Windows Phone emulator work on Windows 8). So I am not knee deep into Windows 8 as a desktop operating system.
NOTE: is that I am using Windows 8 on a non-touch laptop. This means I want to test it as a replacement for Windows 7 on my development machine. This is a particularly important test for the Operating System for me. I've used it on a Tablet for several months now and I really like it. The Samsung Tablet that we were given at Build is a good machine to see how real tablets will be. The lack of apps and battery life make it an approximation of real tablet use for me, otherwise I'd use it a *lot* more!
Authentication and Settings
When I set up the Tablet for Windows 8, I just used my LiveID so that I could get the full integrated experience that consumers would get. But since I use domain authentication for my laptop, I was worried about how the experience would be. Luckily, I was able to login easily with a domain account like I figured. But what I didn't realize was that if I link my domain account with a LiveID, I could do pin and picture password. I've been told that authenticating with an Exchange server breaks this, but for me it's working grand! Pin login FTW!
The New Start Screen
Using the New Start Screen with a keyboard and mouse has gotten a lot of attention as many people don't seem to like it. For me it was a bit of getting used to the new Start "menu". While I can't grab and move the start menu, the scroll wheel moves me through the Start Screen just fine. A couple of hints for those getting used to it:
Corners are Important
While on the Start Screen, when you move to each of the corners, different parts of the Start Screen experience work for you. Upper left shows you the *last* app:

If you move to the upper right corner you get a preview of the charms:

You can also move to the right side to get the full charm experience:

Semantic Zoom
Another important feature is to quickly navigate around your Start Screen as you get more and more tiles is to use semantic zoom. On touch this is done with a pinch move, but with the mouse you can get this by either clicking on the bottom right, or I find it more natural to just hold the Control key while I use the mouse wheel:

Working with the Start Screen
For me the Start Screen is just a big Start Menu. I can simply right-click on an icon to select it, then I can either remove or change the icon like so:

I find that after installing all the software I want, I tend to remove most of the Start Screen icons. I don't use most of them and do wish the Windows 8 RTM will include the ability to select a lot of icons by stretching a box around them (mostly so I can remove most of them). I tend to think that the Start Screen is mostly for Metro apps and updating tiles. If you've used Windows Phone 7, then you can think of the Start Screen like it is there. There is a list of all apps, and you only 'pin' the important ones you want quick access to.
Like the Start Menu, the Start Screen can be accessed quickly with Ctrl-Esc. So my muscle memory of hitting Ctrl-Esc and typing to search for apps works exactly like I expected. In fact, the search is across the machine so I can simply change the search area (e.g. Settings, Documents, Apps) quickly. The Tab key and arrows work as I expected them to:

Navigating Apps
If you are running several Metro apps (including the Desktop), you can also access the apps via the left side like the life-side swipe that works via touch. For example, if you have more than one Metro app running, when you show the last app running, you can move your mouse down (staying on the left side of the screen) to show all the metro apps running:

With access to these apps, you can drag them and create split screens like on the tablet. Finally, you can also close these apps by grabbing the top of the screen and pulling them down:

The app will get small and show the hand-hold icon. Drag to the bottom of the screen and it's closed.
The Desktop
One pet peeve of mine is that I have to "run" the Desktop app to get to the desktop. But since this only happens on a reboot, this won't happen much so I can live with it. The integration of the Desktop feels pretty seamless. It will take a little time to get used to, but luckily most of the things you expect to work on the desktop just do. For example, Alt-Tab will let you navigate through all running apps, metro and desktop (Metro Apps are marked with arrows):

This helps it feel less like two separate worlds. When working on the desktop, you can get to the Metro'ness with the corners too. Upper-left corner for recent Metro Apps, upper right for Charms and (only on the desktop) lower-left for Start Screen:

I tend still spend most of my time on the Desktop (no surprises there) but being able to pin a Metro app to the left or right has been useful...waiting for a Twitter/FB Metro app to really use this:

Development on Windows 8
For me the real test comes when I want to develop on a Windows 8 machine. This has been really good. Visual Studio 2010 and 2011 living side-by-side work well (I notice some additionally crash-y ness out of 2010 but not sure if it's Win8 or the side-by-side installations). But I am running all my main tools without a problem:
- Visual Studio 2010 (Ultimate)
- Visual Studio 2011 Beta
- WebStorm
- Sublime Text 2
- TortoiseHG/VisualHG
- ASP.NET MVC2, 3 and 4
- Silverlight and Windows Phone 7.1.1 SDK tools
- Camtasia and SnagIt
- MS Office
- Zune
No problems with existing development at all. This was a real relief.
Developing for Metro Applications
One of the reasons I wanted to move to Windows 8 was to be able to develop Metro-Style applications easier. Remoting into the Build Tablet works but it's not a very powerful machine. Developing WinRT/Metro apps on a real laptop has been mostly a joy. I use the local machine to develop the app and also have used the remote debugger to debug directly on the tablet without any problems.
Final Thoughts
While I really like the experience and don't want to go back to Windows 7 anytime soon, I do have a couple of odd experiences I thought I'd document:
- All my Win7 drivers worked great and I didn't have to install as many drivers out of the box as before.
- I use PureText to allow me to paste without formatting at a keystroke. I used to use Win-V (as this closely mirrors Ctrl-V paste) but the OS now uses Win-V for something so I had to move it to Win-A. Not as good for my muscle memory ;)
- I find the OS is still Beta (or pre-Beta) quality so expect lockups occasionally, but not enough to make me stop using the operating system. But I suspect this has more to do with my dual video cards (a low and high power card for battery) driver.
- Playing games on my laptop (e.g. SWTOR) work just as well as they did on Win7 so I am not paying an OS penalty.
- The Visual Studio 2010 SP1 installer took 5 minutes without a reboot. This blew me away. I thought it might have failed, but it's working fine. Wow.
Overall, I am loving the OS but not quite ready to anoint it for dev's who don't like Beta quality software. I am not going back personally.
Have you installed it? What do you think?
This is the eighth of ten parts of this blog post. The topics will be:
Oh Facebook…how do you becoming so insistent on integrating you into every website? Well anyway, let’s show you how it actually works. In this post, I’ll show you how to authenticate an app using Facebook.
Getting Started
When you want to integrate with Facebook, you’ll need the Facebook SDK. Unlike other JavaScript APIs, the Facebook API isn’t a download. The API has some specific peculiar patterns that it requires. But if you obey Facebook, it will (usually) bend to your will. To get started you’ll want to visit the Facebook developer site:
https://developers.facebook.com
Before you get started using the Facebook API, you need to have a Facebook application. This is simply registering with Facebook to get a unique key for your use of the API. To do this, you will want to click on the Apps button (or go to https://developers.facebook.com/apps) and choose “New App”:

This will create a new application and take you to your application page:

The App ID and App Secret are the magic numbers you’ll need (as shown by the arrows). The only other part of this process that is important is the “App Domain” specified here. The Facebook API only works (with the App ID and App Secret) from a specific domain and website address. For development I suggest you set this to your localhost address (yes, this works fine). For example:
http://localhost:8080
On the App page this will look like:

This works for a new project, but once you deploy to a live site you no longer can test your development application as you’ll need to change this to the live site’s domain. To address this, I suggest you create two applications – a development application and the application for your deployed application.
NOTE: If you are using Internet Explorer for development, the Facebook SDK doesn’t work on non-standard ports. You should either pick port 80 (or 443) or use another browser for your Facebook work.
So let’s start loading the SDK.
Loading the SDK
Now that you have your application, you can start using the SDK. The Facebook SDK requires you download the .js file, have an element in your HTML that the SDK uses as well as have an initialization method. So first you’ll need an element (usually a DIV) named “fb-root”:
<!-- The required element that the Facebook SDK uses -->
<div id="fb-root"></div>
It doesn’t matter where the element is in your design, I usually just place it right above my script tags at the bottom of the <body/> tag. It will not be visible to your users.
The Facebook SDK exposes all of it’s functionality (pun intended) on global object called “FB”. Before you can use the SDK you will need to initialize this object to include information like your App ID (and other options). This is usually called in a function that is called by the SDK when it is loaded on your page:
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({
appId: '@ConfigurationManager.AppSettings["facebookAppId"]',
cookie: true,
status: true,
frictionless: true,
xfbml: true
});
};
</script>
This function must be added to the ‘window’ object and be called ‘fbAsyncInit’. In the method you should call the init method of the FB object to specify several pieces of information. Note that I am calling this in a Razor page so I can using the @ syntax to load the facebookAppId from my AppSettings in my web.config file. I do this so I can have a debug application and switch it to a release AppId when I deploy it to my live servers. The other options are covered in the Facebook SDK so I won’t repeat that here.
Finally you need to load the Facebook SDK. The SDK is located at “connect.facebook.net/en_US/all.js”. But because of all the initialization that it performs, it is best not to just use a script tag. Instead they suggest you load it asynchronously like so:
// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
} (document));
This creates a new script element after the pages has loaded and loads the script. Notice the src of the script element: “//connect.facebook.net/en_US/all.js”. This URI is used so it will get it via https or http based on how your application is hosted. The workflow here is:
- Load the SDK asynchronously
- Execute the fbAsyncInit method if it exists on the window object
- FB.Init is called with the AppID (et al.)
At this point you’ve done all the work to be able to use the SDK.
Logging into Facebook
For this example, I am going to keep it simple and just show login via clicking on an image and then showing the name of the user that was logged in. So I’ve added a new image in my HTML page that I’ve specified a class called ‘fb-login’:
<img class="fb-login" src="/images/FBLogin.png" alt="Facebook Connect" />
This could be an actual button or even a link, but for my needs I just need some UI element for the users to click. Then I can just add a click handler to the image like so:
// Handle anything that can be clicked as
$('.fb-login').click(function () {
FB.login(function (response) {
if (response.authResponse) {
mwd.showCurrentUser();
}
}, { scope: 'email,user_about_me' }
});
In this case, I am just calling the Facebook SDK’s login function to perform the login. The second parameter of the login function is an object that can be used to specify the ‘scope’. This ‘scope’ is the list of permissions. In this case, we’re just asking for permission to see the email address and the basic user information for the person. You could ask for more permissions (or more appropriately you can expand these permissions as you need them).
When the login function is called it will look for the AppID that was specified and go to Facebook.com and popup a new login dialog for you:

This dialog is shown if the user is not already logged in. If the user hasn’t used Facebook to login before it will also show a permissions dialog. If you login with *your* login that you created the App with, this dialog won’t appear as you’ve already approved the application since you’re the owner. But if you try and login with other users it will simply fail. Why? Because your application isn’t public yet. So either you can make it public or usually you’ll just add testers to your application instead (for early development). To add testers to your application, you can visit the application page again and pick “Roles”:

On the Roles page, you can add Developers and Testers. These must be Facebook users and they will need to approve their role before they can login. Once you do this, you will get the permissions dialog (based on the permissions you asked for in the login method):

This dialog will be shown only when you ask for more permissions than they’ve approved before. For example if you ask for email and user info now, but later expand that to looking at their pictures, this dialog will show asking approval again. In this way you can expand the permissions as a user uses your site without scaring them off with lots of permissions later.
The login function’s first parameter is a callback function that supplies a response of the login. If the response is true, login was successful…otherwise it fails. If you look back at my login callback you’ll see I am calling a method called showCurrentUser that I created. This is where we can actually use the Facebook SDK to get some data.
Using the SDK
You’re logged in, so now you may want to get information from Facebook. The Facebook SDK supports a method called api that is used to get objects from the Facebook Social Graph. For this simple example, we’ll just get the users’ object so we can get their full name. The Facebook SDK has a special object identifier called “me” that represents the logged in user. SO we can just use the “me” URI to get the user object:
// mwd.js
(function (m, $) {
m.showCurrentUser = function () {
FB.api("me", function (result) {
if (result.error) {
alert("Failed to read 'me' from facebook");
} else {
alert(result.name);
}
});
};
} (window.mwd = window.mwd || {}, jQuery));
The FB.api call requests information from the social graph and returns an object. In this case I am just testing the result.error to see if it worked. If it did, I am just showing the name of the user. You can request more objects using a social graph ID. For example if you had permission to the users pictures you could request FB.api(“me/albums”, ...) and it would return a list of the albums for the users. From which you could request the pictures in each album. I find the API very simple to use (once you have all the basics setup).
You can get a copy of the code with my sample facebook application (though you won’t be able to login into the test project as I won’t make it public). You can change it to your own Facebook Application API in the web.config file and go to town!
ModernWebDev_8.zip
Questions?