Soluții - PC Magazine Romania, Iunie 2002
WML: limbajul pentru echipamente mobile
Iulian Radu
În acest articol vom face o scurtă prezentare a WML (Wireless Markup Language),
folosind ca bază specificațiile Wireless Application Protocol Wireless Markup
Language versiunea 1.1. WML este un limbaj markup bazat pe XML (Extensible Markup
Language) și a fost dezvoltat pentru furnizarea de conținut și interfață echipamentelor
cu bandă îngustă de transfer, cum ar fi telefoanele mobile și pager-ele. A fost
proiectat ca să lucreze cu echipamente mobile mici care au patru caracteristici:
ecrane de afișare mici cu rezoluție scăzută;
dispun de puține facilități sau sunt proiectate pentru un anumit scop;
resursele de calcul sunt reduse la un procesor slab, memorie puțină și limitări
ale puterii consumate;
rețeaua dispune de bandă îngustă și întârzieri mari.
Caracteristicile WML pot fi grupate în patru categorii:
oferă suport pentru text și imagine dispunând de o mulțime de comenzi de prelucrare
și amplasare;
cărțile WML sunt grupate în pachete. Un pachet WML este echivalentul unei
pagini HTML, în sensul că este identificat de un URL (Uniform Resource Locators)
și reprezintă unitatea de transfer a conținutului;
WML oferă suport pentru administrarea navigării între cărți și pachete și
conține comenzi pentru gestionarea evenimentelor. Acestea pot fi folosite pentru
navigare sau rularea de scripturi;
pentru toate pachetele WML se pot trimite parametri. Se pot folosi variabile
în loc de șiruri, acestea fiind înlocuite cu valoarea lor în momentul execuției.
Tipurile MIME (Multipurpose Internet Mail Extensions) asociate pachetelor WML
sunt:
text/vnd.wap.wml (în format text)
application/vnd.wap.wmlc (în format de token-uri).
Exemplu
Pentru exemplificare definim un pachet (deck) ce conține cinci cărți (cards)
WML. Echipamentele mobile dispun de un buton care are semnificația de acceptare
a comenzilor (ACCEPT) și altul care are semnificația de înapoi (BACK). Unui
astfel de buton i se pot atașa mai multe acțiuni, caz în care, dacă este apăsat,
se prezintă o listă cu denumirea acțiunilor asociate lui, din care se poate
alege acțiunea dorită. De asemenea, dispozitivele mobile dispun de o stivă în
care se memorează URL-urile vizitate. Aceasta este folosită pentru navigarea
înapoi când se folosește butonul BACK.
Documentele în format WML, fiind bazate pe XML, trebuie să fie bine formatate,
ca de altfel orice document XML. A fi bine formatat înseamnă că fiecare tag
deschis trebuie să fie și închis (<tag ...> ... </tag>), iar în
cazul în care nu conține elemente copii este scris în forma autoînchis (<tag
.../>), iar valoarea unui atribut trebuie să fie conținută între ghilimele.
Atenție, contează dacă se folosesc litere mari sau mici.
Vom analiza în continuare, programul din casetă. (vezi pagina 52).
Liniile 1 și 2 arată că este vorba despre un document în format WML. Deoarece
WML se bazează pe formatul XML, pe prima linie se observă tag-ul <?xml ...?>.
În linia 3 avem un comentariu (tagurile "<!-" și ">>"). Începem definirea
pachetului WML în linia 4 și îl închidem în linia 94. La linia 5 începem definirea
unui model de card. Conținutul acestuia este folosit ca punct de plecare în
definirea tuturor viitoarelor carduri. În cadrul unui astfel de tip de card
se pot utiliza ca elemente direct subordonate tag-ului "<template>" doar
tag-urile "<do type="..." ...>" și "<onevent type="...">". El specifică
faptul că atunci când se va apăsa butonul BACK vom fi trimiși în mod automat
la pagina vizitată precedent (tag-ul "<prev/>") și afișarea pe ecran a
textului "Inapoi" (atributul "label") în locul rezervat pentru acest buton.
La linia 10 începem definirea primului card care va fi afișat pe ecranul echipamentului
mobil. Îi atribuim numele "card1" și anunțăm prin atribuirea valorii "true"
atributului "newcontext" că dorim să ștergem orice informație legată de istoria
navigărilor și să aducem echipamentul la o stare definită în mod implicit. Asociem
butonului ACCEPT eticheta "Urmatorul" și indicăm că trebuie afișat cardul denumit
"card2" în cazul în care se apasă acest buton. Semnul diez aflat în fața numelui
cardului indică faptul că avem de a face cu un fragment de ancoră, adică un
card aflat în deck-ul curent. În liniile 14..16 anulăm acțiunea atribuită implicit
butonului BACK folosind tag-ul "<noop/>". Astfel, pentru acest card nu
avem asociată nici o acțiune a butonului BACK. Liniile 17..19 d efinesc un paragraf
ce conține un text ce are scris cuvântul "Urmatorul" mai gros. În cadrul unui
tag "<card>" se pot folosi mai multe tag-uri "<p>" ca elemente subordonate
direct lui. Pe lângă tag-ul "<em>" mai dispunem și de următoarele taguri
pentru prelucrarea textului: "<strong>", "<b>", "<i>", "<u>",
"<big>" și "<small>". În linia 21 apare atributul "onenterforward"
care indică faptul că dacă în acest card se ajunge în urma unei acțiuni a tag-ului
"<go href="..." ...>" sau a unei acțiuni similare, să se apeleze cardul
denumit "card3" în loc să se afișeze conținutul lui. În linia 23, $(animal)
va fi substituit la afișare cu valoarea variabilei denumită "animal". În linia
26 apare atributul "onenterbackward" care arată că dacă în acest card se ajunge
în urma unei acțiuni a tag-ului "<prev/>" sau a unei acțiuni similare,
să se apeleze cardul denumit "card2" în loc să se afișeze conținutul lui. Trebuie
remarcat că dacă din cardul denumit "card4" ne întoarcem folosind butonul BACK
în cardul "card3", acesta automat va solicita apelarea cardului "card2". Dar
apelarea lui "card2" din "card3" prin intermediul lui "onenterbackword" este
o acțiune echivalentă cu apelarea prin intermediul unui tag "<go ...>",
astfel încât "card2" va apela la rândul său "card3". Deși la prima vedere pare
că întoarcerea în "card3" din "card4" ne va afișa conținutul cardului denumit
"card2", vom constata că ne este afișat totuși conținutul lui "card3". În linia
31 anunțăm că vom defini un grup de câmpuri reunite sub numele de "Animale".
În linia 33 definim o variabilă denumită "animal" și o variabilă denumită "index"
cu valoarea "2". În variabila "index" se va memora în mod automat indexul opțiunii
alese (prima valoarea are indexul 1). În cazul nostru avem în mod implicit selectat
animalul "Caine". Pentru această variabilă ne vor fi afișate două variante:
"de casă" și "animal", prima cu subvariantele: "Pisica", "Caine" și "Hamster",
iar a doua cu subvariantele: "Lup" și "Urs". Când este ales unul dintre aceste
animale, se apelează în mod automat cardul "card4" căruia i se transmit și variabile
"animal" cu una din valorile "cat", "dog", "rat", "wolf" sau "bear", precum
și variabila "index" cu indexul valorii selectate. Cardul "card4" are asociat
butonului ACCEPT funcția de reafișare a conținutului (tag-ul "<refresh/>")
pentru eticheta "Accept" și apelarea cardului "card5" împreună cu variabilele
"site", "passwd" și "animal" pentru eticheta "Apel". Pentru a atașa variabile
unui URL trebuie să se folosească tag-ul "<postfield nume="..." value="...">".
În linia 58 definim un paragraf în care textul este aliniat pe mijlocul paginii
(atributul "align" cu valorea "center"; se mai pot folosi valorile "left" și
"right"), iar cuvintele de pe o linie nu sunt trunchiate, ci afișate pe rândul
următor (atributul "mode" cu valoarea "wrap"; se poate folosi și valoarea opusă
"nowrap"). La linia 59 definim un tabel a cărui coloane, în număr de două, au
conținutul alineat în stânga. Este obligatorie definirea atributului "columns"
când se declară tabele. Cu ajutorul tag-urilor "<tr>" se definesc rândurile,
iar cu ajutorul tag-urilor "<td>" se definesc celulele care aparțin unui
rând. În linia 62 definim o imagine care afișează imaginea corespunzătoare animalului
(atributul "src" cu valoarea "$(animal).wbmp") și care are ca text alternativ
denumirea în engleză a animalului (atributul "alt" cu valoarea variabilei "animal").
În linia 66 se va face automat înlocuirea lui $(site) cu valoarea variabilei
"site". În liniile 69 și 71 definim două casete de introducere de text (tag-ul
"<input name="..." ...>"). Prima afișează exact ce caractere introducem
noi, în timp ce a doua afișează pentru fiecare caracter introdus o steluță.
Atributul "name" face ca unei variabile cu acel nume să i se atribuie șirul
introdus. În atributul "value" putem specifica valoarea implicită pe care dorim
să o aibă această variabilă și care va fi afișată și în cutia de editare. Atributul
"emptyok" specifică dacă trebuie acceptată o valoare vidă pentru această variabilă.
Atributul "size" indică dimensiunea de afișare a cutiei de editare, iar "maxlength"
dimensiunea maximă a șirului. Se poate specifica pentru fiecare câmp de editare
ce formă trebuie să aibă șirul introdus. În linia 70 apare tag-ul "<br/>"
care arată că se dorește trecerea la rândul următor. În linia 74 avem definit
un card care, după trecerea unei anumite perioade de timp, specificată prin
intermediul tagului "<timer value="..." ...>" în linia 75, apelează automat
cardul "card4". Dacă ar fi existat o variabilă denumită "t" atunci s-ar fi folosit
valoarea ei în locul valorii "50" pentru inițializarea timer-ului. În liniile
85..87 se dă varianta lungă a tagului "<a href="..." ...>". De remarcat
că tag-ul "<a>" nu permite apelarea unui URL împreună cu un set de variabile,
ci doar tag-ul "<anchor>". Se observă apariția în liniile 82..92 a d ouă
tag-uri "<p>" ca elemente ce depind direct de tag-ul "<card>".
Concluzii
După cum se poate observa, structura unui pachet WML este foarte simplă. Important
de remarcat este faptul că în cazul unui pachet real, trebuie avută multă grijă
la dimensiunea pachetului trimis echipamentului mobil. Dacă buffer-ul acestuia
este prea mic pentru a memora pachetul WML, se va semnala eroare, deși pachetul
este scris corect. Deoarece fiecare echipament mobil are propriile lui caracteristici,
se recomandă verificarea paginilor WML pe care le creați pe o gamă cât mai mare
de echipamente, iar în cazul în care nu este posibil acest lucru, să se verifice
pentru echipamentele cărora le sunt destinate. Nu vă bazați prea mult pe faptul
că un pachet WML care funcționează bine pe simulatorul unui echipament mobil
se va comporta identic și pe echipamentul real.
Mai multe informații pot fi găsite pe siturile: www.apforum.org/,
www.w3.org/TR/REC-xml/
SURSA
1. <?xml version="1.0"?>
2. <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
3. <! Acesta este un comentariu >->
4. <wml>
5. <template>
6. <do type="prev" label="Inapoi">
7. <prev/>
8. </do>
9. </template>
10. <card id="card1" newcontext="true">
11. <do type="accept" label="Urmatorul">
12. <go href="#card2"/>
13. </do>
14. <do type="prev">
15. <noop/>
16. </do>
17. <p>
18. Apasati <em>Urmatorul</em> pentru a afisa urmatorul card WML
!
19. </p>
20. </card>
21. <card id="card2" title="Cardul al doilea" onenterforward="#card3">
22. <p>
23. Deja ati ales $(animal).
24. </p>
25. </card>
26. <card id="card3" title="Cardul al treilea" onenterbackward="#card2">
27. <do type="accept" label="wap.org">
28. <go href="http:// www.wap.org/ index.wml"/>
29. </do>
30. <p>
31. <fieldset title="Animale">
32. Alegeti un animal:
33. <select name="animal" iname="index" ivalue="2">
34. <optgroup title="de casa">
35. <option value="cat" onpick="#card4">Pisica</option>
36. <option value="dog" onpick="#card4">Caine</option>
37. <option value="rat" onpick="#card4">Hamster</option>
38. </optgroup>
39. <optgroup title="salbatic">
40. <option value="wolf" onpick="#card4">Lup</option>
41. <option value="bear" onpick="#card4">Urs</option>
42. </optgroup>
43. </select>
44. </fieldset>
45. </p>
46. </card>
47. <card id="card4" title="Cardul al patrulea">
48. <do type="accept" label="Accept">
49. <refresh/>
50. </do>
51. <do type="accept" label="Apel">
52. <go href="#card5">
53. <postfield name="site" value="$(site)"/>
54. <postfield name="passwd" value="$(passwd)"/>
55. <postfield name="animal" value="$(animal)"/>
56. </go>
57. </do>
58. <p mode="wrap" align="center">
59. <table columns="2" align="left">
60. <tr>
61. <td>Imagine animal</td>
62. <td><img alt="$(animal)" src="$(animal).wbmp"/></td>
63. </tr>
64. <tr>
65. <td>Apelez</td>
66. <td>$(site)</td>
67. </tr>
68. </table>
69. Sit: <input title="Sit" name="site" type="text" value="" emptyok="false"
size="12" maxlength="128"/>
70. <br/>
71. Parola: <input title="Parola" name="passwd" type="password" value=""
emptyok="true" format="*M"/>
72. </p>
73. </card>
74. <card id="card5" title="Cardul al cincilea" ontimer="#card4">
75. <timer name="t" value="50"/>
76. <do type="accept" label="Apel">
77. <go href="http://$(site)/ index.wml" sendreferer="true">
78. <postfield name="animal" value="$(animal)"/>
79. <postfield name="from" value="Romania"/>
80. </go>
81. </do>
82. <p>
83. Aveti 5 secunde la dispozitie sa apasati butonul ACCEPT pentru a accesa
sit-ul <a href="http://$(site)/index.wml">$(site)</a>
84. <!-
85. <anchor title="Sit">$(site)
86. <go href="http://$(site)/ index.wml"/>
87. </anchor>
88. >>
89. </p>
90. <p>
91. Daca nu, va intoarceti inapoi la 'Cardul al patrulea'.
92. </p>
93. </card>
94. </wml>
|