Must See - Warren Buffett Interview
October 3rd, 2008I highly recommend watching (or at least listening to) the Warren Buffett interview with Charlie Rose.
I highly recommend watching (or at least listening to) the Warren Buffett interview with Charlie Rose.
A bit about me:
OK, those last two don’t go very well together, and that has been my cross to bear.
For years, I have been looking for an open source ASP.NET CMS/blogging engine that I could use for myself and for other small websites. The catch was it had to adhere to Web Standards (valid XHTML 1.0 Strict markup, CSS for layout, etc). I found a few that sort of worked and I even wrote a few custom ones myself, but I was never satisfied.
Well, I give up.
For the last few months, I have been working on the website for my son’s (now former — he started kindergarten on Wednesday) preschool. As usual, I had no problem getting the site working using ASP.NET (everything validated, cleanish CSS), BUT I hadn’t tackled how I was going to handle the CMS.
I started down the road of using the MVC pattern in ASP.NET 3.5 with the help of Chris Tavares’ article, Building Web Apps without Web Forms. But then …
While attending Kelly Goto’s presentation at (the best conference I’ve yet attended) An Event Apart in San Francisco, she made an offhand comment about creating a website for her mom. She talked about simply getting WordPress up and running for her mom in about 15 minutes, and letting her mom take over. Preso … a website.
Now, I don’t know much about WordPress or PHP or MySql, but if Kelly’s mom can do it …
I then spent the next few evening doing some pilot projects to see how easy or hard it would be to get WordPress to act more like a CMS, and I’m converted. So far I haven’t found any gotchas that will prevent me from using WordPress for smaller websites. And even giving my handicap of not knowing PHP, it has been easier to write themes for WordPress than it would have been to write my own CMS in ASP.NET.
I was recently looking for a way to programmatically add and update Meta Tags in ASP.NET 2.0. This is a fairly simple thing to do with standard .aspx pages. Just add ID and Runat attributes to the Head element and reference the control in the code behind. However, this is not so simple when working with MasterPages, which I am. What I wanted was a way to:
content attribute of an existing Meta Tagcontent attribute of an existing Meta TagApp_CodeInitially, in my Master Pages I added a AddMetaTag method, which the Content Pages could call. However, this did not allow me to call the method from User Controls. It was also a maintenance pain, since the code had to be added to each Master Page.
A simple solution was to take advantage of the App_Code folder and add a Utility Class, which could be called from anywhere in the Web project. The AddMetaTag method needs three parameters passed, the Page reference and strings for the Name and Content attributes of the Meta Tag.
Utilities.cs (in App_Code)
public class Utilities {
public static void AddMetaTag(Page thisPage, string name, string content) {
...
}
}
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e) {
Utilities.AddMetaTag(this.Page, "author", "Josh Salwen");
}
Utilities.vb (in App_Code)
Public Class Utilities
Public Shared Sub AddMetaTag(ByVal thisPage As Page, ByVal name As String, ByVal content As String)
...
End Sub
End Class
Default.aspx.vb
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Utilities.AddMetaTag(Me.Page, "author", "Josh Salwen")
End Sub
Using the System.Web.UI.HtmlControls.HtmlMeta class makes it easy to create a Meta Tag.
HtmlMeta meta = new HtmlMeta();
meta.Name = "Author";
meta.Content = "Josh Salwen";
Dim meta As New HtmlMeta
meta.Name = "Author"
meta.Content = "Josh Salwen"
The trick is adding it into the HTML Head element.
By default, Visual Studio 2005 adds a runat="server" to the Head element in both .master pages and .aspx pages (if it is not a content page which references a Master Page). As long as the runat="server" is not removed, the Page.Header property can be accessed. If it is removed, then it is not possible to access the Page.Header, so when referencing the Header is is important to make sure it is not null (or Nothing).
Once the Page.Header is referenced, then you create a new HtmlMeta object and add it to the Page.Header Controls.
public static void AddMetaTag(Page thisPage, String name, String content) {
HtmlHead header = (HtmlHead)thisPage.Header;
if (header != null) {
HtmlMeta meta = new HtmlMeta();
meta.Name = name;
meta.Content = content;
header.Controls.Add(meta);
}
}
Public Shared Sub AddMetaTag(ByVal thisPage As Page, ByVal name As String, ByVal content As String)
Dim header As HtmlHead = DirectCast(thisPage.Header, HtmlHead)
If Not IsNothing(header) Then
Dim meta As New HtmlMeta
meta.Name = name
meta.Content = content
header.Controls.Add(meta)
End If
End Sub
Once the functionality was in place to add a Meta Tag, I just needed to add the ability to update an existing tag. In order to do this, the method does the following:
Controls in the HeaderControl is an HtmlMetaName attributes are the sameContent attribute and exits the method
public static void AddMetaTag(Page thisPage, String name, String content) {
HtmlHead header = (HtmlHead)thisPage.Header;
if (header != null) {
HtmlMeta meta = new HtmlMeta();
// Loop through all the controls in the Header
foreach (Control ctrl in header.Controls) {
// Check if the control is a Meta Tag
if (ctrl is HtmlMeta) {
// Get the Meta Tag and check if the name is the same
meta = (HtmlMeta)ctrl;
if (name.Equals(meta.Name, StringComparison.InvariantCultureIgnoreCase)) {
// Since the Meta Tag already exists, simply update and exit
meta.Content = content;
return;
}
}
}
meta = new HtmlMeta();
meta.Name = name;
meta.Content = content;
header.Controls.Add(meta);
}
}
Public Shared Sub AddMetaTag(ByVal thisPage As Page, ByVal name As String, ByVal content As String)
Dim header As HtmlHead = DirectCast(thisPage.Header, HtmlHead)
If Not IsNothing(header) Then
Dim meta As New HtmlMeta
' Loop through all the controls in the Header
For Each ctrl as Control in header.Controls
' Check if the control is a Meta Tag
If TypeOf ctrl Is HtmlMeta Then
' Get the Meta Tag and check if the name is the same
meta = DirectCast(ctrl, HtmlMeta)
If name.Equals(meta.Name, StringComparison.InvariantCultureIgnoreCase) Then
' Since the Meta Tag already exists, simply update and exit
meta.Content = content
Return
End If
End If
Next
meta = New HtmlMeta
meta.Name = name
meta.Content = content
header.Controls.Add(meta)
End If
End Sub
I noted above that I want to be able to append data as well. I also want to compare the Name and Lang attributes, since you can add the same Meta Tag for different languages. I have included this code in the source code, if you want to check it out.
And finally, in the ASP.NET 2.0 Alpha, the Header had MetaData.Add (I think that is what it was called), so Microsoft was thinking about this at one point. I’m not sure what happened.