2012-08-30

Squishify - Minify JavaScript & CSS Online

Squishify Screenshot

Squishify was created out of the need of a minifier for JavaScript. I quickly put together a web-app on AppHarbor to make minification always available quickly. The code is hosted on GitHub.

The application is an ASP.NET MVC-app, using Justin Etheredge's framework for minification called SquishIt. The app also uses ASP.NET Web API together with some simple jQuery to display the results of the minifications without any page-reloads.

The SquishIt-framework is a very easy to use and provides multiple minifiers for both JavaScript and CSS.

JavaScript minifiers:

* At the moment of writing this post, Google Closure is not working as expected, but should hopefully work soon.

CSS minifiers:

Enjoy it at squishify.apphb.com and fork it on GitHub.

2012-05-21

ASP.NET MVC 4 Razor v2 - New Features

Reference

With the imminent release of ASP.NET MVC 4 my previous post ASP.NET MVC 3 Razor - The Ultimate Quick Reference needed a follow-up on what's new in the view-engine Razor v2, that comes with MVC 4.

App-relative URLs automatically resolved

In Razor v1 your views would be littered with code like this:

<script src="@Url.Content("~/content/scripts.js")"></script>

But in Razor v2 you can shorten it with a tilde in front of the URL, which was used a lot in WebForms:

<script src="~/content/scripts.js"></script>

This will work for any HTML-attribute that starts with the title-sign.

Conditional attributes hides null-valued attributes

Razor v1 treated null-valued attributes as empty string, writing out attributes empty values. Razor v2 will instead skip even writing out the attribute that has a null value:

@{
    string itemId = string.Empty;
    string itemClass = "class-of-item";
    string itemValue = null;
}
<div id="@itemId" class="@itemClass @itemValue" rel="@itemValue"></div>

Will result in this HTML:

<div id="" class="class-of-item"></div>

Note that string.Empty still makes Razor v2 to write out the attribute. Any data-attribute will ignore this rule and always write out the attribute.

Support for unclosed HTML-tags

The HTML5-specs clearly states that unclosed HTML-tags are supported, but Razor v1 didn't have an advanced enough parser to support this. Razor v2 now supports this with the elements listed in W3C's spec.

What else?

There has been some major improvements on how the syntax-trees are structured and other deep functionality in the language. The focus was internal clean-up and future-proofing.

2012-05-14

DevSum Scheduler - Plan Your Attendance

DevSum 2012

Since I'm attending DevSum 2012 at the end of this month, I felt I needed to keep track of which talks to attend... but also the need to play around with some web-technologies.

From those needs I took some evening hours to build DevSum Scheduler. It's a web-app that allows you to highlight which talks you're going to attend.

The app uses HTML Agility Pack to get the data from DevSum's own website and then ASP.NET MVC Razor to display the content properly. To store this I've used HTML 5 LocalStorage to persist the choices made.

There are many other technologies used, which are listed on the about-page. Since the website is suppose to help the attendees by being available on their smart-phones, I've used CSS Media Queries for mobile layout and Modernizr for feature-detection in the web-browser.

Check out the full source-code on GitHub. Again, the outstanding AppHarbour has been used to quickly get the app on the Internet (through a GitHub-service hook of course).

2012-04-18

Making MVC 3 Razor IntelliSense work after installing MVC 4 Beta

After installing the MVC 4 Beta the IntelliSense breaks for Razor-views in MVC 3-applications in Visual Studio 2010. This is stated in the release-notes, but nobody usually reads those.

This time the solution to the problem are actually listed in those release-notes. You need to the explicitly state the version-numbers of the references in your web.config.

Add a new appSettings-entry for explicitly stating the version of WebPages to use:

<appSettings>
    <add key="webpages:Version" value="1.0.0.0"/>
    <!-- ... -->
</appSettings>

Then you have to edit your .csproj-file, where you need to find your references to System.Web.WebPages and System.Web.Helpers and makes sure they have the explicit version-numbers like this:

<Reference Include="System.Web.WebPages, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/> 
<Reference Include="System.Web.Helpers, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />

Hopefully this will be resolved in the final version of MVC 4 or maybe the case is that the references to versions in Razor v1 were just too loose in MVC 3-projects.

2012-03-23

HtmlEncoder - Testing out MVC 4 on AppHarbor & GitHub

ASP.NET, AppHarbor, GitHub

HtmlEncoder is a web-application built on ASP.NET MVC 4, source-controlled on GitHub, deployed on AppHarbor.

GitHub allows you to directly deploy to AppHarbor on checkin/push to the Git-repository, which is a very powerful and useful feature, to quickly get your ASP.NET web-apps online in the cloud.

It started out with a need to encode strings for HTML and developed into a quick test of how Web API on MVC 4 works in an AJAX-enabled web-app.

Try it out at http://htmlencoder.apphb.com and fork it on GitHub.

2012-03-21

ASP.NET MVC 3 Razor - The Ultimate Quick Reference

Reference

With the transition to the Razor view-engine in ASP.NET MVC 3 a need occurred for a quick-reference.

Sections - Replacement for 'asp:ContentPlaceHolder' and 'asp:Content'

Where you the old WebForms view-engine used to use the controls and to dynamically switch out parts of the content on a page, the Razor view-engine uses sections.

_Layout.cshtml (Equivalent to a .master-page):

<div>Template content</div>
@RenderBody()
<div>More template content</div>
@RenderSection("OtherContent", required: false)

Page.cshtml:

@section OtherContent {
    <span>Other content goes here</span>
}
<div>Main page-content</div>

In above code the RenderSection-method in the _Layout.cshtml renders the content within the matching @section in the Page.cshtml. The required-parameter indicates if the section is required and should throw an exception if the section doesn't exist. The RenderBody-method renders the rest of the content in the Page.cshtml, which is not inside any section.

Declaring the ViewModel

In the old WebForms view-engine your declaration of the view-model would look like something like this:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
    Inherits="System.Web.Mvc.ViewPage<MyViewModel>" %>

While in the Razor view-engine declaring your view-model is as easy as this:

@model MyViewModel

Inline C#-code in the HTML

If you wanted to loop over a collection in your view-model in WebForms view-engine your code would look something like this:

<% foreach(var item in Model.Items) { %>
    <% if(item.IsValid()) { %>
        <div class="<%: item.ClassName %>">&;lt;%: item.Title %></div>
    <% } %>
<% } %>

The percent-tags make it a bit hard to quickly get an overview of what is HTML and what is code. This is one of the largest upsides to the Razor view-engine, where the same code would be written much more readable like this:

@foreach(var item in Model.Items) {
    if(item.IsValid())
    {
        <div class="@item.ClassName">@item.Title</div>
    }
}

If you make a proper installation of MVC 3 you will get syntax-highlighting in Visual Studio for separating C#-code and HTML-tags.

Advanced inline C#-code

Razor is extremely intelligent when it comes to determining when code starts and ends behind the @-signs, which is very well visualized by the IntelliSense in Visual Studio.

<div>This is @Model.Name's page</div>

Since the apostrophe doesn't follow any pattern that could make it correct C#-code, Razor knows to cut the code from there.

If you want to be extra clear in your code, against other developers, but also against Razor, as to where the code starts and ends, you can use parentheses like this:

<div>This is @(Model.Name)'s page and has the status "@(Model.Status)"!</div>

Inline C#-code for logic

You can include code on the page that is not necessarily written out on the page directly, but handles logic and page-specific functionality. For this you use the @-sign, followed by curly braces.

<div>Other content</div>
@{
    string capitalizedTitle = Model.Title.ToUpper();
}
<h1>Page about @capitalizedTitle</h1>

This is used in the templates that comes with MVC 3 to set which Layout-file to use. But you can use this on your own for setting the title-text in the title-tag.

Page.cshtml:

@{  
    ViewBag.Title = "Index titel - " + Model.SubTitle;
}

_Layout.cshtml:

<head>
    <title>@ViewBag.Title</title>
    <!-- ... -->

Helpers - Reusing code specific to view-template

With the new @helper-syntax in Razor you can easily write re-usable methods that deals with output-functionality within view-templates.

@helper ShowInfo(string name, bool hasContent) {
    if(hasContent) {
        <div>This is info about @name.ToUpper()</div>
    }
}

Namespaces

Using a namespace is very easy and reminds us a lot of the old way to do it:

@namespace System.ComponentModel.DataAnnotations

Server-side comments

To do server-side comments with Razor you can click the "Comment" toolbar button or press Ctrl+K, Ctrl+C to apply a server-side comment. The commented code is place between a @* and a *@ and looks like this:

@" This is the text of the model. MUST be HTML-encoded. "@
<div class="special-elemet">@Model.Text</div>

Global settings for view-templates

If you place a file named _ViewStart.cshtml in the root of the ~/Views-folder, the Razor-code in this code will be applied as default to all view-templates in the sub-folders. In the templates that comes with MVC 3 this is used to set the default Layout-file to be used for the view-templates.

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Not HTML-encoding content

In the old WebForms view-engine you could use a colon-character instead of an equals-sign to HTML-encode content like this:

<%= ContentToBeOutputWithoutEncoding %>  
<%: ContentToBeEncoded %>

The Razor view-engine automatically HTML-encodes whatever strings you output without explicitly using Html.Raw-method like this:

@Html.Raw(ContentToBeOutputWithoutEncoding)

The <text>-tag for Razor

The way Razor analyzes the code to find the start and end only makes it it possible to have one element (with multiple children of course) inside an expression. To resolve this Razor introduces a <text>-tag, where you can nest multiple lines of code:

<text>
    <div>One nested item</div>
    <span>Another nested item</span>
</text>

2012-02-12

jMapMarker - jQuery-Plugin to Easily Add Google Maps with Markers to Your Website

jQuery

Just uploaded my new project called jMapMarkers to GitHub.

It's a jQuery-plugin that easily allows the user to add one or more Google Maps-maps with markers and info-windows to the website.

It uses a simple object-literal as an argument for configuration when calling. To add a map to a div-tag with and ID, simple use the following code:

$('#map-placeholder').jMapMarkers({
    mapOptions: { // Straight Google Maps API-configuration
        zoom: 1,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: false
    },
    markers: [
        { lat: '59.329444', long: '18.068611', title: 'Stockholm', desc: 'Capital of Sweden' },
        { lat: '59.949444', long: '10.756389', title: 'Oslo', desc: 'Capital of Norway' }
    ]
});

You can even add on more markers after the initial map has been added. Just leave out the mapOptions-argument in the configurations-arguments, like this:

$('#map-placeholder').jMapMarkers({
    markers: [
        { lat: 52.500556, long: 13.398889, title: 'Berlin', desc: 'Capital of Germany' },
        { lat: 48.8567, long: 2.3508, title: 'Paris', desc: 'Capital of France' },
        { lat: 51.507222, long: -0.1275, title: 'London', desc: 'Capital of England' }
    ]
});

You can find examples in the demo.html-file in the GitHub-project.

A big bonus-feature is that if you don't state otherwise the plugin will automatically zoom and move the map so that all markers are visible, after markers are added to the map.

As it say in the GitHub-README: please feel free to fork and/or give feedback.

2011-09-27

Microsoft Word Macro: Convert Word-files to PDF-files

Microsoft Word Macro

This post comes out of me helping a colleague with a quick macro, for Microsoft Office Word, that he needed to speed up service towards a customer.

I simply recorded a macro while converting one Word-file into a PDF-file and then Googled for some code to access files on disc and put it all together in a loop.

Sub ConvertWordsToPdfs()

    Dim directory As String    
    directory = "C:\Wordup"
  
    Dim fso, newFile, folder, files
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Set folder = fso.GetFolder(directory)
    Set files = folder.files
    
    For Each file In files

        Dim newName As String
        newName = Replace(file.Path, ".doc", ".pdf")
                
        Documents.Open FileName:=file.Path, _
            ConfirmConversions:=False, ReadOnly:=False, AddToRecentFiles:=False, _
            PasswordDocument:="", PasswordTemplate:="", Revert:=False, _
            WritePasswordDocument:="", WritePasswordTemplate:="", Format:= _
            wdOpenFormatAuto, XMLTransform:=""
            
        ActiveDocument.ExportAsFixedFormat OutputFileName:=newName, _
            ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
            wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=1, To:=1, _
            Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
            CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
            BitmapMissingFonts:=True, UseISO19005_1:=False
        
        ActiveDocument.Close
      
    Next

End Sub

I guess I won't update or tune this macro a lot, but you can find this macro as a Github Gist as well.