Saturday, 15 August 2009

Converting Subversion to Mercurial (svn to hg) on Windows

If you’re jumping on the DCVS bandwagon and abandoning Subversion, Mercurial seems to be the way to go on Windows thanks to TortoiseHg and the fact that the Mercurial commands feel familiar if you’re used to Subversion.

It is possible to do a full history conversion from a Subversion repository to a Mercurial repository using Mercurial’s Convert extension. This doesn’t work out of the box on Windows so I did it using Cygwin.

Steps
Download Cygwin and select the mercurial and subversion-python packages from the Devel section during install. Selecting these will also select the other packages you need automatically.

Next create a text file named .hgrc in your C:\cygwin\home\Username folder containing the following:
[extensions]
hgext.convert=
Now open up your Cygwin bash shell and you might* be able to run a conversion e.g.
hg convert http://fluent-nhibernate.googlecode.com/svn/trunk/
See http://mercurial.selenic.com/wiki/ConvertExtension for more info and command options.

* If you get a *** fatal error *** about remapping addresses you will need to rebase your dlls. To do this quit the Cygwin shell, open a windows command prompt, CD to C:\cygwin\bin and run ash rebaseall. The hg convert should now work.

Saturday, 25 April 2009

More Umbraco and ASP.NET MVC

Check out this post on the Umbraco forum for a better URL rewrite thanks to Immo.

Friday, 17 April 2009

Umbraco and ASP.NET MVC

I wanted to be able to implement an Umbraco site with some ASP.NET MVC pages so I set up a basic site as follows...

First off, I set up a clean Umbraco under IIS 7 (Classic mode). As it is classic mode I assume the setup should work with IIS 6.

My test site had a few basic pages provided through Umbraco and 2 MVC controllers - Home and Account. I can access the Umbraco pages through URLs like http://umbracomvc/installing-runway-modules.aspx and the MVC actions through URLs like http://umbracomvc/Account.aspx/LogOn.

I used a custom HttpHandler to process the MVC requests and the UrlRewriteModule that comes with Umbraco to redirect MVC requests to the custom handler.

Web.config

Make the following changes to web.config:

 1. Add the following under system.web/pages
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Linq"/>
<add namespace="System.Collections.Generic"/></namespaces>
 2. Add the following under system.web/httpModules (more on this later)
<add name="RegisterRoutesModule" type="RegisterRoutesModule"/>
 3. Add the following under system.web/compilation/assemblies
<add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
mvc.ashx

This is the custom HttpHandler that will process all MVC requests. The actual route is passed to it on the query string - just like Umbraco passes routes to Default.aspx behind the scenes.

Create a file named mvc.ashx in the root of the Umbraco site and paste in the following text:

 

<%@ WebHandler Language="C#" Class="mvc" %>


using System.Web;

using System.Web.Mvc;

 

public class mvc : MvcHttpHandler

{

    protected override void ProcessRequest(HttpContext httpContext)

    {

        string originalPath = httpContext.Request.Path;

        string newPath = httpContext.Request.QueryString["mvcRoute"];

        if (string.IsNullOrEmpty(newPath))

            newPath = "/";

 

        HttpContext.Current.RewritePath(newPath, false);

        base.ProcessRequest(HttpContext.Current);

        HttpContext.Current.RewritePath(originalPath, false);

    }

}


RegisterRoutesModule.cs

We need to set up the MVC routes at some point. We can't do it in Global.asax as Umbraco has its own Global class so I used a custom HttpModule.

Create a file named RegisterRoutesModule.cs in the app_code folder and paste in the following text:

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

 

public class RegisterRoutesModule : IHttpModule

{

    public void Init(HttpApplication application)

    {

        RegisterRoutes(RouteTable.Routes);

    }

 

    public static void RegisterRoutes(RouteCollection routes)

    {

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

        routes.MapRoute(

            "Default",

            "{controller}.aspx/{action}/{id}",

            new { action = "Index", id = "" }

          );

 

        routes.MapRoute(

          "Root",

          "",

          new { controller = "Home", action = "Index", id = "" }

        );

    }

 

    public void Dispose()

    {

 

    }

}


Views and Controllers

We need some Views and Controllers so create a new ASP.NET MVC project. Copy the Views folder from the new project into the root of the Umbraco site and copy the Controllers folder into the app_code folder of the Umbraco site.

URL Rewriting

Finally we need to redirect incoming requests for MVC pages to the MVC handler. Open up config/UrlRewriting.config in Umbraco and add the following entries:

<add name="MVC_Home_Rewrite"
virtualUrl="^~/Home.aspx/(.*)"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/mvc.ashx?mvcRoute=/Home.aspx/$1"
ignoreCase="true" />

<add name="MVC_Account_Rewrite"
virtualUrl="^~/Account.aspx/(.*)"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/mvc.ashx?mvcRoute=/Account.aspx/$1"
ignoreCase="true" />

That should be everything. Next I want to create an Umbraco macro that calls MVC actions via a UserControl...

Monday, 16 March 2009

Um Bongo

Does anyone else have the Um Bongo tune constantly going through their head when working with Umbraco?

Programatically publishing, unpublishing, deleting and renaming nodes in Umbraco

I have an ActionHandler that publishes, unpublishes, deletes and renames nodes (documents) in Umbraco.

At first my published items would appear in the content tree but not in the website and my unpublished or deleted items would grey out or disappear from the content tree but not the website.

I dug around the forums for a bit and found the correct method calls - here they are:

Publish
var myNode = new Document(id);
myNode.Publish(umbraco.helper.GetCurrentUmbracoUser());
umbraco.library.UpdateDocumentCache(myNode.Id);
Unpublish
var myNode = new Document(id);
myNode.UnPublish();
umbraco.library.UnPublishSingleNode(myNode.Id);
Delete
var myNode = new Document(id);
myNode.delete();
umbraco.library.RefreshContent();
Rename
var myNode = new Document(id);
var versions = myNode.GetVersions();
if (versions != null && versions.Length > 1)
{
var previousVersion = versions[versions.Length - 2];
if (myNode.Text != previousVersion.Text)
{
// This is a rename, as an example I will just make sure the new name is lower case...
myNode.Text = myNode.Text.ToLower();
if (myNode.Published)
{
myNode.Publish(umbraco.helper.GetCurrentUmbracoUser());
umbraco.library.UpdateDocumentCache(myNode.Id);
}
}
}
There is no IAction class for renames so I just use ActionUpdate.Instance. My ReturnActions() method looks like this - 
public IAction[] ReturnActions()
{
return new IAction[] {
ActionPublish.Instance,
ActionDelete.Instance,
ActionUnPublish.Instance,
ActionUpdate.Instance
};
}

Wednesday, 7 January 2009

Set Umbraco folder permissions on the command line

When installing Umbraco it is a pain to set all the folder permissions through Explorer. This script does the same job.

icacls app_code /grant "NETWORK SERVICE":(OI)(CI)F
icacls bin /grant "NETWORK SERVICE":(OI)(CI)F
icacls config /grant "NETWORK SERVICE":(OI)(CI)F
icacls css /grant "NETWORK SERVICE":(OI)(CI)F
icacls data /grant "NETWORK SERVICE":(OI)(CI)F
icacls masterpages /grant "NETWORK SERVICE":(OI)(CI)F
icacls media /grant "NETWORK SERVICE":(OI)(CI)F
icacls python /grant "NETWORK SERVICE":(OI)(CI)F
icacls scripts /grant "NETWORK SERVICE":(OI)(CI)F
icacls umbraco /grant "NETWORK SERVICE":(OI)(CI)F
icacls usercontrols /grant "NETWORK SERVICE":(OI)(CI)F
icacls xslt /grant "NETWORK SERVICE":(OI)(CI)F

Saturday, 29 November 2008

XSLT Intellisense in Visual Studio 2008 Standard Edition

First, make sure you have the xslt.xsd file in the C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas folder. If not, copy it from VS2005.

Next, add a new string value to the registry named 'XsltIntellisense' under 'HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\XmlEditor' and set the value to 'True'. This will enable some other nice features to the standard tag completion stuff.

Registry info from the Signs on the Sand blog.