views:

1459

answers:

6

I'm running my site through the W3C's validator trying to get it to validate as XHTML 1.0 Strict and I've gotten down to a particularly sticky (at least in my experience) validation error. I'm including certain badges from various services in the site that provide their own API and code for inclusion on an external site. These badges use javascript (for the most part) to fill an element that you insert in the markup which requires a child. This means that in the end, perfectly valid markup is generated, but to the validator, all it sees is an incomplete parent-child tag which it then throws an error on.

As a caveat, I understand that I could complain to the services that their badges don't validate. Sans this, I assume that someone has validated their code while including badges like this, and that's what I'm interested in. Answers such as, 'Complain to Flickr about their badge' aren't going to help me much.

An additional caveat: I would prefer that as much as possible the markup remains semantic. I.E. Adding an empty li tag or tr-td pair to make it validate would be an undesirable solution, even though it may be necessary. If that's the only way it can be made to validate, oh well, but please lean answers towards semantic markup.

As an example:

<div id="twitter_div">
<h2><a href="http://twitter.com/stopsineman"&gt;@Twitter&lt;/a&gt;&lt;/h2&gt;
<ul id="twitter_update_list">
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"&gt;&lt;/script&gt;
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=twitterCallback2&amp;amp;count=1"&gt;&lt;/script&gt;
</ul>
</div>

Notice the ul tags wrapping the javascript. This eventually gets filled in with lis via the script, but to the validator it only sees the unpopulated ul.

Thanks in advance!

+2  A: 

Perhaps you could use javascript to write the initial badge HTML? You'd probably only want the badge code to be inserted in your document if javascript were available to populate it, right?

You'd just need to make sure your document writing happens before the javascript for your various badges.

Could you give a specific example of the HTML / link to a page with the invalid code?

Rudi
That's an interesting thought. That way, in the original markup, the script is all that's there, not the invalid markup. Hmm... :\
Tim Visher
That just means that you are hiding things that may later turn out to be invalid. I'm not sure WHAT it is you are trying to validate - just the HTML, or the entire page DOM as the browser/user has to use it?
Cade Roux
A: 

At some point the page becomes valid, right? That's the only time it can really be validated.

I'm not sure a non-trivial page will remain valid at every point during its construction if it's constructed with a lot of DOM scripting.

Cade Roux
I'm not sure I follow your reasoning. It is true that at every stage of development your markup is not guaranteed to validate. However, if the final markup doesn't validate, then there is no later point at which it will validate. What am I missing?
Tim Visher
Your validator is running too early. It needs to run on the final constructed page after all the scripts have been applied.
Cade Roux
A: 

This might not be the most popular opinion on this topic, but...

Don't worry about 100% validation. It's just not that big of a deal.

The point of validation is to make your markup as standard as possible. Why? Because browsers that are given markup that doesn't conform to the spec (eg, markup that does not validate) do their own error checking to correct it and display the page the way you intended it to look to the user. The quality of the browsers error checking varies, yadda-yadda-yadda, it's better to have valid markup... But it's not even your code that's causing the validation to fail! The people who wrote those badges probably tested them in multiple browsers (and you should do the same, of course), if they work as expected then just leave it at that.

In short, there's no prize for validating :)

thenduks
I suppose there's no 'prize' for validating except for the general 'goodness' of standards for any practice. Validation doesn't even guarantee that your page will display correctly everywhere. However, I for one want to support the standards movement in web development. :)
Tim Visher
Of course you want to support web standards, as do I (my site validates). My point is that by not worrying about some third-party badges you STILL support web standards without going all zealot about it. The web isn't a perfect place, you're already doing your part.
thenduks
+6  A: 

The following fragment is valid XHTML and does the job:

<div id="twitter_div">
    <h2 class="twitter-title"><a href="http://twitter.com/stopsineman" title="Tim's Twitter Page.">Twitter Updates</a></h2>
    <div id="myDiv" />
</div> 

<script type="text/javascript">
    var placeHolderNode = document.getElementById("myDiv");
    var parentNode = placeHolderNode.parentNode;
    var insertedNode = document.createElement("ul");
    insertedNode .setAttribute("id", "twitter_update_list");
    parentNode.insertBefore( insertedNode, placeHolderNode);
    parentNode.remove(placeHolderNode);
</script>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"&gt;&lt;/script&gt;
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=twitterCallback2&amp;amp;count=5"&gt;&lt;/script&gt;
Panos
I made a small alteration but this is what I ended up going with. I deleted `parentNode.remove(placeHolderNode);`. Works great!
Tim Visher
Shouldn't that be parentNode.removeChild(placeHolderNode)?
wfarr
+2  A: 

The solutions might be different for each badge. In Twitter's case, you can just write your own callback function. Here's an example based on their badge code:

<div id="twitter_div">
  <h2><a href="http://twitter.com/stopsineman"&gt;@Twitter&lt;/a&gt;&lt;/h2&gt;
  <div id="twitter_update_list"></div>
</div>

<script type="text/javascript">
function updateTwitterCallback(obj)
{
  var twitters = obj;
  var statusHTML = "";
  var username = "";
  for (var i = 0; i < twitters.length; i++)
  {
    username = twitters[i].user.screen_name;
    statusHTML += ('<li><span>' + twitters[i].text + '</span> <a style="font-size:85%" href="http://twitter.com/' + username + '/statuses/' + twitters[i].id + '">' + relative_time(twitters[i].created_at) + '</a></li>');
  }
  document.getElementById('twitter_update_list').innerHTML = '<ul>' + statusHTML + '</ul>';
}
</script>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"&gt;&lt;/script&gt;
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=updateTwitterCallback&amp;amp;count=1"&gt;&lt;/script&gt;
Joe Lencioni
A: 

I put a <li> with "display:none" in the <ul> Tag:

<ul id="twitter_update_list"><li style="display:none;">A</li></ul>

<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"&gt;&lt;/script&gt;
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/01241.json?callback=twitterCallback2&amp;amp;count=1"&gt;&lt;/script&gt;

This does not disturb the script and in this case it works, and I think its not a "undesirable solution" :)

Markus