views:

36

answers:

1

I'm using webforms ASP.NET, with masterpages. I want to add a LANG attribute to the <title> tag. ASP.NET automatically generates a title tag. I've tried adding my own tag with an ID and runat="server", like this:

<title id="titleBlock" runat="server"></title>

When doing this, I can set an attribute like the following without any errors.

titleBlock.Attributes.Add("lang", "it");

However, ASP.NET wipes out my <title> tag completely and puts its own in without my LANG attribute. Is there any way to accomplish this? Thanks very much.

+1  A: 

This happens because the HtmlTitle control doesn't provide a RenderAttributes implementation. You can't (easily) subclass the control in this case but there's another option. The power of Control Adapters isn't limited to WebControls - the concept also extends to HtmlControls as well.

Drop the following in a *.browser file under the App_Browsers directory of your site:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter 
        controlType="System.Web.UI.HtmlControls.HtmlTitle"
        adapterType="HtmlTitleAdapter" 
      />
    </controlAdapters>
  </browser>
</browsers>

Here's a prototype for the corresponding adapter:

using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;

public class HtmlTitleAdapter : System.Web.UI.Adapters.ControlAdapter
{
    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        HtmlTitle title = Control as HtmlTitle;

        writer.WriteBeginTag("title");
        title.Attributes.Render(writer);
        writer.Write(">");

        if (title.Text != null)
            writer.Write(title.Text);

        writer.WriteEndTag("title");
    }
}

Note that the internal render implementation of HtmlTitle differs somewhat:

protected internal override void Render(HtmlTextWriter writer)
{
    writer.RenderBeginTag(HtmlTextWriterTag.Title);
    if (this.HasControls() || base.HasRenderDelegate())
    {
        this.RenderChildren(writer);
    }
    else if (this._text != null)
    {
        writer.Write(this._text);
    }
    writer.RenderEndTag();
}

I'm not sure when a title would have child elements, so I don't think this an issue.

Hope this helps.

As an aside, it would be much easier to add this attribute on the client using jQuery.

 <script type="text/javascript">
    $(document).ready(function() {
        $("title").attr("lang", "it");
    });
</script>
Nariman
It works -- wonderful solution, thank you. I understand this would be easy to do with jQuery, but the main reason I'm doing this is for search engines so they recognize the language used in a few elements on the page (title tag, and a couple of DIVs). Search engines aren't going to run JS, so need to output the LANG attribute directly from the server. Thx again.
Ben Amada