You are not logged in Log in Join
You are here: Home » Members » Caseman » Client-Side Script Includes

Log in
Name

Password

 

Client-Side Script Includes

A simple way to organize client-side scripts

Introduction

Most everything you might need to do in a Zope application can be done on the server side with DTML. You may find an occasion, however when a feature is better implemented on the client side using a scripting language like JavaScript (a.k.a. ECMA Script).

Scripting can be especially useful on forms. They enable you to make more intelligent forms that can dynamically change or make calculations without having to refresh the entire page. They can also be used to "enhance" the presentation of your pages, but beware of relying on scripting to get your point across.

Scripting the Zope way

Since Zope can serve up anything you like, scripts can obviously just be added to a DTML Document or Method without any real extra effort. What I have concocted here is an alternative way leveraging the power of Zope to segregate your scripts from your content and DTML. This will also help you keep your scripts organized and modular so they can be distributed throughout your site as needed.

The first step is to create a folder to contain your scripts. In my example I have created a folder called java_script in my root folder. Each script will be in a DTML Method in this folder. It works best if you create separate methods for each specific function. You could also group similar script functions into script "library" methods. The script methods do not need to contain any tags, although you can use DTML in your script methods to do cool things like fill arrays from a database using a Z SQL Method.

Next, we modify our friend and ally standard_html_header so that it inserts scripts for any documents that request them. Simply insert the DTML code below within the <HEAD> section of your standard_html_header.

     <dtml-if scripts>
         <dtml-comment>
              Include Java Scripts Specified by Scripts Property
         </dtml-comment>
         <META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
         <SCRIPT language="JavaScript"><!--
         <dtml-with java_script>
             <dtml-in scripts>
                 //
                 // Script of <dtml-var sequence-item>
                 //       
                 <dtml-var "_.getitem(_['sequence-item'],1)">
             </dtml-in>
         </dtml-with>
         //--></SCRIPT>
     </dtml-if scripts>

The above example assumes you are using JavaScript but with minor modifications, it would work with any scripting language.

Example: A JavaScript Enabled Document

First off, we need a a JavaScript to play with for our example. Below is a very simple JavaScript that filters "$" and "," from a field so that you can process the inputted value as a number. Copy this code into a DTML Method in your java_script folder called money_filter.


    function money_filter(str) {
        re = /\$|\,/g;
        // remove "$" and ","
        return str.replace(re, "");
    }

Now somewhere else in your site, create a DTML Document containing the following:


    <dtml-var standard_html_header>
    <FORM>
        Enter a dollar amount including the "$":
        <INPUT type=text name=amount value="$1,000.00">
        <INPUT type=button value="Fix It!" onClick="this.form.amount.value=money_filter(this.form.amount.value)">
    </FORM>
    <dtml-var standard_html_footer>

Now, add a lines property to your DTML Document called scripts with a value money_filter. Save the changes and when you view the document, and voila, the appropriate script is inserted for you from your java_script folder. View the source to see exactly what's going on.

Another Method

The method described above inserts the actual scripts into the content of your documents when they are rendered by Zope. Scripts can also be passed by reference if you prefer. This means the script text will not appear directly in the source of the document. To have Zope insert scripts this way, insert this into your standard_html_header instead:

     <dtml-if scripts>
         <dtml-comment>
              Include Java Scripts Specified by Scripts Property
         </dtml-comment>
         <META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
         <dtml-with java_script>
             <dtml-in scripts>
                 <SCRIPT language="JavaScript" 
                         src="<dtml-var BASE0>/java_script/<dtml-var sequence-item>">
                 </SCRIPT>
             </dtml-in>
         </dtml-with>
     </dtml-if scripts>

There are advantages and disadvantages to this method. One disadvantage is that the browser must make a separate request for each script the first time a page is opened. This is most costly if you have many small script files included. You may also find that you must insert the following line at the top of your script methods for it to work for all browsers:

    <dtml-call "RESPONSE.setHeader('Content-Type', 'application/x-javascript')">

A potential advantage to using this method is that the browser can cache the scripts separately from the page contents, so that pages sharing the same scripts load faster and place less burden on the server. Both ways work equally well, so you can decide for yourself which is better.

Conclusion

The power inherent in Zope makes this so very simple. We are leveraging the powers of aquisition to make this work. The beauty of this method is that it is invisible to any documents that do not contain a scripts property. So, nothing is inserted in the header of a document that does not specifically request a script. But, you can add scripts to any document at will by adding a scripts property to it with the ids of one or more script methods in your script folder. Also, you can assign a scripts property to a folder so that all the documents in the folder automatically aquire the scripts!

If you are looking for more example JavaScripts of all kinds, check out The JavaScript Source .