Designing a web site using the Yahoo! User Interface Library

by Michael F. Collins, III September 12, 2008 19:03

The hardest part of starting a new web site design is coming up with the killer layout for the site. There are many issues to consider when designing site and implementing the design. Do you use table-based layouts or CSS layouts? If you use CSS layouts do you float specific columns to the left or right side? How big should the page or columns be? What order do I need to put the content in the web page in order to maximize the search engine optimization? How do I do a negative margin to move my secondary content before my primary content? Fortunately, the wonderful developers at Yahoo! thought up some of these issues for you already and provide a great open source toolkit to help take some of these decisions away and make the implementation quicker and much, much easier.

The Yahoo! User Interface Library, available on the Yahoo! Developer's Network web site is a library of reusable components that can be used to design and implement a web site using standard web technologies such as CSS and JavaScript. The current release of the Yahoo! User Interface Library (YUI) is version 2.5.2, but preview releases of version 3 have started to appear on the YUI web site. This post will focus on the 2.5.2 release.

Grading browsers

Yahoo!, being one of the largest and most used web sites on the Internet, has a lot of pressures as a web content provider. First, being Yahoo!, they have to support pretty much any user using almost any browser. Additionally, being Yahoo!, they have to make their web site look and function almost identical in any browser that can surf the web. Therefore, it's important for Yahoo! to have a standard mechanism for designing their web pages once without regard to the browser that's using it.

To accomplish this goal, Yahoo! has defined various classifications of web browsers and identified what level of support each web browser has for the web standards. Yahoo! has defined three grades: A, C, and X for browsers. C-grade is the basic browser providing core services. C-grade browsers are highly accessible and use little or no decoration. Features such as CSS and JavaScript are not available in C-grade browsers. An example of a C-grade browser may be a text-only browser that might be used by someone that is visually impaired.

An A-grade browser is going to be a major browser such as Microsoft Internet Explorer, Firefox, Opera, or Safari on the Mac.  A-grade browsers have high levels of support for rich web content including CSS and JavaScript.

X-grade browsers are those rare or exotic browsers. Maybe someone named Dan creates his own browser named Dan's Browser. Support for the web standards may or may not be there, and may or may not have been tested very well. You may get Dan to browse your web site using his browser, but there's no way that you can test how compliant his browser is going to be with the web standards.

In general, when designing a web site, you'll focus only on the A-grade browsers as those are the major browsers with the most market exposure that you want to support, unless of course your name is Dan and you have written your own browser, in which case you are going to focus on your X-grade browser.

Standardizing browser support

One of the biggest challenges in web design is getting a single page to look the same in each browser. Browsers, by their nature, are all different and implement and render HTML differently. Microsoft Internet Explorer may come pre-configured to use fonts, font sizes, and colors that are deemed to be "more standard" for the Windows platform. Safari may have settings that are more like the standard Mac look and feel. Firefox will have a different set of defaults for fonts, colors, and font sizes. Likewise, margins, padding, borders, and all other rendering features will have defaults that may or may not differ from the other browsers.

The Yahoo! User Interface Library helps to normalize each of the browsers so that a page starts out with a single look-and-feel that is independent of browser differences. YUI does this by providing four CSS style sheets that neutralize the pre-defined browser style settings and defining a common set of base styles that will make a page look the same (within reason) regardless of the browser being used to view the web page.

The YUI library provides four CSS style sheets that can be reused by other web sites:

  • Reset: removes and neutralizes the inconsistent default styling of HTML elements, creating a level playing field across A-grade browsers and providing a source foundation upon which you can explicitly declare your intentions.
  • Fonts: offers cross-browser typographical normalization and control.
  • Grids: offers four preset page widths, six preset templates, and the ability to stack and next subdivided regions of two, three, or four columns.
  • Base: applies a consistent style foundation for common HTML elements across A-grade browsers.

Using the YUI CSS style sheets, you can design and easily implement your basic web page layout without having to create your own style sheets or figure out the browser differences on your own. Later in this post, I'll walk you through using the YUI CSS style sheets in an ASP.NET application and using YUI to design and layout your web pages.

Integrating YUI with an ASP.NET web site

The first task when adding YUI to an ASP.NET web site is putting the YUI CSS style sheets in a place where they can be downloaded by the client web browser. There are three options available to you for adding the CSS style sheets to your web page:

  • Download the CSS style sheets directly from the Yahoo! web server
  • Copy the style sheets into your ASP.NET application and reference the style sheets from your web pages
  • Embed the style sheets into a .NET assembly and access them as a web resources

Because of the way that I structure and use version control for my projects, the third option is actually the easiest for me. When I put projects under version control, I usually create a location in my version control repository where I will put third-party artifacts such as source code or binary files that I'll use in my programs. After placing the third-party artifacts into my version control repository, I will usually "branch them" into my project workspace. My version control repository might look something like the following:

  • /Vendor/YahooUILibrary
  • /ImaginaryRealities.com/Trunk/Libraries/YahooUILibrary
  • /ImaginaryRealities.com/Trunk/SourceCode/www

So, in the /Vendor/YahooUILibrary folder in my repository, I'll place the original YUI source code. My web site files are located in the /ImaginaryRealities.com/Trunk/SourceCode/www folder. I will then branch the YUI code from /Vendor/YahooUILibrary into the /ImaginaryRealities.com/Trunk/Libraries/YahooUILibrary folder. The trick now is that if I copy the CSS files from the /ImaginaryRealities.com/Trunk/Libraries/YahooUILibrary folder into the /ImaginaryRealities.com/Trunk/SourceCode/www folder, I'll lose the branch history with the copy and in the future I'd have to remember to do the manual copy. Not a good scenario, in my opinion.

Instead, what I did was to create a new assembly that will store the current and future YUI artifacts as embedded resources and will access them in my web site and related components. Below is the code that I wrote for embedding the CSS files as resources:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the YahooUIResources class that defines constants for the
// names of the embedded Yahoo! User Interface Library resources.
// 
//------------------------------------------------------------------------

[assembly: System.Web.UI.WebResourceAttribute(
    ImaginaryRealities.Website.UI.Yahoo.UI.YahooUIResources.BaseName,
    "text/css")]
[assembly: System.Web.UI.WebResourceAttribute(
    ImaginaryRealities.Website.UI.Yahoo.UI.YahooUIResources.ResetFontsGridName,
    "text/css")]

namespace ImaginaryRealities.Website.UI.Yahoo.UI
{
    /// 
    /// Defines constants for the names of the embedded Yahoo! User Interface
    /// Library resources.
    /// 
    public static class YahooUIResources
    {
        /// 
        /// The name of the embedded resource containing the CSS definitions
        /// for the base.css style sheet.
        /// 
        public const string BaseName =
            BaseNamespaceName + "base-min.css";

        /// 
        /// The name of the base namespace for the embedded resources.
        /// 
        private const string BaseNamespaceName =
            "ImaginaryRealities.Website.UI.Yahoo.UI.";

        /// 
        /// The name of the embedded resource containing the CSS definitions
        /// for the reset-fonts-grids.css style sheet.
        /// 
        public const string ResetFontsGridName =
            BaseNamespaceName + "reset-fonts-grids.css";
    }
}

I added the YUI base-min.css and reset-fonts-grids.css files to my Visual Studio Class Library project as linked files and set the Build Action property in Visual Studio to Embedded Resource to make sure that the files were embedded into the generated assembly. I then used the WebResourceAttribute attribute to define the files as embedded resources that could be served by ASP.NET. To make it easier to reference the embedded resources by name, as well as make any name changes if necessary in the future, I defined constants for the resource names. The only issue with using constants is that if the names change, then all dependent assemblies that use the constants will also have to be recompiled and redeployed, but to me that was a minor issue.

Designing a layout using YUI

We'll actually use the YUI CSS style sheets in a moment, but I first wanted to go over how a standard layout is built in HTML using the YUI CSS style sheets. A typical web page using YUI would have the following structure:



    
    


    

This HTML sample shows that the web page, or document, has three areas: a header or masthead, the body content, and a footer. The header is the typical top part of a page where the branding, menus, and other special content will go on the page. The body is where the main content for the web page will appear. A footer is present and is typically used for a copyright statement and other navigation features or links that the web site may provide. In ASP.NET, you may typically use master pages (as we will soon) to provide the content for the header and footer.

The main DIV tag with the identifier of "doc" is used to control the relative width of the web page. When I write width, I specially mean the width of the content on the page. Depending on the size of the browser window, the content may be wider or smaller than the width of the window. If the browser window is maximized and is bigger than the content area, then the content area will be centered within the browser window.

The YUI Grids CSS style sheet defines four standard widths for web pages:


...
...
...
...

You can also define your own custom widths for your web pages. See these instructions for how to set up your custom page width in a CSS style sheet.

Once the page width is set, we can look at how to structure the internal body content of the web page. The Yahoo! designers have recognized that a common pattern on the web is to define two main areas of a page. The first area is used for the main page content. The second area is for additional, secondary content, such as a navigation bar or widget bar that may also appear on the page. To make life easier, the YUI Grids CSS style sheet provides built-in support for this common template.  Our markup from above can be enhanced to look like the following:



	
    


    

You'll notice from the above example that we've added more to the bd DIV element in the HTML. Specifically, we've added two blocks (the DIVs with the yui-b CSS class name). One of the DIVs is contained inside of a DIV with the identifier of yui-main. This identifier is used to mark which of the two blocks in the template contains the main content for the web page. The other block DIV will be selected to be used for secondary content.

The placement and size of the blocks on the page are controlled through the new CSS class defined on the main document DIV. The YUI Grid CSS style sheet defines six CSS classes that control both the width of the main and secondary content columns, and their placement with regard to the other:

  • yui-t1: the secondary content is 160 pixels wide and is placed on the left side of the page.
  • yui-t2: the secondary content is 180 pixels wide and is placed on the left side of the page.
  • yui-t3: the secondary content is 300 pixels wide and is placed on the left side of the page.
  • yui-t4: the secondary content is 180 pixels wide and is placed on the right side of the page.
  • yui-t5: the secondary content is 240 pixels wide and is placed on the right side of the page.
  • yui-t6: the secondary content is 300 pixels wide and is placed on the right side of the page.

You may be asking yourself why Yahoo! chose to use these arbitrary placements and sizes. Why not offer a 160 pixel column on the right side of the screen? Or how about a 240 pixel column on the left side of the screen? Like everything else in the world, this decision was driven by money. Specifically, advertisement money. These columns match the standard dimensions for online advertisements.

Other considerations for implementing web page designs

Before we get into the ASP.NET code that I wrote to support the YUI Grids, I thought that I'd go through a couple of other items that I typically do with my web pages. When I build web sites, I typically add an identifier and some CSS classes to the main BODY tag of the HTML page for the purpose of customizing CSS rendering for the web site or page.

First, I set the id attribute of the BODY tag to the domain name of the web site, with the dots in the domain name replaced with dashes. So, for example, the pages on www.imaginaryrealities.com (when the new web site is published) will have the identifier www-imaginaryrealities-com. The purpose of setting this value as the identifier is that it will make it easier for consumers of my web site to customize my pages to meet their needs. For example, if someone browses my web site, but thinks that the text is too small, this person could create a custom style sheet using Internet Explorer and set my fonts to a larger size to make my pages easier for him to read. Because all of the pages on my web site will have the same identifier, the custom style sheet rules would apply to my entire site.

Next, I add CSS attributes to the BODY tag of the HTML page to communicate the following information:

  • The page type. For example, is the page the home page, a contact page, a news page, etc.?
  • The language of the client browser. For example, English, Spanish, Italian.
  • The locale of the client browser. For example, United States, Russia, Italy, United Kingdom, Germany, Brazil.

The page type class is going to be in the form of page-home or page-contact. It's going to be used in my CSS or in a custom CSS style sheet to implement page-specific customizations. I may want the colors for the home page and a special announcement page to be different, or the layouts to be different. Using these page styles, I can customize the look-and-feel of specific pages on my web site.

The language and locale classes are going to be in the form of la-en for English, or la-it for Italian, or lo-US for the United States, or lo-MX for Mexico, for example. These CSS classes will let me create culture-specific customizations for my web site to make the web site more attractive for those browsing my web site. For example, maybe I would want United States readers to see a picture of the U.S. flag, and Mexico readers to see the Mexican flag. I could swap the images using CSS.

Given this, the HTML BODY tag would look like this in the page:


    .
    .
    .

With that now hopefully understood, I'll show you how I built an ASP.NET framework to support the YUI Grids layouts.

Configuring the web site

In the previous sections, I have you several choices that you would have to decide on when designing your web page. First, there's the identifier that you're going to use to identify your pages from Joe Bob's pages. Second, there's the document identifier that controls the width of the page content. Third, there's the width and position of the secondary content related to the page. Now, these could be hard coded into your web pages, but I see an opportunity to support changing or customizing these values site-wide. It would be nice to have those settings in a single place with the option of applying page-specific overrides. If in the future you decided that you wanted to change your width, or if Yahoo! puts out a new release with a new width greater than 974 pixels that you want to use for your pages, you can change it in a single place.

The single point of configuration for these values is actually going to be the Web.config configuration file for your web site:



    
        

I defined a custom configuration section class that will store the default site-wide values for these three options:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the WebsiteConfigurationSection class that is used to
// configure information about the website.
// 
//------------------------------------------------------------------------

namespace ImaginaryRealities.Website.UI.Framework
{
    using System.Configuration;
    using Wintellect.Diagnostics;

    /// 
    /// Configuration section that is used to configure the website.
    /// 
    [CodeOwner("Michael F. Collins, III", "michael@imaginaryrealities.com")]
    public class WebsiteConfigurationSection : ConfigurationSection
    {
        /// 
        /// The name of the configuration property for the
        ///  property.
        /// 
        private const string PageIdPropertyName = "pageId";

        /// 
        /// The name of the configuration property for the
        ///  property.
        /// 
        private const string PageWidthPropertyName = "pageWidth";

        /// 
        /// The name of the configuration property for the
        ///  property.
        /// 
        private const string TemplatePropertyName = "template";

        /// 
        /// Gets or sets the identifier to use for the website pages.
        /// 
        /// 
        /// The value of this property is used as the identifier for the
        /// <body> element of the web page.
        /// 
        [ConfigurationProperty(PageIdPropertyName, IsRequired = true)]
        public string PageId
        {
            get
            {
                return (string)this[PageIdPropertyName];
            }

            set
            {
                this[PageIdPropertyName] = value;
            }
        }

        /// 
        /// Gets or sets the default page width for the website pages.
        /// 
        /// 
        /// The value of this property is a valid id used by the Yahoo! User
        /// Interface Library to specify or control the width of the rendered
        /// web page.
        /// 
        [ConfigurationProperty(
            PageWidthPropertyName,
            DefaultValue = "doc",
            IsRequired = false)]
        public string PageWidth
        {
            get
            {
                return (string)this[PageWidthPropertyName];
            }

            set
            {
                this[PageWidthPropertyName] = value;
            }
        }

        /// 
        /// Gets or sets the default template for the website pages.
        /// 
        /// 
        /// The value of this property is a valid CSS identifier of a Yahoo!
        /// User Interface Library Grids template.
        /// 
        [ConfigurationProperty(
            TemplatePropertyName,
            DefaultValue = "yui-t1",
            IsRequired = false)]
        public string Template
        {
            get
            {
                return (string)this[TemplatePropertyName];
            }

            set
            {
                this[TemplatePropertyName] = value;
            }
        }
    }
}

The only required property for the configuration is the identifier to use for the pages. I default the pageWidth and template configuration properties to doc and yui-t1 respectively.

We'll use these configuration settings in the page definitions below:

Creating a base page type

For every page that we develop, we're going to need the name of the CSS class representing the page or page type, and the value to use to control the width of the page. By default, the width of the page will come from the configuration section that I defined in the previous section, but I want to leave the option open for a page designer to choose a different width or a custom width for a specific page. But since I know that I need the page CSS class and the page width value, and I know that I'll need these values for every page, I'm going to create a new subclass of the System.Web.UI.Page class that I'll use as the base class for every page in my web site. Here's the code for my custom web page base class:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the WebsitePage abstract base class that is used as the base
// class for all web pages on the web site.
// 
//------------------------------------------------------------------------

namespace ImaginaryRealities.Website.UI.Framework
{
    using System.Web.Configuration;
    using System.Web.UI;
    using Wintellect.Diagnostics;

    /// 
    /// Abstract base class for web pages in the website.
    /// 
    [CodeOwner("Michael F. Collins, III", "michael@imaginaryrealities.com")]
    public abstract class WebsitePage : Page
    {
        /// 
        /// Initializes a new instance of the WebsitePage class.
        /// 
        protected WebsitePage()
        {
            this.InitializePageWidth();
        }

        /// 
        /// Gets the CSS class name for the web page.
        /// 
        /// 
        /// The value of this property is the name of the CSS class that
        /// represents the specific web page.
        /// 
        public abstract string PageCssClassName
        {
            get;
        }

        /// 
        /// Gets the identifier that is used to specify the width of the
        /// web page.
        /// 
        /// 
        /// The value of this property is the identifier that is used to
        /// specify the width of the content area of the web page.
        /// 
        public string PageWidth
        {
            get;
            protected set;
        }

        /// 
        /// Initializes the  property by loading the
        /// default page width from the website configuration.
        /// 
        private void InitializePageWidth()
        {
            var configurationSection = (WebsiteConfigurationSection)
                WebConfigurationManager.GetSection("website");
            this.PageWidth =
                configurationSection != null
                    ? configurationSection.PageWidth
                    : "doc";
        }
    }
}

My WebsitePage base class defines two properties: PageCssClassName and PageWidth that contain the values that I'll need for rendering my page. By default, the PageWidth value is initialized with the value from the web site's Web.config configuration file. But there is a protected setter that will allow a page to set a custom value before the page is rendered.

Now that I have this class defined, I can require that the WebsitePage class be used as the base class for all pages in my web site by updating the Web.config file:


    
        
            .
            .
            .
        
    
 

By setting the pages/pageBaseType attribute, the ASP.NET compiler will throw an error if a web page is not a subclass of the WebsitePage class.

Creating master pages for the web site

A cool feature that has been part of ASP.NET since the 2.0 release is master pages. Master pages allow a developer to create a common template for web pages that can be reused over and over again for multiple pages. Master pages work perfectly with what we're trying to do in terms of using the YUI Grids for our layout. We want to define one or more layouts and reuse them with different content.

Before we define our master pages, however, we need to take a look again at the common information that appears on every page just like we did in the last section. In the last section, we looked at page-specific attributes. But when we're creating master pages, we need to consider the global site attributes:

  • The URL of the YUI Reset, Font, and Grid CSS style sheet.
  • The URL of the YUI Base CSS style sheet.
  • The side-wide page identifier (www-imaginaryrealities-com)
  • The name of the CSS class identifying the browser's language (la-en)
  • The name of the CSS class identifying the browser's locale (lo-US)

Since these are going to be used on every web page, I also defined a base class that I'll use for any master pages that I define for the web site:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the WebsiteMasterPage abstract base class that is used as
// the base class for top-level master pages in the website.
// 
//------------------------------------------------------------------------

namespace ImaginaryRealities.Website.UI.Framework
{
    using System;
    using System.Configuration;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Web.Configuration;
    using System.Web.UI;
    using Wintellect.Diagnostics;
    using Yahoo.UI;

    /// 
    /// Abstract base class for top-level master pages used in the website.
    /// 
    [CodeOwner("Michael F. Collins, III", "michael@imaginaryrealities.com")]
    public abstract class WebsiteMasterPage : MasterPage
    {
        /// 
        /// Initializes a new instance of the WebsiteMasterPage class.
        /// 
        protected WebsiteMasterPage()
        {
            this.InitializeGlobalizationProperties();
            this.InitializePageId();
        }

        /// 
        /// Gets a reference to the  object that is
        /// using the master page.
        /// 
        /// 
        /// The value of this property is the page that is using the master
        /// page, cast to a  object.
        /// 
        public new WebsitePage Page
        {
            get
            {
                return (WebsitePage)base.Page;
            }
        }

        /// 
        /// Gets the URL of the web resource containing the CSS for the base
        /// style sheet defined by the Yahoo! User Interface Library.
        /// 
        /// 
        /// The value of this property is the URL where the YUI Base CSS
        /// style sheet can be downloaded.
        /// 
        [SuppressMessage(
            "Microsoft.Design",
            "CA1056:UriPropertiesShouldNotBeStrings",
            Justification = "This property is data bound and works better as a string.")]
        protected string BaseCssUrl
        {
            get
            {
                return this.Page.ClientScript.GetWebResourceUrl(
                    typeof(YahooUIResources),
                    YahooUIResources.BaseName);
            }
        }

        /// 
        /// Gets the name of the CSS class representing the language of the
        /// client browser.
        /// 
        /// 
        /// The value of this property is the name of the CSS class that
        /// represents the language of the client browser.
        /// 
        protected string LanguageCssClassName
        {
            get;
            private set;
        }

        /// 
        /// Gets the name of the CSS class representing the locale of the
        /// client browser.
        /// 
        /// 
        /// The value of this property is the name of the CSS class that
        /// represents the locale of the client browser.
        /// 
        protected string LocaleCssClassName
        {
            get;
            private set;
        }

        /// 
        /// Gets the URL of the web resource containing the CSS for the combined
        /// Reset, Font, and Grid style sheets from the Yahoo! User Interface
        /// Library.
        /// 
        /// 
        /// The value of this property is the URL where the YUI Reset, Font,
        /// and Grid CSS style sheet can be downloaded from.
        /// 
        [SuppressMessage(
            "Microsoft.Design",
            "CA1056:UriPropertiesShouldNotBeStrings",
            Justification = "This property is data bound and works better as a string.")]
        protected string ResetFontGridsCssUrl
        {
            get
            {
                return this.Page.ClientScript.GetWebResourceUrl(
                    typeof(YahooUIResources),
                    YahooUIResources.ResetFontsGridName);
            }
        }

        /// 
        /// Gets the identifier of the web page.
        /// 
        /// 
        /// The value of this property is the identifier that will be used for
        /// the <body> element of the page.
        /// 
        protected string PageId
        {
            get;
            private set;
        }

        /// 
        /// Data binds the properties on the master page with the master page.
        /// 
        /// 
        /// The event arguments.
        /// 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.DataBind();
        }

        /// 
        /// Initializes the  and
        ///  properties with their values
        /// based on the client browser's culture settings.
        /// 
        private void InitializeGlobalizationProperties()
        {
            var cultureInfo = CultureInfo.CurrentUICulture;
            var parts = cultureInfo.Name.Split('-');
            if (parts.Length > 0)
            {
                this.LanguageCssClassName = "la-" + parts[0];
                this.LocaleCssClassName =
                    parts.Length > 1 ? "lo-" + parts[1] : String.Empty;
            }
            else
            {
                this.LanguageCssClassName = String.Empty;
                this.LocaleCssClassName = String.Empty;
            }
        }

        /// 
        /// Initializes the  property
        /// from the configuration settings for the website.
        /// 
        private void InitializePageId()
        {
            var configurationSection = (WebsiteConfigurationSection)
                WebConfigurationManager.GetSection("website");
            if (configurationSection == null)
            {
                throw new ConfigurationErrorsException(
                    Properties.Resources.MissingWebsiteConfigurationSection);
            }

            this.PageId = configurationSection.PageId;
        }
    }
}

I also defined an override of the Page property on the master page class. I wanted to return the Page object cast as a WebsitePage object, since all pages will have to derive from WebsitePage. I'll show you how this is used in the next section.

Implement the master page

With our base classes defined, we can now implement our first master page. In this post, I'll be showing two master pages. The first master page that I'm going to present now just uses the basic Grid layout without either a main or secondary content area defined. The second master page that I'll show later in this post will use the template settings to implement the main and secondary content areas.

My first master page, with just the basic YUI Grids layout, looks like this:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>




    
    
    
    
    


    
Header
Footer

Notice in this page that I am using the ASP.NET data binding syntax (<%#...%>) to bind the property values from the WebsitePage and WebsiteMasterPage classes into the rendered HTML. If you look back at the code for the WebsiteMasterPage class, you'll notice that I implemented the OnLoad method to call the DataBind method. By using the ASP.NET data binding syntax and then calling the DataBind method when the page is loaded, I can automatically insert the values for these properties and the URLs for the YUI CSS style sheets into the rendered HTML. It's a very cool trick for adding property values to web pages.

The code-beside class for the master page is very basic:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the MasterPage class that controls the presentation of the
// master page template.
// 
//------------------------------------------------------------------------

using System;
using ImaginaryRealities.Website.UI.Framework;
using Wintellect.Diagnostics;

/// 
/// Controls the presentation logic for the website's master page.
/// 
[CodeOwner("Michael F. Collins, III", "michael@imaginaryrealities.com")]
public partial class MasterPage : WebsiteMasterPage
{
    /// 
    /// Initializes the master page.
    /// 
    /// The master page object.
    /// The event arguments.
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

Implementing a master page for templates

The other master page that we'll implement will provide the definitions of the main and secondary content areas. First, I defined a new subclass of WebsitePage called TemplateWebsitePage which defines a new property named Template which provides the value that controls the size and placement of the secondary content area (i.e. yui-t1). Any web page that uses the template will be derived from TemplateWebsitePage. The code for the TemplateWebsitePage class is below:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the TemplateWebsitePage abstract base class that is used as
// the base class for web pages that are based on the Yahoo! Grid template
// structure.
// 
//------------------------------------------------------------------------

namespace ImaginaryRealities.Website.UI.Framework
{
    using System.Web.Configuration;
    using Wintellect.Diagnostics;

    /// 
    /// Abstract base class for website pages that are based on the Yahoo!
    /// Grids template structure.
    /// 
    [CodeOwner("Michael F. Collins, III", "michael@imaginaryrealities.com")]
    public abstract class TemplateWebsitePage : WebsitePage
    {
        /// 
        /// Initializes a new instance of the TemplateWebsitePage class.
        /// 
        protected TemplateWebsitePage()
        {
            this.InitializeTemplate();
        }

        /// 
        /// Gets the CSS identifier for the Yahoo! Grids template to apply
        /// to the web page.
        /// 
        /// 
        /// The value of this property is the name of a CSS identifier that
        /// will be embedded in the web page to apply a Grids template style
        /// to the web page.
        /// 
        public string Template
        {
            get;
            protected set;
        }

        /// 
        /// Loads the default template setting from the website configuration.
        /// 
        private void InitializeTemplate()
        {
            var configurationSection = (WebsiteConfigurationSection)
                WebConfigurationManager.GetSection("website");
            this.Template =
                (configurationSection != null)
                    ? configurationSection.Template
                    : "yui-t1";
        }
    }
}

The new master page that will provide the YUI Grid template looks like this:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="TemplateMasterPage.master.cs"
    Inherits="TemplateMasterPage" %>




    
    
    
    
    


    
Header
Main content
Secondary content
Footer

Again, I'm using ASP.NET data binding to get the property values into the rendered HTML.

The code-beside class file for the template master page has a little more to it than the previous master page:

//------------------------------------------------------------------------
// 
// Copyright (c) 2008 ImaginaryRealities Software Company
// 
// 
// Implements the TemplateMasterPage class that controls the presentation
// of the template-based master page.
// 
//------------------------------------------------------------------------

using System;
using ImaginaryRealities.Website.UI.Framework;
using Wintellect.Diagnostics;

/// 
/// Implements the presentation logic for the template-based master page.
/// 
[CodeOwner("Michael F. Collins, III", "michael@imaginaryrealities.com")]
public partial class TemplateMasterPage : WebsiteMasterPage
{
    /// 
    /// Gets a reference to the  object that
    /// is using the master page.
    /// 
    /// 
    /// The value of this property is a reference to the page object that is
    /// using the master page, cast to a 
    /// object.
    /// 
    public new TemplateWebsitePage Page
    {
        get
        {
            return (TemplateWebsitePage)base.Page;
        }
    }

    /// 
    /// Initializes the master page.
    /// 
    /// The master page object.
    /// The event arguments.
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

Just as I did earlier with the WebsiteMasterPage base class, I created a new override of the Page property to provide a TemplateWebsitePage object for access and data binding purposes.

Conclusion

In this post, I introduced you to the Yahoo! User Interface Library and its CSS style sheets that will help you to design and organize your web pages using a pre-built open source framework. While we didn't cover all of the features available in the Grids CSS, we were able to build two master pages that will support a basic page framework. In future posts, we'll explore more of the options that the Grids CSS style sheet gives us for designing web pages and organizing web page content.



Tags: , , , ,

ImaginaryRealities.com | ASP.NET | Yahoo! User Interface Library

Comments

12/15/2008 5:35:38 PM #

pingback

Pingback from xhtml-and-css.com

Posts about XHTML as of December 15, 2008 | XHTML and CSS

xhtml-and-css.com

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen | Modified by Mooglegiant

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

What I'm reading now


Add to Technorati Favorites

Disclaimer

The views expressed on this website/blog are the opinions of Michael F. Collins, III, and do not necessarily reflect the views of my employer.