Thursday, November 5, 2009

Essential Visual Studio add-ins and other tools

Summary: Improve your programming experience with Visual Studio add-ins and other enhancements.

If you are a Windows programmer using Visual Studio, here are a few thing which can enhance your programming experience.

Visual Studio add-ins
  • Code Convert converts source code between C# and Visual Basic.NET.

  • CodeRush Xpress for C# includes hand-picked features taken from CodeRush and Refactor! Pro add-ins.

  • CopySourceAsHtml allows you to copy source code, syntax highlighting, and line numbers as HTML.

  • GhostDoc automatically generates XML documentation comments for methods and properties based on their type, parameters, name, and other contextual information.

  • NArrange automatically organizes code members and elements within .NET classes.

  • SelectionTree adds feature selection tree dialog to appropriate setup and deployment (MSI) projects.

  • Spell Checker supports text verification in HTML style comments, ASP.NET server side comments, JScript, C# and C++ comments, CSS and C, VB and VBScript style comments, as well as in JS, CS, VB, CSS, CPP and H files (requires Visual Studio 2008 SP1 and Microsoft Word 2003 or 2007).

  • StyleCop analyzes C# source code to enforce a set of style and consistency rules.

  • Versioning Controlled Build automates versioning of .NET and VC++ projects (handy for multi-project solutions).
Code snippetsHacks

Wednesday, October 14, 2009

Download free music... legally

Summary: Discover and download free music without violating the law.

If there is such thing as a typical music preference of a typical computer programmer, it probably does not apply to me. Sure, I like Pink Floyd, but my musical preferences diverge from majority of popular rock/hard rock/etc icons. My favorite music genre is baroque (Bach, Palestrina, Vivaldi), but I also enjoy The Mamas & the Papas, Cesária Évora, Angelique Kidjo, Al Bano & Romina Power, ABBA, Leonard Cohen, Joe Dassin, Astor Piazzolla, b-tribe, Canadian Brass, Ivan Kupala, and other performers, who have little in common with each other. Within the last year or so, I have been discovering performance by the less known artists (at least, less known by me), such as The Puppini Sisters, Natalia Clavier, Lee Rocker, and Melody Gardot, and I really liked some of them.

If your interests in music are similar to mine, this is how you can find and enjoy new music; it's free and absolutely legal.
  • Amazon.com
    Amazon.com offers free MP3 downloads, but the list of songs can be overwhelming. You can use the navigation panel to narrow songs by genre:


    In addition to individual songs, Amazon.com also offers free albums. To find free albums, use the Sort by Price: Low to High option.


    Amazon normally offers high quality MP3 files (above 192 Kbps).

  • Podcasts
    A number of radio stations offer one-song-a-day podcast downloads, which are normally of lower quality (128 Kbps - 192 Kbps), but they should sound fine to most ears. Sure most of the downloads are crap, but occasionally, you may stumble upon a gem. There must be more podcasts available, but here are the ones from NPR that I like:
    MPR: The Current Song of the Day (RSS)
    KCRW's Today's Top Tune (RSS)
    KEXP Song of the Day (RSS)
    To download podcasts, you can use a device-specific program, such as iTunes or Zune, but I prefer a free, open-source program called Juice.


    Once you find a track that you like among the downloads, you can use an application like Mp3Tag to edit ID3 tags (you may also want to rename file names, because the downloaded files normally have cryptic names).

  • Use RSS tools
    You can automate the process of searching for free MP3 downloads across multiples sources using RSS tools, such as Yahoo! Pipes. The key is to subscribe to the right aggregation service. I would recommend the SlickDeals' Freebes and Hot Deals forums, as well as Front Page (each of these has a subscribe/RSS link). You can follow this tutorial (and this one) to set up a Yahoo! Pipe filtering only posts containing music-specific keywords, such as free, MP3, music, album, etc.

  • Keep your eyes (and ears) open
    Many vendors offer free promotional MP3s and CDs, some of which are not too bad. For example, I do not remember how I got it, but somehow I received a free Mommy Mix CD from Safeway.


    Being a promotional CD, I did not expect much from it, but it it ended up being one of my family's favorite music CDs (in fact, if it were available for sale, I would've bought it). So don't assume that promotional music is always crappy, some may surprise you.
See also:
How to Get Free and Legal MP3 Downloads from… Universal Music!?
Top 10 Websites For Free & Legal MP3 Music Downloads
The 3 Best Free Classical Music Download Sites

Thursday, September 17, 2009

Technobrief #9

Summary: Recent findings of software, articles, and more.

EnglishGuidelines and standards
  • Windows UX Interaction Guidelines: 828-page guide (PDF) for each aspect of Windows 7 user experience (UX); the first 32 pages cover the UX design principles for Windows 7, a list of inspirations for how to design a great UX, top design guide violations, and more.
Quotes
  • From Don't Believe Anyone by Jurgen Appelo:
    "After eating and sleeping, disagreeing comes third on the list of basic necessities in my life. It's because I like thinking."
Jobs
  • From 7 great reasons to work at Netflix (Reason #5):
    Rules Annoy Us
    Rules creep into most companies as they try to prevent errors by less-than-stellar employees. But rules also inhibit creativity and entrepreneurship, leading to a lack of innovation. Over time this drives a company to being less fun and less successful. Instead of adding rules as we grow, our solution is to increase talent density faster than we increase business complexity. Great people make great judgment calls and few errors, despite ambiguity.
Programming
  • ComposedRegex: Martin Fowler explains how to write more readable regular expressions.
  • Four switch oddities: Eric Lipper explains non-obvious aspects of the switch statement (I did not know any of these).
  • TDD Anti-Patterns: James Carr catalogs the most common misuses of and omissions in Test-Driven Development.
Software
  • AoA Audio Extractor provides you a handy tool to extract audio/sound or background music from video files.
  • Copy Path is a Windows shell extension that adds the ability to copy the path, folder path, or filename within the right click shell extension; works on individual and multiple files and folders.
  • GoOo is another Microsoft Office alternative based on the OpenOffice.org source code; it claims to be fster and slicker.
  • Precision Helper creates and manages help projects; works natively with the Microsoft HTML Help projects format (HHP) and allows to publish resulting help to the CHM, WebHelp, PDF and the single HTML document formats.
  • SmillaEnlarger increases the size of digital images while trying to retain the quality.
  • SpyDLLRemover is the standalone tool to detect and delete spywares from the system.
  • StyleCop analyzes C# source code to enforce a set of style and consistency rules.
  • XMedia Recode is a video converter, which can cut and crop a movie, change the resolution, invert and correct the colors and do more (to change the default German interface to English, use the Optionen - Sprache menu option).
Web developmentWeb tools

Tuesday, August 25, 2009

Sending HTML-based email from .NET applications

Summary: How to use XSL templates to design, build, and test HTML-based email, and avoid common pitfalls in the process.

If you're writing a .NET application that sends HTML-based emails, you have a number of options: you can use .NET Framework's own MailDefinition class, build a custom solution just like Dave did, or use a third party library similar to TemplateEngine by Ader Software. In this post I'll explain how to design, test, and generate complex HTML-based email messages using XSL transformations (XSLT). I'll also explain how to avoid common problems related to HTML-based emails and describe the tools that will help you in doing so.

Before I get to the nitty-gritty, let me briefly summarize the idea. You, a designer (or developer), create an XSLT file that defines an email template. To convert the XSLT template to an HTML message body, you application will load the XSLT file at run time (you will need to make sure that the application has access to the file location) and merge it with the data (data must be formatted as an XML document). The XSLT engine will substitute the placeholders with data and use conditional formatting to generate the HTML markup.

The advantages of using XSLT files for email templates include:
  • No dependency on custom libraries: Everything is built into the .NET Framework.
  • Flexible transformations: XSLT allows rather complex transformations and substitutions. For example, you may not know at design time how many items the message must display, in which case, word-by-word substitution will not work; XSLT handles cases like this nicely.
  • Ease of design and testing: You can build a number of data XML files and use them to test your template without running or debugging the application.
Here are the steps you need to follow:
  1. Define XML structure to hold your data inputs.
    I found it helpful to create static XML files to be used for testing XSLT templates for various combination of inputs. Your sample XML data file may look like this one:

    Newsletter.xml
    <?xml version="1.0" encoding="utf-8" ?>
    <Root>
    <UserName>Mary Sweet</UserName>
    <Message>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</Message>
    <Offers>
    <Offer>Aenean sed nunc nec felis interdum rutrum...</Offer>
    <Offer>Nullam facilisis erat nec dolor tempor sed interdum neque consectetur...</Offer>
    </Offers>
    <UnsubscribeUrl>http://somesite.com/unsubscribe </UnsubscribeUrl>
    </Root>

    You can add sample XML data files to your project so you have them at hand for quick testing once you need to make changes to XSLT files, which you'll create in the next step.

  2. Create XSLT files for HTML-based email templates.
    If your email templates are totally different (say, you use one template for password expiration notices, and another for a weekly newsletter), then you will need to define multiple XSLT files (one for each template), but slight variations in a single template can be handled with the help of XSLT language constructs within the same file. If you end up with more then one XSLT template, I recommend implementing common sections of the message (e.g. header, footer, styles) in separate XSLT files, which you can then include in the final templates. For example here are three shared templates that define common header, footer, and CSS styles:

    Header.xslt
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template name="Header">
    <!-- If you need common header elements (logo, etc), include them here. -->
    </xsl:template>
    </xsl:stylesheet>

    Footer.xslt
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template name="Footer">
    <xsl:param name="UnsubscribeUrl"/>
    <p>Best regards,</p>

    <p>John Doe, Editor</p>

    <!-- Only display message if URL is available -->
    <xsl:if test="string($UnsubscribeUrl) != ''">
    <p>
    <hr/>
    <span class="Footer">
    If you wish to stop receiving this newsletter, please
    <a>
    <xsl:attribute name="href">
    <xsl:value-of select="$UnsubscribeUrl"/>
    </xsl:attribute>unsubscribe</a>.
    </span>
    </p>
    </xsl:if>
    </xsl:template>
    </xsl:stylesheet>

    Style.xslt
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template name="Style">
    <style type="text/css">
    body {
    font-family:Verdana;
    font-size: 10pt;
    background-color: white;
    color: black; }
    td {
    font-family:Verdana;
    font-size: 10pt;
    background-color: white;
    color: black; }
    p {
    margin-top: 8pt;
    margin-bottom: 8pt; }
    p + p {
    margin-top: 8pt;
    margin-bottom: 8pt;
    }
    <!-- More definitions -->
    </style>
    </xsl:template>
    </xsl:stylesheet>

    Assuming that you place the shared files in the Common subfolder under the main XSLT templates, you can reference them from templates as illustrated in the following example (note: when referencing an external template, use relative path in relation to the caller template):

    Newsletter.xslt
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:include href="Common/Style.xslt"/>
    <xsl:include href="Common/Header.xslt"/>
    <xsl:include href="Common/Footer.xslt"/>
    <xsl:output method="html"/>
    <xsl:template match="/">
    <html>
    <head>
    <xsl:call-template name="Style"/>
    </head>
    <body>
    <table>
    <tr>
    <td>
    <xsl:call-template name="Header"/>

    <p>Dear <xsl:value-of select="/Root/UserName"/>,</p>

    <p><xsl:value-of select="/Root/Message"/></p>

    <xsl:if test="/Root/Offers/Offer">
    <p>Here are this week's offers:</p>
    <xsl:for-each select="/Root/Offers/Offer">
    <blockquote>
    <xsl:value-of disable-output-escaping="yes" select="."/>
    </blockquote>
    </xsl:for-each>
    </xsl:if>

    <xsl:call-template name="Footer">
    <xsl:with-param name="UnsubscribeUrl"
    select="/Root/UnsubscribeUrl"/>
    </xsl:call-template>
    </td>
    </tr>
    </table>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>
    Notice how the XSLT markup references data values from the XML document using XPath.

  3. Test XSL transformations.
    Once you got your XSLT templates and sample XML files ready, you can test transformation using Visual Studio (activate XSLT file and select Show XSLT output from the XML menu; on the first attempt you will be prompted to specify the XML file) or other tools. Use different versions of the data XML files to test various permutations of data.

  4. Test HTML-based email in the intended email client programs (web sites).
    Although, your XSLT template may produce perfectly good HTML, there is no guarantee that it will look good in a particular email client. For example, Microsoft Outlook 2007, which uses the Word 2007 HTML rendering engine, does not recognize many of the standard CSS constructs. I learned the hard way that I could not use DIV tags to limit the page width (had to switch to TABLE tags). In the references section at the bottom of the post I included some articles discussing inconsistencies between HTML rendering in various email clients, but they did not help me much (I figured out how to fix formatting issues by trial and error), so the best thing you can do is to check how the mesages appear in various client application (Outlook 2003, Outlook 2007, Thunderbird, Gmail, etc).

    For testing email messages, I recommend using the free Mozilla Thunderbird email client. Unlike other email clients, Thunderbird allows pasting unaltered HTML source in the message body, so you can send the message in the exact same format as your program. To send your HTML-based email messages via Thunderbird, do the following:

    • In the program you use to test your template transformations, select the option to view source of the resulting HTML and copy it to the clipboard.
    • Switch to Thunderbird and create a new message.
    • In the message Compose form, click in the body field and select Insert - HTML from the main menu.

    • Insert the HTML markup from the clipboard into the Insert HTML dialog box, and click the Insert button.


  5. Implement code to handle XSL transformations.
    The following example illustrates how a console program loads an XSLT template, merges it with XML document holding data, and uses the resulting HTML as the email body (note: the example does not contain any error handling):

    Program.cs
    using System;
    using System.Xml;
    using System.Xml.Xsl;
    using System.IO;
    using System.Net.Mail;

    namespace EmailXsltDemo
    {
    class Program
    {
    static void Main(string[] args)
    {
    // Input data will be defined in this XML document.
    XmlDocument xmlDoc = new XmlDocument();

    // We will use XML nodes to define data.
    XmlElement xmlRoot;
    XmlNode xmlNode;
    XmlNode xmlChild;

    // XML structure for data inputs (we'll add <Offer> elements later).
    xmlDoc.LoadXml(
    "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
    "<Root>" +
    "<UserName/>" +
    "<Message/>" +
    "<Offers/>" +
    "<UnsubscribeUrl/>" +
    "</Root>");

    // Set the values of the XML nodes that will be used by XSLT.
    xmlRoot = xmlDoc.DocumentElement;

    xmlNode = xmlRoot.SelectSingleNode("/Root/UserName");
    xmlNode.InnerText = "Mary Sweet";

    xmlNode = xmlRoot.SelectSingleNode("/Root/Message");
    xmlNode.InnerText =
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";

    xmlNode = xmlRoot.SelectSingleNode("/Root/Offers");

    // Insert two <Offer> elements and set their values.
    xmlChild = xmlDoc.CreateNode(XmlNodeType.Element, "Offer", null);
    xmlChild.InnerText =
    "Aenean sed nunc nec felis interdum rutrum vivamus tempor.";
    xmlNode.AppendChild(xmlChild);

    xmlChild = xmlDoc.CreateNode(XmlNodeType.Element, "Offer", null);
    xmlChild.InnerText =
    "Nullam facilisis erat nec dolor tempor sed interdum neque consectetur.";
    xmlNode.AppendChild(xmlChild);

    xmlNode = xmlRoot.SelectSingleNode("/Root/UnsubscribeUrl");
    xmlNode.InnerText =
    "http://somesite.com/newsletter/unsubscribe/?user=1234567890";

    // This is our XSL template.
    XslCompiledTransform xslDoc = new XslCompiledTransform();
    xslDoc.Load(@"..\..\Xslt\Newsletter.xslt");

    XsltArgumentList xslArgs = new XsltArgumentList();
    StringWriter writer = new StringWriter();

    // Merge XSLT document with data XML document
    // (writer will hold resulted transformation).
    xslDoc.Transform(xmlDoc, xslArgs, writer);

    MailMessage email = new MailMessage();

    email.From = new MailAddress(<YOUR_FROM_ADDRESS>);
    email.To.Add(<YOUR_TO_ADDRESS>);
    email.Subject = "Demo message";
    email.IsBodyHtml = true;
    email.Body = writer.ToString();

    // Specify appropriate SMTP server, such as "localhost".
    SmtpClient smtp = new SmtpClient(<YOUR_MAIL_SERVER>);

    smtp.Send(email);
    }
    }
    }
For your convenience, I created a sample Visual Studio 2008 project which illustrates the functionality:

Download sample project

Before running the project, make sure that you substitute the YOUR_FROM_ADDRESS, YOUR_TO_ADDRESS, and YOUR_MAIL_SERVER placeholders with the actual string values.

See also:
What kind of language is XSLT?
How to Code HTML Email Newsletters
The Dark Heart of HTML Email
Guide to CSS support in email clients
2007 Office System Tool: Outlook HTML and CSS Validator
Template Messages Using XSL Transformations and XML Serialization

Friday, August 7, 2009

How to optimize web page width

Summary: One approach for optimizing a web page layout to make it look nice on both smaller and bigger screens.

When it comes to web page width, web designers choose between two basic options: fixed width and liquid (AKA dynamic, stretch, etc) width. Either option has a number of pros and cons, but it looks like the fixed width approach is more prevalent. And this irritates the heck out of me! I just hate having to scroll up and down when navigating a web page half of which content is empty. I do not use small computing devices, but I suspect that people, who view fixed width web pages on 10"-screen netbooks, also do not enjoy scrolling left and right.

Fixed layoutLiquid layout

Dynamic web page layouts maximize the use of screen real estate and minimize scrolling, but they have one drawback: many liquid pages look weird on bigger (24"+) monitors. And just as wide-line paragraphs are difficult to read, really wide web pages are difficult to use.

A few years ago, when 15"-19" monitors used to be the norm and the spread between the small and big monitors was not as big, this was not such a big problem. Now, with cheap large (21"+) monitors and small devices (like 10"-screen netbooks) gaining popularity, it is more difficult to optimize a web page for different screen sizes. So how do you design a web page layout to make it look nice on both 10" and 24" screen?

I have an idea, but before I get to it, let me summarize and justify my goals.
  • Goal #1: No wasted space.
    White space is generally good, but only until it starts causing unnecessary hassles. For example, it makes no sense to force the user to scroll vertically on a page with 40% of blank content (on the left and right sides).

  • Goal #2. Reduce scrolling.
    Vertical scrolling is bad, but horizontal scrolling is worse. There should be no need to scroll horizontally when viewing a page on 12"+ screen. Of course, depending on the displayed content, there may be exceptions (e.g. a grid is more likely to require horizontal scrolling than say textual content). Vertical scrolling should be required only when there is no wasted white space.

  • Goal #3: Trim content width when page is too wide.
    Wide page is normally good, but not too wide. There is a threashold, after which each page width increase will reduce its readability.
With these goals in mind, here is my idea:
When designing a web page layout, use liquid (dynamic) width until a certain threashold is reached (the threashold would depend on the type of the page); when the width of the browser window exceeds the value of this threashold, switch the page layout to fixed width.
This approach offers the best of both worlds: it minimizes wasted space and scrolling on small and medium size screens, and it improves page readability on larger screens. It also does not require to resize the browser window on a bigger screen to make the page smaller.

Now, how do you actually implement this layout? I'm not particularly strong in CSS and web design, so I was not even sure if it was possible. Fortunately, it is. The answer came from user PortageMonkey, who responded to my question at StackOverflow. To make it work, you just need to define the maximum width of the container holding your web page content (normally, a <DIV> or <TABLE> element) using the max-width CSS selector. The max-width selector is supported by all major browsers, except IE 6 (and earlier). To make this functionality work on IE 6, use IE dynamic properties to set up the page width, such as in the following example, which limits the width of an element to 600 pixels:

width: expression(document.body.clientWidth > 600 ? "600px": "auto");
Here is the complete example:

<html>
<head>
<style>
div#content
{
  max-width: 600px;
  width: expression(document.body.clientWidth > 600 ? "600px""auto" );
  border: red 1px solid;
}
div#wrapper {width: auto; border: blue 1px solid;}
</style>
</head>
<body>
  <div id="wrapper">
    <div id="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit.[...]</div>
  </div>
</body>
</html>
If you save this page on a local drive and try to open it in IE, you will notice an ActiveX warning that gets displayed because the CSS style section uses the expression property. If you do not allow blocked content, the page will not work as expected. Fortunately, the warning appears only when you try to open local files (via the file:/// protocol), so it should not be an issue.

This is what the content of a page would look like when the width is below the maximum (the inline images are adjusted, so they appear to have the same width, although they are not [compare the text displayed on each line]; to see the original, click the image):

And once you increase the width beyond the threashold, the content will stay within the maximum width boundary:

When using this approach, simply adjust the value of the maximum width to the size that is most appropriate for your application.