Pylons: Dynamic Templates with Mako Using Controllers and jQuery

So a friend of mine (Yes I do have friends and occasionally the ARE real) asked me if there was a way to have a partial control/template have dynamic content using a controller. At first I was like ‘f— no’ but that passed quickly as I realized I was actually answering myself on whether Species should have yet another sequel. As for his question, I gave it some thought and the easiest way I could think it jquery and using it’s ajax method to call a controller and use the response (json for this example) to create the content. Could it be done? You bet your Rolex knock off that you bought in New York from some guy named Loey that looked legit for a guy selling things out of a dumpster.

Turns out the solution is fairly simple. Use jquery to call a controller’s action on the template’s load. Even can pass in whatever you need from the parent container.

Here is the parent page:

<!--This is the partial template page -->
<%namespace name="getInfo" file="getInfo.html" />

<html>
  <head>
   <script type="text/javascript" src="${h.url('/scripts/jquery-1.4.2.min.js')}"></script>
  </head>
  <body>
    This is just plain text that is pre method call.  Textbox will be fill post method call.
    <!--This is the method set up on the partial template -->
    ${getInfo.getInfo(1) }
  </body>
</html>

Here is the partial template file:

<%def name="getInfo(id)">
  <script type="text/javascript">
    //This is the method to be called to get whatever it is you need from the controller action
    function getInfo(id){
      jQuery.ajax({
        type:'POST',
        url: '${h.url(controller='getInfo', action='index')}',
        dataType:'json',
        data:{ id:id },
        success: function(result){
          onSuccess(result);
        },
        error:function (xhr, ajaxOptions, thrownError){
          alert(xhr.status);
        }
      });
    }

    function onSuccess(result){
      jQuery('#testLabel').val(result.returnValue);
    }
    <!-- This will force the getInfo method to be called when this page loads. -->
    getInfo(${id});
  </script>

  <!-- This is the content to be updated -->
  <input type="text" id="testLabel" name="testLabel" />
</%def>

And really that’s it. Very simple. Have the parent page call the partial template method and have the partial template method use whatever value being passed in to send it on to the right controller/action. Once the response is there, update the content.  In this case, result.returnValue that is just a simple string.  Or maybe a puppy.  Could be both.

A more complicated example could use javascript to construct html based on the return but not real important here.  That’s for smart people, read not me, to figure out.

As a bonus, I will actually post the code. NOVEL IDEA!111

What? Why did I choose purple for the color of Mako markup?  Don’t… just don’t.  You have no right to judge.