Пособие по написанию WAP сайтов
ГЛАВА 19
Рассмотрение приложения RealEstate
Рассмотрение Perl-сценария RealEstateWML.pl
Рассмотрение приложения RealEstate.hdml
Рассмотрение Perl-сценария RealEstateHDML.pl
Если вы когда-либо занимались покупкой дома то, возможно, вам приходилось ввоскресный день колесить по улицам туда и обратно, сожалея, что не обладаетеинформацией о домах, чьи цены попадают в выделенный на покупку бюджет. Вданной главе вы узнаете, как создать приложение RealEstate, предоставляющеепользователям возможность просмотра информации по домам, цены которыхпопадают в определенный диапазон. Когда начинается выполнение приложения,на экран выводится приглашение пользователю на ввод нижней и верхней границ ценового диапазона, как показано на Рис. 19.1. После указания пользователем диапазона цен, приложение отображает на экране список домов, цена которых попадает в указанный диапазон, как показано на Рис. 19.2. Если пользовательвыбирает некоторый определенный дом и затем выбирает опцию просмотра(View), приложение будет отображать дополнительную информацию о доме, какпоказано на Рис. 19.3.
Если вы еще не установили пакет инструментального программного обеспечения (SDK) для разработки WAP-приложенип, аналогичный SDK, который вы можете загрузить с Web-caumawww.openwave.com, то проверить работу приложения RealEstateможно с помощью сотового телефона с WAP-фунщиями, набрав вкачестве URL waplib.com/RealEstate/RealEstate.hdml илиwaplib.com/RealEstate/RealEstate.wml, в зависимости от того,какой язык, HDML или WML, поддерживает ваш телефонный браузер.
Рассмотрение Peri-сценария RealEstateHDML.pl
Рассмотрение Peri-сценария RealEstateHDML.pl
Как и в случае приложения на WML, сценарий RealEstateHDML.pl не взаимодействует с базой данных, содержащей информацию о недвижимости. Вместо этогоиспользуются данные пяти домов, для которых известны цены и информация опродаже. Peri-сценарий RealEstateHDML.pl реализуется с помощью следующегопрограммного кода:
#!/usr/bin/perl
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$PriceLow = $data[0]; $PriceHigh = $data[1];
$Price1 = 99500; $Price2 = 149995; $Price3 = 249995; $Price4 = 500000; $Price5 = 1500000;
if (($PriceLow <= 0) || ($PriceHigh <= 0) || ($PriceLow > $PriceHigh))
{ $Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=Error>
<Action Type=Accept Label=Back Task=GO Dest=../RealEstate/RealEstate.hdml>
<Wrap>Error in price range. Please enter a minimum price and a maximum price.
</Display>
</HDML>";
}
else
{
$Option = "";
if (($Price1 >= $PriceLow) && ($Price1 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/GV01234.hdml>GV01234 &dol;99,500"; }
if (($Price2 >= $PriceLow) && ($Price2 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/LV01234.hdml>LV01234 &dol;149,995"; }
if (($Price3 >= $PriceLow) && ($Price3 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/LV77711.hdml>LV77711 &dol;249,995"; }
if (($Price4 >= $PriceLow) && ($Price4 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/BC01234.hdml>BC01234 &dol;500,000"; }
if (($Price5 >= $PriceLow) && ($Price5 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/LV11711.hdml>LV11711 &dol;1,500,000"; }
if ($Option eq "")
{ $Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=Error>
<Action Type=Accept Label=Back Task=GO Dest=../RealEstate/RealEstate.hdml>
<Wrap>No houses match the price range.
</Display>
</HDML>";
}
else
{ $Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Pick>
<Action Type=Accept Label=View> <Action Type=Soft1 Label=Back Task=GO Dest=../RealEstate/RealEstate.wml>
<Line>Pick a house<br> ...MLS#....Price..
" . $Option . "
</Choice>
</HDML>"; }
}
print $Deck;
Как можно видеть, сценарий использует пять переменных, от $Pricel до$Price5, чтобы отслеживать цены домов, которые известны сценарию. Как и впредыдущем сценарии, для определения факта попадания цены дома в указанныйдиапазон, в программном коде используется серия операторов if. После того какпросмотрены цены всех пяти домов, приложение формирует HDML-страницу, которая с помощью элемента <Choice> создает меню из опций, отвечающих условиям поиска (опции сценарий сохраняет в переменной $0ption). Когда пользователь позднее выбирает из списка некоторый конкретный дом, HDML-приложение загружает HDML-страницу, соответствующую выбранному дому. Например, файл 77711 .hdml содержит следующий программный код:
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=House>
<Action Type=Accept Label=Back Task=PREV>
<Line>MLS #:LV77711<br> &dol;249,995<br> Las Vegas<br> 4 BR / 2 Ba<br> 4100 SF<br> <A Task=GOSUB Dest=#MoreInfo>More Info</A>
</Display>
<Display Name=MoreInfo>
<Action Type=Accept Label=Back Task=RETURN>
<Line>Lot Size: 400X400<br> Year Built: 1998<br> Fireplace: Yes<br> Patio: Yes<br> Pool: Yes<br> Spa: Yes
</Display>
</HDML>
Когда HDML-страница запускает первую карту, браузер выполняет программныйкод, располагающийся внутри элемента House. Если пользователь выбирает опцию More Information (Дополнительная информация), выполняется ветвлениепрограммного кода и переход (с использованием задания GOSUB) на элементMorelnfо.
Рассмотрение приложения Real Estate
Рассмотрение приложения Real Estate
При запуске приложения RealEstate WML-страница RealEstate.wml выводит на экран приглашение пользователю на ввод минимальной и максимальной цены надом. Затем, чтобы обработать введенные данные, приложение запускает Perl-сценарий. WML-страница RealEstate.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="RealEstatePrice">
<onevent type="onenterbackward">
<go method="post" href="../waplibcgi/RealEstateWML.pl"> <postfield name="PriceLow" value="$(PriceLow)&"/> <postfield name="PriceHigh" value="$(PriceHigh)&"/> </go>
</onevent>
<do type="accept" label="Edit"> <noop /> </do>
<do type="options" label="Find"> <go href="#GetRealEstateResults" /> </do>
<p align="center">
Real Estate<br/> Listings<br/>
</p>
<p align="left">
Price Range:
<select>
<option onpick="#GetPriceLow">Low $$$(PriceLow)</option> <option onpick="#GetPriceHigh">High $$$(PriceHigh)</option>
</select>
</p>
</card>
<card id="GetPriceLow">
<do type="accept"> <go href="#RealEstatePrice" /> </do>
<p align="left">
Low: <input name="PriceLow" maxlength="7" format="N6N" />
</p>
</card>
<card id="GetPriceHigh">
<do type="accept"> <go href="#RealEstatePrice" /> </do>
<p align="left">
High: <input name="PriceHigh" maxlength="7" format="N6N" />
</p>
</card>
<card id="GetRealEstateResults">
<onevent type="onenterforward">
<go method="post" href="../waplibcgi/RealEstateWML.pl"> <postfield name="PriceLow" value= "$(PriceLow)&"/> <postfield name="PriceHigh" value= "$(PriceHigh)&"/> </go>
</onevent>
<onevent type="onenterbackward">
<go method="post" href="../waplibcgi/RealEstateWML.pl"> <postfield name="PriceLow" value= "$(PriceLow)&"/> <postfield name="PriceHigh" value= "$(PriceHigh)&"/> </go>
</onevent>
</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 предназначенодля телефона и не должно удаляться каким-либо промежуточным агентом.
Приложение вначале использует элемент <select>, обеспечивающий возможность выбора для ввода минимальной или максимальной цены. На основе сделанного пользователем выбора выполняется ветвление программного кода и переход на определенную локальную карту, которая выдает приглашение пользователю на ввод соответствующих данных. Например, карта GetPriceHigh позволяет пользователю указывать верхнюю границу ценового диапазона. Элемент<input>, расположенный внутри карты GetPriceHigh, используется для выводаприглашения пользователю на форматированный ввод.
После того как пользователь введет необходимую информацию и выберет кнопкупоиска (Find), приложение запускает Peri-сценарий RealEstateWML.pl, который, всвою очередь, находит информацию о домах, чьи цены лежат в указанном пользователем ценовом диапазоне.
Рассмотрение приложения RealEstate.hdml
Рассмотрение приложения RealEstate.hdml
Как и приложение на WML, RealEstate.hdml предоставляет пользователю возможность поиска домов, цена которых попадает в указанный ценовой диапазон, и длявыполнения большей части обработки данных использует Peri-сценарий. Приложение RealEstate.hdml реализуется с помощью следующего программного кода наHDML:
<?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="House">
<do type="accept" label="Back"> <prev/> </do>
<p align="left" mode="nowrap">
MLS #:LV77711<br/> $$249,995<br/> Las Vegas<br/> 4 BR / 2 Ba<br/> 4100 SF<br/> <a href="#MoreInfo" title="Info">More Info</a> </p>
</card>
<card id="MoreInfo">
<do type="accept" label="Back"> <prev /> </do>
<p align="left" mode="nowrap">
Lot Size: 400X400<br/> Year Built: 1998<br/> Fireplace: Yes<br/> Patio: Yes<br/> Pool: Yes<br/> Spa: Yes
</p>
</card>
</wml>
Первый элемент в файле сообщает браузеру (или другим программистам) информацию о версии спецификации HDML, поддерживаемой приложением. Крометого, параметр Markable=True определяет, что браузер может устанавливать наHDML-странице закладку, а параметр TTL=0 предписывает браузеру не выполнятькэширование HDML-страницы. Работа приложения начинается с использованияэлемента <Choice>, который позволяет, если это требуется пользователю, вводить минимальную или максимальную допустимую цену. Основываясь на сделанном пользователем выборе, приложение переходит на именованный элемент<Entry>, который выводит на экран приглашение пользователю на ввод соответствующих данных. После того как пользователь введет требуемую информацию,приложение переходит на элемент GetRealEstateResults, который, в свою очередь, запускает Peri-сценарий RealEstateHDML.pl, чтобы найти все дома, удовлетворяющие условиям поиска.
Рассмотрение Реrl-сценария RealEstateWML.pl
Рассмотрение Реrl-сценария RealEstateWML.pl
После указания пользователем верхней и нижней границы цен в приложенииRealEstate, программа запускает Peri-сценарий для поиска домов, цены которыхпопадают в указанный диапазон. Чтобы выполнить данную обработку, Peri-сценарию уже заранее «известна» информация о некотором ограниченном числедомов (в реальном приложении сценарий получал бы необходимую информациюиз базы данных). Чтобы сравнить стоимость известных ему домов с ценовымдиапазоном, сценарий использует серию ветвлений if-else. Если цена на домпопадает в диапазон, сценарий добавляет дом в опции меню.
Perl-сценарий RealEstateWML.pl реализуется с помощью следующего программного кода:
#!/usr/bin/perl
require 'DeckUtils.pl';
%cgiVars = &AppUtils::ParseCGIVars();
$PriceLow = $cgiVars{"PriceLow"}; $PriceHigh = $cgiVars{"PriceHigh"};
$Price1 = 99500; $Price2 = 149995; $Price3 = 249995; $Price4 = 500000; $Price5 = 1500000;
if (($PriceLow <= 0) || ($PriceHigh <= 0) || ($PriceLow > $PriceHigh))
{ $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=\"Error\">
<do type=\"accept\" label=\"Back\"> <go href=\"../RealEstate/RealEstate.wml\" /> </do>
<p align=\"left\" mode=\"wrap\">
Error in price range. Please enter a minimum price and a maximum price.
</p>
</card>
</wml>";
}
else
{
$Option = "";
if (($Price1 >= $PriceLow) && ($Price1 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate/GV01234.wml \">GV01234 \$\$99,500</option>"; }
if (($Price2 >= $PriceLow) && ($Price2 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate/LV01234.wml \">LV01234 \$\$149,995</option>"; }
if (($Price3 >= $PriceLow) && ($Price3 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate/LV77711.wml \">LV77711 \$\$249,995</option>"; }
if (($Price4 >= $PriceLow) && ($Price4 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate /BC01234.wml\">BC01234 \$\$500,000</option>"; }
if (($Price5 >= $PriceLow) && ($Price5 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate /LV11711.wml\">LV11711 \$\$1,500,000</option>"; }
if ($Option eq "")
{ $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=\"Error\">
<do type=\"accept\" label=\"Back\"> <go href=\"../RealEstate /RealEstate.wml\" /> </do>
<p align=\"left\" mode=\"wrap\">
No houses match the price range.
</p>
</card>
</wml>"; }
else
{ $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=\"Pick\">
<do type=\"accept\" label=\"View\"> <noop /> </do>
<do type=\"options\" label=\"Back\"> <go href=\"../RealEstate /RealEstate.wml\" /> </do>
<p align=\"left\" mode=\"nowrap\">
Pick a house<br/> ...MLS#....Price..
<select> " . $Option . " </select>
</p>
</card>
</wml>"; }
}
print $Deck;
Выполнение сценария начинается с анализа параметров, передаваемых ему WML-страницей Real Estate.wml. Далее, сценарий присваивает переменным, начиная с$Pricel до $Price5, значения в долларовом выражении. Пять переменныхсоответствуют ценам на пять домов, известных сценарию. Затем сценарийиспользует оператор if, чтобы определить введены пользователем минимальнаяи максимальная цены или нет; если это не сделано, сценарий выводит на экрансообщение об ошибке.
Если же пользователь указал ценовой диапазон, программа сравнивает цену каждого из пяти домов с максимальной и минимальной допустимой ценой. Если ценана дом попадает в указанный диапазон, сценарий добавляет информацию о доме(такую, как списочный номер, цена и соответствующий WML-файл) в переменную$0ption. Далее, когда сценарий обработает данные всех пяти домов, будет создансписок домов с желаемой ценой путем размещения переменной $Option внутриэлемента <select>.
Когда позже пользователь выбирает из списка какой-либо дом, приложение загружает соответствующую WML-страницу. Например, WML-страница LV77711.wmlреализуется с помощью следующего программного кода:
Как можно видеть, WML-страница содержит две карты. Когда WML-страница загружает первую карту, приложение выполняет элементы карты House. При выборе пользователем опции More information (Дополнительные данные), приложениезагружает карту Morelnfо.
Приглашение пользователюна ввод ценового диапазона
Рис.. 19.1. Приглашение пользователюна ввод ценового диапазона
Отображение списка домов,чья цена попадает в указанный пользователем диапазон
Рис.. 19.2. Отображение списка домов,чья цена попадает в указанный пользователем диапазон
Отображение на экране данных о доме
Рис.. 19.3. Отображение на экране данных о доме