web.py – šablonovací systém

Šablonovací systém je důležitou součástí webového frameworku, proto se dnes budeme věnovat šablonovacímu systému web.py – Templatoru. Vypíšeme si hlavní konstrukce, řekneme si něco o slučování šablon a vše si předvedeme na příkladech.

Seriál: Webový framework web.py (5 dílů)

  1. Úvod do webového frameworku web.py 14.11.2013
  2. web.py – první aplikace 22.11.2013
  3. web.py – šablonovací systém 9.12.2013
  4. web.py – databáze 27.12.2013
  5. web.py – autentizace a autorizace 1.9.2014

V minulém díle jsme se věnovali základům vývoje aplikací ve frameworku web.py, především pak komponentě controlleru. V dnešním díle se budeme věnovat jiné důležité komponentě, a to pohledům (views), které zajišťují vykreslování uživatelského prostředí. Povíme si o šablonovacích systémech Pythonu, konstrukcích známých z prostého Pythonu a slučování šablon.

Templetor

Součástí web.py je šablonovací systém Templetor. Jeho syntaxe je velice podobná (takřka totožná) syntaxi Pythonu, jeho ovládnutí je tedy otázkou několika chvil. Pokud chcete raději používat šablonovací systémy jako Jinja2 nebo Cheetah, i ty lze po krátké konfiguraci ve web.py používat.

Pokud chcete Templetor v aplikaci použít, je nutné jej nejdřív nakonfigurovat. Do hlavního souboru aplikace stačí přidat render a jako parametr mu předat složku obsahující šablony:

render = web.template.render('templates')

Funkce vykreslující šablonu může vypadat například takto, tečkovou konvencí zde určíme její umístění ve složce šablon:

return render.informace.kontakt()

Samotná šablona je soubor s koncovkou html, v němž do obyčejného HTML kódu vkládáme konstrukce Templatoru.

Proměnné

Přístup k proměnným (a funkcím) aplikace je v Templatoru standardně omezen pouze na proměnné předané při vykreslení šablony. Díky tomu je aplikace od šablon maximálně oddělena.

Pokud předáváme proměnnou aplikace šabloně:

return render.informace.kontakt("Petr", "Letovice")

je třeba na začátku šablony určit přijímané proměnné (ve správném pořadí) a jejich názvy:

$def with (jmeno, mesto)

K proměnným lze poté přistupovat hned několika způsoby:

$jmeno
${jmeno + ' ' + mesto}
$slovnik[klic].funkce('argument'). 
$(promenna)nanana.

Pro přiřazování hodnot do proměnných lze použít následující konstrukci:

$ promenna = (10 / 5) * 3

Templator standardně filtruje „nebezpečné“ znaky, které by mohly ovlivnit šablonu, pokud tedy necháte vypsat 1 < 2, systém vyrendruje 1 &lt; 2. Pro vypnutí filtru stačí při vypisování namísto $promenna použít $:promenna.

Protože je znak dolaru $ využit pro syntaxi, pro vypsaní samotného znaku budete muset použít $$.

Globální proměnné

Pokud chcete šablonám zpřístupnit nějakou proměnnou či funkci z aplikace, stačí při tvorbě renderu předat do proměnné globals slovník.

render = web.template.render('templates', globals={'funkce':funkce_aplikace,'promenna':promenna_aplikace})

Komentáře

Pro zapsání komentářů stačí na začátek řádku přidat $#. Tento kód se potom neobjeví ve výsledném HTML.

$# komentář kódu šablony

Větvení

Větvení kódu zde funguje takřka stejně jako v samotném Pythonu. Stačí zapsat $if, $elif či $else, podmínku a za dvojtečku už samotný kód. Nezapomeňte stejně jako v Pythonu, odrážet kód bloků.

$if 1 < 2:
    Jedna je menší než dvě.
$else:
    Jedna je větší nebo rovno dvěma.

Kód lze psát i do jednoho řádku:

$if 1 < 2: Jedna je menší než dvě.

Cykly

Pro cyklení zde slouží $for a $while, zápis je podobný jako u větvení:

$for i in range(10): 
    Číslo $i

$while podminka:
    Žluťoučký kůň úpěl.

Z objektu loop můžete získat proměnné určující stav procházení cyklem, to se může hodit například při práci s tabulkami:

loop.index: počet projití cyklu (začíná 1)
loop.index0: počet projití cyklu (začíná 0)
loop.first: True pokud jde o první projití
loop.last: True pokud jde o poslední projití
loop.odd: True když jde o liché projití
loop.even: True když jde o sudé projití
loop.parity: vrací odd pri lichém projití a even při sudém
loop.parent: vrací vnější smyčku

Funkce

V šabloně je možné díky $def definovat i samotné funkce:

$def pozdrav(jmeno):
    Ahoj $jmeno

$pozdrav("světe")

Samotný kód

A konečně, do šablon lze pomocí $code zapisovat čistý kód Pythonu:

$code:
    x = 2
    for i in range(4):
        x = x * x

    def funkce():
        ...
        ...

Z bezpečnostních důvodů ale není možné využívat exec, importy, přistupovat k atributům začínajících podtržítkem _ a používat vestavěné funkce jako open, getattr, setattr a podobně.

Základní šablona

Aby nebylo nutné v každé šabloně opakovat kód hlavičky, menu, patičky apod., je možné vytvořit základní šablonu, do které se budou další šablony vnořovat. Soubor základní šablony určíme při vytváření renderu pomocí atributu base:

render = web.template.render('templates', base='base')

Základní šablona by pak mohla vypadat například takto, proměnnou content určujeme místo, na které se má vložit obsah dalších šablon, proměnnou titulek získanou z objektu content využijeme pro vypsání titulku stránky:

$def with (content)

<html>
<head>
    <meta charset="utf-8">
    <title>$content.titulek</title>
</head>
<body>
$:content
</body>
</html>

Kód vnořené šablony by mohl vypadat takto, pomocí $var zde definujeme proměnnou titulku, jako content se použije zbytek šablony:

$var titulek: Nadpis stránky

<h1>Ahoj Světe</h1>

Poté už stačí jen použít použít render k vykreslení stránky.

Seznamy v proměnných

Pokud chcete vkládat celé seznamy proměnných (například adresy CSS souborů), není nutné je definovat jednotlivě. Stačí do proměnné v podšabloně zapsat seznam hodnot oddělený mezerami:

$var csssoubory: style.css fonty.css

<h1>Ahoj Světe</h1>

V hlavní šabloně pak proměnnou rozdělíme do seznamu a ten necháme pomocí cyklu vypsat:

$def with (content)

$if content.csssoubory:
    $for c in content.csssoubory.split():
        <link rel="stylesheet" href="$c" type="text/css"/>

Statické soubory

Protože nelze z vnějšku přistupovat k souborům aplikace, je nutné pro statické soubory (jako jsou kaskádové styly, obrázky, JavaScript) vytvořit složku static. K souborům z této složky lze poté přistupovat na adrese /static/nazev-souboru.css.

Příklad aplikace

V dnešním příkladu budeme vycházet z aplikace vytvořené minule. Upravíme úvodní stránku, která zatím pouze vrací text „Ahoj“.

Nejdříve přidejte do projektu složku templates a v ní vytvořte soubor základní šablony base.html:

$def with (content)

<html>
<head>
    <meta charset="utf-8">
    <title>$content.titulek</title>
    <style>
        body {
            background-color: #DEFCD7;
        }
    </style>
</head>
<body>
$:content
</body>
</html>

Dále vytvořte šablonu úvodní strany uvod.html:

$var titulek: Úvodní strana

<h1>Ahoj Světe</h1>

Nyní otevřete základní soubor aplikace main.py, přidejte render a pozdrav „Ahoj“ nahraďte vykreslením šablony:

# -*- coding=utf-8 -*-
import web

urls = (
    '/','Uvod',
    '/umocni/(\d+)', 'Umocni',
)

app = web.application(urls, globals())
render = web.template.render('templates', base='base')

class Uvod:
    def GET(self):
        return render.uvod()
class Umocni:
    def GET(self, cislo):
        return int(cislo) * int(cislo)

if __name__ == "__main__":
    app.run()

Nakonec si můžete aplikaci pustit, při otevření adresy http://localhost:8080/ by se měla zobrazit stránka s pozdravem v nadpisu.

Závěr

To je pro tento díl vše. Příště se budeme věnovat databázím, autorizaci a autentizaci uživatelů.

Absolvent gymnázia a budoucí student FI MUNI se zájmem o programování, Linux, hudbu, elektroniku, umění a černobílou analogovou fotografii. Začal jsem u modrého Dosu, přešel přes C#, Javu a nyní se věnuji hlavně Pythonu, mimo jiné i jako stážista v Red Hatu.

Komentáře: 6

Přehled komentářů

golf nejsnadnější syntaxe
diverman Re: nejsnadnější syntaxe
Jakub Kulhan Re: nejsnadnější syntaxe
Lamicz
golf Re:
tomas Drobné překlepy?
Zdroj: https://www.zdrojak.cz/?p=10544