Blog
E3 Retail Web Site
What they needed
E3 Retail had some good looking products including Point of Sale, Enterprise promotions, Returns, and 4690 hardware migration. Which used Microsoft’s Windows Presentation Foundation (WPF), to provide a visually rich user experience. However, E3 Retail didn’t have a comparable website to show them off.
While the marketing team at E3 created the copy for the site, numerous images, and features were added to the design to complement the marketing copy.
What I did
E3 retail wanted to focus on images to convey much of their marketing concepts. The marketing director created mock-ups in PowerPoint to work through details of the wording, general layout and selection of images with the board of directors.
Once there was agreement on the message and general images for publication, the images were adjusted, tuned, resized, and optimized for web publication. Both Microsoft Expression Design, Photoshop and other image manipulation tools were used to generate the final results. In addition to the main images, gradients, buttons, glass look layers and icons were added throughout the site.
Presentation of the images went through several different prototypes of user interaction and looks before finally settling on a flash control that provided the richness and quality presentation of the desired images.
the solution is hosted on IIS7 server on Windows 2008 using ASP.NET and .Net 3.5.
The result
The result was an image intensive web site that quickly conveys the product and service capabilities for E3 Retail and provides the ability for the marketing director to quickly update and add new content and news without requiring a technical development team for every change.
Services Provided
Design
- Prototypes
- Final image generation (sizing, quality adjustments, layout, gradients)
- Photography
Development
- Content management features added (Pretty URLs, Multi Post user control)
- Windows Live Writer support
- Theme design (background, colors, layout)
- Flash customization
- XHTML / CSS / Javascript
- Jquery support added for tabs, menus
- Browser CSS design and testing: IE8, IE7, Safari, IE6
- Deployment and configuration of IIS7 and Windows Server 2008
Features
- Rotating image banners on all product pages
- Pretty URLs
- Content management
- Windows Live Writer Support (edit or create pages / posts)
- Web WYSIWIG editor
- IIS7 Hosting on Windows Server 2008 platform
- Multi Post user control
- Modular page components can be used on other pages
- JQuery 1.2.6 support
- JQuery UI 1.5.3 support (tabs)
- JQuery dropdown menus (superfish)
- Search and Opensearch support
- RSS Syndication feeds
- Browser support: IE 8, IE7, Firefox 3, Safari (limited IE6 support)
- Ratings
- Bookmarks: favorites, e-mail, digg, dzone, stumbleupon, reddit, del.ico.us, newvine, furl, blinklist
Related Items
Pretty URLs And IIS6
IIS7 can support pages without extensions without administrator configuration settings. IIS6 can also support URLs without extensions, but it requires an administrator setting. Here's a tip on how to configure IIS6 to support URLs without extensions.
On the website properties, The configuration tab must be selected.
A wildcard application map must be added. Select the INSERT option and add the following file, and turn off the checkbox to verify the file exists.
File: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
The new setting should now be in place.
This should now allow URL rewriting on URL's like: http://e3retail.com/page/products/.
Related Items
Pretty URLs And IIS7 Authentication
One side effect of using Pretty URLs in IIS7 is that IIS7 doesn’t authenticate these URLs because they don’t have the .aspx file extension. Here is a quick tip on how to fix it.
IIS7 Authentication only authenticates against .aspx file extensions by default. This means, that if you try to create a pretty URL (http://tim-stanley.com/page/about/), then the UTL isn’t authenticated the same way if it had a .aspx page extension (http://tim-stanley.com/page/about.aspx).
Normal .aspx Results
Sample URL: http://tim-stanley.com/page/about.aspx
HttpContext.Current.User.Identity.IsAuthenticated => true
HttpContext.Current.User.IsInRole("Administrators")) => true
System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated => true
System.Threading.Thread.CurrentPrincipal.IsInRole("Administrators") => true
Html Extension Results
Sample URL http://tim-stanley.com/page/about.html
Sample URL http://tim-stanley.com/page/about/
Because both URL’s above are not .aspx files, they both return the same results (i.e. Isinrole, is false).
HttpContext.Current.User.Identity.IsAuthenticated => true
HttpContext.Current.User.IsInRole("Administrators")) => false
System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated => false
System.Threading.Thread.CurrentPrincipal.IsInRole("Administrators") => false
The Fix
After much research, I found a solution to this perplexing problem. The key was in in searching for and finding the schema file that had the keywords. I believe this fix will also change authentication for *.axd handlers as well.
C:\Windows\System32\inetsrv\config\schema\IIS_schema.xml
IIS7 Forms authentication changes in the section: <system.webServer>
<modules runAllManagedModulesForAllRequests="true" >
<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="integratedMode" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="integratedMode" />
<remove name="DefaultAuthentication" />
</modules>
Changing the above web.config entries will also change the results. The new results are listed below.
HttpContext.Current.User.Identity.IsAuthenticated => true
HttpContext.Current.User.IsInRole("Administrators")) => true
System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated => true
System.Threading.Thread.CurrentPrincipal.IsInRole("Administrators") => true
References
Related Items
Network Names For Systems
When you have five machines to keep track of, the naming format for those machines may not be important. When you have 500,000 in twelve countries, identifying and locating a machine or groups of machines becomes impossible if you haven’t planned ahead. Even if you have a simple home network, it doesn’t take long for iPods, routers, file servers, workstations, laptops to add up.
Here are some tips for naming physical device machine names so that they can easily be identified down the road. It may seem a bit obsessive compulsive at first, but there is logic behind the naming guidelines.
Searching Names
Why Names Are Important
The name of a system is only important for a few reasons. The most common is when you need to access a resource on the system and you need to know the DNS name. In secure environments, system logs record the machine where services are open or running, or they record the machines used to access other resources on the network. These become important for auditing requirements certain regulatory compliance laws. The next most common is the name used for system admin purposes when managed from other services.
Group Policies
Microsoft’s Active Directory allows applying group policies to certain machines. It’s a bit easier if all the same type of machine have a similar pattern.
Regulatory Compliance
Many of the recent laws including PCI DSS Compliance, Sarbanes Oxley, Gramm-Leach-Bliley Act (GLBA), HIPPA, and the Fair Credit Reporting Act require the auditing and logging of access to secure resources. Having a consistent machine naming convention makes it much easier to identify and process the information.
Resources Should Use Logical Names
Good server resources and network shares should be like URls that don’t change. The most common situation I’ve seen over the years is putting installation resources on a server, then over time, the network share is moved or the server changes name and then when workstations need to update, reinstall, the path to the original resource is no longer valid and it’s difficult to configure where to search for the new one. This is due to the fact that quite a bit of software (including Microsoft’s) embeds in the registry the original installation path.
The problem can be avoided by creating a DNS name that is separate from the physical name of the server. For example, if the copies of all CD software is on a server, create a CDSW.domain.com DNS entry, then create a share on the server and you can move it to another server easily without having to re-configure the workstations. The same technique can be used with a Distributed Files System (DFS). I recommend the DNS approach because in the circumstances where I’ve seen DFS used in an Active Directory environment, it becomes impossible nearly to remove or move a DFS share if one of the servers holding the share happens to be down.
Characters Allowed In Names
Physical names ultimately convert to DNS domain names and have limits on the characters that can be included in the name. Allowed characters include the ASCI LDH set: A..Z, 0..9, and - (hyphen or dash).
Token Combination Schemes
Defining the name format in a way it can be parsed and broken into tokens will give tremendous flexibility down the road. Organizations will go through buyouts, mergers, or reorganizations every few years. A well planned naming scheme should be able to remain consistent despite these changes.
Note: I’ve added spaces to the examples below to aid in readability. Spaces aren’t permitted characters in real device names.
Examples:
- {string} {number}
- {string} - {string}
These two patterns can be extended and chained together. Keeping the tokens of strings are separated by numbers or hyphens gives a lot of flexibility for future expansion without breaking things already in place.
Tip: I don’t recommend using N characters or N numbers. These always are ignored at some point and cause limitations (when store # 1000 is opened and you have a three number scheme). Using some leading zeros can help with making some of the number a little bit more readable though (i.e. svr001, svr032)
Examples:
- {IATA} - {Building} {Floor} {Office} - {Workstation Role} {Workstation #}
- {IATA} - {Building Type} {Building #} {Workstation Role} {Workstation #}
- {IATA} - {Workstation Role} {Workstation #}
- {IATA} - {User} - {Device Role} {Device #}
Token Types
Airport Codes
It’s often helpful to characterize a device’s physical name with it’s physical location. The airline industry has a convention using unique airport locator codes that I’ve used that is helpful in tracking devices. Airport locator codes include IATA codes and are mostly unique three letter codes and the ICAO provides unique four letter codes.
Usually the nearest international airport is unique enough for most organizations I’ve seen.
Examples:
- KRDU – ICAO for Raleigh, Durham Airport
- RDU – IATA for Raleigh, Durham Airport
Building Codes Or Numbers
Adding a building name or number, floor, and office number can be helpful in identifying and locating a machine. If you decide to include a floor and office, I recommend using some string to differentiate the token 2314 could be office 314 on the second floor or office fourteen on the twenty third floor. F23O14 seems pretty clear to me.
This works fine for physical equipment that doesn’t move often like routers, firewalls, hubs and such. I don’t recommend this for user workstations. Users will move frequently and any scheme that takes a users building and floor location into place is going to be obsolete in three to six months.
Examples:
- {Building} {Building # } – S1433 (Store 1433), W27 (Warehouse 27), O23, B8 (
- {Floor} - FL2
- {Office} – O22
Tip: Don’t us HQ as a building type. Mergers and buyouts will change this at some point and cause conflicts.
Machine Type Or Roles
Using a dictionary of preferred machine types helps when collecting inventory, or multiple administrators are involved on a network. Some sample machine types
- AP – Access Point
- RTR – Router
- SWT – Switch
- DC – Domain Controller
- WKS – Workstation
- LT - Laptop
- SVR - Server
- DB – Database Server
- WEB – Web Server
Machine Numbers
Giving between two and four digits for numbers to a machine name is useful, but sometimes confusing. Let’s see, was the web server on SVR13 or SVR12? I’ve seen various names used to help folks instead. Anything from Sleepy, Dopey, and the other dwarves to Donald and Mickey. I still have found that using some role and number is easiest, then using a DNS name for easy access for resources seems to work best.
User Names
Because user names have to be unique in a company, user machines can often be named after the user. Using a suffix like WKS for workstations or LT for laptops is helpful when users have both.
References
Related Items
Growth of Target
Target has grown since 1962 to over 1600 stores. Flowing Data illustrates the growth of new Target stores over time.
Related Items
Pretty Good URLs
With a little forethought and planning, it’s possible to create URLs that can be around the web for a long time and as Tim Berners-Lee pointed out cool URIs don't change. Choose wisely though, you may have to live with the URLs for much longer than you think, or if your not careful, you may end up with too many URLs pointing to the same content.
Domains Without WWW
The first part of the URL includes the domain which may or may not include the www sub domain. Leaving out the www as part of the domain name makes it easier for users to type. However, removing the www sub domain has some technical side effects. Using no sub domain in the URL means that cookies will be shared across all sub domains and cookies will be sent on all requests (including requests for static content). Large cookies can lead to slightly more traffic and slower content processing.
Weather using the www sub domain or not, the non preferred URL domain should be redirected by performing a 301 redirect to the preferred URL domain. This keeps search engines clear on the preferred URL and keeps from splitting inbound link counts on search engines.
Examples:
- http://tim-stanley.com/ (no www sub domain)
- http://www.tim-stanley.com/ (redirects to http://tim-stanley.com/)
URLs Without Extensions
File extensions don’t add value to users. They are there for the server (and programmers) benefit. Removing the need for the extension on a content only URL I believe helps users and helps with any long term migration issues. Content on an Apache server running php may be on an IIS server running ASP.NET in the future and vice-versa. Users shouldn’t have to know they have to specify .htm, .php, or .aspx after a name.
The biggest problem with removing extensions is what to decide to do with old content and how to create rules to rewrite the URL as needed. For the longest time, Apache had an advantage over IIS 5/6 in this regard, but with IIS7 and the URL rewrite module, that has changed.
Don’t allow two URLs with and without extensions to point to the same content. If you do decide to remove the required extensions, use a 301 redirect from the old to the new URL to ensure search engines only recognize one URL.
Examples:
- http://example.com/post/Nikon-Lens-Rentals.aspx
becomes http://example.com/post/Nikon-Lens-Rentals - http://example.com/post/Nikon-Lens-Rentals.html
becomes http://example.com/post/Nikon-Lens-Rentals
Rewriting URL Extensions
In the same way that extensions can be removed, extensions can be rewritten to a different file type. HTM or HTML is the most common destination type and masks the internal type (.php, .aspx, etc.) and technology used to drive a site.
Examples:
- http://example.com/post/Nikon-Lens-Rentals.aspx
becomes http://example.com/post/Nikon-Lens-Rentals.htm
Distinct URLs
The URLs should be distinct. A well though out structure can provide a clean ability to rewrite the URL should the platform be moved in the future. The path and the URL should be distinct within the path.
Examples:
- /page/*
- /post/*
- /category/*
- /tag/*
- /product/*
- /authors/*
Adding Trailing Slashes
References to a sites root path should always include a trialing slash. If the trailing slash isn’t provided on the root of the site, when it’s referenced, both Apache and IIS servers will respond with a 301 redirect and it doubles the traffic for the request.
A trailing slash should not be added to a URL with a file extension (i.e. one should not use http://example.com/post/Nikon-Lens-Rentals.aspx/ ). Beyond the root path, it is arguable if a trailing slash should be added to URLs without extensions. If trailing slashes are are added for a site, the site needs to take into account the scenarios when trailing slashes are not provided by users or referrers, and the site needs to perform a 301 redirect to the appropriate URL.
Removing both the extensions and adding the trailing slashes means that the URL rewrite rules and handlers must be configured properly.
In IIS 6, this was more difficult to do on a platform that was hosted because ISAPI rewrite components had to be added to the server. Hosting providers rarely could offer this support on IIS6. With IIS7, and the URL rewrite module, and other configuration settings, a developer can write an HTTP Module that handles and rewrites URL’s without requiring any special permissions.
The search results from Yahoo and Microsoft Live search remove the slashes in the results displayed (although not from the actual destination links themselves) while Google search does not alter the slashes.
ASP.NET MVC allows links with and without trailing slashes and users must code for the 301 redirects for the preferred URL or risk having duplicate content and cutting SEO rankings.
Wordpress provides the ability to have links to all pages and posts with trailing slashes. From what I read, Drupal wants to remove the trailing slashes.
After some extensive research, I believe my preference is the combination of removing extensions and to append trailing slashes to URLs. Even though I’m an avid .Net lover, I’ve never really liked the fact that some-page.aspx displays for a site running ASP.NET.
My secondary preference would be to rewrite the file extension to .htm and not append the trailing slash.
Don’t switch a site developed without trailing slashes to trailing slashes. There will always be a million and one references internally that will never fully resolve correctly. If appending trailing slashes is done, this needs to be done up front and at the beginning of development before a site goes live.
Examples:
- http://example.com/post/Nikon-Lens-Rentals/
Use Dashes Not Spaces For Words
When creating a title for a page, separating the words with something appropriate and readable. Some approaches I’ve seen use the underscore character. This becomes difficult to discern because most URLs have some form of underline when displayed.
Other approaches I’ve seen use Camel Case. The latter becomes difficult to read when case is ignored (CamelCase becomes camelcase). This can also lead to some unanticipated interpretations when words run together (think Speed Of Art).
The link with spaces http://example.com/post/Nikon%20Lens%20Rentals.aspx (%20 = spaces) is inherently more difficult to read and type by hand than one where words are separated by dashes.
Examples:
- http://example.com/post/Nikon-Lens-Rental.aspx (dashes)
Best Practices
These apply to externally facing URLs. URLs used for administration or not available to the general public don’t require this level of URL
- Be practical. Changing URLs strategies may likely break a lot of stuff and it’s a lot of work to get 100% all scenarios right.
- Choose URLs with distinct patterns (/category/*, /post/*, /page/*, etc.).
- URL’s without extensions are preferred. If extensions are needed, use .htm or .html.
- Use Dashes not spaces to separate words in URLs.
- Pick a www sub domain strategy and stick with it and redirect to the alternative.
- Always put a trailing slash on the domain reference (i.e. http://tim-stanley.com/ ).
- Always put the trailing slash on directories.
- Never include the index page in the URL (default.htm, index.html, default.asp, default.aspx).
- Pick a trailing slash strategy and stick with it and redirect the alternative URL with / without the trailing slash to the proper target URL.
Astute readers may note that this site at the time may not have pretty URLs with all the best practices in place. The chief reason; it’s a lot of work to remove extensions and get URL 301 redirects for older inbound links working correctly for all features on a site. I knew this when I started the site, but I couldn’t fine a good URL rewriting solution on IIS6 at the time. Now the site has moved to IIS7, I have a solution, but I’m not confident of all the redirect and the impact it will have on searches.
However, if your starting a new site, In my opinion, it’s good to start off with planned good clean and pretty URLs and it will be easier to maintain down the road.
References
- Cool URIs don't change
- Slash Forward (Some URLs are Better Than Others)
- URLs as UI
- SEO advice: URL canonicalization
- http://labs.apache.org/webarch/uri/rfc/rfc3986.html
- Why you should be using disambiguated URLs
- Architecture of the World Wide Web, Volume One
- Uniform Resource Identifier
- Uniform Resource Locator
- URL Normalization
- Why storing URLs with truncated trailing slashes is an utterly idiocy
- The Hyperlink Trailing Slash
- ASP.NET MVC and the new IIS7 Rewrite Module
- http://www.ytechie.com/2008/10/aspnet-mvc-what-about-seo.html
- When should one use a ‘www’ subdomain?
- No-www.org
- http://developer.yahoo.com/performance/rules.html#cookie_free
- SEO-sanitizing a WordPress theme in 5 minutes
- http://en.wikipedia.org/wiki/Permalink
- http://en.wikipedia.org/wiki/Mod_rewrite
Related Items
Multi Post User Control
Trailing on the lead from Chris Blankenship and his singlepost user control, I created a multi-post user control. I’ve never been quite satisfied with the results of the recent posts control and Chris’s control filled in enough gaps for me to pursue this further.
I happen to keep my custom controls in /UserCustom instead of /UserControls. That way, I know these controls are not Blog Engine.Net controls and won’t need to be merged in the future.
Example
[ usercontrol: ~/UC/ItemList.ascx ShowDescription=true; Count=3;
ShowContent=false; ShowAuthor=false; ShowDate=false; ShowTitle=true;
ContentLength=120; CategoryList=photography; DateFormat={0:MM/dd/yyyy};]
Usage from ASP
<%@ Register src="../../UserCustom/MultiPosts.ascx" tagname="MultiPosts" tagprefix="uc7" %>
<uc7:MultiPosts ID="MultiPosts1" runat="server"
CategoryList="photography"
ContentLength="120"
Count="3"
DateFormat="{0:MM/dd/yyyy}"
ShowAuthor="false"
ShowContent="true"
ShowDate="false"
ShowDescription="true"
ShowTitle="true" />
Usage in Posts or Pages
Remove the space between the bracket and the word usercontrol.
[ usercontrol: ~/UserCustom/MultiPosts.ascx
ShowDescription=true;
Count=3;
ShowContent=false;
ShowAuthor=true;
ShowDate=true;
ShowTitle=true;
ContentLength=360;
CategoryList=photography;
DateFormat={0:MM/dd/yyyy}; ]
Post.cs Add AuthorAbsoluteLink
In order to reduce some of the clutter in the ASCX control template, I created a new property on the Post object to display the Authors link. If you want to stay with the mainline BE code base, you’ll need to modify the ASCX to set the asp:Hyperlink for AuthorLink to the code shown below.
public Uri AuthorAbsoluteLink
{
get
{
string authorLink = Utils.RemoveIllegalCharacters(Author);
authorLink = Utils.RelativeWebRoot + "author/" + HttpContext.Current.Server.UrlEncode(authorLink) + BlogSettings.Instance.FileExtension;
return Utils.ConvertToAbsolute(authorLink);
}
}