Home > IE, Web > [PL] Tworzenie dostawcy wyszukiwania dla przeglądarki IE (i nie tylko)

[PL] Tworzenie dostawcy wyszukiwania dla przeglądarki IE (i nie tylko)

February 8, 2010 Leave a comment Go to comments

Od jakiegoś czasu zainteresował mnie wzorzec projektowy MVC w ASP.NET (jeszcze jak był w fazie BETA wersji 1.0) jednak ze względu na brak czasu i inne zajęcia nie bardzo miałem sił wgryźć się w szczegóły. Teraz próbując nadrobić zaległości zamierzam, jak z każdą nową technologią poznać ją od podstaw (wynika z tego, że mam czas?). Jednak mimo, że zacząłem ten post od paru zdań na temat ASP.NET MVC, to nie będzie on bezpośrednio go dotyczył.

Mimo wielu wad i uwag na temat Internet Explorera bardzo zainteresowała mnie wersja 8 tej przeglądarki. Nie dość, że już obsługuje CSS 2.1 w pełni kompatybilne, potrafi symulować starsze edycje tej przeglądarki, to udostępnia nam szereg różnych dodatkowych funkcjonalności, które zwykły użytkownik może zignorować myśląc, że nie wniosą nic nowego. W tym poście chciałbym się skupić na jednym z kilku elementów dostępnych w IE – dostawcach wyszukiwania.

Każdy praktycznie wie czym jest dostawca wyszukiwania i do czego służy (może większość używa tego, ale nie potrafi nazwać). Wpisując jakieś hasło w przeglądarce możemy w łatwy sposób znaleźć je w internecie (np. na Wikipedii, czy Bingu, Googlu). Funkcja ta dostępna jest już od jakiegoś czasu we wszystkich przeglądarkach – zawsze interesowało mnie jednak, jak coś takiego działa, ewentualnie jak można taki mechanizm zaimplementować u siebie na stronie.

W przykładzie MVC dotyczącym galerii, którą rozwijam i mam nadzieje, że kiedyś jakoś to lepiej rozwinę dodałem mechanizm pozwalający na proste wyszukiwanie zdjęć w galerii. Już na wstępie wspomnę, że nie skupiam się tutaj na algorytmach wyszukiwania i sposobach wyciągania informacji, czy bezpieczeństwie strony, tylko na metodzie, dzięki której możemy wyciągnąć dane i przedstawić je użytkownikowi.

Szczegóły implementacji dostawcy wyszukiwania możemy znaleźć na stronach Microsoftu [3]. Postaram się tutaj wyjaśnić podstawy tworzenia dostawcy od strony klienta i od strony serwera wskazując ewentualne haczyki.

Część klienta

Dostawca wyszukiwania w IE to nic innego, jak XML określający sposób komunikacji z serwerem czy nazwę dostawcy. Na chwilę obecną ustalimy sobie adres naszej strony na http://localhost:9807/.

Struktura Open Search

Przyjrzymy się najpierw strukturze tego XMLa. Plik zawiera podstawowe informacje na temat dostawcy wyszukiwania i udostępnianych przez niego usługach wyszukiwania. Przeanalizujemy czemu służą niektóre z poniższych linii.

    1 <?xml version="1.0" encoding="UTF-8"?>

    2 <OpenSearchDescription

    3   xmlns="http://a9.com/-/spec/opensearch/1.1/"

    4   xmlns:ie="http://schemas.microsoft.com/Search/2008/">

    5   <ShortName>Gallery search</ShortName>

    6   <Image height="16"

    7          width="16"

    8          type="image/icon">http://localhost:9807/example.ico</Image>

    9   <Url type="text/html"

   10        template="http://localhost:9807/search?Query={searchTerms&#125;"/>

   11   <Url type="application/x-suggestions+xml"

   12        template="http://localhost:9807/search/preview/{searchTerms&#125;?rowHeight={rowHeight}"/>

   13   <ie:PreviewUrl type="text/html"

   14                  template="http://localhost:9807/search/accelerator/{searchTerms&#125;"/>

   15 </OpenSearchDescription>

Linia 5

określa nazwę dostawcy wyszukiwania, która w liście dostawców wyszukiwania będzie dostępna. Linia 6-8 określa nam ikonę, za pomocą której możemy naszego dostawce wyróżnić. Najciekawsze są jednak linie 9-13. Je przeanalizujemy sobie dokładniej.

Linia 9-10

określa adres strony, w której wyświetlane będą wyniki wyszukiwania. Samo zapytanie (czyli rzecz o którą pytamy) będzie zawarta w polu {searchTerms}. Podając adres do strony naszego wyszukiwania musimy koniecznie podać ten ‘tag’. Dzięki temu przeglądarka wstawi w to miejsce nasze zapytanie.

Linia 11-12

podczas wpisywania w polu wyszukiwania słów pojawia się nam czasami lista z podpowiedziami, a czasami także i zawartością (zdjęciami). Lista taka przeważnie zwracana jest w postaci XML, jednak może być także zwrócona w postaci JSON (np. w przypadku googla). W naszym przykładzie pominiemy JSONa, chyba, że w przyszłości na naszej stronie zaimplementujemy dynamiczne podpowiedzi w polu tekstowym. JSON przykładowo jest wykorzystywany prze googla do zwracania podpowiedzi na stronie Googla lub w przeglądarkach.

Linia 13-14

linia ta, rozpoznawana tylko przez przeglądarkę IE (ale nie martwcie się, dokument jest nadal poprawny, pozostałe przeglądarki zignorują to pole), pozwala na użycie tak zwanego akceleratora. Warto temu przyjrzeć się bliżej w innym poście, jednak jeżeli pozbędziemy się nawyku – znajdź na stronie tekst, zaznacz, skopiuj, wklej i wyszukaj – to docenimy ten mechanizm polegający na znajdź, zaznacz i kliknij.

 

Przeglądarka sama znajdzie Twoją usługę, jeżeli

w meta tagach w nagłówku strony dodasz następujący link przedstawiony w liniach 11-14, określający nazwę Twojej usługi i adres do pliku opisującego szczegółowo usługę wyszukiwania – zawartość została przedstawiona wyżej w strukturze dokumentu open search.

    8 <head runat="server">

    9   <title> </title>

   10   <!––>

   11   <link title="My Gallery – Search Provider"

   12         rel="search"

   13         type="application/opensearchdescription+xml"

   14         href="http://localhost:9807/OpenSearchDescription.xml" />

   15 </head>

Dzięki temu przeglądarka automatycznie wychwyci dostępność dostawcy wyszukiwania na stronie i wyświetli go w listach dostawców. Nic nie stoi na przeszkodzie, aby dodać kilka różnych dostawców wyszukiwania na naszej stronie. Wtedy na liście pojawi się więcej elementów.searchprovider_a Z tego co wiem, podpowiadanie nie będzie dostępne do czasu, gdy sami nie zainstalujemy dostawcy w przeglądarce.

 

Dodawanie do HTML

Można także wskazać użytkownikowi, możliwość zainstalowania dostawcy wyszukiwania przy pomocy prostego kliknięcia w przycisk na naszej stronie. Przykład podany jest na stronach Microsoftu, jednak użyjemy trochę bezpieczniejszej techniki – wyświetlimy przycisk umożliwiający dodawania dostawcy jedynie dla przeglądarki w wersji IE 8 wzwyż. Dzięki temu inne przeglądarki nie powinny wyrzucić wyjątka. Przejdźmy do analizy problemu. Wewnątrz strony z wyszukiwaniem mam zdefiniowany przycisk pozwalający na dodanie dostawcy wyszukiwania po kliknięciu przycisku, może to być dowolny element obsługujący zdarzenie typu mouseclick.

   12 <input type="button" value="Add search provider" id="addsp" />

Następnie zdefiniowałem wewnątrz strony funkcję jQuery, która ukrywa lub pokazuje przycisk pozwalający na dodanie dostawcy wyszukiwania. Najważniejsze są następujące linie:

   38 $(function() {

   39     $(‘#addsp’).hide();

   40     if (($.browser.msie) && ($.browser.version >= 8)) {

   41         var spUrl = http://localhost:9807/OpenSearchDescription.xml&#8217;;

   42         if (window.external.IsSearchProviderInstalled(spUrl) == 0) {

   43             $(‘#addsp’).click(function() {

   44                 window.external.AddSearchProvider(spUrl);

   45                 $(‘#addsp’).hide();

   46             });

   47             $(‘#addsp’).show();

   48         }

   49     }

   50 });

linia 40 – sprawdzająca, czy przeglądarka to IE w wersji od 8 wzwyż. Linia 42 sprawdza, czy dostawca został zainstalowany w przeglądarce (używamy do tego celu funkcji IsSearchProviderInstalled). W linii 44 dodane zostało polecenie pozwalające na dodanie dostawcy do przeglądarki (funkcja AddSearchProvider). Jeżeli przeglądarka IE nie ma zainstalowanego naszego dostawcy wyszukiwania, to na stronach wyszukiwania, obok przycisku ‘Search’ powinien znaleźć się nasz przycisk.

searchprovider_b

Część serwera

Zajmiemy się teraz tworzeniem części serwerowej, a dokładniej części odpowiedzialnej za wyświetlanie podpowiedzi. W załączonym przykładzie jest przedstawiony sposób pobierania danych od użytkownika, jednak zasada działania nie będzie tutaj opisana. Wyszukiwanie polega jedynie na pobieraniu z bazy danych elementów, w których w tytule, bądź w opisie znajduje się szukany tekst. Przejdźmy jednak do opisu danych zwracanych do przeglądarki.

    1 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MVCGallery.Controllers.SearchSuggestion>"

    2     ContentType="text/xml" ResponseEncoding="UTF-8" %><?xml version="1.0" encoding="UTF-8" ?>

    3 <SearchSuggestion xmlns="http://schemas.microsoft.com/Search/2008/suggestions"&gt;

    4     <Query><%= Html.Encode(Model.Query) %></Query>

    5     <% if ((Model.Results != null) && (Model.Results.Count() > 0)) { %>

    6         <Section>

    7             <Separator title="Gallery images"/>

    8             <% foreach (var item in Model.Results) {%>

    9                 <Item>

   10                     <Text><%= Html.Encode(item.Title) %></Text>

   11                     <Description><%= Html.Encode(item.Description)%></Description>

   12                     <Image alt="Image" width="<%= Model.RowHeight %>" height="<%= Model.RowHeight %>"

   13                             source="http://localhost:9807/Images/thumb_<%= item.ImageName %>" />

   14                     <Url>http://localhost:9807/Gallery/Details/<%= item.GalleryID %></Url>

   15                 </Item>

   16             <% } %>

   17         </Section>

   18     <% } %>

   19 </SearchSuggestion>

Odpowiedzią serwera na pytanie klienta jest XML zawierający informacje w określonych polach. Cały XML musi być kodowany w postaci UTF-8. Ważne jest, aby w polu Query zwracać to co wpisał użytkownik, ale jest mała uwaga. Wpisując w pole wyszukiwania wyrazy rozdzielone spacją można otrzymać informacje o błędzie spowodowaną tym, że w wysłanym zapytaniu spacje zamieniane są na znaki ‘+’ (plus). W polu Query znaki te nie mogą występować (?). Warto wtedy zamienić ten znak na spację.

searchKolejnym ważnym tagiem XMLa jest tag ‘Section’, w którym zwracane są wyniki. I tutaj jest kolejny haczyk. Jeżeli okaże się, że w bazie nie ma zdjęcia z naszą frazą, o którą pytamy, to nie możemy zwrócić pustego taga typu: ‘<Section></Section>’ czy też ‘<Section />’. W takim przypadku nie zwracamy tego taga. W powyższym przykładzie, aby sprostać temu wyzwaniu :) posłużyłem się rozwiązaniem przedstawionym w linii 5.

Wewnątrz sekcji zwracamy wyniki zapytania. Wyniki te możemy grupować za pomocą taga ‘<Separator>’ przedstawionego w linii 7. W naszym przykładzie na chwilę obecną znajduje się tylko jeden separator, jeżeli na naszej stronie jest tylko jeden typ danych (jak w naszym przypadku zdjęcia galerii), to warto opuścić ten tag, ale tutaj został dodany jedynie dla przykładu. Jeżeli mielibyśmy dodatkowo forum, to możemy grupować odpowiedzi i przekazywać je użytkownikowi. Na zdjęciu obok zostały przedstawione podpowiedzi z miniaturkami zdjęć – rezultat działania naszej aplikacji.

   

Co zapamiętać najbardziej i dodatkowe uwagi

1. Struktura XMLa zwracającego wyniki – kodowanie UTF-8

2. Uważaj, przy formatowaniu struktury dokumentu w Visual Studio, aby przed tagiem <?xml nie było żadnego znaku, nawet końca linii. Podany wyżej przykład był jedynie prostym, mało estetycznym przykładem wysyłania odpowiedzi. Lepiej w tym celu użyć serializacji i HTTP Handler.

3. Jeżeli nie ma wyników, to nie zwracaj pustego taga <Section/> – nie zwracaj go w tym przypadku w ogóle

4. W polu Query nie zwracaj znaków np. +, zamień go na spację

Linki

[1] Czym jest wzorzec MVC:

http://pl.wikipedia.org/wiki/MVC 

http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

[2] ASP.NET MVC: http://www.asp.net/mvc/

[3] Open search i tutorial: http://msdn.microsoft.com/en-us/library/cc848862(VS.85).aspx

Projekt – wymaga Visual Studio 2010. Jest dużo w nim błędów programistycznych, jednak celem tego projektu jest pokazanie działania Open Search w przeglądarce IE8.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: