Migration from version 2 to 3

Some features are no longer necessary in PLP 3. Because backwards compatibility would be too much of a mess, you need to convert existing scripts.

Begin blocks

The underscore-blocks no longer exist. They are obsoleted by the fact that you can now set headers anywhere, as long as you haven't output anything before. To convert existing scripts, use Perl's BEGIN block feature:
PLP 2:
<_ $header{Content_Type} = 'text/plain'; _>
PLP 3:
<: BEGIN { $header{Content_Type} = 'text/plain'; } :>
Formatting blocks

This confusing feature wasn't used by many. It wasn't necessary either, because Perl already has subs for recurring things.
PLP 2:
<[1title]><h2><[2]></h2><[3]>
<[title:Hello, world!]>
PLP 3:
<:
        sub title { print '<h2>', shift, '</h2>'; }
        title 'Hello, world!';
:>
Inline double quotation

Another feature that lead to a lot of confusion. PLP now uses ASP/PHP style equal-signs. Please not that you can not add a semi-colon and another command.
PLP 2:
<{Hello, $name!}> // Hello, <{$name}>!
PLP 3:
<:="Hello, $name!":> // Hello, <:=$name:>!
Code inclusion

In PLP 2, it was possible to use <(filename)> in code, and it would literally include the contents of the file at that place. However, that made it impossible to easily use regexes like /<<([^>]*)>/. You can use Perl's built-in do() for pure-perl inclusion, or the new PLP include() function (or a <(filename)> tag outside of code). If you choose for PLP inclusion, don't forget to add code tags to the included file!
PLP 2:
<: <(filename)> :>
PLP 3:
<(filename)> <: ... :>
<: include('filename'); :>
<: do('filename'); # perl-only file
:>
Comments

In PLP3, you can comment closing :> tags. That means that you need an extra line break if you had :> after #.
PLP 2:
<: # foo :>
PLP 3:
<: # foo
:>



After all of this, you might like to know that PLP 3 is a lot faster, and supports mod_perl. Happy hacking!