13

Umbraco 4.5 & Visual Studio 2010 & .Less & jQuery vsdoc & SquishIt & masterpages

Posted by kipusoep on Jul 23, 2010 in Asp.NET, C#.NET, CSS, Umbraco, XHTML

Using Umbraco with VS2010

… and masterpages, jQuery vsdoc, dotless, SquishIt

Welcome all to this magnificent blogpost about using Umbraco 4.5 with Visual Studio 2010 and everything you’ll need to know about some other tools! ;-)

First things first; we, at InfoCaster, use Visual Studio 2010 and .NET to develop our Umbraco web applications. We try not to use XSLT, just because .NET is much better ;-) and everyone at InfoCaster knows .NET, unlike XSLT. I always like to say that .NET with LINQ can do like everything, but XSLT can’t or does things inefficient. It’s not even possible to assign a value to a variable for a second time. How variable is that ‘variable’ then? But that’s another discussion!

So a few months ago I started developing our own ‘Umbraco Website Starter project’. It’s like a clean Umbraco installation wrapped in a Visual Studio solution, with some extra’s, like some handy extension methods, pre-installed packages and default properties for the homepage (title prefix/suffix, Google analytics code, meta data etc.).

Now I migrated it to Umbraco 4.5 and removed all packages and installed the necessary packages again. I’d like to tell you all what I did and how.

Blueprint CSS

We’re using Blueprint CSS from now on to have a good start on creating our templates and stylesheets, this is combined with SquishIt.

.Less

We’re using .Less for our custom stylesheet. You can read everything about how to set this up in VS(2010), so I’m not going to explain that: http://www.dotlesscss.com/

I’m using SquishIt to generate the CSS files out of the .css.less files. These .css.less files can be opened with VS2010 with css highlighting / autocompletion by using this plug-in: http://visualstudiogallery.msdn.microsoft.com/en-us/dd5635b0-3c70-484f-abcb-cbdcabaa9923

<%= Bundle.Css()
	.Add("~/css/blueprint/screen.css")
	.Add("~/css/style.css.less")
	.WithMedia("screen, projection")
	.Render("~/css/output/screen_#.css")
%>

SquishIt and jQuery vsdoc

SquishIt download page: http://www.codethinked.com/post/2010/05/26/SquishIt-The-Friendly-ASPNET-JavaScript-and-CSS-Squisher.aspx

VS2010 has better intellisense features when it comes to JavaScript. So why not use jQuery with vsdoc and let SquishIt minimize and combine it for production environments?

Great idea! BUT this is how SquishIt requires it’s mark-up:

<%= Bundle.JavaScript()
    .Add("~/js/jquery-1.4.2.js")
    .Add("~/js/jquery-ui-1.8.1.js")
    .Render(&quot;~/js/combined_#.js")
%>

Hmm… That’s not going to work with intellisense/vsdoc, because Visual Studio looks for real <script> tags…

So what I did is this:

<asp:Literal runat="server" ID="ltlScripts">
    <script type="text/javascript" src="~/scripts/jquery-1.4.2.js"></script>
</asp:Literal>

Then you can just add any JavaScript reference you’d like :-) To enable vsdoc intellisense, you must also have the vsdoc file in the same folder as the realy jQuery file

The literal is being parsed in code-behind by using regex and it gets rewritten:

Regex scriptTagRegex = new Regex(@"<script(.*)type=""text/javascript""(.*)src=""(.*)"".*></script>");
IJavaScriptBundle jsBundle = Bundle.JavaScript();
IJavaScriptBundleBuilder jsBundleBuilder = null;
foreach (Match match in scriptTagRegex.Matches(ltlScripts.Text))
{
    if (jsBundleBuilder == null)
        jsBundleBuilder = jsBundle.Add(match.Groups[3].Value);
    else
        jsBundleBuilder.Add(match.Groups[3].Value);
}
ltlScripts.Text = jsBundleBuilder.Render("~/scripts/output/js_#.js");

Simple as that ;-) (using SquishIt.Framework.JavaScript)

Default meta properties

(title prefix/suffix, meta tags, meta description, meta title, favicon, Google analytics)

This is the markup I have as <head>:

<head runat="server">
    <title>Title will be filled from codebehind</title>

    <!-- meta data -->
    <meta name="author" content="InfoCaster B.V." />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="keywords" content="<%= CurrentNode.GetPropertyValueRecursive("pageKeywords") %>" />
    <meta name="description" content="<%= CurrentNode.GetPropertyValueRecursive("pageDescription") %>" />

    <asp:Literal runat="server" ID="ltlFavicon">
    <!-- favicon -->
    <link rel="shortcut icon" href="#HandledInCodeBehind" type="image/x-icon" />
    </asp:Literal>

    <!-- css -->
    <%= Bundle.Css()
        .Add("~/css/blueprint/screen.css")
        .Add("~/css/style.css.less")
        .WithMedia("screen, projection")
        .Render("~/css/output/screen_#.css")
    %>
    <%= Bundle.Css()
        .Add("~/css/blueprint/print.css")
        .WithMedia("print")
        .Render("~/css/output/print_#.css")
    %>
    <!--[if lt IE 8]>
    <%= Bundle.Css()
        .Add("~/css/blueprint/ie.css")
        .WithMedia("screen, projection")
        .Render("~/css/output/ie_#.css")
    %>
    <![endif]-->
    <asp:ContentPlaceHolder runat="server" ID="cphHead" />

    <!-- js @ bottom -->

    <asp:Literal runat="server" ID="ltlGoogleAnalytics">
    <!-- Google Analytics -->
    <script type="text/javascript">
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', '{0}']);
        _gaq.push(['_trackPageview']);

        (function () {{
            var ga = document.createElement('script');
            ga.type = 'text/javascript';
            ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0];
            s.parentNode.insertBefore(ga, s);
        }})();
    </script>
    </asp:Literal>
</head>

The title, favicon and Google analytics gets set from code-behind.

The meta tags/description are filled by using a recursive extension method I wrote.

I also added a content placeholder in the head and also at the end of the XHTML document, right before the </body>, so it’s possible to load custom CSS (head) and JS (bottom) per sub masterpage.

This is the code-behind which belongs to this mark-up:

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);

    #region Page stuff (google analytics, favicon, title)
    // Google analytics
    if (!string.IsNullOrEmpty(CurrentNode.GetPropertyValueRecursive("analyticsCode")))
        ltlGoogleAnalytics.Text = string.Format(
            ltlGoogleAnalytics.Text,
            CurrentNode.GetPropertyValueRecursive("analyticsCode")
        );
    else
        ltlGoogleAnalytics.Visible = false;

    // Favicon
    int faviconId;
    if (!string.IsNullOrEmpty(CurrentNode.GetPropertyValueRecursive("favicon")) && int.TryParse(CurrentNode.GetPropertyValueRecursive("favicon"), out faviconId))
        ltlFavicon.Text = string.Format(
            "{0}{1}{2}",
            ltlFavicon.Text.Substring(0, ltlFavicon.Text.IndexOf("href=\"") + ("href=\"").Length),
            new Media(faviconId).getProperty("umbracoFile").Value,
            ltlFavicon.Text.Substring(ltlFavicon.Text.IndexOf("href=\"\"") + ("href=\"").Length)
        );
    else
        ltlFavicon.Visible = false;

    // Title
    Page.Title = string.Format(
        "{0}{1}{2}",
        CurrentNode.GetPropertyValueRecursive("titlePrefix"),
        CurrentNode.GetPropertyValueOrDefault("pageTitle", CurrentNode.Name),
        CurrentNode.GetPropertyValueRecursive("titleSuffix")
    );
    #endregion
}

Easy right? :-)

Extension methods

I wrote some extension methods to ease some default tasks.

These extension methods are duplicated, for use in multilingual sites.

You can download the .cs file right here, it contains enough comments/documentation. Look at the end of this post :-)

Masterpage intellisense VS2010 bug

There is a bug in VS2010 when using Umbraco’s masterpage as root master (umbraco.presentation.masterpages._default). The intellisense doesn’t work anymore. I’ve created a bug report on Microsoft Connect about this: https://connect.microsoft.com/VisualStudio/feedback/details/567771/no-asp-tag-intellisense-in-some-cases-when-using-masterpages

I’ve got a ‘dirty’ work-around. I don’t know if this work-around works with the ‘Canvas-editing’ feature in Umbraco (we and our customers don’t use it).

Just let every main masterpage (with <html> tags) inherit: umbraco.presentation.masterpages._default

#Protip: Creating new templates

When using Visual Studio, it’s nice to have code-behind files for your templates (at least, that’s how we do stuff). If you create a template in Umbraco, it creates a masterpage without code-behind…

Then you would have to add a code-behind manually, link it with the mark-up and create designer file. That sucks right?

Just do this:

  1. Create a nested masterpage in VS and use your ‘master’-masterpage as masterpage in the masterpages folder. Lol, there’s a lot of ‘masterpage’ in that sentence hehe.
  2. VS creates a masterpage for you with code-behind, sweet!
  3. VS opens the mark-up of this newly created masterpage, keep it opened!
  4. Then go to your Umbraco back-end and create a template like you would normally do. Give it the same name as you defined in step 1.
    This should create an Umbraco template by using the already created masterpage as file.
  5. Now return to Visual Studio. It should notify you that the file has changed and gives you the option to reload the file. Reload and then use CTRL+Z to undo the changes made by Umbraco (else the code-behind won’t be linked to the mark-up) and save it.
  6. You’re done!

Downloads

‘Master’-Masterpage with code-behind: StefanKip.InfoCaster.Umbraco.masterpage

Extension methods: UmbracoExtensions.cs (remove ending .txt)

 
0

301 URL Tracker v1.1 for Umbraco

Posted by kipusoep on Mei 12, 2010 in Asp.NET, C#.NET, Umbraco

I just released an update for the 301 URL Tracker for Umbraco: http://bit.ly/301URLTracker

Changelist

  • [Bug fix (critical)] The 404 Handler returned ’301 URL Tracker’ as HTTP Status instead of ’301 Moved Permanently’
  • [New feature] View/manage Url Mappings on the node itself with the new 301 URL Tracker Datatype (ofcourse you must add a property, with the 301 URL Tracker Datatype, to a Document Type and !!!REMOVE IT WHEN YOU ARE GOING TO UN-INSTALL THE 301 URL TRACKER !!!)
  • [New feature] Create RegEx Url Mappings (url mappings will be tried to match first, if no match found RegEx matching kicks in, ordered by Insertion date ascending)
  • [New feature] Option to disable the 301 URL Tracker (add to appSettings: <add key=”infocasterDisable301URLTracker” value=”true” />
  • [New feature] When clicking on the ’301 URL Tracker’ node in the tree, there’s a button to view all not found requests

 
0

301 URL Tracker for Umbraco

Posted by kipusoep on Apr 28, 2010 in Asp.NET, C#.NET, Umbraco

Just released my second package for Umbraco; the 301 URL Tracker.

I could really use some feedback for my graduation report, so please leave some when you’ve given it a run!

Release notes

About the 301 URL Tracker package

The 301 URL Tracker package is created by InfoCaster. The original idea comes from Soeteman Software.

The purpose of the 301 URL Tracker package, is to create some SEO friendlyness.
Search engines crawl your website and store links to all pages within your website.
The 301 URL Tracker keeps track of all the url changes of these pages:

  • When a document is moved it gets a new url
  • When a document is renamed it gets a new url

The old urls are stored and when someone requests one of these old urls, they are automatically transfered to the correct new url, with a 301 HTTP response.
Search engines recognize this HTTP response and replace the old location with the new location.

All features of the 301 URL Tracker package:

  • Keeps track of url changes and redirects requests from these ‘old’ urls to the new ones
  • Ability to create custom url mappings, e.g. when you get a new website, the urls can be changed. This way you can map old urls to new ones
  • Remove any url mapping; automatically tracked urls and custom mapped urls

Some hints

  • When a document gets a new url, the old url is saved and the document is automatically added to the 301 URL Tracker tree (including all child documents)
  • When one wants to create a custom url mapping, just right-click on the 301 URL Tracker node and click ‘Create’. Select the document to create the custom url mapping for
  • The reason for an automatic mapping is shows next to the mapping url. When creating custom mappings, you can add your own note to the mapping
  • To delete all url mappings for a document, just right-click on the document in the 301 URL Tracker tree and press ‘Delete’. Important note: the documents underneath the deleted one will NOT be removed, although it looks like they are
  • The url mappings are ordered by date descending. To view the creation date of a mapping, hover with the mouse over the url of a mapping entry
  • When a document with configured url mappings gets recycled, it won’t show up in the 301 URL Tracker tree anymore (and the url mappings won’t work)
  • When a document gets moved back from the recycle bin, it shows up again in the 301 URL Tracker tree. When a document gets deleted for real, the url mappings get deleted too

Graduation project

This package is part of my graduation project. Yes, I’m trying to graduate with Umbraco as graduation topic. So I would like to call in your help!
I really need feedback for my graduation report. So please, if you have a spare moment, leave some feedback in the ‘Feedback forum’ below.
Thank you all very much in advance!

Requirements

  • .NET 3.5
  • SQL Server

Tested on

  • .NET 3.5
  • SQL Server 2008
  • Windows 7 Ultimate
  • IIS 7.5

 
0

True Color Picker for Umbraco

Posted by kipusoep on Nov 13, 2009 in Umbraco

This package will create a DataType called “True Color Picker”.
You may be wondering, what’s “True” doing there?
Well I was looking for a color picker without the need to provide pre-defined colors.
I saw the built-in Color Picker, but that’s not a color picker! It’s an approved color picker.
So I create a TRUE color picker.

This package will create the following files / directories:

/umbraco/css
    colorpicker.css
/umbraco/js/colorpicker
    colorpicker.js
/umbraco/images/colorpicker
    *

Link: http://our.umbraco.org/projects/true-color-picker 

Screenshot:

 
0

Ajax Control Toolkit 30390 for Umbraco

Posted by kipusoep on Nov 5, 2009 in Umbraco

I modified the Ajax Control Toolkit version 30390 so it can be used next to Umbraco’s ACT version.

Look at http://our.umbraco.org/projects/ajaxcontroltoolkit-30930-for-umbraco

Copyright © 2010 kipusoep’s tech blog All rights reserved. Theme by Laptop Geek.