When building professional internet sites using MOSS 2007 and its WCM features, you should also think about two major things that will make your site better found when using search engines:
1. Self-speaking, keyword-dense page titles
2. A full set and keyword-dense set of metatags
While the later is often declared as obsolete today, it still helps to describe your site and adds, if cleverly used, keyword density to your sites - which in turn again makes your site better found.
I will start with metatags. Unfortunately, MOSS doesn't really ship with a lot of webcontrols that help you to build up a good metatag system. In fact, except the RobotsMetaTag-Control, there is absolutely no Control that will facilitate automatic Metatag generation.
OK; what can we do about it? Let's first look at the requirements. We have to types of Metatags we should consider:
- "Static" Metatags: They are pretty much the same for all of your site or at least some major areas
- "Dynamic" Metatags: They are content-specific, for example "keywords" or "abstract" etc.
If we want to create a MetaTag Control, it should be flexible enough to handle both cases: Static Text but also dynamic text rendered using the standard SharePoint publishing web controls. Like that, we can create custom fields to store the keywords, abstracts etc.
Let's look at it without putting the SharePoint glasses on: We need a control that renders static text or the dynamic output of a contained webcontrol as a metatag. That's actually pretty easy to achieve:
- Create a Class Library
- Create a new class that inherits from WebControl
[ParseChildren(false), ToolboxData("<{0}:MetaTag runat=\"server\"
name=\"\"> </{0}:MetaTag>"), PersistChildren(true),
AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal),
DefaultProperty("Name")]
public class MetaTag : WebControl
{
- In the constructor make sure that the rendered Tag is a "Meta" Tag
public MetaTag() : base(HtmlTextWriterTag.Meta) {}
- Add a public property to store the "name"-Attribute of the metatag
protected string m_Name = "";
[Bindable(true), Category("Appearance"), DefaultValue(""), Description("Sets the MetaTag's name attribute.")]
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
- Override the needed Rendering method. Important: Our control has no inner content. The contained controls are rendered in the "value"-Attribute
protected override void Render(HtmlTextWriter writer)
{
// Render control only if there is a tagname specified
if (!m_Name.Equals(string.Empty))
base.Render(writer);
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
// Write the name attribute
writer.AddAttribute("name", m_Name);
// Write the value attribute
StringWriter sw = new StringWriter();
base.RenderContents(new HtmlTextWriter(sw));
writer.AddAttribute("value", sw.ToString());
// the metata does not have any other attributes that could be rendered: don't call base...
}
protected override void RenderContents(HtmlTextWriter writer)
{
// this control does not render any contents
}
- Strong name the assembly and build it.
To test your new control, create an ASP.NET webapplication and add the control into your head section. You may add static text or add (for example) a Literal Web Control render the content of your metatag dynamically. Here is an example:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="PublishingEnhancementsTest._Default" %>
<%@ Register Assembly="MichaelHofer.SharePoint.PublishingEnhancements" Namespace="MichaelHofer.SharePoint.PublishingEnhancements"
TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<cc1:MetaTag ID="MetaTag1" runat="server" Name="author">Michael Hofer</cc1:MetaTag>
<cc1:MetaTag ID="MetaTag2" runat="server" Name="Classification">Business to Business, B2B, Manufacturing, Industrial Supplies, Machinery and Tools, Machine Tools, Cutting Tools, Wire Strippers</cc1:MetaTag>
<cc1:MetaTag ID="MetaTag3" runat="server" Name="keywords"><asp:Literal ID="keywordsLiteral" runat="server"></asp:Literal></cc1:MetaTag>
</head>
<body>
<form id="form1" runat="server">
<div>Check out the markup of this page to see the generated metatags.
</div>
</form>
</body>
</html>
Bye the way: the Literal Controls is filled in the Page_Load event:
protected void Page_Load(object sender, EventArgs e)
{
keywordsLiteral.Text = "Our innovative automatic and semi-automatic wire processing machines are designed to cut, strip, crimp, and mark wire and cable of all types including single conductor wire, coaxial, multi-conductor, POF, flat flexible and glass fiber optic (GOF) cables";
}
OK, and here is the output when the page is rendered:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Untitled Page
</title><meta name="author" value="Michael Hofer" /><meta name="Classification" value="Business to Business, B2B, Manufacturing, Industrial Supplies, Machinery and Tools, Machine Tools, Cutting Tools, Wire Strippers" /><meta name="keywords" value="Our innovative automatic and semi-automatic wire processing machines are designed to cut, strip, crimp, and mark wire and cable of all types including single conductor wire, coaxial, multi-conductor, POF, flat flexible and glass fiber optic (GOF) cables" /></head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTk3OTI3MTg5Mw9kFgICAQ9kFgICAw9kFgJmDxYCHgRUZXh0Bf0BT3VyIGlubm92YXRpdmUgYXV0b21hdGljIGFuZCBzZW1pLWF1dG9tYXRpYyB3aXJlIHByb2Nlc3NpbmcgbWFjaGluZXMgYXJlIGRlc2lnbmVkIHRvIGN1dCwgc3RyaXAsIGNyaW1wLCBhbmQgbWFyayB3aXJlIGFuZCBjYWJsZSBvZiBhbGwgdHlwZXMgaW5jbHVkaW5nIHNpbmdsZSBjb25kdWN0b3Igd2lyZSwgY29heGlhbCwgbXVsdGktY29uZHVjdG9yLCBQT0YsIGZsYXQgZmxleGlibGUgYW5kIGdsYXNzIGZpYmVyIG9wdGljIChHT0YpIGNhYmxlc2Rk109UGxUCkSxNTt9wnyBj2PdOv5g=" />
</div>
<div>Check out the markup of this page to see the generated metatags.
</div>
</form>
</body>
</html>
The metatags are rendered as compacted as possible, including dynamic content.
Part 2 will take care of how to deploy this control into a SharePoint environment and how to render any publishing page field content as metatag. Since SharePoint controls are basically just ordinary ASP.NET webcontrols, you may already figure out, that the only special thing to consider is the deployment... Stay tuned...