Рассмотрение приложения Restaurant
Рассмотрение приложения Restaurant
При запуске пользователем приложения Restaurant WML-страницаRestaurantCall.wml отображает список разных типов ресторанов и выводит приглашение пользователю на выбор типа предпочитаемой кухни. WML-страницаRestaurantCall.wml реализуется с помощью следующего программного кода:
<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<head>
<meta http-equiv="Cache-Control" content="max-age=0" forua="true"/>
</head>
<card id="GetRestType">
<do type="accept" label="Pick"> <go href="../waplibcgi/RestCallTypeWML.pl ?$(RestType)" /> </do>
<p align="center">
Restaurants
</p>
<p align="left">
<select name="RestType">
<option value="American">American</option> <option value="Chinese">Chinese</option> <option value="FastFood">Fast Food</option> <option value="HealthFood">Health Food</option> <option value="Italian">Italian</option> <option value="Mexican">Mexican</option> <option value="Seafood">Seafood</option>
</select>
</p>
</card>
</wml>
Первые два элемента WML-страницы сообщают WAP-браузерам версию WAP-спецификации, которую поддерживает приложение. В данном случае WML-страница совместима с XML 1.0 и описанием типа документа (DTD) версии 1.1,разработанным ассоциацией WAP Forum. Любая WML-страница, размещаемаяпосле информации о версии, начинается с тега <WML>. В конце каждой WML-страницы должен находиться соответствующий тег </WML>, который завершаетэлементы WML-страницы.
Теги <HEAD> и </HEAD>, располагающиеся после тега<WML>, позволяют указывать данные о WML-странице, включая метаданные и информацию, управляющую доступом.
Элемент <meta> позволяет определять для WML- страницы метаинформацию. Внашем случае параметр http-equiv=Cache-Control сообщает WAP-браузеру, чтоданная часть метаинформации относится к системе кэширования памяти. Аналогично, параметр content=max-age=0 сообщает браузеру, что максимальное время, в течение которого должно выполняться кэширование WML-страницы, равнонулю секунд; то есть, браузер должен не запоминать, а повторно загружать данные с сервера каждый раз, когда поступает запрос. Для данной книги нулевоезначение было выбрано, чтобы помочь читателю в разработке программы. Привыборе нулевого значения каждый раз, когда происходит изменение, оно передается на телефон. В реально эксплуатируемом приложении статическое меню,подобное рассматриваемому здесь, по-видимому, должно использовать интервалхранения, установленный по умолчанию, равным 30 дням. Наконец, параметрforua="true" определяет, что данное значение Cache-Control, управляющеекэшированием, предназначено для телефона и не должно удаляться каким-либопромежуточным агентом.
Для отображения разных типов ресторанов WML-страница использует элемент<select>. После того как пользователь сделает свой выбор, WML-страница запускает Peri-сценарий RestCallTypeWML.pl, который выводит на экран список соответствующих типов ресторанов. Сценарий RestCallTypeWML.pl реализуется с помощью следующего программного кода:
#!/usr/bin/perl
$RestType = $ENV{'QUERY_STRING'};
if ($RestType eq "American")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetAmerican\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallAmerWML.pl? \$(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> American<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"AllStar\">All Star Cafe</option> <option value=\"MarysDiner\">Mary\'s Diner</option> <option value=\"Timberline\">Timberline Inn</option>
</select>
</p>
</card>
</wml>"; }
elsif ($RestType eq "Chinese")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <! DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetChinese\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallChineseWML.pl? \$(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> Chinese<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"ChinaGarden\">China Garden</option> <option value=\"GoldenDragon\">Golden Dragon</option> <option value=\"PlumTree\">Plum Tree Inn</option>
</select>
</p>
</card>
</wml>"; }
elsif ($RestType eq "FastFood")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <! DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetFastFood\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallFastFoodWML.pl? \$(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> Fast Food<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"BurgerKing\">Burger King</option> <option value=\"McDonalds\">McDonald's </option> <option value=\"TopSpot\">Top Spot </option>
</select>
</p>
</card>
</wml>"; }
elsif ($RestType eq "HealthFood")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetHealthFood\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallHealthFoodWML.pl? \$(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> Health Food<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"GeneralNutrition\">General Nutrition</option> <option value=\"HealthExpress\">Health Express</option> <option value=\"LivingHealthy\">Living Healthy</option>
</select>
</p>
</card>
</wml>"; }
elsif ($RestType eq "Italian")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <! DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetItalian\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallItalianWML.pl? \$(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> Italian<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"Marios\">Mario's</option> <option value=\"OliveGarden\">Olive Garden</option> <option value=\"PapaMurphys\">Papa Murphy's</option>
</select>
</p>
</card>
</wml>"; }
elsif ($RestType eq "Mexican")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <! DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetMexican\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallMexicanWML.pl?\ $(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> Mexican<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"BajaFresh\">Baja Fresh</option> <option value=\"Guadalajara\">Guadalajara Grill< /option> <option value=\"LaVilla\">La Villa</option>
</select>
</p>
</card>
</wml>"; }
elsif ($RestType eq "Seafood")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"GetSeafood\">
<do type=\"accept\" label=\"Pick\"> <go href=\"RestCallSeafoodWML.pl?\ $(RestName)\" /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RestaurantCall/ RestaurantCall.wml\" /> </do>
<p align=\"center\">
Restaurants<br/> Seafood<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select name=\"RestName\">
<option value=\"KPSeafood\">K \& P Seafood</option> <option value=\"FishCompany\">Las Vegas Fish Company</option> <option value=\"SevenSeas\">Seven Seas</option>
</select>
</p>
</card>
</wml>"; }
print $Deck;
В реальном приложении Peri-сценарий получал бы информацию о ресторанах изкарт WML-страницы, затем следовал бы запрос в базу данных относительно соответствующих ресторанов. Далее, используя результаты опроса базы данных, сценарий моментально формировал бы WML-карту для отображения наименованийресторанов. Однако в нашем случае сценарий сам выполняет функцию базы данных. Вначале сценарий анализирует параметры для извлечения типа ресторана.Затем используется серия ветвлений if-else для определения типа ресторана и,основываясь на выбранном типе, формируется WML-карта, содержащая названиясоответствующих ресторанов.
После выбора пользователем конкретного ресторана вновь сформированнаяWML-страница вызывает отвечающий типу кухни сценарий, такой, как RestCallltalian или RestCallMexican, и передает сценарию название желаемого ресторана.
Сценарий, в свою очередь, находит название ресторана и формирует для ресторана
#!/usr/bin/perl
$RestName = $ENV{'QUERY_STRING'};
if ($RestName eq "Marios")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"Marios\">
<do type=\"options\" label=\"Back\"> <go href=\"RestCallTypeWML.pl?Italian\" /> </do>
<p align=\"center\">
Restaurants<br/> Italian<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
Mario's<br/> 111 North Rainbow<br/> Las Vegas, NV<br/> <a href=\"wtai://wp/mc;7025551212\" title=\"Call\">702-555-1212</a>
</p>
</card>
</wml>";
}
elsif ($RestName eq "OliveGarden")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"OliveGarden\">
<do type=\"options\" label=\"Back\"> <go href=\"RestCallTypeWML.pl?Italian\" /> </do>
<p align=\"center\">
Restaurants<br/> Italian<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
Olive Garden<br/> 7890 West Sahara<br/> Las Vegas, NV<br/> <a href=\"wtai://wp/mc;7025551212\" title=\"Call\">702-555-1212</a>
</p>
</card>
</wml>";
}
elsif ($RestName eq "PapaMurphys")
{ $Deck = "Content-type: text/vnd.wap.wml
<?xml version=\"1.0\"?> <!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">
<wml>
<head>
<meta http-equiv=\"Cache-Control\" content=\"max-age=0\" forua=\"true\"/>
</head>
<card id=\"PapaMurphys\">
<do type=\"options\" label=\"Back\"> <go href=\"RestCallTypeWML.pl?Italian\" /> </do>
<p align=\"center\">
Restaurants<br/> Italian<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
Papa Murphy's<br/> 123 Main Street<br/> Las Vegas, NV<br/> <a href=\"wtai://wp/mc;7025551212\" title=\"Call\">702-555-1212</a>
</p>
</card>
</wml>";
}
print $Deck;
Как можно видеть, сценарий просто определяет название ресторана, затем формирует соответствующую WML-страницу. Наиболее интересной частью данногопрограммного кода является существующий для каждого ресторана элемент привязки (anchor - анкер) <а>, который позволяет пользователю автоматическизвонить в ресторан:
<a href=\"wtai://wp/mc;7025551212\" title=\"Call\">702-555-1212</a>
Внутри данного анкера код wtai определяет, что программа будет использоватьфункцию из интерфейса приложений для беспроводных телефонов (WTAI-Wireless Telephony Application Interface).Код wp сообщает, что функция находится в общей библиотеке, а код тс представляет собой имя выполняемой функции(make call-телефонный вызов).