Hlavní navigace

Šablony stránek pro Zope: sbírání objednávek

Miloš Průdek

Přinášíme další krok v Tajemství proutěného košíku. Položka typu ":records" je příjemným vynálezem pro generování opakovaných řádků v objednávkovém formuláři. Použijeme ji pro sbírání objednávek. Dále uvidíme, jak se tzv. řízení relace používá pro uchovávání údajů a jak se načítají a ukládají údaje.

Sbíráme objednávky

Na konci zdrojového textu šablony index_html jsou dvě položky s poněkud nestandardní syntaxí z hlediska HTML; položka name= totiž obsahuje dvojtečku a klíčové slovo records.

Nejprve je třeba si uvědomit, že tato „úchylka“ nemá nic společného s jazykem šablon ZPT. Není totiž uvedena v rámci prefixu tal:. Z hlediska této šablony je to prostě kód HTML, který je vstupem pro skript addItems. Ten je uvedenen v zahajovacím zaklínadle formuláře <form action=„addItems“>. Záleží tedy na tomto skriptu, co si počne s proměnnými, které se jmenují orders.id:records a orders.quanti­ty:records.

Abych řekl pravdu, nejsou to žádné čáry. Samotné HTML prostě nemá datové struktury typu pole. To znamená, že potřebujeme-li generovat předem neznámý počet značek typu <input…>, museli bychom značky uměle dynamicky číslovat (order1_id, order2_id atd.) a zpětně je rozkládat v přijímacím skriptu. To je pracné a Zope se snaží pracné úkoly eliminovat. Nazveme-li naše proměnné podle syntaxe <proměnná>.<a­tribut>:recor­ds, bude práce s výsledkem snadná, což si ukážeme v popisu skriptu addItems.

Skript addItems

Skript addItems se postará o uložení nových objednávek do košíku. Použije k tomu subsystém pro řízení sezení. V devátém dílu tohoto seriálu jsem psal o vypalování cejchu webovému prohlížeči pomocí cookie. Díky tomuto označkování, které provede Zope zcela automaticky1, můžeme uchovávat libovolné údaje na serveru, přičemž tyto údaje jsou svázané s původním klientským (ocejchovaným) webovým prohlížečem. Této operaci se říká Řízení relace (Session Management). Každý prohlížeč, který otevře vaše dynamické stránky v Zope, má svůj cejch a na serveru jsou jeho jménem uchovávány údaje v jeho vlastní relaci – tedy v jeho vlastní schránce, vybudované automaticky a bez ohledu na to, zda má na vašem serveru účet. Relace tedy slouží i tzv. anonymním uživatelům.

Ukládání a načítání dat relace se provádí pomocí objektu REQUEST.SESSION. Na začátku skriptu addItems vidíte načítání obsahu relace v praxi:

session=context.REQUEST.SESSION
items=session.get('items',{})

Metoda get(‚items‘,{}) vrátí položku itemsuloženou v relaci a zapíše ji do proměnné items skriptu. Na začátku, čili když je košík prázdný, ale položka items v relaci vůbec neexistuje.  Požehnaná  metoda get v takovém případě vrátí prázdný slovník, tedy {}. Máme tak postaráno o inicializaci proměnné items skriptu. Tato syntaxe je použita ve skriptu addItems ještě jednou.

for order in orders:
  quantity=int(order.quantity)
if quantity != 0:
  items[order.id]=items.get(order.id, 0) + quantity

Ve výše uvedeném zdrojovém textu už probíhá zpracování objednávek. V iteraci vidíme, že formulářová položka orders:records z předchozí kapitoly se používá opravdu snadno, protože je přímo dostupná pro skript addItems bez nutnosti jakéhokoliv explicitního přenosu. Stačí uvést ji jako parametr skriptu. Po spuštění iterace se musíme vyrovnat s tím, že v relaci se vše ukládá jako typ řetězec. To se nehodí pro proměnnou quantity, a tak je převedena na celočíselný typ. Když je výsledek operace nenulový, přičte se quantity (množství) k už objednanému množství stejného zboží.

Pokud máte cit na bezpečnostní rizika, určitě vás napadne, že by bezcitný zákazník mohl zadat záporné množství. Trefa! Skript není na takovou situaci připraven a připustí objednávku záporného množství zboží.

session['items']=items
if REQUEST is not None:
   return container.index_html(REQUEST)

Na závěr uložíme nový stav proměnné items do položky items a zavoláme znovu šablonu index_html.

Předpokládám, že si činnost košíku už dávno zkoušíte v praxi. Abyste viděli více do vnitřností relace, neškodilo by průběžné zobrazování obsahu relace. To lze snadno zařídit. Stačí, když někam do šablony index_html přidáte buď zobrazení relace pomocí cesty request/SESSI­ON2, nebo rovnou zobrazíte celý požadavek pomocí cesty request. Chcete hotový funkční příklad a radu pro vhodné umístění? Vložte následující text těsně před značku </div>.

<hr>
   <p tal:content="request/SESSION"></p>
   <hr>
   <p tal:content="structure request"></p>

1 Za předpokladu, že máte v kořenové složce Zope instanci typu Session Data Manager. To je v čerstvé instalaci Zope splněno.
2 Všimněte si, že ve skriptech Python se pro REQUEST.SESSION používají velká písmena, kdežto v jazyce šablon ZPT se musí psát <p tal:content=„re­quest/SESSION“>. Nepopleťte to, jinak se objeví zmatené chybové hlášení o neexistenci požadovaného klíče. Kéž by jednotlivé technologie Zope byly konzistentnější, lidé na sebe hodnější a dívky povolnější!

Našli jste v článku chybu?