1. can ajax sit on zafu ?

    It is very nice to have all the freedom you like to create your own templates. But how do we replace/insert content in such a page using ajax ?

    From the model we are developing for Zena, each node is rendered with a template chosen from the node template (fun), node class (project) and mode (print) :

    templates

    So how do we find how to insert something into something so complicated ?

    example with ‘comments’

    We want to have comments enabled on our page, so we design a nice template to display comments. We use include to display each ‘comment’, so we have a template for each comment, and we name this template ‘comment’ (that’s a convention). Our templates might look like :

    fun
     +- _fun.html          (this is the main template)
     +- comment.html       (display 1 comment)
     +- comment_add.html   (form to add 1 comment)
    fun_project.html       (template for class 'Project')
    

    We render our project with fun_project.html. Near the end of this template, there is :

    <z:comments>
      <h3>comments</h3>
      <ul>
        <z:each><z:include template='comment'/></z:each>
        <z:add form='comments_form' template='comment'>add comment</z:add>
      </ul>
    </z:comments>
    

    The interesting part in this code is the <z:add> tag. From the context, we can guess we are adding a comment. From there it is possible to create the necessary calls to show the form, send it’s content with clues on the template to use for rendering and insert the information back into the list (above or below ‘add’).

    will it work ?

    All this looks nice, but we have yet no idea if it will actually work. We are working hard to finish the work on templates, so we will soon be fixed.

    how about ‘edit’ ?

    We use a popup to edit articles, but how do we edit ‘comments’ ? Actually, they are edited ‘in place’: the comment is replaced by a form, which in turn is replaced by the comment on validation. This could work just the same as the <z:add/> tag, except that we need a unique id to replace the current comment. How do we set this id ?

    We could use the ‘zafu tag’ :

    <li zafu='each'>....<z:edit>edit</z:edit></li>

    The edit tag could pass back some clue to ‘each’ (using @pass ) telling it that it should add the ‘id’ parameter to it’s tag : <li id='comment34'>. If the ‘each’ tag is not a ‘zafu tag’, then it should add a <div id='comment34'> tag.

    example

    A complete example could look like:

    <z:comments>
      <h3>comments</h3>
      <ul>
        <z:each><z:include/></z:each>
        <z:add>add comment</z:add>
      </ul>
    </z:comments>

    This would be rendered to the following html code (node_id = 12, comment_id = 34) :

    <h3>comments</h3>
    <ul>
      <li id='comment34'>...
        <a href='#' onclick='...template=/fun...id=34..'>edit</a> ...
      </li>
      <li id='comments_add12'><a onclick='..toggle..'>add comment<a..></li>
      <li id='comments_form12' style='display:none;'>...
        <input type='hidden' name='template' value='/fun'/>
        ...
      </li>
    <ul>
    

    From the context starting with <z:comments> followed by <z:each>, we can guess the included template is ‘comment’. We also know we are rendering ‘fun’ template. Rendering the template after form validation from either ‘edit’ or ‘add’ will use the same rules to guess where ‘comment’ lies as described in unknown link.

    But what happens if we do not want to create template files for very simple forms and rendering ? We could use a tag that produces some sub erb template when rendering:

    <z:comments>
      <ul>
        <z:each make='comment'><li>...</li></z:each>
      </ul>
    </z:comments>
    

    When rendering an include tag, we set the first tag’s id if the template contains a direct <z:edit> tag. An <z:edit> tag that is not in an included template (we do not have a context id to replace with ajax) will produce an html edit <%= link_to(...) %> instead of the ajax <%= link_to_function(...) %>.

    Gaspard Bucher