Windows 8 DP with Boot Camp 4.0

Today I downloaded the Apple Boot Camp 4.0 using the BootCamp Assistant in OSX Lion with the intention of installing it on my Windows 8 Developer Preview.  After burning it to CD and re-booting in Windows 8, I discovered that Boot Camp 4.0 only supports Windows 7, and promptly refused to install under Windows 8.

After searching the 'net for a solution to no avail (the best advice on offer was to go into the Drivers directory and install each one individually), I tried something radical.  I turned on the Compatibility settings for the actual BootCamp64.MSI. Lo and behold, it worked! Boot Camp proceeded to install itself and the relevant drivers without a hitch.

So here's the process:

  1. Navigate to the folder containing the BootCamp MSI files
  2. Right-click on the relevant BootCamp[64].msi file for your system (i.e., if you are running 32-bit Windows, select the BootCamp.msi file)
  3. Open up the Properties dialog and go to the Compatibility tab.
  4. Turn Compatibility Mode on (select "Run this program in compatility mode for:") and choose "Previous version of Windows" in the drop down (actually, it's probably the only choice available to you).
  5. Click OK, and go run the installer again.
  6. Restart your computer, and enjoy.

That's about it.

 

Introducing the Umbraco View Counter

Over the last couple of days we've been busy creating an Umbraco package that deals with Content View Counters - it enables the web master to track the number of times content has been viewed on the site.

The Documentation and package has just been uploaded to the Umbraco Project Repository and can be downloaded from here.  This post deals with a few of the features of the package, which was built agains Umbraco 4.7 and dotNet 4.0

Introduction

TheRefactored Content Viewspackage is essentially a content views (number of times  viewed) counter.  The current functionality offered by this package includes:

  • Optional Data Type that allows for configuring view counters with various categories and the ability to instruct Macros etc. to "hide" the view Count yet still increment it.
  • Optional incrementing when displaying the view count (useful when you want to display the view count in a content listing, for example)
  • Example Razor Script and Macro.
  • Library methods to manipulate the counters and retrieve details as an XML fragment for use with XSLT.

Basic Usage.

To simply retrieve and/or increment the counter for a specific content item, call the following library method.  The category and increment parameters are optional, with default values shown initalics:

ViewCount.GetViewCount(nodeId, category: "<empty string>", increment: false);

There is no requirement to configure a DataType; supplying the node id of any valid Content-based node (Member, Document, Media, etc.) will create the Views record in the database if it doesn't exist.  However configuring and using a DataType will allow you to control the advanced features of the counter.

Out of the box

Out of the box you get a default DataType (View Count) and a sample Razor Macro that displays the current View Count of the node being displayed.  If you have set up the Document Type with the View Count DataType, the macro will check whether the View Count should be displayed or not.

Macro Parameters for Page Views:

  • Category (text) - optionally specifies the Category to record the Page Count against.
  • Increment (bool) - set to true to increment the Page Count when the macro is called.

Macro Script Contents:

@inherits umbraco.MacroEngines.DynamicNodeContext
@using umbraco.MacroEngines;
@using umbraco.NodeFactory;
@using Refactored.UmbracoViewCounter;

@if (!ViewCount.HideCounter(Model.Id, category: Parameter.Category)) {
  <span># Views:@ViewCount.GetViewCount(@Model.Id, category: @Parameter.Category, increment: @Parameter.Increment == "1").ToString("N0")</span>
} else {
  ViewCount.Increment(Model.Id, category: Parameter.Category);
}

 Setting up a Data Type

The Data Type has the following Parameters:

View Count DataType

  • Category- Specifyinga different category for multiple DataTypes allows you to differentiate between multiple View Counts in a single content item.  You can then render the content in different views and have a different View Count for each rendering.
  • Hide View Count- Allows you to control (in conjunction with the API and Razor or XSLT macros, for example) whether to hide or show the view count at a Data Type level.
  • Enable View History- Turns on recording of View Count History data including the time the view was incremented.  Also recorded is Reset command events.  This data is stored in the refViewCountHistory table and persists even if the current view count is reset.  This is off by default.
  • Disable Counter Reset- Turning this on disables the Reset action on Content configured with a View Count DataType.

The Playground - interactive Canvas goodness

We've just created a Playground for testing out Javascript and the Canvas tag with Raphaël and EaselJS... At the moment, we're still loading example code to use with the playground, however there is also a default "blank" sandbox that you can use to test your own code in provided as well.

The feature set will grow over time, including contributing your own examples; however for now feel free to have a play and leave a comment here with any suggestions for features or code samples you may like to share.

Enjoy!

High School Students and the Internet - not just consumers

Yesterday I met with the local High School to discuss the possibilities of getting involved by running programs for interested students in the areas of web and games development.  During the course of the meeting, I was asked to come up with a few paragraphs that the staff could use when promoting these programs, so I thought I'd put it up here (partly to help consolidate my thoughts into a hopefully cohesive introduction rather than just rambling on...).  So here goes.  Any constructive comments or suggestions are entirely welcome, so please don't be shy - jump right in to the conversation!

First a little background.  The school, Lara Secondary College in Victoria, Australia is really what you would call a regional school - Lara is situated outside of the nearest large city (Geelong) and is considered to be "The country between the cities" to quote one local resident.  While Lara is by no means a small country town and is rapidly growing, it still retains that small town community atmosphere.  The school itself has a Connections program for Year 9 Students running for a good part of the year one day a week, in which students are encouraged to take on projects that directly benefit the community in some way.

My original vision for setting up a what might look like a club within the school was to teach students some of the more cutting edge web technologies focussing on two areas:

  1. Web page layout and design utilising HTML5 and CSS3, and
  2. Online Games development utilising open source javascript frameworks and tools.

We would do this by coming up with a project that would benefit the community in some way - perhaps by re-desiging one of the local not-for-profit community organisations, or by designing a game with an educational focus to be used by the wider school community (and even by other schools)

So this is what I have come up with to introduce students to the idea and to generate some interest:

. o o o 0 0 O 0 0 o o o .

Online Computing these days is pervasive in all areas of our daily lives - whether it be reading emails or chatting on Facebook, or perhaps playing your favourite game of Pac Man, the humble Web Browser is fast becoming less of an application in its own right and taking a seat in the background while it acts as simply a host to highly interactive and expressive web-based applications.  These days you can play games and watch movies; connect with people from across the globe; or just write that business document - all from within one of the popular Web Browsers without having to install a thing.

Today we have tools freely available within our grasp to not only create visually compelling web sites, but also make those websites dynamically interactive with video, sound, and animation.  There are tools and frameworks upon which games are being built, and high quality graphics can be rendered right within the browser window.  In fact, you can author a complete website  from scratch without having to open anything more than your favourite browser.

JavaScript - the programming language of the web browser - can be used to program a website to pull information and present it from sources all over the web - want your Facebook status displayed on your website? no problem.  Perhaps you have uploaded a new YouTube video and want to embed it on your site. Easy.  Or maybe you want to be able to plot geographical data and connect the dots with Google Maps.  JavaScript can be used to do all this and more.

We are looking for a group of students with an interest in computing, and who have a passion to do more than just use the web - they want to build it.  Students will gain an understanding of the building blocks of a website, and we then go beyond that to examine what it takes to create a game from scratch that can be used to deliver value to the wider community.  We will also have professionals who are experts in their field come in and hold workshops in the areas of Graphic Design and Web Development.

. o o o 0 0 O 0 0 o o o .

That's it.  If anyone has anything to add, or any other comments, suggestions or thoughts, please, drop me a line...

Blog 4 Umbraco Extensions Documentation

Finally, some 8 months after the Blog4Umbraco Extensions library became available, I decided to post it to the package repository on our.umbraco.org and create some actual documentation for it - this is the result...

This document may also be downloaded as a PDF from here.

Introduction

The Refactored Blog4Umbraco Extensions came about because the current version of Blog4Umbraco (currently 2.0.26) had some issues when it came to creating multiple blogs within a single website, and in addition under some circumstances creating a new blog entry would cause a "Yellow Screen of Death" (YSod).

In order to address these shortcomings this package was created, and later extended with other functionality.  The current functionality offered by this package includes:

  • Allowing Comments to be Disabled at the Blog Level
  • Enable setting a Blog-wide Category and having Tags bound to that Category

An additional Datatype called Blog Tags and derived from the built in Tags Datatype is also provided which is the basis upon which the Blog-wide Category is built.

For a more detailed and technical description of the package, the reader is directed to the blog entries found at /blog:

The Future

Work is currently underway to release a version 3 of Blog4Umbraco (B4U) which will address the issues discussed here and add other much needed functionality including Trackbacks and Comment Notifications.

Post-Installation Steps

After installing the package, additional steps are required in order to activate the features.  These involve modifying the Blog-related document types as follows:

Globally Disabling Comments

In order to be able to globally disable comments, edit the Blog Document Type by adding a new property based on the True/False data type as follows:

Blog DisableComments Property 

If the Disable Comments checkbox is checked on a Blog page then the Close comments field will be also become checked when it is saved.

Blog Categories

Updating the Blog Document Type

In order to facilitate Blog Categories, an additional property needs to be added to the Blog Document Type as follows:

BlogCategory 

Coupled with the change to the Blog Post Document type below, this will cause tags added to blog posts to use the category set in this property of the corresponding Blog.

Updating the Blog Post Document Type

Change the Tags property in the Blog Post Document so that it uses the "Blog Tags" type instead of the built-in "Tags" data type:

 blogPost Blog Tags

Enabling Time fields in the Blog Entry Post Date

In the original Blog4Umbraco package, there is no way to enable the Post Date to use time as well as date, which results in all posts being set as being posted at midnight. 

The updated Umlaut.Umb.Blog.dll file included in this package addresses this issue, but you still need to modify the Blog Post document type in order to take advantage of the change.  In order to do so, change the Post Date property type from "Date Picker" to "Date Picker with time":

blogPost PostDate Property 

Other Issues:

Blog for Umbraco generates the following error when attempting to create a new Blog:

Issue # 5612 - http://blog4umbraco.codeplex.com/workitem/5612

Operand type clash: int is incompatible with ntext
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: Operand type clash: int is incompatible with ntext

Workaround:

If you encounter this type of error, double-check the Author Picker and make sure that the datatype is set tointinstead ofntext.

Conditionally disabling Ajax in MVC3 Forms

While working with MVC3 and Razor views recently, we came across the need to disable the Ajax behaviour in a form when the user pressed a certain submit button.  To give you some background, we were working on a Shopping Cart whereby the user had the following possible actions:

  • Edit an item,
  • Delete an item
  • Update the quantity of an item,
  • Submit the cart to Checkout
  • Clear the cart
  • Refresh the cart.

Now, for most cases, we wanted the cart to be refreshed without the user having to see a post back, so Ajax was the best way to handle this, of course.  Although the application is based on the Umbraco CMS, we developed the e-Commerce side of things in MVC3 from scratch and integrated it with Umbraco using the excellent MVCBridge add-on.  This allowed us to take advantage of all MVC has to offer.  However, the solution that follows is not dependant on Umbraco or MVCBridge at all.

Because this is a new project and has no legacy MVC code in it, we are able to take full advantage of the new Unobtrusive Ajax style for binding Ajax to the form.  This means that under the hood we are using jquery's ajax engine only, and not the legacy Microsoft one.  Here's the basic form:

@using (Ajax.BeginForm(new AjaxOptions
{
    OnSuccess = "updateCart"
}))
{

    @Html.RenderFormToken();
<section id="shoppingCart">
    <h1>Items in your Shopping Cart</h1>
    <table cellpadding="0" cellspacing="0">
    @foreach (var item in Model.Items.Values)
    {
        // Render the items, including the Edit, Delete and Update submit buttons...
    }
    <tr>
        <td colspan="3" class="totalValue">Total Value:</td>
        <td class="totalValue">@Html.DisplayFor(model => model.TotalIncTax)
        @Html.HiddenFor(model => model.TotalItemCount)
        @Html.HiddenFor(model => model.TotalIncTax)</td>
        <td class="totalValue"></td>
    </tr>
    </table>
    <span class="submit"><input type="submit" value="Refresh Cart" name="refresh" id="refresh" />
    <input type="submit" value="Clear" name="reset" id="reset" />
    <input type="submit" value="Checkout" name="checkout" id="checkout" /></span>
</section>
}


Now, when a user presses any of the submit buttons, the form will be posted back to the server, and the new page content will be returned to the updateCart function so that we can update the user's view without having to refresh the page.

But we want the item Edit and the Checkout buttons to re-direct to a new page instead of submitting back to the shopping cart.  For that to happen, we need to do two things (let's focus on the Checkout button, which we want to re-direct to the Checkout page):

  1. In the ShoppingCartController we need to check which submit button was pressed by inspecting the form elements, and do a Resonse.Redirect() to the appropriate page if the user pressed the Checkout button, for example; and
  2. Disable the Ajax behaviour when the user presses the Checkout button.

The code to handle the second step is as follows:

   // These variables are defined here as they may be referenced in other code blocks.
   // The $().ready function is used to populate them.
    var cartSection = null;
    var eShopCartForm = null;

    $(document).ready(function () {
        cartSection = $("#shoppingCart");
        eShopCartForm = cartSection.closest("form");

        // Disable the ajax behaviour if the checkout button is pressed.  We want the form
        // to submit normally so that the page can be redirected. 
        var checkoutSubmit = cartSection.find("#checkout");

        // We supply our own handler for this button to remove the form's ajax submit handler.
        checkoutSubmit.live("click", function (evt) {
            // Setting this attribute to false means the ajax form submit handler won't be triggered...
            eShopCartForm.attr("data-ajax", "false");
        });
    });

If you care to dig deeper, then I recommend taking a look through the jquery.unobtrusive-ajax.js file that is bundled with the MVC3 projects.  Basically though we are changing the data-ajax attribute that is generated on the form element when the user clicks the checkout button so that the ajax submit handler doesn't trigger.

There you have it.  Any questions, suggestions, remarks, please leave a comment...

Resetting IE9's Javascript Engine

Quick post this time - lately I've come across this obscure error in Javascript with Internet Explorer 9 whenever I tried to run a jQuery ligthbox script:

appendChildOriginal(element);

jscript debugger
breaking on jscript runtime error - invalid calling object

after tearing my hair out and "researching" the problem on Google, I came across this obscure solution:

IE:  Tools->Options Advanced Settings "Reset"

(found here: "Microsoft J")

Seems that all that is needed to fix the problem is resetting the Internet Explorer settings fixes the problem.

A translation of the line above is as follows:

In Internet Explorer 9, Open the "Internet Options" either from the Tools menu (hit ALT to make the menu appear) or the "Cog" icon drop down.

Go to the Advanced Tab, and hit the "Reset..." button.  On the dialog that pops up, hit "Reset" again.

That's it. problem solved.  No need to reinstall IE 9.

Umbraco and JSON-RPC

We recently created a companion iPhone application for a website we released late last year, which needed to retrieve content from the website.  Rather than just retrieve pages of information as html, we wanted to display lists of content, and we also wanted to cache the content on the device for offline viewing.  To do this, it was decided we would use JSON as the transport as it is lightweight.

On the client side, we used the JSON-Framework Cocoa based library created by Stig Brautaset.  On the server side we used JayRock JSON-RPC library for dotNet. Oh, and the website was based on the Umbraco CMS.

Background on JSON-RPC

The JSON-RPC specification is fairly straightforward - it consists of a request, a response, and a notification.  The request sent to the server has 3 parameters as follows:

  • Method Name
  • Parameters, and
  • Id - This is used to associate the request with it's respective reply, and provided it is unique can be used to quarantee that the calling code receives the correct reply for the request - very important if you are sending multiple requests asynchronously.

The response from the server also has 3 parameters:

  • Result object - the result in JSON notation
  • Error object - if an error is thrown by the called method, the details will be contained in this object, including any exceptions thrown, which is very useful for debugging
  • Id - this is the same as the id passed in with the Request.

Creating a JSON-RPC Service

Using the JayRock library, this is all encapsulated, and we can just go about writing our Service Methods like so:

  1. In Visual Studio, or your favourite editor, start by creating a Generic Handler (.ashx type).
  2. Change the class definition so that it derives from the JsonRpcHandler class instead
  3. Create your Method declarations as per normal, but decorate them with the JsonRpcMethod Attribute.

An example is as follows (this is the base class we have created for authenticating user requests to the Umbraco backend):

using System.Web.Security;
using Jayrock.JsonRpc;
using Jayrock.JsonRpc.Web;
using System;
using System.Web;

namespace refactored.WebServices.json
{
    /// <summary>
    /// Provides a base class for JSON-RPC Services and handles authentication.
    /// </summary>
    public class BaseJSONService : JsonRpcHandler
    {
        protected string AuthenticationToken { get; set; }

        [JsonRpcMethod("AuthenticateMember")]
        public string AuthenticateMember(string username, string password)
        {
          ..
..
} [JsonRpcMethod("AuthenticationExpired")] public bool AuthenticationExpired(string authToken) { return (HttpRuntime.Cache[authToken] == null); }
 protected bool IsUserValid() { return (!string.IsNullOrEmpty(AuthenticationToken) && !AuthenticationExpired(AuthenticationToken)); } protected string GetUserName() { if (IsUserValid()) return HttpRuntime.Cache[AuthenticationToken].ToString(); else return string.Empty; } protected MembershipUser GetMember() { if (IsUserValid()) return Membership.GetUser(GetUserName()); else return null; } private bool ValidateUser(string username, string password) { return Membership.ValidateUser(username, password); } } }



Once you compile and load the dll into Umbraco, along with the associated ashx file, you can test the webservice in your favourite web browser:

JSON-RPC Service Discovery

User Authentication and Web Services

One of the features of the iPhone Application was that it allowed users to provide feedback on the content, as well as create "favourite" lists.  This required that users be able to authenticate with the website in order to make changes to their profile and update the lists on the website.

Because Web Services cannot store the users session, we need to provide some way of authenticating the user each call. In order to do this, an AuthenticateMember(string username, string password) method was created on the Service that returned an authentication token to be used in subsequent calls:

        [JsonRpcMethod("AuthenticateMember")]
        public string AuthenticateMember(string username, string password)
        {
            if (string.IsNullOrEmpty(username) || !ValidateUser(username, password))
                throw new Exception("Your Username or Password is incorrect");

            // Create and store the AuthenticatedToken before returning it
            AuthenticationToken = Guid.NewGuid().ToString();
            HttpRuntime.Cache.Add(
                   AuthenticationToken,
                   username,
                  null,
                  System.Web.Caching.Cache.NoAbsoluteExpiration,
                   TimeSpan.FromMinutes(60),
                  System.Web.Caching.CacheItemPriority.NotRemovable,
                  null);

            return AuthenticationToken;
        }

Then, on subsequent calls, we just pass the authentication token in to be validated against the cached version.

Lets test out the method:

JSON-RPC Service Testing with error

Notice wth this screen shot that the returned result was actually the error - it even includes the Exception details along with the erorr message.

Fixing up the parameters results in the following:

JSON-RPC Service Testing with expected result

Note the returned value - this is the authentication token generated by the server - we use this when calling subsequent methods that require validation.

Well, that's it for now, hopefully you can see from this how we can use JSON-RPC to retrieve information from a website and consume it in other applications, or even using AJAX.  Not only can we retrieve information, we can also create new content and otherwise manipulate information on a website.

Embedded YouTube Videos and iPad Rotation

While working on the iPhone/iPad application for the ChickenChannel website, I needed to have the embedded YouTube video resize dynamically to fit properly and in proportion across the screen of the device.  Moreover, the iPad allows for rotating the view, and we needed the video to resize to accomodate both orientations dynamically as you rotate the device.

The Chicken Channel is written in Umbraco, and the iOS application takes advantage of that by presenting existing pages with a customised template.  So while you might look at a recipe on the website and see the nice embedded Youtube video (hidden behind a banner image that prompts you to click it to start playing the video - this was covered in a post last November here.), the iPhone and iPad views are somewhat different.

Step 1: Make the video automatically fill the width of the screen.

This was quite easy:  all I needed to do was clear the width and height the enclosing div and the object tags and set the width to 100% on the embed tag.  I could have set the height as well, but given that there are 3 possible width with the devices, and I'm "veiling" the page until it's loaded anyway, I didn't see any point.  This displays a rather wide but short video on the iPhone:

<div class="youTubePlayer">
  <object class="youTubePlayer">
    <param name="movie" value="http://www.youtube.com/v/rldN0jSBbZQ?fs=1&rel=0" />
    <param name="allowFullScreen" value="true" />
    <param name="allowscriptaccess" value="always" />
    <embed class="youTubePlayer" src="http://www.youtube.com/v/rldN0jSBbZQ?fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" />
  </object>
</div>



Step 2: Use Javascript to add the aspect ratio back in (set the Height).

Using jQuery this is a really simple excercise:  We simply get the width of the window, and, because all our videos are in 16:9 aspect ratio, we use that to derive the height before applying it to the relevant tags.  (Notice the embed and object tags also have the class="youTubePlayer" attribute above?) - you'll also need to add the jQuery core library to your page...

  <script type="text/javascript">
    $(document).ready(function() {
      var newHeight = $(window).width()*9/16;
      if (newHeight > 500)
          newHeight = 500;
      $('.youTubePlayer').attr("height", newHeight);
    });
  </script>      



Right, after testing a little, we notice that the page renders, then the video gets lengthened to the correct ratio and all is good in the world.  However, when rotating the iPad application, the videos dimensions aren't resized along with the rest of the content.  Actually, the video's width is resized, but the height stays where we left it.

Step 3: Use the Resize event to adjust the aspect ratio on Rotation

The final step to this process was to take advantage of the UIWebView's resize javascript event to perform the resize again:

  <script type="text/javascript">
    $(window).resize(function() {
      var newHeight = $(window).width()*9/16;
      var oldHeight = $('div.youTubePlayer:first').attr("height");
      if (newHeight > 500)
          newHeight = 500;
      if (newHeight = oldHeight)
          return;
      $('.youTubePlayer').attr("height", newHeight);
    });
</script>



After a little more testing (ie, me madly waving the iPad around in the air and doing acrobatic contortions in the process) we have established that the video now resizes gracefully when the device is rotated to Portrait or Landscape mode.  All is better in the world.

Side note: While playing around with this, I had a javascript alert(newHeight); line in the resizing code.  on my iPad with the shiny new iOS 4.3.1 installed just last night, this promptly caused the application to crash.  I've submitted a bug report to Apple, and we'll see how it goes.

As always, comments and suggestions are always welcome.

I love NuGet!

It's official.  NuGet is now my all-time favourite Visual Studio Add-on.

The other day I was trying to upload a simple website to my hosting platform, but was having trouble with the dependencies.  As it happens, the hosting environment doesn't have MVC3 installed, or SqlServer Ce 4 for that matter.  MVC wasn't much of a problem, but the Ce database server on the other hand - well.  That's a different story.

Since the website was very simple in functionality - it provides a form that users can fill out to be notified of developments for a piece of real-estate in Melbourne's Yarra Valley region - and we only had a day to build it, I thought the combination of MVC3 with SqlServer Ce (we used the Code-First data model approach, which worked out really well) would be a no-brainer.

That was until I proceeded to upload the database, and started having to hunt around for all the necessary dll's.  It wasn't enough to just mark the dependencies so they would be copied to the output directory, I actually had to go and manually hunt around for additional dll's as well.

Enter NuGet.

Nuget allows you to download and automatically set up additional packages and libraries with ease.  It takes care of the dependencies, and updates your configuration files as well so you can just start using the new functionality without having to worry about web.config settings, for example.

So.  I added the package for EFCodeFirst.SqlServerCompact to the project, which resulted in all the dependencies being added as well in one easy step, and then all I had to do was make a few tweaks here and there and upload the changes.  Too easy!

Thank you, NuGet, you've just made my life that much easier.