Archive for the 'Development' category

27
Apr

Localizing MVC for ASP.NET views and master pages

Microsoft's MVC for ASP.NET is still under serious development but at the moment support for localization is a little weak. Here's one approach that works with the 04/16 source-drop.

LocalizingWebFormViewLocator class

This class helps by trying to identify language-specific versions of views, user controls and master-pages where they exist, falling back to the generic one where necessary.

public class LocalizingWebFormViewLocator : ViewLocator
{
	public LocalizingWebFormViewLocator() : base()
	{
		ViewLocationFormats = new[] { "~/Views/{1}/{0}.{2}aspx", "~/Views/{1}/{0}.{2}ascx",
			"~/Views/Shared/{0}.{2}aspx", "~/Views/Shared/{0}.{2}ascx" };
		MasterLocationFormats = new[] { "~/Views/{1}/{0}.{2}master", "~/Views/Shared/{0}.{2}master" };
	}

	protected override string GetPath(RequestContext requestContext, string[] locationFormats, string name)
	{
		string foundView = FindViewLocation(locationFormats, requestContext, name, CultureInfo.CurrentUICulture.Name + ".");
		if (String.IsNullOrEmpty(foundView))
			foundView = FindViewLocation(locationFormats, requestContext, name, "");
		return foundView;
	}

	protected string FindViewLocation(string[] locationFormats, RequestContext requestContext, string name, string cultureSuffix)
	{
		string controllerName = requestContext.RouteData.GetRequiredString("controller");
		foreach (string locationFormat in locationFormats) {
			string viewFile = string.Format(CultureInfo.InvariantCulture, locationFormat, name, controllerName, cultureSuffix);
			if (HostingEnvironment.VirtualPathProvider.FileExists(viewFile))
				return viewFile;
		}
		return null;
	}
}

Using the class

To use the class you must set the ViewLocator on the WebFormViewEngine to a new instance of LocalizingWebFormViewLocator (either in the constructor or in your common controller subclass) and ensure that any master pages are specified on the RenderView calls to ensure the localized version is detected.

public class HomeController : Controller
{
	public HomeController() {
		((WebFormViewEngine)ViewEngine).ViewLocator = new LocalizingWebFormViewLocator();
	}

	public ActionResult Index() {
		return RenderView("Index", "Site");
	}

	public ActionResult About() {
		return RenderView("About", "Site");
	}
}

You must also ensure the thread's current UI culture is set. The easiest way to do this is to specify the following in your web.config file's system.web section which will pick it up automatically from the user's browser settings via the HTTP language-accept header.

<globalization responseEncoding="UTF-8" requestEncoding="UTF-8" culture="auto" uiCulture ="auto" />

MVC for ASP.NET default page in pseudo-Japanese via the Babelfish
Then all you need to do is create views and master pages that have the culture name appended between the name and .aspx, e.g:

/Views/Home/Index.aspx (common fall-back for this view)
/Views/Home/Index.ja.aspx (Japanese view)
/Views/Home/Index.en-GB.aspx (British English view)

/Views/Shared/Site.Master (common fall-back for this masterpage)
/Views/Shared/Site.ja.Master (Japanese masterpage)

Caveats

There are some limitations to this solution:

Only primary language is attempted

Only the user's primary language specified in their browser is attempted despite browsers having a complete list in order of preference. Ideally we would scan down this entire list before giving up but that would need more code and there is the issue of whether scanning for several languages across several folders could be too much of a performance hit.

Specifying the masterpage on RenderView

It would be nice if you didn't have to specify the masterpage on renderview but if you do not then the ViewLocator never gets called to resolve the actual masterpage address. This may be for backward compatibility within MVC.

Creating files in Visual Studio

Visual Studio 2008 seems to get a little confused if you create a Index.ja.aspx or Site.ja.aspx - whilst the files are created okay the names are not and you will need to adjust the class names to ensure they don't conflict and make sure the opening declaration on the .aspx file points to the right code-behind page and inherits from the correct name.

Of course the beauty of this approach is you can mix-and-match using dedicated views where required and localising labels in the fall-back view when it isn't.

[)amien

14
Apr

More screen-shots of Envy Code R preview #7

Work on my Envy Code R programming font has resumed and I've spent hours playing with the hinting process to ensure it looks good at sizes above and below 10 point:

Screen-shot of Envy Code R PR7 without smoothing on WindowsScreen-shot of Envy Code R PR7 with standard smoothing on WindowsScreen-shot of Envy Code R PR7 with ClearType on Windows

These look great - even more so when you consider there are no embedded bitmaps and very few delta hints.

There is still a lot of work to do - all the foreign characters, symbols and box-drawing characters (another 600 glyphs) require hinting and I should test it on the Mac, Java and Flash font rendering engines to make sure there are no show-stoppers there.

Preview 7 will consist of of just a plain style regular and bold because I need to get this out - it's been too long since the last release. Preview 8 will add back italics and the Visual Studio italics-as-bold hack shortly afterwards.

Check out Talios's shots using Java/Linux and Eddy Young's shots in NetBeans.

[)amien

10
Apr

Using LINQ to foreach over an enum in C#

I can't be the only person in the world who wants to foreach over the values of an enum otherwise Enum.GetValues(Type enumType) wouldn't exist in the framework. Alas it didn't get any generics love in .NET 2.0 and unhelpfully returns an array.

Thanks to the power of LINQ you can do this:

foreach(CustomerTypes customerType in Enum.GetValues(typeof(CustomerTypes)).Cast<CustomerTypes>())

That is okay, but this is more concise:

foreach(CustomerTypes customerType in Enums.Get<CustomerTypes>())

The tiny class to achieve that is, of course:

using System.Collections.Generic;
using System.Linq;

public static class Enums {
	public static IEnumerable<T> Get<T>() {
		return System.Enum.GetValues(typeof(T)).Cast<T>();
	}
}

Great.

[)amien

02
Apr

Windows 2008 Server on my MacBook Pro

A troublesome disk (a story for another time) has forced me to reinstall my MacBook Pro and review my Windows partition.

My Boot Camp partition was running Vista Ultimate x86 which felt sluggish, ignored the last 1GB and bugged me with UAC. One Windows update kept failing to install which also prevented SP1 from completing.

Apple's Boot Camp doesn't support 64-bit Windows (except on the Mac Pro) and my 64-bit experiences have been unpleasant so far (no Flash for IE x64, limited 64-bit shell extensions, Live! refusing to install, drivers etc.) The increased x64 memory consumption would also be an issue when running in a 1.5GB virtual machine via Parallels or VMware Fusion.

Windows XP was one option but losing IIS7 and DirectX 10 would see me reinstalling Vista within weeks so I decided to try Windows 2008 Server x86.

Boot Camp happily accepted the 2008 Server x86 CD where I chose the BOOTCAMP partition, formatting it as NTFS and electing for a standard installation. The Boot Camp drivers subsequently installed without complaint, all 4GB of RAM was accessible and there are no 64-bit compatibility issues.

Microsoft are giving away 1 year evaluation copies of Windows 2008 Enterprise Server x86 as part of their Heroes Happen Here launch program for Windows 2008, SQL Server 2008 and Visual Studio 2008 if you don't happen to have an MSDN subscription to hand. There are however a few tweaks you need to do to get a more desktop-like experience:

Install desktop features

Head into Server Manager and Add Features then choose Desktop Experience to install Windows Media Player, Aero etc.

Go into Services and set the Themes service to Automatic and Start it to make themes available and then choose Browse... from the Theme Settings in Personalisation to select %windir%\Resources\Themes\Aero.theme

Install wireless networking

This one had me stumped for a while as I thought my wireless card/drivers weren't working. The reality is that 2008 Server has wireless networking removed by default so head into Server Manager > Add Features > Wireless LAN Service to install it.

Enabling hibernate

Open a command prompt and enter:

powercfg.exe /hibernate on

Remove annoying shutdown

Head into the registry to HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Reliability and change the ShutdownReasonOn DWORD key to 0.

Relaxing local password policy

A controversial change I'm sure but I'd rather choose something complex and unique that will last 90+ days than something memorable every 30. Head into Local Security Policy > Account Policies > Password Policy > Maximum password age and change it to something more reasonable.

Going further

A great guide with screen-shots on additional tweaks for a more workstation-like experience also exists - wish I known about that earlier!

Simone Chiaretta has highlighted the that tap-to-click is absent and there are some Bluetooth issues stemming from missing drivers.

[)amien

18
Mar

Safari 3.1 includes developer tools

Safari 3.1 has just been released and besides the partial CSS3 (fonts) and partial HTML5 (media tags, off-line storage) support there are some new developer tools included.
Safari has had a hidden Debug menu for some time and WebKit featured developer tools but with 3.1 Apple have unleashed them to the masses.

Head into Preferences > Advanced and choose Show Develop menu in menu bar to get this new Develop menu.

It includes:

  • Open Page With (Internet Explorer, Firefox 2/3, Camino, MobileSafari etc.)
  • User Agent switching
  • Show Web Inspector (inspect element)
  • Show Error Console (including HTML errors)
  • Show Network Timeline (like Firebug's network view)
  • Show Snippet Editor
  • Disable Caches/Images/Styles
  • Disable JavaScript/Runaway JavaScript Timer/Site-specific hacks

Here's the Network Timeline in action on OS X:
Screen-shot of Safari 3.1's Network Timeline on Mac OS X

There are some odd drawing issues within the snippet editor and inspecting from the inspector on Windows but with this, Firebug and Internet Explorer 8's Developer Tools we're spoilt for choice!

[)amien
And no, it doesn't pass the rather abstract Acid3 test

07
Mar

Testing web sites with the iPhone SDK

Apple's iPhone SDK is now available in beta format for free download (running your apps on a real iPhone is a one-time $99 charge).

The 2.1GB download contains the full XCode 3.1 environment for Mac app development but also an extra 22MB of iPhone-specific SDK goodness including an iPhone simulator named Aspen Simulator (perhaps the code-name for iPhone). Whilst most of the iPhone's apps are absent you can still access settings, photos, Safari and contacts.

Besides the cool idea of creating real iPhone apps you can also use Mobile Safari to test your sites on an iPhone - very cool! Here's DamienG.com in the simulator when twisted round 90'.

DamienG.com rendered on the iPhone

[)amien

04
Mar

Future of AnkhSVN (Subversion for Visual Studio)

Now that AnkhSVN 1.0.3 is out with support for Visual Studio 2008 we can discuss our future plans for AnkhSVN.

We have moved over to openCollabNet and welcomed Jeremy Whitlock and Bert Huijben to the team!

Our preliminary roadmap for AnkhSVN 2.0 is:

  • Improve user experience
    • Refine windows, options and icons
    • Localise dialogs and messages
    • Support customisation of icons & menus
    • Develop interactive log window
    • Add keyboard support (short cuts & tab order)
  • Extend integration
  • Foster developer participation
    • Simplify build environment with MSBuild
    • Reduce code-base with SharpSvn
    • Switch Visual Studio API from automation to source control
    • Provide source-on-demand using Sourceserver

Switching the provider model means we have to drop Visual Studio 2003 support for 2.0 but means we get to use .NET 2.0+ features as well as a much faster and more robust mechanism for extending Visual Studio.

The timetable is quite aggressive and I'm hoping we can get quick regular builds out for people to try.

[)amien

08
Feb

Humane theme for TextMate and Xcode

My Humane theme for Visual Studio is getting a fair bit of traffic today courtesy of Scott Hanselman. Given I have been messing with Mac development lately I thought it was worth porting to TextMate and Xcode 3.

Panic Sans coding font

My Envy Code R programming font isn't great on the Mac yet so I have configured these to use the excellent but overlooked Panic Sans in 12 point which unlike Monaco is available in bold, italic and bold italic variants. (I love my comments to be italics)

To install this font you must:

  1. Download Panic Software's Coda application
  2. Navigate to the Coda application and choose Show Package Contents
  3. Navigate to the Contents/Resources folder
  4. Double click on the Panic Sans.dfont and press Install Font
  5. Panic Sans is now available to other applications too

TextMate

Screenshot of the Humane Theme and Panic Sans 12 point inside TextMate

Download Humane theme for TextMate (5 KB)

Launching the downloaded .tmTheme file will cause it to copy to ~/Library/Application Support/TextMate/Themes
Select Humane from the Preferences > Fonts & Colors pane in the drop-down list box

Xcode 3

Screenshot of the Humane Theme and Panic Sans 12 point inside Xcode 3

Download Humane theme for Xcode (4 KB)

Copy to ~/Library/Application Support/Xcode/Color Themes
Select Humane from the Preferences > Fonts & Colors pane in the drop-down list box

Porting themes

Until somebody comes up with an IDE-independent theme format or cool converter we'll have to do it by hand. The easiest way I have found is:

  1. Install Hex Color Picker on the Mac to allow entering hex into the standard color picker
  2. Open the Visual Studio theme .vssettings file in a text editor
  3. Open up the Fonts & Colors preferences pane up in your Mac IDE
  4. Go through each one and choose the nearest match in the .vssettings
  5. Transcribe each color by reading the VS colour pairs backward, e.g. 00631409 becomes #091463

[)amien




Feed subscription

Subjects