jQuery Templates - XHTML Validation

Maybe you have already tried, and I don't know what are your results but here is my opinion regarding this.

By default, Visual Studio.NET adds the xhtml1-transitional.dtd schema

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

So, if you try to validate your page which has jQuery Templates against this schema, your page won't be XHTML valid. Why?

It's because when creating templates, we use HTML tags inside <script> ... </script> block. Yes, I know that the script block has type="text/html" but it's not supported in this schema, thus it's not valid.

Let's try validate the following code

Code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>jQuery Templates :: XHTML Validation</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js" type="text/javascript"></script>
    
    <script language="javascript" type="text/javascript">
        $(function () {
            var attendees = [
                { Name: "Hajan", Surname: "Selmani", speaker: true, phones: [070555555, 071888999, 071222333] },
                { Name: "Denis", Surname: "Manski", phones: [070555555, 071222333] }
            ];

            $("#myTemplate").tmpl(attendees).appendTo("#attendeesList");
        });
    </script>

    <script id="myTemplate" type="text/html">
         <li>
            ${Name} ${Surname}
            {{if speaker}}
                (<font color="red">speaks</font>)
            {{else}}
                (attendee)
            {{/if}}
        </li>
    </script>
    
</head>
    <body>
    <ol id="attendeesList"></ol>
</body>
</html>

To validate it, go to http://validator.w3.org/#validate_by_input and copy paste the code rendered on client-side browser (it’s almost the same, only the template is rendered inside OL so LI tags are created for each item).

Press CHECK and you will get:

Result: 1 Errors, 2 warning(s) 

The error message says:


Validation Output: 1 Error

Error Line 21, Column 13: document type does not allow element "li" here

         <li>


Yes, the <li> HTML element is not allowed inside the <script>, so how to make it valid?


1st SOLUTION: Using <![CDATA][…]]>

The first thing that came in my mind was the CDATA. So, by wrapping any HTML tag which is in script blog, inside <![CDATA[ ........ ]]> it will make our code valid. However, the problem is that the template won't render since the template tags {} cannot get evaluated if they are inside CDATA.

Ok, lets try with another approach.


2nd SOLUTION: HTML5 validation

Well, if we just remove the strikethrough part bellow of the !DOPCTYPE

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

our template is going to be checked as HTML5 and will be valid.

Ok, there is another approach I've also tried:


3rd SOLUTION: Separate the template to an external file

We can separate the template to external file. I didn’t show how to do this previously, so here is the example.

1. Add HTML file with name Template.html in your ASPX website.

2. Place your defined template there without <script> tag

Content inside Template.html

<li>
    ${Name} ${Surname}
    {{if speaker}}
        (<font color="red">speaks</font>)
    {{else}}
        (attendee)
    {{/if}}
</li>

3. Call the HTML file using $.get() jQuery ajax method and render the template with data using $.tmpl() function.

$.get("/Templates/Template.html", function (template) {
    $.tmpl(template, attendees).appendTo("#attendeesList");
});

So the complete code is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>jQuery Templates :: XHTML Validation</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js" type="text/javascript"></script>
    
    <script language="javascript" type="text/javascript">
        $(function () {
            var attendees = [
                { Name: "Hajan", Surname: "Selmani", speaker: true, phones: [070555555, 071888999, 071222333] },
                { Name: "Denis", Surname: "Manski", phones: [070555555, 071222333] }
            ];

            $.get("/Templates/Template.html", function (template) {
                $.tmpl(template, attendees).appendTo("#attendeesList");
            });
        });
    </script>
    
</head>
    <body>
    <ol id="attendeesList"></ol>
</body>
</html>

This document was successfully checked as XHTML 1.0 Transitional!

Result: Passed


UPDATE

SOLUTION 4: Separate the template to an external file and place it inside JavaScript variable

I was pretty sure that someone will mention the <script src="file-name" /> to load the template. Well, if it's on the normal HTML-like format we write it, it won't work

Of course, if you put the template in JS variable and place it in separate JS (or HTML) file, it will work prefectly.

So, we can write the template on the following way:

 /Templates/Template.js file

var myTemplate =
        "<li>" +
            "${Name} ${Surname}" +
            "{{if speaker}}" +
                "(<font color=\"red\">speaks</font>)" +
            "{{else}}" +
                "(attendee)" +
            "{{/if}}" +
        "</li>";

So, you can reference this file in your page using <script src="http://localhost/Templates/Template.js" type="text/javascript"></script>

And, to make this work, here is the jQuery code

<script language="javascript" type="text/javascript">
    $(function () {
        var attendees = [
            { Name: "Hajan", Surname: "Selmani", speaker: true, phones: [070555555, 071888999, 071222333] },
            { Name: "Denis", Surname: "Manski", phones: [070555555, 071222333] }
        ];
        //myTemplate is the name of the variable
        $.template("myExternalTemplate", myTemplate); // Compile the template as named template so we can reuse it
        $.tmpl("myExternalTemplate", attendees).appendTo("#attendeesList"); //append it to HTML
    });
</script>

Instead of using AJAX call, we have replaced this code with the two lines which contains //COMENTS.

This way solves the problem we have. Of course, this is beta version plugin and I do expect in the future to have some functionality to load external templates much easier.

If you have any additional methods for XHTML validation, you can share it :).

Thanks,
Hajan

No Comments