Tutorial: how to create a Smartlet

Release 1.1 - ...

In this tutorial, we will create a Smartlet that illustrates some of the capabilities of the Smartlet Architecture. First, a basic Smartlet will be created that will output a string, then, the Smartlet will be made Ajax-enabled. 

 

  1. Create a Strict Web Page folder to store the Smartlet and its resources in.
    1. For this tutorial, name it Smartlet Tutorial
  2. Add a Smartlet item to that folder.
    1. Add an se:smartlet macro.
      1. For this tutorial, use the name sml_test()
    2. Add a parameters section to the macro.
    3. Add an xml parameter. This parameter is used to store all SXML logic to execute when the Smartlet is rendered, both initially and on Ajax roundtrips.
      1. Add the following data to the xml property:

        <div id="{smartlet.id()}">{smartlet.get(data)}</div>
    4. Add a properties collection parameter. The properties parameter is used to define both the translation arguments that can be passed to the Smartlet and the Ajax (JSON) data that will be exchanged between the HTML pages Smartlets will live in and the server-side Smartlet.
    5. For this tutorial, add a member to the collection:

      <se:member name="data">
           This is a Smartlet
      </se:member>
  3. Save the sml_test() item as Active.
  4. Create a new Strict Web Page item in the Smartlet Tutorial folder.
    1. In the SXML Logic field, add the following code:

      {sml_test()}
    2. Preview the page. The line 'This is a Smartlet' should appear.
    3. Now, modify the call to the Smartlet:

      {sml_test(data='This is passed as an argument...')}
    4. Again, preview the page. The line 'This is passed as an argument...' should appear.
  5. So far, so good.
    What we've done until now is in fact create a Translation with a few stricter rules...
    The greatest thing about Smartlets however is the ability to pass data back and forth using Ajax.
    Let's continue by adding this capability to our Smartlet.
    We will do so by adding a button that will update the text that we have the Smartlet emit on initial rendering with the current server date and time.
  6. Open the Smartlet item again, and go to the data member within properties parameter data.
    For Ajax to work, we first have to specify the data interchange access rules. In this case, we will have the button request data from the server, so we need the following contract:

    <se:member name="data" callbackaccess="write" clientaccess="read" >
         This is a Smartlet
    </se:member>
  7. Now, let's modify our code to show a button that will update the text.
    Before we do this, think about what we want to do. Pressing the button should update the text we emit by default. Since we use jQuery, and we want to have all script that is needed to be unobtrusive, it's best to encapsulate our Smartlet's output in a DIV and add a CSS class that can be easily accessed using jQuery. For this, use the Smartlet name, which corresponds with the translation code that is used by the Smartlet:


    <div class="{smartlet.name()}" id="{smartlet.id()}">
          <div>{smartlet.get(data)}</div>
          
          <button>Update</button>    
    </div>
  8. Now, only two steps remain: the SXML code to return the server date and time when requested, and the client (jQuery) code to do so.
    Let's start with the client code.
    The Smartlet architecture comes with a nice feature that all scripts and css items in a special subfolder named 'ClientData' of any Smartlet folder will automatically be included when calls to those Smartlets exist in a page, so let's take advantage of that.
  9. Create a CMS folder named 'ClientData' in the Smartlet Tutorial folder.
  10. Add a Javascript item with the following code:

    $j(function(){ // add code to document-ready function
       $j('{smartlet.nameselector()} button').click(function(){
          var root = $j(this).parent(); // lookup parent of button
          var sml = $j.scf.smartlet.get(root.get(0)); // find Smartlet object
      
          sml.ajax(function(){ // do the Ajax call
             $j($j('div', root)).html(sml.get('data')); // update the inner DIV
          });
       })
    });
  11. Finally, open the Smartlet item again and update the xml property.
    To account for Ajax callbacks, use an se:if macro with an expression to test for ajax callback mode:


    <se:if expression="smartlet.isajaxcallback()">
       <se:then rem="Ajax callbacks">
           {smartlet.set(data, locale.formatdatetime(datetime.now()))}
       </se:then>
       <se:else rem="Initial rendering">
          <div class="{smartlet.name()}" id="{smartlet.id()}">
             <div>{smartlet.get(data)}</div>
          
             <button>Update</button>    
          </div>
       </se:else>
    </se:if>