locked
Thoughts on version 2 of these adapters RRS feed

  • Question

  • User-1385398420 posted

    I've been thinking about what can be done as part of a version 2.0 rewrite of the CSS adapters, and over the past few nights did some test coding to see what works and what doesn't.

    First, let me outline some of the things that I feel should be a key part of version 2.0.

    • Improved testability. The source code should include unit tests.
    • Improved rendering. Wherever possible, the code generated should be improved.
    • Improved configuration. There's limited configuration options right now unless you change the source code.
    • Improved documentation. The typical need of an open source project.

    With these things in mind, and after some experimentation using a simple control (CheckBoxList), I came up with a few ideas...

    Improving Configuration

    The obvious choice is to use the web.config file, but what should be allowed in the configuration? The first obvious choice is CSS class names. For example, consider the following mock configuration:

    <CSSFriendly>
    <CheckBoxList cssClass="AspNet-CheckBoxList"
    disabledCssClass="AspNet-CheckBoxList-Disabled" itemCssClass="AspNet-CheckBoxList-Item"
    repeatDirectionCssClass="AspNet-CheckBoxList-RepeatDirection-" />
    </CSSFriendly>

    Note the <CSSFriendly> configuration section, which includes a <CheckBoxList /> element that allows you to edit the generated CSS classes. Say you don't want the default? You can specify this as a configuration:

    <CSSFriendly>
    <CheckBoxList cssClass="checkbox"
    disabledCssClass="disabled" itemCssClass="" repeatDirectionCssClass="repeat-" />
    </CSSFriendly>

    In this case, you have new class names. An attribute that is blank (itemCssClass) would not get a class applied. In the CheckBoxList case, the repeatDirectionCssClass would append the repeat direction of the control. Or something like that... Remember, this is just a first concept!

    Improving Testability

    There are two ways to test web controls: to look at the HTML code they generate, or to do user behavior testing (possibly automated using something like Selenium). The latter is complex, but the former is not -- if you can somehow extract the HTML code generated by an adapter.

    Unfortunately, this is easier said than done, so I started thinking about a new approach, which became a different way to look at how the adapters worked.

    The adapters really do two things:

    1. Generate HTML markup
    2. Apply WebForms-specific scripts (such as Page.ClientScript.RegisterForEventValidation(checkList.UniqueID)).

    My thinking is to split the HTML generation out of the adapter by deriving everything from two abstract classes: CssFriendlyAdapter<T> and HtmlRenderer<T>. (In both cases, T is a WebControl.)

    The CssFriendlyAdapter would have an abstract method, CreateHtmlRenderer(). That method would be responsible for creating an HtmlRenderer for the adapter. The HtmlRenderer is responsible for making the HTML markup for a given WebControl; the adapter serves as a wrapper around its renderer, and can still apply WebForms extras.

    This improves testability because we can now test our HtmlRenderer classes to ensure they generate the expected HTML markup for a given control. Since the HtmlRenderer is easy to instantiate and has limited dependencies, it is easy to do so.

    The flow looks something like this:

    WebControl as T
     -> CSSFriendlyAdapter<T>
            .OnPreRender()
                 -> CreateHtmlRenderer(); [abstract]
                 <- HtmlRenderer<T>
            .RenderBeginTag()
                 -> _renderer.RenderBeginTag();
            .RenderContents()
                 -> _renderer.RenderContents();
            .RenderEndTag()
                 -> _renderer.RenderEndTag();

    HtmlRenderer -- renders basic HTML
    CssAdapter -- adds WebForms specific features

    The following code is a sample of an NUnit test that actually works in my current sandbox.

    [TestFixture]
    public class CheckboxListHtmlRendererTests
    {
    	private StringWriter stringwriter;
    	private HtmlTextWriter htmlwriter;
    	[SetUp]
    	public void SetUp()
    	{
    		stringwriter = new StringWriter();
    		htmlwriter = new HtmlTextWriter(stringwriter);
    	}
    	[Test]
    	public void TestValidHtml()
    	{
    		CheckBoxList control = new CheckBoxList();
    		control.ID = "test";
    		CheckBoxListHtmlRenderer renderer = new CheckBoxListHtmlRenderer(control);
    		Assert.AreEqual(renderer.RenderBeginTag(htmlwriter), 
    			"&lt;ul class=\"AspNet-CheckBoxList AspNet-CheckBoxList-RepeatDirection-Vertical\" id=\"test\"&gt;\r\n");
    	}
    }
    

    Cool stuff.

    Improved Rendering and Documentation

    Obviously, any effort in rewriting the controls should include both improving the rendered HTML and the available documentation. For the latter, my idea is to document as we go, and provide a matrix for each adapter that illustrates what features work for a control.

    Documentation is something that, if done early and continuously, is easier to manage. Note that when I say "documentation" I am thinking moreso of API documentation and implementation documentation -- that is, how an adapter will change markup and what control properties are supported by it.

     

    Not sure when I'll have something for public consumption -- at this point, I am just experimenting with one control (CheckBoxList) before moving to more complex objects.

     

    Comments? Feedback? Anyone interested in contributing? 

    Tuesday, September 16, 2008 10:33 PM

All replies

  • User89553585 posted

    Althought I haven't have that much experience with the Adapter (I downloaded it about a year ago, couldn't get it to work with my exisiting project, so I gave up on it) but now that I'm in the process of building a new and improved version of my project from scratch targeting .NET 3.5, I decided to give them a try.  They work as I expected them to do,so I'm happy so far [:D]

    I wish I could tell you if what you mention is needed, but I do have to agree that there needs to be more documentation.  Hell, I might even try to write some custom controls myself.  I definitely like the idea of  <CSSFriendly> inside the web.config.

    Tuesday, September 23, 2008 5:13 PM
  • User-1385398420 posted

     Documentation is definitely a big thing that's missing.

    Since this post (and a similar post on my blog) there have been only two replies -- one here (yours) and one on my blog. That's not much of an endorsing need to rewrite these adapters. :(

     

    Sunday, September 28, 2008 9:04 PM
  • User-859514523 posted

    Let me wholeheartedly add a third(?) request for a comprehensive rewrite of the CSS-Friendly control adapters.

    I would recommend starting with the following: extend the improved rendering behavior to more controls.

    It's kind of a death spiral the way it is now - the default set only renders three controls, developers give up on it because they'd have to write the renderers for all the other ones they want, they give up and lose interest, no feedback, no impetus to innovate, the default set only renders three controls, lather, rinse, repeat.

    If a large code base is out there, it's much easier for developers to tweak (and to submit fixes for stuff that doesn't quite satisfy). Doc is also easier than core dev.

    My current woodie is for the wizards to render as divs and not tables. I'm happy that with the community build, there is framework to go by when 'rolling your own.' And when I do, I'll push it up.

    That said, here beginneth the rant: 

    But even more than the default rendering, even in ASP.Net 3.5, and even finessing my game for IE6, which sucks tailpipes as a browser (and they're going to roll it out to Windows Mobile 7??), the thing that frosts my ^&%$! tips about Microsoft is the poor attitude and the apathy they show toward people who want to make VStudio render better. Even ScottGu sends people to this pack when they ask the "why don't it div?" question - and that was back in 2.0, and NOTHING'S CHANGED in 3.5. No one gives a $#!+ until they actually have to work it. That above anything else is why anybody in GUI who's seen anything else spits on .Net development. You think Ruby renders table tags? WTF is this, 1994?

    Here endeth the rant.

    I'll be back when I can do up a set of wizard controls to add to the stack. Thanks for listening.

    Peace,
    JD

    Tuesday, September 30, 2008 4:43 PM
  • User575409785 posted

    As someone who only recently (as in, this past April) started learning ASP.NET--while trying to head up the expansion of our corporate site from <300 to >600 pages (it seemed liked such a good idea at the time...)...

    I wholeheartedly support the drive for documentation. I managed to get the menu adapter working in both a vertical & a horizontal layout, but it was tough.

    Of course, a big part of the problem was my newness to ASP.NET, but judging by the number of posts I found from people having the same problems I was having, there must be a lot of newbies out there trying to use these things.

    The one other issue I had with the menu adapter was that it didn't handle &s correctly. Fortunately, I found a post by someone who had a fix for it, and was able to decipher his C# code to make the necessary changes to the VB version that I was using.

    It's a great tool, though--I'm really happy to have found it.

    Tuesday, September 30, 2008 10:49 PM
  • User-1385398420 posted

    OK, so I guess there's at least enough interest to make an effort worth trying.

    My thinking is to create a separate project for the next version. In fact, I'm wondering if they should get a different name entirely. Random thoughts on the matter follow.

    • I plan on switching to either Google Code or Assembla, because I think both are superior to CodePlex. Probably will go with Google Code + a Google Group.
    • What's in a name... The logical idea is CSSFriendly2. But are these really "CSS Friendly" adapters, or adapters that render proper, customizable semantic markup for ASP.Net web controls? I say the latter. The intent of the adapters isn't to make them CSS friendly, but markup friendly. WebControlAdapters is a very simple, but descriptive, name, as is AspNetAdapters (has the added benefit of "AspNet" in the name).
    • Initially we will tackle some very simple controls to flesh out a coding, configuration, and documentation methodology. My test code used the CheckBoxList, which is a good example of a simple control that can use some markup-friendly adapting.
    • As much as I'd like to say .Net 3.5, there's really no reason to, because from a web control standpoint there is little changed between 2.0 and 3.5, and there is a huge installed base of 2.0 framework apps that would benefit from the project. No need to exclude them for the sake of the latest and greatest.
    • C# only. I wouldn't even suggest someone try to maintain a simultaneous VB.Net version. The intent is not to give sample code but to give a working, binary drop-in solution that adds well-documented functionality.

    So, for those who care, let me know what you think, and if you want to contribute to the effort, let me know.

    (BTW -- I was reminded how important this project can be when I recently started a new project to beautify an ASP.Net web site for a new client... and was reminded how TABLE tags are added around things where they shouldn't be. Ugh...)

    Tuesday, September 30, 2008 11:27 PM
  • User-859514523 posted

     I'm in, and I'm good with all of that. 2.0 adapters should work in 3.5, anyway. But I'll warn you - my GUI-fu far outstrips my C# or my javascript. In fact, I came at this from GUI, when I was about to choke some developers. I'm calmer now, and ready to (help) code.

    Wednesday, October 1, 2008 12:20 AM
  • User-1385398420 posted

    I am proud to announce the new project: ASP.Net Control Adapers!

    The project site is hosted through Google Code: http://code.google.com/p/aspnetcontroladapters/

    I have checked in my original test code, cleaned up a bit to make it more useful. It implements limited support for the CheckBoxList control. Source code includes the main project, a UnitTests project (using NUnit), a WebTests project (a web app that invokes the adapted control in a web page), license/readme files, and an NAnt build script.

    I also started working on a documentation format, which you can see at http://code.google.com/p/aspnetcontroladapters/wiki/CheckBoxList.

    There's still a lot missing in terms of implementation (not even postback support yet!), and unit testing, but in general the programmers out there should be able to understand the approach I'm taking, and designers/front-end developers can understand the GUI approach.

    Still lots to do before this is consumable by others, but I wanted to get this up and hosted.

    Also -- there's a Google Group for it: http://groups.google.com/group/aspnetcontroladapters -- be sure to head there to add to the discussion. 

    Saturday, October 4, 2008 11:36 PM
  • User575409785 posted

     Great news! Can't wait until this gets its Big Girl Panties on and is ready to be used by those of us who had to Google NUnit and NAnt ;-)

    Sunday, October 5, 2008 12:58 PM
  • User-1385398420 posted

     For those following along, I just made some changes and implemented more support for CheckBoxLists.

    Take a look at the implementation notes here: http://code.google.com/p/aspnetcontroladapters/wiki/CheckBoxList

    Tuesday, October 7, 2008 12:55 PM
  • User-538256727 posted

    first off: good initiative!

    just to put in my two cents.....

    The adapters should not write classes on rendered nodes the way they do. A perfect example is the menu adapter which writes a cssclass on all li nodes. This is the first thing I stripped out of the original adapters. Furthermore.....

    I use the adapters to ensure developers working on a project include all necessary attributes to the controls they write (throwing errors where they don't). The problem is that the more complex controls, like datagrid and such writeout controls like labels, literals, linkbuttons as well, causing everything to collapse. I have written a number of exceptions based on the parent container (there are usually td elements for example) but there are just 'fixes', not really structured. What I really want to do is disable them for certain parent controls.

    So in short, I think control adapters for the more complex controls should have an option to disable all defined controls adapters in the browser file for their children. Hope this makes sense :-)

    Tuesday, October 7, 2008 5:55 PM
  • User-1385398420 posted

    First, note that initialy I'm keeping the adapted controls somewhat in line with what the CSSFriendly adapters do. THAT BEING SAID... keep in mind that there will be many configuration options -- in fact, as it is right now, if you do NOT specify a class in your configuration file, no class is added. In other words -- the default is to NOT add any classes at all.

    Once I get the first adapter to a point where I'm comfortable with it, I will greatly simplify the "sample" CSS. Ultimately, the "default" situation for, say, the adapted CheckBoxList control would be to apply the class you specify in your <asp:CheckBoxList CssClass=""> to the top unordered list, and that's it. Everything else will be optional.

    Trust me, I like simple markup, too, and believe very strongly in the first "C" of CSS (i.e. CASCADING). :)

    BTW feel free to move the discussion over to http://groups.google.com/group/aspnetcontroladapters

    Tuesday, October 7, 2008 7:04 PM
  • User1265453780 posted

    This is a great initiative, a much needed project. Can't see why Microsoft don't just bite the bullet and generate css friendly code though.

    I agree that the adapters shouldn't issue hard-coded class names on the elements that they generate. But rather than use the configuration file, why not use the original control classes? An adapted control is supposed to use the same semantics as the original control. For example the Menu control has numerous properties to allow you to specify class names to control various states (selected, hover etc). These could be picked up and used by the adapter. The same goes for other properties such as StaticDisplayLevels.

    Thursday, October 16, 2008 4:45 PM
  • User1265453780 posted

    Anyone know where the .vsi file has gone for this project? All the links seem to point to an MSDN library page at present, with no sign of the file itself.

    Thursday, October 16, 2008 5:28 PM
  • User-1385398420 posted

    I agree that the adapters shouldn't issue hard-coded class names on the elements that they generate. But rather than use the configuration file, why not use the original control classes? An adapted control is supposed to use the same semantics as the original control. For example the Menu control has numerous properties to allow you to specify class names to control various states (selected, hover etc). These could be picked up and used by the adapter. The same goes for other properties such as StaticDisplayLevels.

     

    The original ("CssClass property" classes will also be used. Configuration will give you the option to have certain classes always added to your markup. No configuration, and no additional classes (the default is to add nothing).

    For example, look at the CheckBoxList in the partial implementation (http://code.google.com/p/aspnetcontroladapters/wiki/CheckBoxList). If you don't add any configuration value for the CheckBoxList CssClass, no class name will be added to the <ul> that wraps your checkboxes.

    That being said, we do need to provide some baseline CSS and baseline functionality that ensures the adapted controls look nearly identical to the current controls -- in a sense, a default implementation. That will be provided, and it is illustrated in the aforementioned web page.

    Eventually, every class name will be customizable or, if left out, omitted -- though there may be exceptions where a class name is necessary to denote rendering behavior. For example, the CheckBoxList has a RepeatDirection property, which can be Horizontal or Vertical. Some class must be added to allow markup to use this. Whether this should be omitted if not defined in configuration or not is up to debate. Ultimately, it comes down to one of the following:

    1. Default class names are added unless the configuration specifically states NO class (i.e. empty strings).
    2. No class names are added unless the configuration specifically states a class (i.e. non-empty strings).

    Not sure which approach to take. #1 has merit in that it is more "plug and play". #2 has merit in that it only does what you tell it to do. Come to think of it, there is a third option...

    1. Allow a "UseDefaultClasses" configuration property (perhaps TRUE by default, implying #1 behavior is the default). Setting this to FALSE would make the adapters behave as #2.
    I kind of like that...
    Thursday, October 16, 2008 9:14 PM
  • User1265453780 posted

    A question about the stylesheets. There appear to be two sets: one that provides default functionality, the other providing "theme-related" styling. Am I right in thinking that the intended implementation is that pages using (say) the adapted Menu control should link to the former styles as well as the "theme" styles? When I remove the link to the basic styles in the source code project, I don't notice any difference in appearance or behaviour... have I missed or misunderstood something?

    Friday, October 17, 2008 7:15 AM
  • User1265453780 posted

    The same goes for other properties such as StaticDisplayLevels.

    By the way, the reason I mentioned this property is so that the menu can be used with the SiteMapDataSource. Sitemaps only allow one root element, conventionally the site home page. Displaying just a single menu item for the home page is usually not enough; normally you want to display the second tier of links as well. To achieve this with the Menu control, you set the StaticDisplayLevels property to 2, thereby "flattening" the first two tiers of the hierarchy into one. If you try this with the adapted control, it doesn't work.

    Friday, October 17, 2008 7:19 AM
  • User1265453780 posted

    When I remove the link to the basic styles in the source code project, I don't notice any difference in appearance or behaviour... have I missed or misunderstood something?

    OK, I see it now, you're using embedded stylesheets, so the link from the page to the .css is not necessary. I suggest removing those explicit links in the pages and highlighting somewhere that you are using embedded css definitions so as to avoid confusion.

    Friday, October 17, 2008 7:51 AM
  • User-1385398420 posted

    The same goes for other properties such as StaticDisplayLevels.

    By the way, the reason I mentioned this property is so that the menu can be used with the SiteMapDataSource. Sitemaps only allow one root element, conventionally the site home page. Displaying just a single menu item for the home page is usually not enough; normally you want to display the second tier of links as well. To achieve this with the Menu control, you set the StaticDisplayLevels property to 2, thereby "flattening" the first two tiers of the hierarchy into one. If you try this with the adapted control, it doesn't work.

     

    The goal is to implement all properties so they have the same behavior as they do today. The only thing the adapters should do is change HTML markup -- not behavior. So, yes, a proper implementation would include support for StaticDisplayLevels.

     

    Friday, October 17, 2008 12:03 PM
  • User-1385398420 posted

    For those following along, I just made some notable updates to the AspNetControlAdapters project (see http://code.google.com/p/aspnetcontroladapters).

    Of note...

    I'd love to get more feedback, either here or (preferably) at http://groups.google.com/group/aspnetcontroladapters.
    Wednesday, October 22, 2008 11:34 AM
  • User-1763423073 posted

    I'm interested!

    I need to render a Wizard in a standards compliant way. I embarked on writing my own page from scratch to reflect the functionality of the wizard, but have run into problems.

    I found Tokely's WizardAdapter at http://andrewtokeley.net/archive/2008/05/16/css-adapter-for-asp.wizard-control.aspx and so installed the CSSFriendlyAdapters. The problem I have is that I can't specify my own layout. Some of the divs are in the wrong place for my liking. I guess I'd have to write my own adapter to output the divs as I wanted them. However I daren't jump into that just yet - I'm only a junior developer with 2 years experience, and I have deadlines looming!

    Friday, February 27, 2009 7:38 AM
  • User-1385398420 posted

    I have done a little work on a new Wizard Adapter in the AspNetControlAdapters project: http://code.google.com/p/aspnetcontroladapters

    It is very much incomplete, but if someone can provide some real-world examples of current usage, it would be easier for me to finish coding it. (I don't do much WebForms development now, so real-world samples are lacking.)

    If you want to contribute to the effort, post on the Google group at http://groups.google.com/group/aspnetcontroladapters -- provide as much as you can in terms of an example of your CURRENT Wizard code (aspx and codebehind), the CURRENT generated output, and the DESIRED output.

    Friday, February 27, 2009 9:10 AM