4.1 Processing Instructions

Python scripts can be directly embedded in HTML using processing instruction tags, similar to PHP syntax. Because the parser validates the HTML syntax, you won't have to worry about hunting down a missing quote or tag symbol. PSE processing instructions look like this:

<? statement ?>

PSE understands processing instructions in three different ways. First is the most simple case, where raw Python statements appear in the tag. You can have one or as many statements as you like. However, if you use more than one statement, it is recommended that your first statement begins on a new line, separate from the opening <? tag, like this:

<?
statement 1
statement 2
 ...
statement n
?>

This is because Python uses indentation to recognize program blocks. Overall indentation is managed by PSE (you'll see how later), so you don't have to worry about making sure the code in any particular tag is lined up with any previous code. However, you must complete any block within a single tag, as indentation control is returned to PSE when it reaches the closing ?>.

If you want to control indentation between processing instructions, then let PSE manage the indentation for you. If the last statement in an instruction ends in a colon (":"), this signals PSE to begin a new indentation level. Therefore, the instruction:

<? if condition: ?>

will generate the if statement and increase indentation by one level. Any subsequent code generated from proceding markup will be indented at the correct level, even code indented manually as described above.

If the first statement in a processing instruction begins with a colon, then the instruction will be treated as a ``pseudo-instruction'' and backdent one level. For example, to stop indentation generated by the if statement above, you could do the following:

<? :if condition ?>

What follows the inital colon is ignored by PSE, so you can use this as a comment space to help you remember which block it is you are closing. Since all Python blocks begin with a statement that ends in a colon, you can use this construct with for, try or any other statement that uses a block.

Often you want to match an if or try with an else or except. This can be cumbersome with the method described, so there is a shortcut you can use in these cases. If you begin a statment with a colon and end it with a colon, PSE will backdent, use the statement, and re-indent again. This may sound confusing, but it should be clear with the following example:

<? try: ?>
other code and markup here
<? :except ValueError: ?>
exception handling
<? :except: ?>
maybe you will want catch more
<? :else: ?>
you can even do this; it doesn't matter as long as it's valid Python
<? :try (to backdent when finished) ?>

Finally, there is one other way to use the processing instructions. You can cause the resulting code to produce output of the value of any Python expression using the following syntax:

<?=valid python expression ?>

In this tag, white space can appear between the initial "?" and "=" or between the "=" and the expression, as long as "=" is the first character in the instruction. The resulting code does a str() on the expression, so you don't have to worry about ValueError exceptions being raised from non-string values.