A couple of handy helper razor scripts for Umbraco CMS
by Luke Daffron Thursday, September 1st, 2011
I’ve recently started a project for a new marketing site for our projects. One of the biggest issues with our current marketing site is that it was developed as an application – so changes need to go through a developer and be deployed. This basically resulted in the site being stagnant for a couple of years. This is bad – there are lots of things we offer now that we didn’t 2 years ago – and there are many opportunities where a page that speaks to a particular system, market, or feature could be very good for business/SEO.
I decided to use a CMS to allow anyone in our business edit and add content. Since we were a web consulting firm before we built products – we’ve had a number of custom solutions over the years for managing site content. I didn’t want to create that maintenance pain again, so I looked for another maintained solution I could use. I settled on Umbraco – it’s free, open source, has a great plugin architecture using the .NET/Razor architecture we already know – so it was a perfect fit.
I wanted to share a couple of handy scripts I came up with to make Umbraco even better:
Add “/edit” redirect to all pages:
To use this, add a couple of rewrite rules to UrlRewriting.config:
<add name="editrewrite"
virtualUrl="^~/(.*)/edit/?"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/editredirect?path=foliotek/$1"
ignoreCase="true" />
<add name="edithomerewrite"
virtualUrl="^~/edit/?"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/editredirect?path=foliotek"
ignoreCase="true" />
Add a new scripting file (and macro) called “EditRedirect”
@using uComponents.Core
@using umbraco.presentation.nodeFactory
@using uComponents.Core.uQueryExtensions
@{
Node n = null;
var path = Request.QueryString["path"].Split("/".ToCharArray());
for(int i=0; i<path.Length; i++)
{
if(n==null)
{
n = uQuery.GetRootNode().GetChildNodes().Where(x=>x.Name.ToLower()== path[i].Trim().ToLower()).First();
}
else
{
var name = path[i].Trim();
if(i==path.Length-1 && name.IndexOf(".")>0)
{
name=name.Substring(0,name.LastIndexOf("."));
}
n = n.GetDescendantNodes().First(c=>c.Name.ToLower()==name.ToLower());
}
}
Response.Redirect("/umbraco/actions/editContent.aspx?id="+n.Id);
}
Add a new “EditRedirect” template that uses the macro:
<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %> <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server"> <umbraco:Macro runat="server" Alias="EditRedirect" /> </asp:Content>
And, finally, add a new page called EditRedirect to the root of your site that uses the macro. Now you can hit http://site/anydirectory/anypage/edit and it will take you to the editor screen of that page.
Simple path to access media by url and in css files
The abstraction umbraco allows for media is great – your editors can create a media item and replace the file later to their hearts content. Unfortunately, it’s not very simple to pull this media in scripts, templates, simple html, and especially css files. I wrote a macro/script to handle this too. Set up is pretty much like the edit redirect:
The script:
@using uComponents.Core
@using umbraco.cms.businesslogic.media
@using uComponents.Core.uQueryExtensions
@{
Media m = null;
if(!( Model.Media is umbraco.MacroEngines.DynamicNull || (Model.Media is string && Model.Media=="")))
{
m = uQuery.GetMedia(Model.Media);
}
else
{
var path = Request.QueryString["path"].Split("/".ToCharArray());
for(int i=0; i<path.Length; i++)
{
if(m==null)
{
m = uQuery.GetMediaByName( path[i].Trim()).First();
}
else
{
var name = path[i].Trim();
if(i==path.Length-1 && name.IndexOf(".")>0)
{
name=name.Substring(0,name.LastIndexOf("."));
}
m = m.GetChildMedia().First(c=>c.Text==name);
}
}
}
Response.Clear();
Response.ContentType = GetContentType(m.GetProperty<string>("umbracoExtension"));
Response.TransmitFile(m.GetProperty<string>("umbracoFile"));
}
@functions{
protected string GetContentType(string ext)
{
var contentTypes = new Dictionary<string, string>
{
{"3dm", "x-world/x-3dmf"},
{"3dmf", "x-world/x-3dmf"},
{"a", "application/octet-stream"},
{"aab", "application/x-authorware-bin"},
{"aam", "application/x-authorware-map"},
{"aas", "application/x-authorware-seg"},
{"abc", "text/vnd.abc"},
{"acgi", "text/html"},
{"afl", "video/animaflex"},
{"ai", "application/postscript"},
{"aif", "audio/aiff"},
{"aifc", "audio/aiff"},
{"aiff", "audio/aiff"},
{"aim", "application/x-aim"},
{"aip", "text/x-audiosoft-intra"},
{"ani", "application/x-navi-animation"},
{"aos", "application/x-nokia-9000-communicator-add-on-software"},
{"aps", "application/mime"},
{"arc", "application/octet-stream"},
{"arj", "application/arj"},
{"art", "image/x-jg"},
{"asf", "video/x-ms-asf"},
{"asm", "text/x-asm"},
{"asp", "text/asp"},
{"asx", "application/x-mplayer2"},
{"au", "audio/basic"},
{"avi", "video/avi"},
{"avs", "video/avs-video"},
{"bcpio", "application/x-bcpio"},
{"bin", "application/octet-stream"},
{"bm", "image/bmp"},
{"bmp", "image/bmp"},
{"boo", "application/book"},
{"book", "application/book"},
{"boz", "application/x-bzip2"},
{"bsh", "application/x-bsh"},
{"bz", "application/x-bzip"},
{"bz2", "application/x-bzip2"},
{"c", "text/plain"},
{"c++", "text/plain"},
{"cat", "application/vnd.ms-pki.seccat"},
{"cc", "text/plain"},
{"ccad", "application/clariscad"},
{"cco", "application/x-cocoa"},
{"cdf", "application/cdf"},
{"cer", "application/pkix-cert"},
{"cha", "application/x-chat"},
{"chat", "application/x-chat"},
{"class", "application/java"},
{"com", "application/octet-stream"},
{"conf", "text/plain"},
{"cpio", "application/x-cpio"},
{"cpp", "text/x-c"},
{"cpt", "application/x-cpt"},
{"crl", "application/pkcs-crl"},
{"css", "text/css"},
{"def", "text/plain"},
{"der", "application/x-x509-ca-cert"},
{"dif", "video/x-dv"},
{"dir", "application/x-director"},
{"dl", "video/dl"},
{"doc", "application/msword"},
{"dot", "application/msword"},
{"dp", "application/commonground"},
{"drw", "application/drafting"},
{"dump", "application/octet-stream"},
{"dv", "video/x-dv"},
{"dvi", "application/x-dvi"},
{"dwf", "drawing/x-dwf (old)"},
{"dwg", "application/acad"},
{"dxf", "application/dxf"},
{"eps", "application/postscript"},
{"es", "application/x-esrehber"},
{"etx", "text/x-setext"},
{"evy", "application/envoy"},
{"exe", "application/octet-stream"},
{"f", "text/plain"},
{"f90", "text/x-fortran"},
{"fdf", "application/vnd.fdf"},
{"fif", "image/fif"},
{"fli", "video/fli"},
{"for", "text/x-fortran"},
{"fpx", "image/vnd.fpx"},
{"g", "text/plain"},
{"g3", "image/g3fax"},
{"gif", "image/gif"},
{"gl", "video/gl"},
{"gsd", "audio/x-gsm"},
{"gtar", "application/x-gtar"},
{"gz", "application/x-compressed"},
{"h", "text/plain"},
{"help", "application/x-helpfile"},
{"hgl", "application/vnd.hp-hpgl"},
{"hh", "text/plain"},
{"hlp", "application/x-winhelp"},
{"htc", "text/x-component"},
{"htm", "text/html"},
{"html", "text/html"},
{"htmls", "text/html"},
{"htt", "text/webviewhtml"},
{"htx", "text/html"},
{"ice", "x-conference/x-cooltalk"},
{"ico", "image/x-icon"},
{"idc", "text/plain"},
{"ief", "image/ief"},
{"iefs", "image/ief"},
{"iges", "application/iges"},
{"igs", "application/iges"},
{"ima", "application/x-ima"},
{"imap", "application/x-httpd-imap"},
{"inf", "application/inf"},
{"ins", "application/x-internett-signup"},
{"ip", "application/x-ip2"},
{"isu", "video/x-isvideo"},
{"it", "audio/it"},
{"iv", "application/x-inventor"},
{"ivr", "i-world/i-vrml"},
{"ivy", "application/x-livescreen"},
{"jam", "audio/x-jam"},
{"jav", "text/plain"},
{"java", "text/plain"},
{"jcm", "application/x-java-commerce"},
{"jfif", "image/jpeg"},
{"jfif-tbnl", "image/jpeg"},
{"jpe", "image/jpeg"},
{"jpeg", "image/jpeg"},
{"jpg", "image/jpeg"},
{"jps", "image/x-jps"},
{"js", "application/x-javascript"},
{"jut", "image/jutvision"},
{"kar", "audio/midi"},
{"ksh", "application/x-ksh"},
{"la", "audio/nspaudio"},
{"lam", "audio/x-liveaudio"},
{"latex", "application/x-latex"},
{"lha", "application/lha"},
{"lhx", "application/octet-stream"},
{"list", "text/plain"},
{"lma", "audio/nspaudio"},
{"log", "text/plain"},
{"lsp", "application/x-lisp"},
{"lst", "text/plain"},
{"lsx", "text/x-la-asf"},
{"ltx", "application/x-latex"},
{"lzh", "application/octet-stream"},
{"lzx", "application/lzx"},
{"m", "text/plain"},
{"m1v", "video/mpeg"},
{"m2a", "audio/mpeg"},
{"m2v", "video/mpeg"},
{"m3u", "audio/x-mpequrl"},
{"man", "application/x-troff-man"},
{"map", "application/x-navimap"},
{"mar", "text/plain"},
{"mbd", "application/mbedlet"},
{"mc$", "application/x-magic-cap-package-1.0"},
{"mcd", "application/mcad"},
{"mcf", "image/vasa"},
{"mcp", "application/netmc"},
{"me", "application/x-troff-me"},
{"mht", "message/rfc822"},
{"mhtml", "message/rfc822"},
{"mid", "audio/midi"},
{"midi", "audio/midi"},
{"mif", "application/x-frame"},
{"mime", "message/rfc822"},
{"mjf", "audio/x-vnd.audioexplosion.mjuicemediafile"},
{"mjpg", "video/x-motion-jpeg"},
{"mm", "application/base64"},
{"mme", "application/base64"},
{"mod", "audio/mod"},
{"moov", "video/quicktime"},
{"mov", "video/quicktime"},
{"movie", "video/x-sgi-movie"},
{"mp2", "audio/mpeg"},
{"mp3", "audio/mpeg3"},
{"mpa", "audio/mpeg"},
{"mpc", "application/x-project"},
{"mpe", "video/mpeg"},
{"mpeg", "video/mpeg"},
{"mpg", "video/mpeg"},
{"mpga", "audio/mpeg"},
{"mpp", "application/vnd.ms-project"},
{"mpt", "application/x-project"},
{"mpv", "application/x-project"},
{"mpx", "application/x-project"},
{"mrc", "application/marc"},
{"ms", "application/x-troff-ms"},
{"mv", "video/x-sgi-movie"},
{"my", "audio/make"},
{"mzz", "application/x-vnd.audioexplosion.mzz"},
{"nap", "image/naplps"},
{"naplps", "image/naplps"},
{"nc", "application/x-netcdf"},
{"ncm", "application/vnd.nokia.configuration-message"},
{"nif", "image/x-niff"},
{"niff", "image/x-niff"},
{"nix", "application/x-mix-transfer"},
{"nsc", "application/x-conference"},
{"nvd", "application/x-navidoc"},
{"o", "application/octet-stream"},
{"oda", "application/oda"},
{"omc", "application/x-omc"},
{"omcd", "application/x-omcdatamaker"},
{"omcr", "application/x-omcregerator"},
{"p", "text/x-pascal"},
{"p10", "application/pkcs10"},
{"p12", "application/pkcs-12"},
{"p7a", "application/x-pkcs7-signature"},
{"p7c", "application/pkcs7-mime"},
{"pas", "text/pascal"},
{"pbm", "image/x-portable-bitmap"},
{"pcl", "application/vnd.hp-pcl"},
{"pct", "image/x-pict"},
{"pcx", "image/x-pcx"},
{"pdf", "application/pdf"},
{"pfunk", "audio/make"},
{"pgm", "image/x-portable-graymap"},
{"pic", "image/pict"},
{"pict", "image/pict"},
{"pkg", "application/x-newton-compatible-pkg"},
{"pko", "application/vnd.ms-pki.pko"},
{"pl", "text/plain"},
{"plx", "application/x-pixclscript"},
{"pm", "image/x-xpixmap"},
{"png", "image/png"},
{"pnm", "application/x-portable-anymap"},
{"pot", "application/mspowerpoint"},
{"pov", "model/x-pov"},
{"ppa", "application/vnd.ms-powerpoint"},
{"ppm", "image/x-portable-pixmap"},
{"pps", "application/mspowerpoint"},
{"ppt", "application/mspowerpoint"},
{"ppz", "application/mspowerpoint"},
{"pre", "application/x-freelance"},
{"prt", "application/pro_eng"},
{"ps", "application/postscript"},
{"psd", "application/octet-stream"},
{"pvu", "paleovu/x-pv"},
{"pwz", "application/vnd.ms-powerpoint"},
{"py", "text/x-script.phyton"},
{"pyc", "applicaiton/x-bytecode.python"},
{"qcp", "audio/vnd.qcelp"},
{"qd3", "x-world/x-3dmf"},
{"qd3d", "x-world/x-3dmf"},
{"qif", "image/x-quicktime"},
{"qt", "video/quicktime"},
{"qtc", "video/x-qtc"},
{"qti", "image/x-quicktime"},
{"qtif", "image/x-quicktime"},
{"ra", "audio/x-pn-realaudio"},
{"ram", "audio/x-pn-realaudio"},
{"ras", "application/x-cmu-raster"},
{"rast", "image/cmu-raster"},
{"rexx", "text/x-script.rexx"},
{"rf", "image/vnd.rn-realflash"},
{"rgb", "image/x-rgb"},
{"rm", "application/vnd.rn-realmedia"},
{"rmi", "audio/mid"},
{"rmm", "audio/x-pn-realaudio"},
{"rmp", "audio/x-pn-realaudio"},
{"rng", "application/ringing-tones"},
{"rnx", "application/vnd.rn-realplayer"},
{"roff", "application/x-troff"},
{"rp", "image/vnd.rn-realpix"},
{"rpm", "audio/x-pn-realaudio-plugin"},
{"rt", "text/richtext"},
{"rtf", "text/richtext"},
{"rtx", "application/rtf"},
{"rv", "video/vnd.rn-realvideo"},
{"s", "text/x-asm"},
{"s3m", "audio/s3m"},
{"saveme", "application/octet-stream"},
{"sbk", "application/x-tbook"},
{"scm", "application/x-lotusscreencam"},
{"sdml", "text/plain"},
{"sdp", "application/sdp"},
{"sdr", "application/sounder"},
{"sea", "application/sea"},
{"set", "application/set"},
{"sgm", "text/sgml"},
{"sgml", "text/sgml"},
{"sh", "application/x-bsh"},
{"shtml", "text/html"},
{"sid", "audio/x-psid"},
{"sit", "application/x-sit"},
{"skd", "application/x-koan"},
{"skm", "application/x-koan"},
{"skp", "application/x-koan"},
{"skt", "application/x-koan"},
{"sl", "application/x-seelogo"},
{"smi", "application/smil"},
{"smil", "application/smil"},
{"snd", "audio/basic"},
{"sol", "application/solids"},
{"spc", "application/x-pkcs7-certificates"},
{"spl", "application/futuresplash"},
{"spr", "application/x-sprite"},
{"sprite", "application/x-sprite"},
{"src", "application/x-wais-source"},
{"ssi", "text/x-server-parsed-html"},
{"ssm", "application/streamingmedia"},
{"sst", "application/vnd.ms-pki.certstore"},
{"step", "application/step"},
{"stl", "application/sla"},
{"stp", "application/step"},
{"sv4cpio", "application/x-sv4cpio"},
{"sv4crc", "application/x-sv4crc"},
{"svf", "image/vnd.dwg"},
{"svr", "application/x-world"},
{"swf", "application/x-shockwave-flash"},
{"t", "application/x-troff"},
{"talk", "text/x-speech"},
{"tar", "application/x-tar"},
{"tbk", "application/toolbook"},
{"tcl", "application/x-tcl"},
{"tcsh", "text/x-script.tcsh"},
{"tex", "application/x-tex"},
{"texi", "application/x-texinfo"},
{"texinfo", "application/x-texinfo"},
{"text", "text/plain"},
{"tgz", "application/x-compressed"},
{"tif", "image/tiff"},
{"tr", "application/x-troff"},
{"tsi", "audio/tsp-audio"},
{"tsp", "audio/tsplayer"},
{"tsv", "text/tab-separated-values"},
{"turbot", "image/florian"},
{"txt", "text/plain"},
{"uil", "text/x-uil"},
{"uni", "text/uri-list"},
{"unis", "text/uri-list"},
{"unv", "application/i-deas"},
{"uri", "text/uri-list"},
{"uris", "text/uri-list"},
{"ustar", "application/x-ustar"},
{"uu", "application/octet-stream"},
{"vcd", "application/x-cdlink"},
{"vcs", "text/x-vcalendar"},
{"vda", "application/vda"},
{"vdo", "video/vdo"},
{"vew", "application/groupwise"},
{"viv", "video/vivo"},
{"vivo", "video/vivo"},
{"vmd", "application/vocaltec-media-desc"},
{"vmf", "application/vocaltec-media-file"},
{"voc", "audio/voc"},
{"vos", "video/vosaic"},
{"vox", "audio/voxware"},
{"vqe", "audio/x-twinvq-plugin"},
{"vqf", "audio/x-twinvq"},
{"vql", "audio/x-twinvq-plugin"},
{"vrml", "application/x-vrml"},
{"vrt", "x-world/x-vrt"},
{"vsd", "application/x-visio"},
{"vst", "application/x-visio"},
{"vsw", "application/x-visio"},
{"w60", "application/wordperfect6.0"},
{"w61", "application/wordperfect6.1"},
{"w6w", "application/msword"},
{"wav", "audio/wav"},
{"wb1", "application/x-qpro"},
{"wbmp", "image/vnd.wap.wbmp"},
{"web", "application/vnd.xara"},
{"wiz", "application/msword"},
{"wk1", "application/x-123"},
{"wmf", "windows/metafile"},
{"wml", "text/vnd.wap.wml"},
{"wmlc", "application/vnd.wap.wmlc"},
{"wmls", "text/vnd.wap.wmlscript"},
{"wmlsc", "application/vnd.wap.wmlscriptc"},
{"word", "application/msword"},
{"wp", "application/wordperfect"},
{"wp5", "application/wordperfect"},
{"wp6", "application/wordperfect"},
{"wpd", "application/wordperfect"},
{"wq1", "application/x-lotus"},
{"wri", "application/mswrite"},
{"wrl", "application/x-world"},
{"wrz", "model/vrml"},
{"wsc", "text/scriplet"},
{"wsrc", "application/x-wais-source"},
{"wtk", "application/x-wintalk"},
{"xbm", "image/x-xbitmap"},
{"xdr", "video/x-amt-demorun"},
{"xgz", "xgl/drawing"},
{"xif", "image/vnd.xiff"},
{"xl", "application/excel"},
{"xla", "application/excel"},
{"xlb", "application/excel"},
{"xlc", "application/excel"},
{"xld", "application/excel"},
{"xlk", "application/excel"},
{"xll", "application/excel"},
{"xlm", "application/excel"},
{"xls", "application/excel"},
{"xlt", "application/excel"},
{"xlv", "application/excel"},
{"xlw", "application/excel"},
{"xm", "audio/xm"},
{"xml", "text/xml"},
{"xmz", "xgl/movie"},
{"xpix", "application/x-vnd.ls-xpix"},
{"xpm", "image/x-xpixmap"},
{"x-png", "image/png"},
{"xsr", "video/x-amt-showrun"},
{"xwd", "image/x-xwd"},
{"xyz", "chemical/x-pdb"},
{"z", "application/x-compress"},
{"zip", "application/x-compressed"},
{"zoo", "application/octet-stream"},
{"zsh", "text/x-script.zsh"}
};
if(contentTypes[ext]==null)
{
return "application/octet-stream";
}
return contentTypes[ext];
}
}
The template:
<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %> <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server"> <umbraco:Macro runat="server" MediaID="[#media]" Alias="getMedia" /> </asp:Content>
The redirect rule:
<add name="cssmediarewrite"
virtualUrl="^~/css/media/(.*)"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/cssmedia?path=$1"
ignoreCase="true" />
Finally, add a page called CssMedia that uses the template. Now, you can reference /css/media/mediapath/medianame.fileextension to get the item. This also means that your css files can use media/mediapath/medianame.fileextension to reference Umbraco media.
Tags: media, rewrite, umbraco, umbraco css image, umbraco css media, umbraco image
« Scrollable DataGrid table with Fixed Header with jQuery Weebly Automatically Generated Left Menu via jQuery »


September 1st, 2011 at 3:44 pm
Hey Luke,
Some nice tips there, I”d not thought of doing the /edit redirect, but looks pretty cool.
I have a suggestion though, you could look to simplify these by using alt templates. For the /edit you could just create a template called Edit, and then access that template as an alt template by going to http://my.domain.com/my-page/edit. This will render the Edit template in the context of My Page, so you could grab the currentNode ID and then do the redirect. This will save you having to setup the URL Rewrite, and having unnecessary pages in your site structure.
The same could also help for the second example also.
Hope this helps.
Cheers
Matt
September 2nd, 2011 at 6:15 pm
Woah, both of these are handy but that media one is awesome! Thanks for posting this. I”m going to implement it this weekend.
Way to go, keep up the good work! Blog about more of these if you have them.
September 6th, 2011 at 2:14 pm
Great tip! I”m a relatively new Umbraco developer, so I had no idea the alternate url for additional templates existed. Thanks!
September 13th, 2011 at 10:18 pm
Excellent article, thank you for sharing! I liked the idea for setting up the “edit” alias, this will make it easier for our clients to work with their sites and is also somewhat faster for even us. I did like Matt”s suggestion here in the comments of using alternate templates to do this and followed that approach instead. I think this was a bit simpler to setup, didn”t require uComponents, nor did it require any extra nodes in the content tree. I also just put the one line of code for the Response.Redirect (using @Model.Id instead of having to use uQuery and path-splitting to determine) directly into the Edit template as an inline macro so I didn”t even need the spearate macro + script.
One last interesting thing I wanted to note is that doing it this way means it only works if you leave off the trailing slash after “edit”… e.g., /some-page/edit will work but /some-page/edit/ will not. No big deal, just wasn”t expecting it and thought I had setup something wrong, since I tend to put slashes at the end of things by habit.
Thank you again!