Рассмотрение приложения 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-телефонный вызов).