Python je víceúčelový jazyk. V minulých lekcích jsme tvořili aplikace pro příkazovou řádku, nyní se podíváme na aplikace webové.
Webových frameworků pro Python je více, mezi nejznámější patří Django nebo Flask. Pro naše účely použijeme Flask, protože je nejrychlejší na pochopení.
Flask opět můžete nainstalovat do virtuálního prostředí.
(__venv__) > python -m pip install Flask
Základní použití Flasku je poměrně primitivní.
Do souboru hello.py
napište:
# soubor hello_flask.py
# nejjednodušší Flask webová aplikace
from flask import Flask
app = Flask(__name__)
app.config['DEBUG'] = True
@app.route('/')
def index():
"""Tato funce se zavolá, když uživatel přijde
na domovskou stránku naší aplikace.
Vrátí řetězec, který se zobrazí v prohlížeči.
"""
return 'Ahoj Pyladies!'
if __name__ == "__main__":
# spustí aplikaci
app.run()
Pak aplikaci spusťte následovně:
(__venv__) > python hello.py
* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 189-972-345
Na zmíněné adrese byste měli v prohlížeči vidět použitý text.
Tím, že jsme nastavili konfigurační hodnotu DEBUG
jsme zapli ladícím režim,
který si popíšeme za chvíli.
V programu jsme jako app
vytvořili flaskovou aplikaci.
Argument __name__
je jméno modulu – Flask podle něj hledá soubory,
které k aplikaci patří (viz static
a templates
níže).
Pomocí dekorátoru @app.route
jsme zaregistrovali takzvaný view (pohled) –
funkci, která vrací obsah pro danou cestu v URL.
Tomuto spojení cesty a pohledové funkce se říká route (nebo počeštěně „routa“).
My konkrétně říkáme, že na cestě /
(tedy na „domovské stránce“) bude
k dispozici obsah, který vrátí funkce index
.
Více různých adres lze obsloužit jednoduše přidáním dalších funkcí:
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello/')
def hello():
return 'Hello, World'
Na adrese http://127.0.0.1:5000/hello/
pak uvidíte druhou stránku.
Při povolení ladícího režimu (konfigurační proměnná DEBUG
) zapneme příjemnější
výpis chyb a aplikace se automaticky restartuje po změnách.
Zkuste ve funkci hello()
vyvolat výjimku (například dělení nulou – 1/0
)
a podívat se, jak chyba v ladícím režimu „vypadá“:
Flask ukáže traceback podobný tomu z příkazové řádky a navíc vám na každé
úrovni umožní pomocí malé ikonky spustit konzoli.
Bezpečnostní PIN k této konzoli najdete v terminálu, kde server běží.
Ladící režim je užitečný, ale nebezpečný – návštěvníkům stránky může (po prolomení celkem jednoduchého „hesla“) umožnit spustit jakýkoli pythonní kód. Navíc aplikaci zpomaluje. Používejte ho proto pouze na svém počítači.
Když vytváříte dynamický web, ne vždy můžete všechna URL znát dopředu.
Budete například chctít zobrazit informace o uživatelích na adresách
jako /user/hroncok/
, ale nemůžete při každé registraci nového uživatele
přidávat novou funkci do kódu.
Musíte použít dynamické routy:
@app.route('/user/<username>/')
def profile(username):
return 'User {}'.format(username)
Proměnnou část cesty ohraničíte lomenými závorkami a použijte jako parametr
funkce. Pokud chcete, můžete specifikovat, na jaký obsah se pravidlo vztahuje.
Například číselný idenifikátor článku pro adresy jako /post/42/
můžete zadat
takto:
@app.route('/post/<int:post_id>/')
Můžete použít různá pravidla, např.:
string
akceptuje jakýkoliv text bez lomítek (výchozí)int
akceptuje celá čísla (a pohledové funkci je předá jako int
, ne text)float
akceptuje i desetinná čísla s tečkou (a předá je jako float
)path
akceptuje text i s lomítkyRout můžte definovat i víc pro jednu funkci. Často se to používá s výchozí hodnotou argumentu:
@app.route('/hello/')
@app.route('/hello/<name>/')
def hello(name='world'):
return 'Hello, {}!'.format(name)
Opačným způsobem jak k routám přistupovat je, když potřebujete získat URL
nějaké stránky, například protože potřebujete zobrazit odkaz.
K tomu se používá funkce url_for()
, která jako první parametr bere jméno
routy (neboli jméno funkce, která routu obsluhuje), a pak pojmenované argumenty
pro pravidla v dynamické routě:
from flask import url_for
...
@app.route('/url/')
def show_url():
return url_for('profile', username='hroncok')
Tuto funkci jde použít jen uvnitř pohledové funkce, Pokud ji chcete vyzkoušet například v interaktivní konzoli, můžete použít speciální kontext:
>>> with app.test_request_context():
... print(url_for('profile', username='hroncok'))
...
/user/hroncok/
Možná si říkáte, proč tu URL prostě nevytvořit ručně. S takovým přístupem byste ale mohli narazit na problém, pokud cestu později změníte – což se může stát např. i když web nasadíte na jiný server. Generování URL vám také může zjednodušit nasazení statické verze stránek.
Pro URL v rámci vašich stránek proto doporučujeme url_for
používat důsledně.
Zatím jsou naše webové stránky poměrně nudné: obsahují jen prostý text, nepoužívají HTML.
HTML se dá psát přímo v Pythonu:
@app.route('/')
def hello():
return '<html><head><title>...'
...ale není to nebylo příliš příjemné. Python je jazyk dělaný na popis algoritmů, procesů a logiky spíš než obsahu. Lepší je HTML dát do zvláštního souboru a použít ho jako šablonu (angl. template). Z Flasku vypadá použití šablony takto:
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>/')
def hello(name=None):
return render_template('hello.html', name=name)
Funkce render_template
nejen vrátí HTML z daného souboru, ale umí do něj
i doplnit informace, které dostane v pojmenovaných argumentech.
Ukažme si to na příkladu: vedle souboru s kódem vytvořte složku templates
a v ní hello.html
s tímto obsahem:
<!doctype html>
<html>
<head>
<title>Hello from Flask</title>
</head>
<body>
{% if name %}
<h1>Hello {{ name }}!</h1>
<a href="{{ url_for('hello') }}">Go back home</a>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
</body>
</html>
Šablony používají (jako výchozí variantu) šablonovací jazyk Jinja2,
který se s Flaskem a jinými frameworky pro Python používá často.
Kompletní popis jazyka najdete v dokumentaci, ale
pro většinu stránek se obejdete s doplněním hodnoty ({{ promenna }}
)
a podmíněným obsahem ({% if %}
) jako výše,
případně s cyklem: {% for %}
/{% endfor %}
.
Veškerý kontext (proměnné) do šablony musí přijít z volání render_template()
.
Navíc můžete použít vybrané funkce, např. url_for()
.
(Jiné funkce známé z Pythonu ale použít nejdou – ač jsou podobné, je Jinja2
jiný jazyk než Python.)
Pokud budete potřebovat nějaké statické soubory (např. styly CSS nebo
obrázky), dejte je do adresáře static
vedle souboru s kódem
a přistupujte k nim pomocí routy static
:
url_for('static', filename='style.css')
V šabloně pak například:
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet">
Flask umí i další věci – například zpracování formulářů, chybové stránky nebo přesměrování.
Všechno to najdete v dokumentaci.
{ "data": { "sessionMaterial": { "id": "session-material:2019/brno-jaro-2019-ut:file:2", "title": "Flask", "html": "\n \n \n\n <h1>Webové aplikace: Flask</h1>\n<p>Python je víceúčelový jazyk.\nV minulých lekcích jsme tvořili aplikace pro příkazovou řádku,\nnyní se podíváme na aplikace webové.</p>\n<p>Webových frameworků pro Python je více, mezi nejznámější patří <a href=\"https://www.djangoproject.com/\">Django</a> nebo <a href=\"http://flask.pocoo.org/\">Flask</a>.\nPro naše účely použijeme <a href=\"http://flask.pocoo.org/\">Flask</a>, protože je nejrychlejší na pochopení.</p>\n<h2>Flask</h2>\n<p>Flask opět můžete nainstalovat do virtuálního prostředí.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"go\">(__venv__) > python -m pip install Flask</span>\n</pre></div><p>Základní použití Flasku je poměrně primitivní.\nDo souboru <code>hello.py</code> napište:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"c1\"># soubor hello_flask.py</span>\n<span class=\"c1\"># nejjednodušší Flask webová aplikace</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">flask</span> <span class=\"kn\">import</span> <span class=\"n\">Flask</span>\n\n<span class=\"n\">app</span> <span class=\"o\">=</span> <span class=\"n\">Flask</span><span class=\"p\">(</span><span class=\"vm\">__name__</span><span class=\"p\">)</span>\n<span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">config</span><span class=\"p\">[</span><span class=\"s1\">'DEBUG'</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">True</span>\n\n\n<span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">index</span><span class=\"p\">():</span>\n <span class=\"sd\">"""Tato funce se zavolá, když uživatel přijde</span>\n<span class=\"sd\"> na domovskou stránku naší aplikace.</span>\n<span class=\"sd\"> Vrátí řetězec, který se zobrazí v prohlížeči.</span>\n<span class=\"sd\"> """</span>\n <span class=\"k\">return</span> <span class=\"s1\">'Ahoj Pyladies!'</span>\n\n\n<span class=\"k\">if</span> <span class=\"vm\">__name__</span> <span class=\"o\">==</span> <span class=\"s2\">"__main__"</span><span class=\"p\">:</span>\n <span class=\"c1\"># spustí aplikaci</span>\n <span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">()</span>\n</pre></div><p>Pak aplikaci spusťte následovně:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"go\">(__venv__) > python hello.py</span>\n<span class=\"go\"> * Serving Flask app "hello"</span>\n<span class=\"go\"> * Forcing debug mode on</span>\n<span class=\"go\"> * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)</span>\n<span class=\"go\"> * Restarting with stat</span>\n<span class=\"go\"> * Debugger is active!</span>\n<span class=\"go\"> * Debugger PIN: 189-972-345</span>\n</pre></div><p>Na zmíněné adrese byste měli v prohlížeči vidět použitý text.</p>\n<p>Tím, že jsme nastavili konfigurační hodnotu <code>DEBUG</code> jsme zapli ladícím režim,\nkterý si popíšeme za chvíli.</p>\n<p>V programu jsme jako <code>app</code> vytvořili flaskovou aplikaci.\nArgument <code>__name__</code> je jméno modulu – Flask podle něj hledá soubory,\nkteré k aplikaci patří (viz <code>static</code> a <code>templates</code> níže).</p>\n<p>Pomocí dekorátoru <a href=\"http://flask.pocoo.org/docs/1.0/api/#flask.Flask.route\"><code>@app.route</code></a> jsme zaregistrovali takzvaný <em>view</em> (pohled) –\nfunkci, která vrací obsah pro danou <a href=\"/2019/brno-jaro-2019-ut/fast-track/http/#url-anatomy\">cestu v URL</a>.\nTomuto spojení cesty a pohledové funkce se říká <em>route</em> (nebo počeštěně „routa“).\nMy konkrétně říkáme, že na cestě <code>/</code> (tedy na „domovské stránce“) bude\nk dispozici obsah, který vrátí funkce <code>index</code>.</p>\n<p>Více různých adres lze obsloužit jednoduše přidáním dalších funkcí:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">index</span><span class=\"p\">():</span>\n <span class=\"k\">return</span> <span class=\"s1\">'Index Page'</span>\n\n<span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/hello/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">hello</span><span class=\"p\">():</span>\n <span class=\"k\">return</span> <span class=\"s1\">'Hello, World'</span>\n</pre></div><p>Na adrese <a href=\"http://127.0.0.1:5000/hello/\"><code>http://127.0.0.1:5000/hello/</code></a> pak uvidíte druhou stránku.</p>\n<h3>Ladící režim</h3>\n<p>Při povolení ladícího režimu (konfigurační proměnná <code>DEBUG</code>) zapneme příjemnější\nvýpis chyb a aplikace se automaticky restartuje po změnách.</p>\n<p>Zkuste ve funkci <code>hello()</code> vyvolat výjimku (například dělení nulou – <code>1/0</code>)\na podívat se, jak chyba v ladícím režimu „vypadá“:\nFlask ukáže <em>traceback</em> podobný tomu z příkazové řádky a navíc vám na každé\núrovni umožní pomocí malé ikonky spustit konzoli.\nBezpečnostní PIN k této konzoli najdete v terminálu, kde server běží.</p>\n<p>Ladící režim je užitečný, ale nebezpečný – návštěvníkům stránky může\n(po prolomení celkem jednoduchého „hesla“) umožnit spustit jakýkoli pythonní kód.\nNavíc aplikaci zpomaluje.\nPoužívejte ho proto <em>pouze</em> na svém počítači.</p>\n<h3>Dynamické routy</h3>\n<p>Když vytváříte dynamický web, ne vždy můžete všechna URL znát dopředu.\nBudete například chctít zobrazit informace o uživatelích na adresách\njako <code>/user/hroncok/</code>, ale nemůžete při každé registraci nového uživatele\npřidávat novou funkci do kódu.\nMusíte použít <a href=\"http://flask.pocoo.org/docs/1.0/quickstart/#variable-rules\">dynamické routy</a>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/user/<username>/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">profile</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"p\">):</span>\n <span class=\"k\">return</span> <span class=\"s1\">'User {}'</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"p\">)</span>\n</pre></div><p>Proměnnou část cesty ohraničíte lomenými závorkami a použijte jako parametr\nfunkce. Pokud chcete, můžete specifikovat, na jaký obsah se pravidlo vztahuje.\nNapříklad číselný idenifikátor článku pro adresy jako <code>/post/42/</code> můžete zadat\ntakto:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/post/<int:post_id>/'</span><span class=\"p\">)</span>\n</pre></div><p>Můžete použít různá pravidla, např.:</p>\n<ul>\n<li><code>string</code> akceptuje jakýkoliv text bez lomítek (výchozí)</li>\n<li><code>int</code> akceptuje celá čísla (a pohledové funkci je předá jako <code>int</code>, ne text)</li>\n<li><code>float</code> akceptuje i desetinná čísla s tečkou (a předá je jako <code>float</code>)</li>\n<li><code>path</code> akceptuje text i s lomítky</li>\n</ul>\n<p>Rout můžte definovat i víc pro jednu funkci.\nČasto se to používá s výchozí hodnotou argumentu:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/hello/'</span><span class=\"p\">)</span>\n<span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/hello/<name>/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">hello</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">'world'</span><span class=\"p\">):</span>\n <span class=\"k\">return</span> <span class=\"s1\">'Hello, {}!'</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"p\">)</span>\n</pre></div><h3>Získání URL</h3>\n<p>Opačným způsobem jak k routám přistupovat je, když potřebujete získat URL\nnějaké stránky, například protože potřebujete zobrazit odkaz.\nK tomu se používá funkce <a href=\"http://flask.pocoo.org/docs/1.0/api/#flask.url_for\"><code>url_for()</code></a>, která jako první parametr bere jméno\nrouty (neboli jméno funkce, která routu obsluhuje), a pak pojmenované argumenty\npro pravidla v dynamické routě:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">flask</span> <span class=\"kn\">import</span> <span class=\"n\">url_for</span>\n\n<span class=\"o\">...</span>\n\n<span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/url/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">show_url</span><span class=\"p\">():</span>\n <span class=\"k\">return</span> <span class=\"n\">url_for</span><span class=\"p\">(</span><span class=\"s1\">'profile'</span><span class=\"p\">,</span> <span class=\"n\">username</span><span class=\"o\">=</span><span class=\"s1\">'hroncok'</span><span class=\"p\">)</span>\n</pre></div><p>Tuto funkci jde použít jen uvnitř pohledové funkce,\nPokud ji chcete vyzkoušet například v interaktivní konzoli,\nmůžete použít speciální kontext:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"k\">with</span> <span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">test_request_context</span><span class=\"p\">():</span>\n<span class=\"gp\">... </span> <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">url_for</span><span class=\"p\">(</span><span class=\"s1\">'profile'</span><span class=\"p\">,</span> <span class=\"n\">username</span><span class=\"o\">=</span><span class=\"s1\">'hroncok'</span><span class=\"p\">))</span>\n<span class=\"gp\">...\n</span><span class=\"go\">/user/hroncok/</span>\n</pre></div><p>Možná si říkáte, proč tu URL prostě nevytvořit ručně.\nS takovým přístupem byste ale mohli narazit na problém, pokud cestu později\nzměníte – což se může stát např. i když web nasadíte na jiný server.\nGenerování URL vám také může zjednodušit nasazení statické verze stránek.</p>\n<p>Pro URL v rámci vašich stránek proto doporučujeme <code>url_for</code> používat důsledně.</p>\n<h3>Šablony</h3>\n<p>Zatím jsou naše webové stránky poměrně nudné: obsahují jen prostý text,\nnepoužívají HTML.</p>\n<div class=\"admonition note\"><p>O webových technologiích <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML\">HTML</a> a <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS\">CSS</a> se můžete dočíst více\nnapř. na stránkách <a href=\"https://developer.mozilla.org/en-US/docs/Web\">MDN</a>.</p>\n</div><p>HTML se dá psát přímo v Pythonu:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">hello</span><span class=\"p\">():</span>\n <span class=\"k\">return</span> <span class=\"s1\">'<html><head><title>...'</span>\n</pre></div><p>...ale není to nebylo příliš příjemné.\nPython je jazyk dělaný na popis algoritmů, procesů a logiky spíš než obsahu.\nLepší je HTML dát do zvláštního souboru a použít ho jako <em>šablonu</em>\n(angl. <em>template</em>).\nZ Flasku vypadá použití šablony takto:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">flask</span> <span class=\"kn\">import</span> <span class=\"n\">render_template</span>\n\n<span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/hello/'</span><span class=\"p\">)</span>\n<span class=\"nd\">@app.route</span><span class=\"p\">(</span><span class=\"s1\">'/hello/<name>/'</span><span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">hello</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span>\n <span class=\"k\">return</span> <span class=\"n\">render_template</span><span class=\"p\">(</span><span class=\"s1\">'hello.html'</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"n\">name</span><span class=\"p\">)</span>\n</pre></div><p>Funkce <code>render_template</code> nejen vrátí HTML z daného souboru, ale umí do něj\ni doplnit informace, které dostane v pojmenovaných argumentech.</p>\n<p>Ukažme si to na příkladu: vedle souboru s kódem vytvořte složku <code>templates</code>\na v ní <code>hello.html</code> s tímto obsahem:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"cp\"><!doctype html></span>\n<span class=\"p\"><</span><span class=\"nt\">html</span><span class=\"p\">></span>\n <span class=\"p\"><</span><span class=\"nt\">head</span><span class=\"p\">></span>\n <span class=\"p\"><</span><span class=\"nt\">title</span><span class=\"p\">></span>Hello from Flask<span class=\"p\"></</span><span class=\"nt\">title</span><span class=\"p\">></span>\n <span class=\"p\"></</span><span class=\"nt\">head</span><span class=\"p\">></span>\n <span class=\"p\"><</span><span class=\"nt\">body</span><span class=\"p\">></span>\n <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">name</span> <span class=\"cp\">%}</span>\n <span class=\"p\"><</span><span class=\"nt\">h1</span><span class=\"p\">></span>Hello <span class=\"cp\">{{</span> <span class=\"nv\">name</span> <span class=\"cp\">}}</span>!<span class=\"p\"></</span><span class=\"nt\">h1</span><span class=\"p\">></span>\n <span class=\"p\"><</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">"</span><span class=\"cp\">{{</span> <span class=\"nv\">url_for</span><span class=\"o\">(</span><span class=\"s1\">'hello'</span><span class=\"o\">)</span> <span class=\"cp\">}}</span><span class=\"s\">"</span><span class=\"p\">></span>Go back home<span class=\"p\"></</span><span class=\"nt\">a</span><span class=\"p\">></span>\n <span class=\"cp\">{%</span> <span class=\"k\">else</span> <span class=\"cp\">%}</span>\n <span class=\"p\"><</span><span class=\"nt\">h1</span><span class=\"p\">></span>Hello, World!<span class=\"p\"></</span><span class=\"nt\">h1</span><span class=\"p\">></span>\n <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n <span class=\"p\"></</span><span class=\"nt\">body</span><span class=\"p\">></span>\n<span class=\"p\"></</span><span class=\"nt\">html</span><span class=\"p\">></span>\n</pre></div><p>Šablony používají (jako výchozí variantu) šablonovací jazyk <a href=\"http://jinja.pocoo.org/docs/2.10/templates/\">Jinja2</a>,\nkterý se s Flaskem a jinými frameworky pro Python používá často.\nKompletní popis jazyka najdete v <a href=\"http://jinja.pocoo.org/docs/2.10/templates/\">dokumentaci</a>, ale\npro většinu stránek se obejdete s doplněním hodnoty (<code>{{ promenna }}</code>)\na podmíněným obsahem (<code>{% if %}</code>) jako výše,\npřípadně s <a href=\"http://jinja.pocoo.org/docs/2.10/templates/#for\">cyklem</a>: <code>{% for %}</code>/<code>{% endfor %}</code>.</p>\n<p>Veškerý kontext (proměnné) do šablony musí přijít z volání <code>render_template()</code>.\nNavíc můžete použít vybrané funkce, např. <code>url_for()</code>.\n(Jiné funkce známé z Pythonu ale použít nejdou – ač jsou podobné, je Jinja2\njiný jazyk než Python.)</p>\n<h3>Statické soubory</h3>\n<p>Pokud budete potřebovat nějaké statické soubory (např. styly CSS nebo\nobrázky), dejte je do adresáře <code>static</code> vedle souboru s kódem\na přistupujte k nim pomocí routy <code>static</code>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">url_for</span><span class=\"p\">(</span><span class=\"s1\">'static'</span><span class=\"p\">,</span> <span class=\"n\">filename</span><span class=\"o\">=</span><span class=\"s1\">'style.css'</span><span class=\"p\">)</span>\n</pre></div><p>V šabloně pak například:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"p\"><</span><span class=\"nt\">link</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">"</span><span class=\"cp\">{{</span> <span class=\"nv\">url_for</span><span class=\"o\">(</span><span class=\"s1\">'static'</span><span class=\"o\">,</span> <span class=\"nv\">filename</span><span class=\"o\">=</span><span class=\"s1\">'style.css'</span><span class=\"o\">)</span> <span class=\"cp\">}}</span><span class=\"s\">"</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">"stylesheet"</span><span class=\"p\">></span>\n</pre></div><h3>A další</h3>\n<p>Flask umí i další věci – například zpracování formulářů, chybové stránky nebo\npřesměrování.</p>\n<p>Všechno to najdete\n<a href=\"http://flask.pocoo.org/docs/1.0/quickstart/\">v dokumentaci</a>.</p>\n\n\n " } } }