7. Embedding JavaScript and CSS

Modern websites make a heavy use of JavaScript and CSS. An XML template engine must provide a proper support for them and Open Power Template is not an exception. Since now, our basic tool are CDATA sections. The XML standard says that the contents enclosed within a CDATA section are treated as a single block of static text and are not parsed. We are allowed to enclose XML tags there, break XML rules, use XML special symbols etc. without any problems. Open Power Template keeps the semantics of the CDATA sections and does not parse their contents. It is rewritten to the output together with the CDATA delimiters, so that browsers should also ignore its internal structure, at least theoretically.

Unfortunately, sometimes CDATA sections are not enough. Let's consider a following example, where we want to read a piece of JavaScript code from an OPT variable:

<script type="text/javascript">
<![CDATA[
    document.write('Test: {$variable} or ]]>{$variable}<![CDATA[?');
]]>
</script>

After executing this template we would get:

<script type="text/javascript">
<![CDATA[
    document.write('Test: {$variable} or ]]>variable value<![CDATA[?');
]]>
</script>

This is not exactly what we would like to get. The compiler must have broken the CDATA section in order to display a variable value, and then open it again. It does not look nice and moreover, many browsers could have problems with parsing it properly. A solution is provided by the opt:literal instruction which controls the CDATA section behaviour:

<script type="text/javascript">
<opt:literal type="comment_cdata">
<![CDATA[
    document.write('Test: {$variable} or ]]>{$variable}<![CDATA[?');
]]>
</opt:literal>
</script>

opt:literal makes the CDATA delimiters in the template not to be sent to the browser, although they are still parsed properly. What is more, the instruction allows to pack the content with one of four delimiter types selected with the type attribute:

  • cdata - the content is packed within <![CDATA[ and ]]> delimiters.
  • comment_cdata - the content is packed within /* <![CDATA[ */ and /* ]]> */.
  • comment - the content is packed within <!-- and --> (a dynamic comment).
  • transparent - does not pack the content within anything. It just hides the <![CDATA[ and ]]> delimiters in the content.

So, the final result of our template will be:

<script type="text/javascript">
/* <![CDATA[ */
    document.write('Test: {$variable} or variable value?');
/* ]]> */
</script>

The <![CDATA[ content is still not processed, but the delimiters are hidden, giving us a nice and correct JavaScript code. Moreover we have packed it within the delimiters that guarantee a proper JavaScript execution in both newer and older browsers.

The same trick can be used to create conditional Internet Exporer comments. We leave it as an exercise for you.