Che è una limitazione di tutti i template engine non è vero.

Anzi devo dire che perfino Smarty (a malincuore visto che non ho avuto un buon rapporto) lo consente.

Tutto dipende dalla logica a mio parere.

Io ho fatto un template engine del genere.
Codice PHP:
//Variabile semplice
{$variabile}
//Semplice funzione
{FUNZIONE|parametri}
//Lo stesso di sopra come separatore si può usare | oppure uno spazio
{FUNZIONE parametri}
//Funzione che ha del testo al proprio interno
{FUNZIONE parametri}
 
Testo
{/FUNZIONE
Dove ogni volta che il template engine arriva a {FUNZIONE} controlla se ha parametri e del testo tra i tag e chiama una funzione PHP che si chiama tpl_func_FUNZIONE passandogli l'istanza della classe del template engine e un array contenente il parametro e testo.

Esempio:
Codice PHP:
function tpl_func_FUNZIONE($params, &$tpl)
{
    if(isset(
$params['text']))
    return 
$params['text'];
    else
    return 
"No text is present";

Per il parsing adesso uso le espressioni regolari e questa strada non mi convince del tutto, infatti sto pensando di scrivere un parser fatto in casa fatto apposta per analizzare la sinstassi del mio template engine.

Questa strada ti può dare tutta la flessibilità che ti serve, in questo modo mi sono implementato IF, LOAD, FOR scrivendo rispettivamente 3 funzioni.
E in più è facilmente personalizzabile per ogni tipo di script.

Questa è la strada che ti suggerisco, poi può darsi che un giorno pubblicherò il mio template engine, quando sarà serio si intende con un proprio parser e capace di compilare in codice PHP.