nik

Last month, a few days before my birthday, I decided that I needed to acquire some new skills and do some new things, while broadening my knowledge of things I already know (i.e. software development). More importantly, I wanted to not spend as much time in front of the computer. Instead of posting about it and then hoping to follow through, I decided to do the opposite. I started the process and am now happy to report that I have made good progress in five areas:

1) Building Stuff: I love working with tools and making things. My first project was to build a swing set for my daughters. I got lumber from Lowe’s and built one from scratch. My kids love it and it’s great not having to drive down to the playground every day.

My second project is to build earth boxes, five to be precise. Savi wants to grow vegetables and the earth boxes are the perfect solution. It’s labor intensive to build one, but not very difficult. I have completed one and am working on the rest.

2) Baking: I love bread but rarely find bread I like at the store. Solution — bake my own. Savi got me a bread-maker for my birthday and I love it. So far I have baked a loaf of plain, white bread and yesterday, I baked a walnut-raisin loaf. I am not much of a cook and making eggs is the extent of my culinary expertise. But after baking this bread, I am beginning to see why so many people love to cook. It is quite relaxing and to have an end product that family and friends can enjoy is quite rewarding.

3) Mixing: As I have mentioned on this blog before, I am an avid fan of A/V. Until about 2003, one of my favorite things to do was to V.J. parties and weddings for friends. I never did it for money as then it would become work and stop being fun. After moving to DC in 2003, I never did any gigs until last week. Friday (8/8/08), my friends Todd and Diana got married in Napa. My daughter Gia was the flower girl and I had the honor of providing the entertainment for the wedding. Since I did not want to abandon the wife and kids during the reception, I did something novel (for me) — I created a video mix on DVD for the entire evening’s entertainment. Everything from the bride/groom dances to the various dance sets were all on DVD and all I had to do was press Play. I used an 80′s theme and mixed lots of music videos from the decade along with an intro scene from “Back to the Future,” Todd’s favorite movie. I enjoyed making the mix so much, that I am now motivated to create more DVD mixes of my kids photos/videos for family back in India.

4) Software: This item is more about broadening my skills beyond ASP.Net and DotNetNuke. I have been an avid fan of Google AppEngine since the day it went live. Since I had no prior knowledge of Python or Django, I had to come up to speed fast. I attended a few meet-ups at Google and picked-up a copy of Python Power. Between the book and the meet-ups and just tinkering with code, I now have progressed far enough to create fairly advanced apps on AppEngine in Python. I plan on continuing to learn more advanced concepts and focus on developing a single application that will also be the basis of my AppEngine presentation at the DotNetNuke OpenForce / SDN Conference in Amsterdam this October. More about this application in a future post.

5) Teaching: I love to teach kids. It doesn’t matter what the subject matter is, it’s just fun to be able to share and help them learn. This summer, I have undertaken to teach my 12-year-old nephew how to program, continuing indefinitely. After researching the topic, I settled on Phrogram as the language to use for instruction. So far, I am quite impressed with everything about the IDE and the language. I setup a virtual machine, put it on a DVD and mailed it to him (he is not allowed to use the Internet other than for class assignments). He was able to install VPC, get the virtual machine up and running and write his first Phrogram. I will have some detailed blog posts about my experience on this in the near future also.

Yes, it’s true that three of the five things require time in front of the computer. But they still represent a shift and have helped me achieve my goals.

 

At the height of the dot-com boom, I founded a venture-funded startup
called iWidgets.com. My vision was to have mini-apps called “widgets”
that you could plug into web portals that were all the rage at the
time. Unfortunately, the market was not ready for widgets back in 1999,
and when the stock market took a dive a couple of years later, so did my
company.

Fast-forward to present day and there is a new iWidgets.com site created by someone else. Here’s how eHub describes it:

Create custom widgets for your website or your brand with iWidget.
Using their online wizard, you can easily create widgets that your
website visitors or customers can add to their iGoogle start page,
Facebook profile, or their own blog. Your widget is customizable by
your users so that it fits right in with their design.


It
felt very strange seeing the site…sort of like seeing someone else
wearing your favorite shirt. I spent some time on the site playing with
their tools and was very, very impressed. Great job iWidgets.com team,
wish you much success.

On the LinkedInBloggers group, there is an interesting discussion on how to prevent blog harvesting. Turning off RSS feeds and subscription feeds seemed to be the suggested solution. I think this is an impractical solution and makes your blog harder to find and harder to consume with RSS readers.

I wonder if disabling RSS/subscription widgets is the only way? What if there was a simple way to ensure that your content only displays in a browser if it is being served from your site and when displayed on a harvester’s site, it simply redirects the browser back to your site?

I came up with a solution that might work. My solution is based on two assumptions:

1) RSS readers ignore Javascript

2) Most blog engines have a templating feature that allow the URL of the blog post to be injected anywhere on the page containing the post

The solution is pretty simple:

Embed a simple script in your blog post that checks to see if the location where your blog content is being displayed is valid (i.e. your blog) or invalid (i.e. harvester site). If it is invalid, then redirect the browser to your blog.

Not only does this approach thwart harvesters (at least until they filter out the script), but it has the added benefit of getting the search traffic from the harvester’s site back to your blog.

Let’s walk through the changes you would make to your blog’s template in order to enable this capability:

Original blog HTML:

This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog.

Steps for modifying blog HTML:

Step 1: Add DIV element wrapper for content

<div id="BlogContent" title="http://www.yourblogsite.com/URL-of-your-blog-post.htm">This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog.</div>

I used an id of “BlogContent” but you can use anything you want. If your blog displays the entire contents of more than blog post on a page, you will want this entry to be changed for each blog. In that case, try using “BlogContent{{ ID }}” where {{ ID }} is your blog engine’s token for some unique identifier associated with your blog. If you take this approach, be sure to modify the “BlogContent” string in Step 2 also.

Also, note the URL in the value of the “title” attribute of the

containing the blog content. You should not actually type in a URL there, but instead use the token feature of your blog engine that will inject the URL of the blog post page. Something like:

<div id="BlogContent" title="{{ PostURL }}">

({{ ID }} and {{PostURL}} are not an actual tokens…I just made them up. You will need to look at your blog engine’s documentation to figure out the tokens you should use.)

This URL serves two purposes:
- It provides a standards-compliant way to include the original URL of your blog in the blog content so that no matter where the content is posted, the original URL is always in the HTML source code, and
- It provides the script in Step 2 to have a known place to find the original URL

Step 2: Embed script to foil harvesters

The script to embed is:

<script type="text/javascript">// <![CDATA[

var blogContent = document.getElementById("BlogContent");
if (location.href.toLowerCase().indexOf(blogContent.title.toLowerCase()) != 0) location.href = blogContent.title;
// ]]></script>

Here’s what the script is doing:

a) Find the HTML element containing the blog content

var blogContent = document.getElementById("BlogContent");

b) Test if the content is running on the original site, if not, then redirect to the original site

if (location.href.toLowerCase().indexOf(blogContent.title.toLowerCase()) != 0) location.href = blogContent.title;

Here’s what the final content might look like:

<div id="BlogContent" title="{{PostURL}}">This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog.
<script type="text/javascript">// <![CDATA[

var blogContent = document.getElementById("BlogContent");
if (location.href.toLowerCase().indexOf(blogContent.title.toLowerCase()) != 0) location.href = blogContent.title;
// ]]></script>

Step 3: (Optional) Putting the script in a separate file

Instead of placing the script in each blog post as described above, you can also put the script into a separate file such as harvestblock.js. This will reduce the page size as the entire script will not be repeated for each blog post. You only need to include this part of the script in the file

var blogContent = document.getElementById("BlogContent");
if (location.href.toLowerCase().indexOf(blogContent.title.toLowerCase()) != 0) location.href = blogContent.title;

If you do this, the revised content might look like:

<div id="BlogContent" title="{{PostURL}}">This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog. This is the content of my blog.
<script src="http://www.yourblog.com/harvestblock.js" type="text/javascript"></script></div>

Note: The URL used for the script must be a fully-qualified URL because it must work no matter whether the content is running on your site or on the harvester’s site.


Let’s look at what happens when you make this change:

1) User looking at content on your site

The script will detect a match between the URL being displayed in the browser and the URL of the blog post. As a result, it will do nothing and there will be no change in behavior from what your users are already seeing.

2) User looking at content in their RSS reader

The script will not run and as a result there will be no change in behavior from what your users are already seeing.

3) User looking at content on harvester site

The script will detect a mis-match between the URL being displayed in the browser and the URL of the blog post. As a result, it will redirect the user to the original blog post.

This solution is not fool-proof. If a harvester is stripping script embedded in a blog post then it will not work. I highly doubt this will happen very often because most harvested content is simply the content from the RSS feed as-is.

If you employ this solution please provide information on the specific token you use with your blogging engine in the comments.

I have been learning how to create apps for Google AppEngine, relying mostly on videos. I figured other people might be interested in the same thing so I setup a Ning site that aggregates AppEngine videos.

Here it is: http://www.AppEngine.tv

Enjoy.

As I go through the process of getting familiar with Google AppEngine, I’ll post interesting things I learn (mostly so I can find them later). Here’s a quick note on GQL query syntax:

Assuming a model called Customer, you can use:

1) customers = db.GqlQuery(“SELECT * FROM Customer ORDER BY name LIMIT 10″)

2) And since GQL queries always return data objects, you can skip the SELECT * and abbreviate to:

customers = Customer.gql(“ORDER BY name LIMIT 10″)

3) You can also use parameters like this:

customers = Customer.gql(“WHERE name = :1 ORDER BY name LIMIT 10″, “Smith”)

4) And finally, #3 with named parameters like this:

customers = Customer.gql(“WHERE name= :person ORDER BY name LIMIT 10″, person=”Smith”)

© 2012 TechBubble Suffusion theme by Sayontan Sinha