WMLScript

Jazyk WMLScript umožňuje provádění jednoduchých operací přímo v mobilním zařízení. Typicky se používá například pro kontrolu vstupních údajů ve wapových aplikacích a pro jednoduché výpočty (např. přepočty kurzů měn). Standard umožňuje pomocí skriptů ovládat i některé funkce telefonu jako je posílání SMS zpráv, sestavení a přijetí hovoru, práce s adresářem na SIM kartě a podobně. Bohužel, tyto užitečné vlastnosti zatím většina telefonů nepodporuje.

Proměnné

Než se podíváme na samotný skriptovací jazyk WMLScript, musíme se seznámit s koncepcí proměnných, kterou zavádí jazyk WML. Na stránkách lze používat proměnné, do kterých si můžeme ukládat libovolné hodnoty. Hodnotu proměnné může interaktivně nastavit uživatel. Samozřejmě, že proměnnou můžeme předat i WMLScriptu nebo dokonce aplikaci běžící na nějakém internetovém serveru. Proměnné nám zajistí komunikaci mezi uživatelem a aplikací.

Abychom od sebe jednotlivé proměnné mohli rozeznat, musí mít každá z nich své jméno. Volba jména je v podstatě libovolná, nicméně by jméno mělo začínat písmenem nebo podtržítkem. Pokud se ve WML odvoláváme na proměnnou, je potřeba ji uzavřít do závorek a před ně napsat znak `$'. Pokud chceme do stránky vložit samotný znak pro americký dolar, musíme napsat dva dolary za sebe:

<p>Cena auta je $$3500.</p>

Pro nastavení proměnné slouží element setvar. Ten můžeme použít například uvnitř elementu go, který umožňuje vytváření odkazů, podobně jako element a. Následující kód ilustruje použitích proměnných.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Karta 1">
    <p>Obsah promenne x je&nbsp;<b>$(x)</b></p>
    <p>Prechodem na dalsi kartu nastavite 
      obsah promenne.</p>
    <do type="accept" label="Dalsi karta">
      <go href="#karta2">
	<setvar name="x" value="Mobil"/>
      </go>
    </do>
  </card>
  <card id="karta2" title="Karta 2">
    <do type="prev">
      <prev/>
    </do>
    <p>Obsah promenne x je&nbsp;<b>$(x)</b></p>
  </card>
</wml>

Po zobrazení stránky a její první karty je proměnná x prázdná (viz obr. 1). Její obsah do stránky vkládáme pomocí zápisu $(x). Při přechodu na další kartu ji pomocí <setvar> nastavíme na hodnotu „Mobil“. Obsah proměnných si telefon pamatuje, a proto při návratu na předchozí stránku je obsah proměnné rovněž zobrazen.

Obrázek 1. Obsah proměnné si při přechodu mezi kartami zachová

Pokud chceme, aby při vstupu na kartu prohlížeč zapomněl obsah všech proměnných, stačí u karty použít atribut newcontext a nastavit ho na true.

<card newcontext="true">
  ...
</card>

Vstupní pole

Většina alespoň trochu smysluplných aplikací musí umět komunikovat s uživatelem. Jazyk WML proto nabízí vstupní pole, do kterého může uživatel zadávat hodnoty. Vstupní pole se vytváří pomocí elementu input. Jako hodnotu atributu name musíme uvést název proměnné, která se má nastavit. Následující příklad dovolí uživateli zadat jeho jméno, které se také hned na kartě zobrazí.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Zadani jmena" newcontext="true">
    <p><input name="jmeno"/></p>
    <p>Jmeno: $(jmeno)</p>
  </card>
</wml>

Obrázek 2. Vstupní pole pro zadání textu

Můžeme použít i další atributy, které umožní upravit velikost vstupního pole a hodnoty, které do něj lze zapsat. Velikost vstupního pole určuje atribut size – jako hodnota se zadává počet znaků. Pokud chceme za uživatele do pole předvyplnit nějakou implicitní hodnotu, můžeme ji zadat do atributu default.

Chceme-li, aby uživatel musel do pole zadat alespoň jeden znak, stačí nastavit atribut emptyok na hodnotu false. Mnohem přesněji můžeme vstup vymezit pomocí atributu format. Jako jeho hodnota se uvádí maska specifikující možné vstupy. Znaky, které lze v masce používat shrnuje tabulka 1. Jejich použití usnadní uživateli vstup, ale ne všechny telefony umějí pohlídat dodržení vstupní masky.

Tabulka 1. Znaky použitelné v masce vstupního pole

ZnakVýznam
ALibovolné velké písmeno nebo interpunkce.
aLibovolné malé písmeno nebo interpunkce.
NLibovolná číslice (0-9).
XLibovolné velké písmeno nebo další znak.
xLibovolné malé písmeno nebo další znak.
MLibovolné písmeno nebo další znak, prohlížeč by měl primárně nabízet vstup velkých písmen.
mLibovolné písmeno nebo další znak, prohlížeč by měl primárně nabízet vstup malých písmen.
*fLibovolný počet znaků, které vyhovují některému z předchozích formátů f. Tuto konstrukci lze v masce použít jen jednou a pouze na konci.
nfMaximálně n znaků, které vyhovují některému z předchozích formátů f. Tuto konstrukci lze v masce použít jen jednou a pouze na konci.

Použití masky vstupních polí ilustruje následující jednoduchý příklad.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Omezeni vstupu">
    <p>Jmeno: <input name="jmeno" format="M*m"/></p>
    <p>PSC: <input name="psc" format="NNN NN"/></p>
  </card>
</wml>

Výběr ze seznamu

V mnoha případech je výběr možností pro uživatele omezený. WML nám proto nabízí element select, kterým můžeme do stránky vložit seznam hodnot, z nějž si můžeme vybrat jednu nebo více hodnot. Jednotlivé možnosti se zadávají pomocí elementu option. Proměnnou, do které se uloží hodnota výběru, určíme opět pomocí atributu name u elementu select.

Následující kód obsahuje seznam, ze kterého si uživatel může vybrat jednu hodnotu. Do proměnné se pak uloží hodnota atributu value příslušné volby.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Vyber ze seznamu">
    <p>Vyberte si menu:
      <select multiple="false" name="mena">
	<option value="DEM">nemecka marka</option>
	<option value="USD">americky dolar</option>
	<option value="CZK">ceska koruna</option>
      </select>
    </p>		
    <p>Kod vybrane meny: $(mena)</p>
  </card>
</wml>

Seznamy mají samozřejmě mnohem více možností, ale nemáme zde bohužel prostor je dále podrobněji rozebírat.

Základy „bezdrátového“ skriptování

WMLScript je velice jednoduchý skriptovací jazyk. Až na pár detailů je hodně podobný jazyku JavaScript, který se používá pro tvorbu skriptů na webových stránkách.

Všechny skripty se musí zapisovat odděleně od WML kódu do samostatných souborů, které mají obvykle příponu .wmls. Soubor se skripty typicky obsahuje definice několika funkcí. Některé z těchto funkcí jsou definovány jako externí. To znamená, že je můžeme zavolat z nějaké wapové stránky.

Definice funkce, kterou lze zavolat z nějaké stránky, se musí držet následující kostry:

extern function název (parametry)
{
  tělo funkce
}

Když chceme z nějaké stránky takovou funkci zavolat, musíme vytvořit odkaz ve speciálním tvaru. Pokud by se naše funkce jmenovala fun a byla uložena v souboru skript.wmls, pro její vyvolání by sloužila URL adresa:

skript.wmls#fun()

Tento dost neobvyklý způsob volání funkce má jednu podstatnou výhodu – skripty jsou zcela odděleny od WML kódu. Problém však je, jak od funkce převzít zpět nějaký výsledek. Používají se k tomu proměnné. Z WMLScriptu můžeme nastavovat hodnoty proměnných, které se zobrazují na stránce.

Nastavení proměnné se provede zavoláním speciální funkce WMLBrowser.setVar(). Jako parametry se musí předat název proměnné a její nová hodnota. Po nastavení všech proměnných je ještě potřeba zavolat funkci WMLBrowser.refresh(), která překreslí kartu a zaktualizuje zobrazení proměnných.

Pokud si do souboru smajlik.wmls uložíme následující kód

extern function ukaz()
{
  WMLBrowser.setVar("smajlik", ";-)");
  WMLBrowser.refresh();
}

nic nebrání tomu udělat stránku, na které se smajlík zobrazí až v okamžiku aktivace odkazu uživatelem

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Smajlik" newcontext="true">
    <p>$(smajlik)</p>		
    <p><a href="smajlik.wmls#ukaz()">Ukaz smajlika!</a></p>
  </card>
</wml>

Celý princip práce stránky a skriptu je přitom velice jednoduchý. Na stránku je vložený obsah proměnné (pomocí zápisu $(smajlik)). Po aktivaci odkazu skript změní obsah této proměnné a vyvolá překreslení obrazovky prohlížeče.

Obrázek 3. Smajlík vygenerovaný skriptem

Proměnné, podmínky, cykly, …

Kromě proměnných na stránce můžeme ve WMLScriptu používat vlastní proměnné. Ty je potřeba předem deklarovat. Ve WMLScriptu se neurčuje typ proměnné, pouze se za slovo var napíše seznam proměnných, které chceme deklarovat. Pokud budeme ve funkci používat například proměnné a a b, uvedeme na jejím začátku:

var a, b;

Přiřazení hodnoty do proměnné se děje pomocí operátoru =. Do proměnné můžeme přiřadit číslo nebo textový řetězec. Hodnoty textových řetězců je potřeba uzavřít do uvozovek nebo apostrofů.

a = 10;
b = "Ahoj";

Jak vidíte, je dobré příkazy oddělovat středníkem, aby prohlížeč poznal, kde jeden příkaz končí a další začíná.

Podle potřeb můžeme části skriptu provádět podmíněně. Slouží k tomu příkaz if, který má následující syntaxi:

if (podmínka)
{
  příkazy při splnění podmínky
}
else
{
  příkazy při nesplnění podmínky
}

Část else je přitom nepovinná a nemusíme ji uvádět. Pokud chceme v závislosti na podmínce provést jen jeden příkaz, můžeme vynechat i složené závorky.

V podmínce se nejčastěji porovnává hodnota proměnné. Pro porovnání dvou hodnot se ve WMLScriptu používá operátor ==. Ne, není to překlep, rovnítka musí být dvě za sebou. Např.

if (a == 10)
{
  b = "Desetkrát ahoj!!!!!!!";
}

Ve WMLScriptu můžeme používat i několik druhů cyklů. Jednak je to klasický cyklus while, který probíhá dokud je splněna nějaká podmínka. Stále dokola se vykonávají všechny v něm použité příkazy.

while (podmínka)
{
  příkazy
}

Pokud chceme přesně určit počet opakování příkazů, je většinou výhodnější použít cyklus for. Pokud chceme něco provést desetkrát, poslouží k tomu následující skript.

var i;
for (i=0; i<10; i++)
{
  příkazy
}

Praktické využití ukazuje následující variace na smajlíky. Stránka nyní obsahuje tři odkazy, každý vyvolá zobrazení jiného počtu smajlíků. Příklad rovněž ukazuje, jak lze funkci předávat parametry. Nejprve definice funkce v souboru smajlici.wmls.

extern function ukaz(n)
{
  var s = "", i;
  
  if (n > 0)
  {
    s = s + ";-";
    for (i=0; i<n; i++)
    {
      s = s + ")";
    }
  }

  WMLBrowser.setVar("smajlik", s);
  WMLBrowser.refresh();
}

A nyní stránka, která skript používá:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Smajlik" newcontext="true">
    <p>$(smajlik)</p>		
    <p>
      <a href="smajlici.wmls#ukaz(10)">Ukaz 10 smajliku!</a><br/>
      <a href="smajlici.wmls#ukaz(20)">Ukaz 20 smajliku!</a><br/>
      <a href="smajlici.wmls#ukaz(0)">Zrus smajliky!</a><br/>
    </p>
  </card>
</wml>

Obrázek 4. S funkcemi a parametry lze vykouzlit různé věci. Otázkou zůstává, jak moc jsou užitečné ;–)

Knihovny funkcí

Pro usnadnění práce programátora obsahuje WMLScript sadu několika knihoven, které podporují práci s čísly, textovými řetězci, URL adresami apod. Podrobný popis všech knihoven naleznete ve specifikacích W@Pu (internetové adresy jsou na konci článku).

Kromě těchto standardních knihoven jsou k dispozici i knihovny, které umožňují spolupracovat s prohlížečem. Ty jsme používali pro nastavení hodnoty proměnné nebo pro překreslení karty.

Kalkulačka

Na závěr našeho krátkého výletu do světa WMLScriptu si ukážeme, jak pomocí WMLScriptu vytvořit jednoduchou kalkulačku. Nejprve si vytvoříme stránku s kartou, kde můžeme zadat dvě čísla a ze seznamu si vybrat jednu ze čtyř matematických operací. Čísla a operátor se pak pomocí parametrů předají funkci, ta spočítá výsledek a vrátí nám ho v proměnné.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Kalkulacka" newcontext="true">
    <p>A: <input name="a" type="text" format="*N" 
		 emptyok="false" size="5"/><br/>
      B: <input name="b" type="text" format="*N" 
		emptyok="false" size="5"/><br/>
      Operace: 
      <select multiple="false" name="operace">
	<option value="+">scitani</option>
	<option value="-">odcitani</option>
	<option value="*">nasobeni</option>
	<option value="/">deleni</option>
      </select>
    </p>		
    <do type="accept" label="Spocti!">
      <go href="kalkulacka.wmls#spocti($(a),$(b),'$(operace)')"/>
    </do>
    <p>Vysledek: $(vysledek)</p>
  </card>
</wml>

Všimněte si, že když předáváme jako parametr funkce proměnnou, která může obsahovat textový řetězec (v našem případě operátor), musíme její hodnotu uzavřít do apostrofů nebo uvozovek.

O samotný výpočet se stará následující skript kalkulacka.wmls.

extern function spocti(a, b, op)
{
  // deklarace pomocne promenne
  var vysl;

  // dekodovani textoveho parametru
  op = URL.unescapeString(op);

  // vyber prislusne operace a jeji provedeni
  if (op == "+") 
    vysl = a + b;
  else if (op == "-")
    vysl = a - b;
  else if (op == "*")
    vysl = a * b;
  else if (op == "/" && b == 0)
    vysl = "Nulou nelze delit";
  else
    vysl = a / b;

  // nastaveni promenne s vysledkem
  WMLBrowser.setVar("vysledek", vysl);

  // aktualizace prohlizece
  WMLBrowser.refresh();
}

Jedinou novinkou v tomto skriptu je volání funkce URL.unescapeString(), která slouží k dekódování řetězce z tvaru, ve kterém byl přenesen ze stránky. Funkce se volají jako součást URL adresy a proto se i jejich parametry převádí v souladu s URL konvencemi.

© Jiří Kosek 2000-2001