I don't want no stinkin <span>

by joey.westcott 26. March 2009 15:34

Goal:
The label control adds <span> tags around the text when rendered, I needed to have these removed. I also show how to replace the <span> tag with whatever tag you would like.

I currently work on a site that has a custom built CMS, which is not always a good thing.  Now don't get me wrong there are some great ideas in this home grown CMS, but just like any application there are some wrong/bad things as well.  Here is one of those bad things that I had the time to fix recently. 

The web site content is entered via a WYSIWYG editor by whoever is responsible for the content, this markup (from the WYSIWYG) is stored in the database along with flags/keys that determine when to display this content.  If a few content items score the same then they all get built together, each one in its own Label control.  This is all fine and dandy, but when it comes time to dynamically create this content and add it to the current page is when they go less than ok.  Because of some limitations of the rest of the framework the content has to be built inside a System.Web.UI.WebControls.WebControl, ok this is fine except we are limited to a select few controls that fall into that category.

Here are these Controls:
System.Web.UI.ScriptControl
System.Web.UI.WebControls.BaseDataBoundControl
System.Web.UI.WebControls.BaseDataList
System.Web.UI.WebControls.Button
System.Web.UI.WebControls.Calendar
System.Web.UI.WebControls.CheckBox
System.Web.UI.WebControls.CompositeControl
System.Web.UI.WebControls.DataListItem
System.Web.UI.WebControls.FileUpload
System.Web.UI.WebControls.HyperLink
System.Web.UI.WebControls.Image
System.Web.UI.WebControls.Label
System.Web.UI.WebControls.LinkButton
System.Web.UI.WebControls.LoginName
System.Web.UI.WebControls.Panel
System.Web.UI.WebControls.SiteMapNodeItem
System.Web.UI.WebControls.Table
System.Web.UI.WebControls.TableCell
System.Web.UI.WebControls.TableRow
System.Web.UI.WebControls.TextBox
System.Web.UI.WebControls.ValidationSummary

So these controls are great and all but because of this limitation all of the content (well most of it) is being built by adding the content from the database into a label and then added to the page in order.  This is fine but as most of you probably know the label control adds <span> tags around the content/text inside of it.  Now I know that for the most part a <span> will not break much, in terms of displaying HTML in the browser.  In fact the site has run this way for years now with out much problem.  Although this works, it also does not follow standards, for example; if the WYSIWYG editor adds a <div> tag then you will have a <div> inside a <span> and we all know this should not be.

In order to remove the <span> tag while still being a WebControl was not going to happen unless I rolled my own control that was a WebControl. So I got to work and ended up creating a new Control that inherited from the Label Control.  My new control... say LabelNoSpan, only has one small bit of code that makes this all work.  If you were to look into the code of the WebControl class you will see a perfect place to hook into and change how the parent class (label) does its Rendering (hint hint).  If I change how the render works then I should be able to remove those nasty <span> tags. Here is what my new class/control looks like.

   1:  namespace Some.Big.Important.Namespace
   2:  {
   3:      /// <summary>
   4:      /// This class was created to remove those nasty <span> tags around all the content on the site.
   5:      /// this sidesteps the renderbegintag and renderendtag methods by just calling the rendercontents from
   6:      /// within the render method.... norm the render method calls all three of those in order.
   7:      /// </summary>
   8:      class LabelNoSpan : Label
   9:      {
  10:   
  11:          protected override void Render(System.Web.UI.HtmlTextWriter writer)
  12:          {
  13:              base.RenderContents(writer);
  14:          }
  15:   
  16:      }
  17:  }

 

Now the reason this works is because the render method of the WebControl class, parent of label, calls these three methods:
    RenderBeginTag(writer)
    RenderContent(writer)
    RenderEndTag(writer)

Now if all we need to do is remove those two tag calls!  My new control just overrides the base Render method and just leaves out the call to those two.  and bing bang, a label control with no tags.

The draw back to this is that all the style/css class crap that is an option for a label is now broken, for me this was/is not an issue, but if I still needed them then I would have probably replaced the <span> with a <div> and pulled in all the attributes that were added to the "label". I have an example of doing just that!  it will allow you to change the tag in which this control renders.

So you want to change that <span> to a <div> or other tag?
The WebControl class defines a property called TagKey, that is an enum of type HtmlTextWriterTag and is used in the render methods.  In the render methods the writing of the html is carried out by the HtmlTextWriter class, this class relies on the HtmlTextWriterTag inoder to know what tag to wrap around that control.  With out requiring these tags then there is no way that the writer can apply style, css classes etc. (which is why none of those work on the LabelNoSpan class). 

So without anymore delay here is the super simple code to change out the tag that is applied to a WebControl

   1:  using System.Web.UI.WebControls;
   2:  using System.Web.UI;
   3:   
   4:   
   5:  public class LabelWithDiv : Label
   6:  {
   7:      public LabelWithDiv(){}
   8:   
   9:      public override void RenderBeginTag(System.Web.UI.HtmlTextWriter writer)
  10:      {
  11:          //Force the tagKey to be a div.
  12:          this.AddAttributesToRender(writer);
  13:          writer.RenderBeginTag(HtmlTextWriterTag.Div);        
  14:      }
  15:  }
 
 

Currently rated 3.3 by 3 people

  • Currently 3.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Development | .Net | Work

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen