7.3. Python Inside HTML

Python Inside HTML behaves much like Microsoft's Active Server Pages, Sun's Java Server Pages and PHP : it's basically a HTML document, in which you insert portions of code written in a programming language - here Python

In Python Inside HTML, these portions of code are separated from the HTML code inside special tags : <% and %>

Suppose you want to display the current date, you'll mix html and Python code this way :

The current date is
<% import datetime
print datetime.date.today().strftime("%d:%m:%y")
%>

With a text editor, write the code above and save it under time.pih in your Root Directory. Enter http://localhost/time.pih and see what happens

You'll notice that the code inside the <% and %> tags is ordinary Python code, in which you can import modules, create and instanciate classes, use variables, read or write to the file system, etc. Access to HTTP environment, to form fields, to the exceptions defined by Karrigell are made the same way as in Python scripts

7.3.1 Python variables

When you only want to print a variable's value, instead of <% print var %> you can use the shortcut <%= var %> :
  Current directory <%= os.getcwd() %>
In this example you'll notice that you don't have to explicitely import the os module : for convenience, it is already in the namespace when you execute the script ; so are two other modules, string and Cookie, because they will probably be used in many scripts (but of course, if you explicitely write import string your script will work as well)

7.3.2 Strings for translation

Since internationalization is important in Karrigell, there is a shortcut for the strings or string variables you'll want to be translated according to user preferences : use <%_ string %>
  <% import time %>
  <%_ "Current directory is " %> <%= os.getcwd() %>
  <%_ "Current day " %> <%_ time.strftime("%a",time.localtime()) %>

If you have prepared a translation for the string Current directory is , when the user calls the script and his language preference is French, his browser will display Le répertoire courant est

See Karrigell support for internationalization

7.3.3 Indentation

The result of processing a PIH file is Python code ; this code must be indented. Since a PIH script is a mixture of HTML, in which indentation has no other meaning than readability, and of chunks of Python code, it may be difficult to produce a code that is easily readable and correctly indented

7.3.3.1 Basics

PythonInsideHTML follows simple rules :

  • at the start of the script, indentation is zero
  • every part is indented according to the current indentation
  • this current indentation can be modified by two means :
    1. when a Python code part ends with a colon (:) the indentation of what follows is incremented by 1
    2. to decrement indentation use <% end %>

A simple condition example :

 
# indentation
<% if hour<12: %>
    Good morning
    <% end>
<% elif hour<18: %>
    Good afternoon
    <% end>
<% else: %>
    Good evening
<% end>
 Ladies and Gentlemen
# 0 - next one : 1
# 1
# 1 - next one : 0
# 0 - next one : 1
# 1
# 1 - next one : 0
# 0 - next one : 1
# 1
# 1 - next one : 0
# 0

and a for loop :

 
# indentation
<table border=1>
  <tr>
    <th>Number</th>
    <th>Square</th>
  </tr>
  <% for i in range(10): %>
    <tr>
      <td><% print i %></td>
      <td><% print i**2 %></td>
    </tr>
  <% end %>
</table>
# 0
# 0
# 0
# 0
# 0
# 0 - next one : 1
# 1
# 1
# 1
# 1
# 1 - next one 0
# 0

Without this <% end %> tag the </table> tag would have been inserted in the loop

A last one with two levels of indentation

 
# indentation
<% for i in range(10): %>
    <% if i % 2: %>
        <td class="odd"><%= i %></td>
        <% end %>
    <% else: %>
        <td class="even"><%= i %></td>
        <% end %>
    <% end %>
End of table
# 0 - next one : 1
# 1 - next one : 2
# 2
# 2 - next one : 1
# 1 - next one : 2
# 2
# 2 - next one : 1
# 1 - next one : 0
# 0

Note that after the 1st line the tag must be closed by %>, if not, the indentation after the second line will be only 1

7.3.3.3 The <indent> tag

For longer or more complex code the repetitive use of <% end %> may become tedious. If you want some parts of your code to be indented in Python as it is in the PIH code, embed it with the <indent> tag

First example :

 
# indentation
<indent>
<% if hour<12: %>
    Good morning
<% elif hour<18: %>
    Good afternoon
<% else: %>
    Good evening
Ladies and Gentlemen
</indent>
# 0
# 0
# 1
# 0
# 1
# 0
# 1
# 0
 

Second one :

 
# indentation
<table border=1>
  <tr>
    <th>Number</th>
    <th>Square</th>
  </tr>
  <indent>
  <% for i in range(10): %>
    <tr>
    <td><% print i %></td>
    <td><% print i**2 %></td>
    </tr>
  </indent>
</table>
# 0
# 0
# 0
# 0
# 0
# 0
# 0 (A)
# 1
# 1
# 1
# 1
# next one : 0
# 0

On the line noted (A) above you see that the indentation of the line is relative to the indentation of the <indent> tag

Also note that after an indented part (after the </indent> tag) indentation returns to zero

An example with embedded loops :

<indent>
<table border=1>
<% for i in ['h']+range(10): %>
    <tr>
    <% for j in ['h']+range(10): %>
        <% if i!='h' and j!='h': %>
            <td><%= i*j %></td>
        <% elif i!='h': %>
            <th><%= i %></th>
        <% elif j!='h': %>
            <th><%= j %></th>
        <% else: %>
            <td>*</td>
    </tr>
</table>
</indent>

7.3.4 PIH as a templating system

PIH scripts can be used to create HTML files outside of the Karrigell server, making them a "templating system"

For instance, this HTML documentation is produced from PIH scripts. The chapter number is not fixed but inserted like this :

<h1><%= chapter %>. Python Inside HTML</h1>

To produce HTML from a PIH script, use the module Template.py in folder karrigell/core, create an instance passing it the path of the PIH file , then apply its method render([name_space[,out]]), passing it the namespace in which it will find the required variables, and a file object with a write() method (defaults to sys.stdout)

import Template
script=Template.Template("pythoninsidehtml.pih")
chapter=5
# run script in global namespace and write result to sys.stdout
script.render(globals())

7.3.5 Debugging


For debugging purposes start the PIHapp.py script. It is a small GUI application that shows how PIH files are translated into Python scripts. The result of the script can be saved to an HTML file and shown on a browser, if it does not call outer variables. The syntax is highlighted