Python, Pyramid, and Mako… How to get Mako Working With Pyramid…

Well looks like Pylons is now Pyramids, and here go hell come. Now I could go on explaining the differences (Which most likely I will once I get farther in), but this is more just a quick post.

ANSWER:

In the development.ini file, place this under the [app:pytrends] area

mako.directories=projectName:folderWhereYourTemplatesAre

For example, the project I have is pyzazz (Don’t ask me what that is cause I don’t even know) and the template folder is… well templates. So I have it as:

mako.directories=pyzazz:templates

MORE USELESS WORDS:

When using pylons I used mako. It was fast and well it was by default. Now the default template engine is Chameleon which (Sorry Chameleon creator) sucks. First time using it, it was throwing parser errors in javascript lines like:

 if (urlParams.actual && urlParams.actual == 'true')

and it forced me to end an input with the </input> tag. And if you know anything about HTML, input tags DO NOT HAVE END TAGS. True story, go check w3.org if you feel like. Little things like that just annoy the hell out of me. Yeah I know it’s just html and javascript, the runts in the litter as far as programmers care, but you still can’t jack things up like that. And on that note: if someone who uses chameleon (Or helped write it) actually comes here, you are welcome to shoot down my claims.

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.

Quick Example of Inheritance in Templates with Mako: Using Next

So as I further my side journey into Python, or Pylons to be more exact, one of the decent things I’ve run into is that Mako templating system. What is that? It’s what runs along side of Pylons (Or at least one of many) for displaying the View side of the whole MVC thing. Now if you’re here, chances are you just searched on this so I wouldn’t go into a huge thing about Pylons or Mako. I’ll just get to the damn point.

This is just an example of a three layer template I use to help with pumping out pages with out repeating a lot of code. The nice thing about Mako is how simple it is to have multiple layers of templates to make up a single page. This is basically done with using the next keyword.

What is next?
Mako has a system that works something like an abstract class. A page template can define a certain area in a method like way and like an abstract method, there is no method body. Any page template that “inherits” the base has to fill in the body or create an abstract method itself to call the original method.

Now with that being said, there are two key words for doing this and the default keyword is self. Problem with self is that it looks at the top most template only. So if you have say 3 layers:

BasePage -> SecondLayer -> ThirdLayer

self will always look to the third layer:

BasePage -> ThirdLayer

While second layer is all like, “Yeah whateve”. Overall, this isn’t very helpful if you want a sort of chain like effect. Its basically like a base class not giving a flying… not caring about what any child classes do except the top most child class. What if you have a div that holds content on the base, and the second layer has its own content area to hold the third layer. This would be useless if you used self since that second layer would just be ignored. Sad day. This is where next comes in. Next, like an abstract method, basically just sets a place holder for the next template to “inherit” the said template. Now the danger of next is that just like an abstract method, the system will be all “Waaaaaah, you didn’t override the method. Waaaaaah.” if you forget to define the method in the next layer. The huge advantage is you can create a nice consistent design in which you can just bang out child templates since you know exactly what the baser (Yeah I wrote baser.) page will have.

On to the example. And this is an example of what a template structure could look like.

The base page:

  <html>
    <head>
       //next.title will allow all children to add on to the title
       <title>First Level - ${next.title()} </title>

        //next.styleSheetIncludes will allow all children to add any included css files if needed.
        <link rel="Stylesheet" href="${h.url('/css/base.css')}" />
        ${next.styleSheetIncludes()} 

        //next.javascriptIncludes will allow all children to add any included javascript files if needed.
        <script type="text/javascript" src="${h.url('/scripts/base.js')}"></script>
        ${next.javascriptIncludes()} 

        //next.styleSheet allow all children to add any page specific css that wasn't included in files.  Why
        //  have the style tags instead of just having the  ${next.styleSheet()}.  Well you could but then you would
        //  end up with more than one style tag when the page is built.
        <style type="text/css">
          ${next.styleSheet()}
        </style>

        //next.javascript allows all children to add any page specific javascript that wasn't included in files. This
        //  follow the same idea as the next.styleSheet above.  Why have a possible 3...4...5... script tag when
        //  the child templates can just add to this one?
        <script type="text/javascript">

          function firstLevel(){
          }

          ${next.javascript()} 

          //next.javascript allows all children to add any page jquery document.ready javascript that is specific to the
          //  given child.  Once again this is an example of add to instead of repeating a section
          jQuery(document).ready(
            function () {
              jQuery('button').button();

              ${next.documentReady()} 

            }
          );
        </script>
    </head>
    <body>
      <div class="header">
      </div>
        <div class="bodyContainer">
          //This will be where the child html will fall.
          ${next.body()}
        </div>
      </div>
   </body>
  </html>

The second layer:

  <%inherit file="base.html" />

  <%def name="title()">
    - Second Level
  </%def>

  <%def name="styleSheetIncludes()">
    <link rel="Stylesheet" href="${h.url('/css/secondLevel.css')}" />
    ${next.styleSheetIncludes}
  </%def>

  <%def name="styleSheet()">
    ${next.styleSheet()}
  </%def>

  <%def name="javascriptIncludes()">
    <script type="text/javascript" src="${h.url('/scripts/secondLevel.js')}"></script>

    ${next.javascriptIncludes()}
  </%def>

  <%def name="javascript()">
    function secondLevel(){
      //Method in second level
    }
    ${next.javascript()}
  </%def>

  <%def name="documentReady()">
    //nothing here on second level
    ${next.documentReady()}
  </%def>

  <%def name="body()">
    <div class="leftMenu">
      <a href="something.html">something</a>
      <a href="somethingElse.html">something else</a>
    </div>
    <div class="rightArea">
      ${next.body()}
    </div>
  </%def>

As you can see, all the abstract areas defined in the base are being used by this layer and then this layer is in turn adding its own abstract methods that share the same name as the base template’s method. The nice this is you can do this using the next keyword as the current template will only respond to the template immediately inheriting it. You don’t get any kind of method name clash.

And the final layer:

  <%inherit file="secondLevel.html" />

  <%def name="title()">
     - Third Level
  </%def>

  <%def name="styleSheetIncludes()">
    <link rel="Stylesheet" href="${h.url('/css/thirdLevel.css')}" />
  </%def>

  <%def name="styleSheet()">
    .thirdLevel
    {
    }
  </%def>

  <%def name="javascriptIncludes()">
    <script type="text/javascript" src="${h.url('/scripts/thirdLevel.js')}"></script>
  </%def>

  <%def name="javascript()">
    function thirdLevel(){
      //Method in second level
    }
  </%def>

  <%def name="documentReady()">
    //nothing here on third level
  </%def>

  <%def name="body()">
    <div> Hi from third level</div>
  </%def>

The third layer now closes off the chain by no longer adding any abstract methods of its own. Now if I knew there could be yet another layer, all I would have to do is use the same naming convention and add the needed next.methods.

And this is what the source should look like:

  <html>
    <head>
      <title>First Level - - Second Level - Third Level </title>

      <link rel="Stylesheet" href="${h.url('/css/base.css')}" />
      <link rel="Stylesheet" href="${h.url('/css/secondLevel.css')}" />
      <link rel="Stylesheet" href="${h.url('/css/thirdLevel.css')}" />

      <style type="text/css">

      .thirdLevel
      {
      }

      </style>

      <script type="text/javascript" src="${h.url('/scripts/base.js')}"></script>
      <script type="text/javascript" src="${h.url('/scripts/secondLevel.js')}"></script>
      <script type="text/javascript" src="${h.url('/scripts/thirdLevel.js')}"></script>

      <script type="text/javascript">

        function firstLevel(){
        }

        function secondLevel(){
          //Method in second level
        }

        function thirdLevel(){
          //Method in second level
        }

        jQuery(document).ready(
          function () {
            jQuery('button').button();
	      //nothing here on second level
              //nothing here on third level
          });
        </script>
    </head>
    <body>
      <div class="header">
      </div>
      <div class="bodyContainer">
        <div class="leftMenu">
          <a href="something.html">something</a>
          <a href="somethingElse.html">something else</a>
        </div>
        <div class="rightArea">
          <div> Hi from third level</div>
        </div>
      </div>
    </div>
   </body>
  </html>

As you can see, things like the ${next.documentReady()} really helped to keep the source code clean and avoid repeated code on the source side. Now go forth, all 2 of you… including me…, and use this knowledge to do something.