Hi I'm Jon Kragh you can learn more about me here.

The Poor Man Buys Twice – Why More Expensive is Oftentimes Cheaper

One of my old co-workers Val had a great Russian saying that was translated as: “the poor man buys twice”.  It means that when you buy something cheap, it will not last as long as the more expensive option and often times costs you more in the long run (since you have to buy it twice).  We live in a society where so many things are now throw-away items.  I am finding more often than not that cheaper options are generally more expensive in the long run for all kinds of things.

Here is an example of this old saying proving true for me this weekend.  Below is a photo that shows my rusty old shower caddy $19.99 and my new simplehuman shower caddy $103.99 after coupon.

shower 

This is the third time that I replaced my old shower caddy in three years.  Each one really should have been replaced after 6 months because they rusted that fast!  Now, if you look at just the prices, an argument could be made that the cheaper shower caddy is still cheaper pricewise even after replacing it. But, that does not take into account the cost of my time.  As a successful computer consultant the extra 2.5 hours of my time to take this stupid shower caddy project on each time that it rusts, far outweighs the dollar value of the more expensive caddy that I put in.

It also does not take into account that the more expensive product has a better design.  It has easily adjustable shelves, better spring mounting for positioning the caddy and looks so much better.  Not to mention the intangible of “wow I have a nice shower” every time that I take a shower.

Not only did the old shower caddy look bad after a few months from rust, it also had me pay a “death tax” for its inevitable rusting together.  That is, it was rusted together which made getting this long thing almost impossible to remove from my shower!  Here is a video of the trouble that I had just taking the old shower caddy out.

Get the Flash Player to see this player.

Now here is the new shower caddy.

Get the Flash Player to see this player.

In this situation the “more expensive” shower caddy is actually cheaper for me when weighing eventual cost ($19.99 * N Years vs $103.99 * 1), cost of my time, and quality of life.  In software development this topic often comes up with consulting and/or the price of an employee.  It is hard to generalize every situation of value because I have seen cheap and expensive consultants produce equally bad results. So I will not say that more expensive equals better.

I will however say that this shower caddy situation resembles certain hiring decisions I have seen organizations face.  Since I am a consultant I have had an opportunity to see how different organizations approach hiring.  From my experience, the organizations who value the best talent and are willing to pay for it, end up spending less and getting further ahead in the long run.  The key is finding and keeping the talent that is actually worth the extra upfront investment.

Rendering an ASP.net UserControl to a String

I have been converting one of my side projects from ASP.Net WebForms to ASP.Net MVC.  In order to reuse some of my existing ASP.net UserControls from WebForms in ASP.Net MVC, I tweaked a rending method found here and here.

I improved on these methods by enabling the caller of the utility function to be the one to set properties on the UserControl in a strongly typed fashion. The is no reflection or any other special interface needed on the user control.  The key was adding a callback.

Here is what it looks like to call and render the control to a string by the caller.  In this example I am rendering my GoogleMap UserControl to a string.  The last argument I am passing is an anonymous method that is called by the utility function to initialize my control.

UIUtil.RenderUserControl<GoogleMap>("~/UserControls/GoogleMap.ascx",
    uc =>
    {
        uc.CollegeToShow = CollegeToShow;
        uc.Height = Height;
        uc.Width = Width;
        uc.Mode = Mode;
    });

The helper method is as follows:

public delegate void InitializeControlDelegate<T>(T ControlToUse);

public static string RenderUserControl<T>(string ControlPath, InitializeControlDelegate<T> InitControlCallback) where T : UserControl
{
    System.Web.UI.Page pageHolder = new Page();
    T ControlToRender = (T)pageHolder.LoadControl(ControlPath);
    pageHolder.Controls.Add(ControlToRender);
    InitControlCallback.Invoke(ControlToRender);
    StringWriter result = new StringWriter();
    System.Web.HttpContext.Current.Server.Execute(pageHolder, result, false);
    return result.ToString();
}

This method uses a similar technique as to the methods linked above, but it has a callback which calls back the anonymous method that I declared in the caller.  The callback method passes back a strongly typed UserControl as the argument that we can use to set properties on the initialized UserControl.

That is all you need to make it all work.  To make things a little nicer for myself I added “RenderToString” methods on my UserControls.  If you can’t update the UserControls themselves you can just stick code like this in a helper library.

public partial class GoogleMap : System.Web.UI.UserControl
{
    public static string RenderToString(Item ItemToShow, string Height, string Width, Constants.MapMode Mode)
    {
        return UIUtil.RenderUserControl<GoogleMap>("~/UserControls/GoogleMap.ascx",
            uc =>
            {
                uc.ItemToShow = ItemToShow;
                uc.Height = Height;
                uc.Width = Width;
                uc.Mode = Mode;
            });
    }
}

Now from within my Asp.Net MVC page (or any place else), I can render my ASP.net WebForms UserControl Google Map like so:

<%=GoogleMap.RenderToString(ItemToUse, "250px", "100%", Constants.MapMode.SingleItem)%> 

Cheers,

Jon

Twitter Syntax / Commands – Facebook should also support them

Something that amazes me on Twitter, is that regular humans (non-Twitter-Hashtag programmers) are fine with, even good at adding little markup tags in tweets.  So now that we have seen that the masses are cool with adding little tags and markup to freeform content, we should embrace it!

Since Facebook is the leading social network, they should also support a markup syntax in comments & status updates because it is useful for humans and computer programs.

It would be in Facebook’s best interest to improve the human user-Humansexperience and also in their interest to add semantics to status updates and comments so that they are more useful for Computer Programs. Facebook is trying to push what they call “Platform” which is a way to write computer programs that integrate with Facebook.

Here are a few of examples of how Twitter markup syntax is beneficial for humans and computer programs. Maybe with enough retweets of this article, it could actually happen :)

Twitter Replies and Mentions

Twitter supports the ability to reply and or mention another user and link to that user. From the Twitter getting started guide:

Any tweet beginning with @username is considered a reply.  We call tweets with @username elsewhere in the update mentions.

Example Twitter Mention

User benefits

  • Get mentioned and new people notice you
  • Notice people that other people are mentioning

Computer program benefits

  • Indicates some kind of relationship between users – Example algorithm: mentions between two users may mean that those two users are interested in each other

Twitter Hashtags

Twitter supports the ability to group tweets. From the Twitter getting started guide.

Because Twitter provided no easy way to group tweets or add extra data, the Twitter community came up with their own way: hashtags.  A hashtag is similar to other web tags- it helps add tweets to a category.  Hashtags have the ‘hash’ or ‘pound’ symbol (#) preceding the tag, like so: #traffic, #followfriday, #hashtag.  Hashtags can occur anywhere in the tweet: some people just add a # before a word they’re using, like so:

Hashtags are huge and they have so much potential that it is far too much to fathom, but I’ll take a stab:

User benefits

  • Easy way to tag / tie your post to a topic for others to find
  • Easy way to search on a topic
  • Real-time trends

Computer program benefits

  • Provides additional meaning to posts
  • Almost limitless possibilities

I could go on with more specific examples, but it boils down to this.  Markup in free-form content:

  • Makes new tools possible for users
  • Provides semantics for computer programs

At the end of the day, I really don’t Computercare if Facebook adds markup extensions.  However, I do think it would be good for the web, so that user-generated content has more meaning.  I would also push that if Facebook does implement some kind of markup, that they use the same popular markup that already exists on Twitter.  Standards are the backbone of the web.

Cheers,

Jon

How to get Google to index only part of a Webpage

As of today, there is no way to explicitly have Google index only certain parts of a single Webpage.  I am writing this post in order to show my need for partial page indexing support and to discuss a few possible solutions for this today.  iStock_000005882596XSmallMy need for this stems from the Personalization of WebPages, a feature that makes the web better for people.  I hope that this post can create discussion between us and maybe someone from Google will be kind enough chime in and provide us with guidelines on how to design websites where we want Google to ignore parts of a WebPage in their index.

The premise of my need is that I have WebPages that have content for everyone, and content customized for the specific user viewing the webpage.  I lump this user specific content under the term “Personalization”.

  image

Personalization is a powerful mechanism for making the Web more useful for people.  Most of us are familiar with the personalization on Amazon.com where they target items to you based on your viewing and buying habits.

On www.VastRank.com (a College Review Website site that I created) when a user is viewing a College Profile page, they are also shown partial college reviews for other colleges that they may be interested in.  I go deep into the personalization implementation in my Google I/O presentation Using AJAX APIs to Navigate User-Generated Content.  Here is a slide from that deck that illustrates the “personalized” suggestions that are shown to users on the right hand side of college profile pages. 

image

The main issue here is that Googlebot is now going to see partial user reviews for other colleges on different college profile pages. This causes two major issues:

  • Duplicate content problems
  • Text from other college reviews show up in the search results for Other College Profile pages in the Google.com Search

Should Google support robots-nocontent?

One implementation that would solve my problem would be if Google implemented Yahoo’s robots-nocontent tag.  I recently tweeted back and forth on this topic with Google’s Matt Cutts on Twitter:

Jon Kragh

“Google (@mattcutts) please support Robots-Nocontent – I have partial content tailored for each specific user, that should not be indexed”

Matt Cutts

mattcutts@jonkragh we looked at how many sites use robots nocontent on the web and it was miniscule, so we decided not to do it.

Jon Kragh

@mattcutts if Google blessed Robots-Nocontent more people would use it-should personalized content (i.e. suggestions) be loaded via AJAX?

So at this point, it looks like robots-nocontent is not one of Google’s top priorities.

robots-nocontent is not right either

Initially I looked at robots-nocontent because it was the closest thing I could find for a partial content indexing solution.  However, robots-nocontent is so general, that it might not be the best long-term solution for the web.  Looking back at what I have conceptually, I have content for everyone, and content for a particular user.

image

A better solution than robots-nocontent would be to create a new tag for this scenario that has more meaning.

robots-user-specific-content

I suggest a new tag that can denotes content that will be different for each user that visits the website: robots-user-specific-content.  For the time being Google could ignore that content, much like an implementation of robots-nocontent would work.  However, having this extra meaning would allow for possible extensions to Google in the future, where a user could search with their identity and get results back from websites with content personalized for that user. 

What can I do now?

For now I am stuck!  I am considering loading personalized content through AJAX to avoid having it indexed.  However, this would be a guess on my part on Google’s indexing algorithm.  Will Google index AJAX content?  Will it penalize me because I’m loading different content in a section of a page via AJAX each time Googlebot visits my site?  This is where I would like your feedback, and hopefully some guidance from Google!

Cheers,

Jon

Setting up a Headless iTunes Server

In my home office, I have a headless server running Windows

IMG_4650

Server 2008 with iTunes 8 installed.  This machine is where I store all of my music, photos, videos, and other entertainment related files.  The interesting thing is that I also use this server to wirelessly broadcast my iTunes music digitally to my kick-ass home studio setup (a Benchmark DAC1, Coleman Audio M3, Quested Powered F11As, and a REL Subwoofer). The setup that I am about to describe should work equally as well for those of you who have any kind of audio playback equipment that has an optical audio input. 

The setup is simple.  I bought a Shuttle XPC SD30G2B and a IMG_4638RocketRaid 1740 card off of NewEgg.com.  Here is the machine stashed away behind some of my other gear.  The server has no monitor attached and I use Remote Desktop to connect to it.  The other key component is the Apple Airport Express which has a digital audio out.

Look ma, no monitor!

Applew Airport Express

 

 

 

 

 

When I launch iTunes, it get the following error message, since the onboard audio card is not configured properly (I believe that is because I do not have anything hooked up to the onboard audio card).  This message can be ignored.

itunes-error

After iTunes launches you can choose the Airport Express from the dropdown list on the bottom of iTunes.  You only have to do this once, if your Airport Express is always plugged in.

itunes-select speaker

Here is the Benchmark DAC1 (on the bottom of the rack) set to its optical input with it’s blue status light lit up.  The blue status light will light up on the Benchmark DAC1 as long as something is playing from iTunes. 

IMG_4645 2

This area also doubles as my home office, where I work as an independent Software Development Consultant.  I get to listen to music on a kick-ass system while coding!

The setup is also very reliable, Windows Server 2008 is rock solid and so is the Airport Express.  One last note: Originally I had setup Windows Home Server but it has file corruption issues, so I highly recommend staying away from WHS.

EDIT: 7/24/2009 – This does not work when you try to use the physical soundcard connected to the server.

I just tried switching from using AirTunes to a physical sound card on the Server and it does not work when using via RDP (Remote Desktop).  When I RDP into the server and click on Control Panel –> Sound, I see a message: “No audio devices are installed”.  If I log on locally at the physical computer, I can see all of the devices fine.

No-audio-devices-are-installed

It turns out that this is “by design” and choosing “Leave at Remote Computer” in Remote Desktop is ignored by Windows Server 2008 x64".  Here is a link to the KB article and a thread on the TechNet forums describing this.

So, at least for the time being, I can still play iTunes from the server to AirTunes, even when logged into the server via Remote Desktop.

Cheers,
Jon

My Journey to Google

copybeanbagRecently, I had the great honor of being asked by Google to present at Google I/O 2009.  Here is the story of my journey including: how to get noticed by Google, getting invited to present at Google I/O, practicing the presentation with my Google contact, the hours leading up to the presentation, the presentation itself, and the after party!  I have included some behind the scenes photos and videos as well.

How did I get noticed by Google?

Google_Map_Marker_Google_IO_2009 Recently, I saw a beer commercial that said “Rule #1 of how to get the girl: be good looking!”.  So here is my rule of how to get noticed by Google “Rule #1 of how to get noticed by Google: use the Google APIs in some kick-ass way!”.  Google is building a developer platform and they want to show off developers utilizing said platform. So if you do something cool with the Google APIs, it is easier to get noticed than you may think.

How did I get asked to present at Google I/O?

Google_IO_2009_RegistrationMy main “in” at Google was that anytime that I did something rather cool with the Google APIs, I pinged the Google Employee Developer I met in the Google Developer Newsgroups.  I did not expect anything in return from him. I thought “hey I just implemented something really cool and they might be interested”. It turns out that they were indeed interested and extremely friendly.  Every time that I implemented something substantially new and cool, we would have an open dialog about what would make my application better and they would say things such as “hey did you know we have the Client Location API, this would be really cool for your site…”.  It turns out that I must have pinged my Google contact at the exact right time (with information about major updates to my site).  I had just completed some advanced Google Maps coding and once they saw it, they officially invited me to Google IO to be in the Developer Sandbox and to present a session.

Preparing my presentation

Google_IO_2009_Conference_RoomSo now there I was, Google asked me (OMG!) to come out and speak and they wanted me to send out a rough concept of what I might want to present.  Initially I proposed a session called “Building a cool app on an hour a day, a rebel’s view of the world”.  That presentation would have been all about the mindset that I had and steps I took to successfully building www.VastRank.com in my spare time.   Google liked that presentation, but they wanted it to be more focused on the APIs since that is what a lot of visitors to Google I/O would be looking for.

So I changed my presentation to “Using AJAX APIs to Navigate User-Generated Content”.  The presentation was about how do you take all of this information that users have submitted and sort and present it to other users in an interesting and useful  way.  The title of the session was play on a Don Box title “Navigating the Programmable Web”.

Rehearsing with the Google AJAX API Team

Once I had my presentation prepared, I rehearsed it over two video conferences with Adam Feldman, the Google AJAX APIs Product Manager.  Adam was extremely smart, and had a way to hear what I was saying and then summarize some things into a much more compelling concise point.

I arrived to the conference a day early, where I was able to do my presentation in the actual conference room to a group of Googlers.  I  am so glad that I had that opportunity, because I rushed through my first live run and was 15 minutes short of the target time. I needed to slow down the next day!

The Session: Using AJAX APIs to Navigate User-Generated Content

Here is a link to the full to the official Google I/O Session page which has the video and slides.

 

  • 00:24 – Who am I?
  • 01:26 – Introduction to VastRank.com
  • 02:56 – Overview of the Google AJAX APIs Used
  • 07:15 – Using Google Maps on the College Profile

  • 11:41 – VastRank.com Client Architecture
  • 12:39 – Setting the Map Center
  • 14:07 – Loading Map Markers via AJAX
  • 15:07 – Algorithm for What is in View on a Map
  • 28:25 – Map InfoWindows
  • 30:38 – Geocoding via AJAX and HTTP
  • 34:45 – Personalization & Suggestion Engine (ClientLocation)
  • 39:28 – Translation / Languages API
  • 45:01 – Questions

The After Party

Google I/O 2009 was a two day event.  I presented on day one and at the end of day one Google through a massive after party.  Here I took a quick video near the end of the evening.

Cheers,
Jon

Jon Kragh Video Interview – at Google I/O Speaking About Vast Rank and the Google APIs

Jon_Kragh_Developer_Sandbox_Google_IO

Recently I was invited by Google to attend Google I/O 2009.  Google invited me to show off Vast Rank in the Developer Sandbox, and also present a session to attendees: Using AJAX APIs to Navigate User-Generated Content.

Soon, Google will be posting my session on YouTube.  I am anxiously waiting for that! In the meantime, here is a very quick impromptu interview of me speaking about Vast Rank and my use of the Google APIs.  The interviewers provided me with the questions ahead of time, but I did not have enough  time to read them since I was so focused on preparing for my session.  So here I am shooting from the hip, answering questions about the Google APIs.

Vast Rank – Google SERP Drop and Return

Back in October I saw a large drop in Vast Rank’s Google SERP.  In other words, when people searched for certain terms where a Vast Rank page (normally a college profile) would appear on the first Google search result page for a few weeks, these same searches yielded the same Vast Rank college profile page to show up many pages into the Google search results.iStock_000006548118XSmall

At the time I was worried because I was unsure of what would happen next.  This was the first time I really cared about SEO.  When I worked at barnesandnoble.com, people would just show up and pump millions of dollars of products through my code a day.  It was magic, and I thought, dam I am good!  Well, the reality is they have a brand, and I do not!

If your site does not appear in Google Search results, it is pretty much skull_and_crossbones_classicdeath to your site if you depend on organic trafficGoogle matters much less if you have a website that people have to use for their school, job, bank account or whatever.  But when you depend on organic traffic, you rely on Google.

If your site drops in SERP, the Google webmaster tools do not tell you in general about any penalties on your site.  I imagine that this is so that crafty little SEO experts can not reverse engineer some of Google’s algorithms.  So during these times of doom and gloom for your site, you are pretty much left to looking at SEO discussion sites and the Google Webmaster Help discussion group.

Luckily, Vast Rank returned to Google’s searchiStock_000003644147XSmall results after a huge drop from October 26th, 2008 – November 5th, 2008.  I am posting this to show other webmasters that there is hope if your new site suddenly disappears from Google search results.   So take a deep breath, the world is not ending, and wait it out! I’m serious,  take a deep breathe, and count 1000-1, 1000-2, 1000-3. Now Exhale.  Calm yet?  If not, go here, or keep reading, I have proof that there is hope.

Below is a screen screen shot from Vast Rank’s Google Analytics page.  The screen shot shows traffic from launch day until today (notice the huge drop in traffic in October-November).

image

I updated quite a few things on Vast Rank during the downtime period: accurate sitemap last mod dates, unique title tags, better meta descriptions, etc.  Some of these items were called out in the Google Webmaster Tools for Vast Rank, and other items were just common sense items that I needed to get to implementing (i.e. accurate last mod dates in the xml sitemap).  However, I think the biggest reason I saw the huge drop was that Vast Rank was so new. 

If you are a webmaster experiencing SERP drops, it would be great for you to post a comment so we can collectively share our experiences!

iPhone Development, a bad use of time for a .NET Developer?

OK, so even though I’m a “.NET Developer”, I’m really not just a “.NET Developer”, but at this point it is the technology stack that pays the bills around here, so lets just keep it at that for the sake of this post.

Recently I bought a refurbished MacBook Pro, that had all of the MBPRO15OLD_AV1upgrades for the Feb 2008 Rev. (7200 RPM Drive, 2.6 Ghz Intel Peryn Dual Core, 6MB L2 Cache, 512 MB Video RAM, etc).  My main use for this machine currently is for all of my personal software including Cubase SX 4.5 (an audio sequencer), loads of VST plugins, samples, pictures, videos, etc.  In addition to running those apps, I can now run the iPhone SDK.

I have quite a few software product ideas right now, and some of them are iPhone apps, some of them are web based, and some are some cross platform desktop app ideas. 

So without thinking logically about any of this, I started digging through the iPhone SDK and Developer Videos.  I gave myself all kinds of reasons that this would be an ok use of my time, like “hey learning other languages makes you a better developer”, “hey seeing other architectures is good too”, “oh, I consider myself a software designer because I create applications that are well designed that people want to use so maybe I should learn more about Apple”, “ “this iPhone market doesn’t really seem too saturated, and I bet I could compete with a lot of leading apps”, on, and on, and on.

Then reality kicked in and I said to myself, WTF am I doing here?  I’m going to spend my time managing memory in Objective C? I’m going to create an app that sells for a couple bucks and then hope that it sells how many apps to be somewhat profitable? Hmm, umm, and what can I use this Objective C experience for the next time I’m deep in ASP.net, WPF, javascript or CSS?

So I went from one extreme to the other and now I’m kind of sitting in this nice little pocket of gray where there is no clear answer.  I figure I’m just going to finish up some web oriented features that I want to get out onto Vast Rank (internationalization is coming!), and kind of poke around with Cocoa, UIKit, Objective-C, and XTools for fun on the side.  After I play around with the SDK for a little bit, I can see if I want to commit to taking on some of the iPhone app ideas I have.

Are you a .NET or Java developer considering developing an iPhone app?  Do you think it is a good use of your time, if your app does not take off?  I’m still on the fence right now.

Extending Community Server User Profiles in Vast Rank

I built Vast Rank integrating a lot of different pieces of technology, ASP.Net, ASP.NET AJAX, Google Maps API,  Google Ajax Search API,  Google Custom Search, CSS, and the list goes on and on.

I have been a Microsoft oriented developer all of my life so when I built Vast Rank, I wanted to find a decent profile system and forum system  based on .NET that I could build on top of.  Community Server was by far the best platform to use when I started developing Vast Rank in 2007.

One of the challenges that I faced was that I wanted to extend the Community Server User Profiles in such a way that those profiles can be queried based on the extended properties.  Before you follow this post any further, if you are considering going down path, ask yourself “do I really need to query these extended attributes?”, because it gets complicated.  If you don’t need to query this extended user profile data, but just store and display it, then I suggest using the out of the box ExtendedAttirute storage mechanism that comes with CS. It is a heck of a lot less work.

Anyway, I spent the time extending user profiles and detailed it in an old post here. In that post I went through changing the source code in the CS SDK, but here I will post a few blurbs from the CS forums that I posted about how to extend CS User profiles without changing any CS SDK source code.  I originally did these modifications in CS 2007, then I rolled them into CS 2008.5 in one day.  (Some of the CS code changed a little but it was easy to fix up my extensions to align with these changes).  So the big payoff of using this new strategy: ease of upgrade to new versions of CS.

The basic “A Ha” moment for this new extension strategy was, hey doesn’t CS use the provider model?  Maybe I can hook in at that level to override and extend the CRUD and search operations.  Well that worked. 

I am posting some CS specific source code directly from Vast Rank here:

Download

Since so many people were interested in more details around this new strategy, I slotted an hour out of the many other dev things I’m working on to put this up for my friends over in CS land. I figured it was better to get something into your hands than nothing at all…

So… the code posted does not compile because it depends on Community Server (which you can download from them) and my own Service / Data Access Layer (which I’m not posting:) ).  But, if you are pretty good dev you can look through the code and get some “A Ha” moments.

The code has a sample configuration where I load my overridden version of the the CommonDataProvider.  That file in my project is called “VRSqlCommonDataProvider” and it shows how I extended the CRUD and search code.  I also included a few of my theme files where you can see where I integrate the extended data (creating, editing, viewing, and searching profiles).  There are also some sub forms and helpers in there.  You’re just going to have to dig through…

Here are a couple of links to my “A HA” moments from the CS forums. You can test these things live at http://www.vastrank.com

Please chime in on this post if this helps ya, or if you have any feedback.  As I said it’s a little sloppy but I wanted to get something into my friends hands over on the CS forums.