Отправляет email-рассылки с помощью сервиса Sendsay

.NET: Записки программиста

  Все выпуски  

Web Slices для IE 8 или "легко ли сластить писиками"


Рассылка сайта .NET: Записки программиста Сайт .NET: Записки программиста

Web Slices для IE 8 или "легко ли сластить писиками"

Web Slices IE 8 Если вы слушали доклады или читали статьи о новинках IE 8, то должны помнить, что добвить web slices (веб-фрагменты) к своему сайту проще простого. Легкий взмах руки (добавление 2-3 аттрибутов в html) - и вы смело можете утверждать, что ваш сайт по полной использует возможности новой версии браузера!

Но так ли все просто на самом деле? Конечно, в наше время верить в чудеса стало легче. Кто-то еще помнит, сколько усилий и времени нужно было потратить, чтобы заставить общаться клиентскую и серверную части кода по DCOM? Чувствуете разницу, реализуя все то же сейчас на WPF? (кстати, намного больше усилий приходилось тратить не на реализацию, а на поддержку этого рершения в локальных сетях заказчиков; в десяти случаях все нормально, в одиннадцатом - нет; и сеть такая же, и руки админ мыл - а не работает. Ладно, это так, лирика :)

Знаете, в программировании, да и в любой другой высокотехнологичной среде, вместо ответов "да" и "нет" практически всегда звучит "да, но ..." и "нет, хотя ...". И это правильно, ведь для того, чтобы правильно задать вопрос, нужно знать большую часть ответа. Вот и сейчас, можно смело сказать, "да, легко, но ...".

Ну что, посмотрим, что скрывается за этим многоточием?

Для наглядности возьмем пример, на котором я разбирался с web slices сам: модуль, выводящий последние результаты футбольных матчей. Для web slices это практически идеальный кандидат - часть страницы с постоянно обновляющейся информацией, которая интересна многим пользователям.

В лучших традициях инкапсуляции сам модуль выглядит у нас так:
<common:LiveResults ID="lr" runat="server"/>
Итак ...

Web slices - взгляд первый

Web Slices FanNet.org Легкий взмах руки:
  • Выделяем нужную нам область тегом div, отмечаем его классом "hslice" и придумываем какой-нибудь id (это обязательное условие для web slices, не важно какой, но id нужен)

  • Внутрь div-а добавляем тег, помеченный классом "entry-title". Он нужен для того, чтобы IE мог определить название нашего веб-фрагмента. Устанавливаем ему стиль "display:none", чтобы сделать невидимым для пользователя.

    Кончно, можно прекрасно использовать и тег с заголовком внутри нашего модуля. Я вынес заголовок, чтобы полностью изолировать логику web slice от user control и оставить ему только отрисовку результатов. А будут они отображаться на странице или как web slices - не user control-ного ума дело.
Получаем вот что:
<div id="liveRes" class="hslice">
    <span class="entry-title" style="display:none">Online-результаты</span>
    <common:LiveResults ID="lr" runat="server"/>
</div>
И все действительно работает. Наводим на модуль мышкой, выбираем "Добавить на панель избранного" и получаем симпатичную кнопку с последними матчами.

Часть ответа со словом "да" мы честно отработали. Теперь посмотрим, что у нас означает "но".

Web slices - взгляд второй

Изучаем описание web slices в MSDN и сразу расстраиваемся от неэффективности нашего решения. Всякий раз, когда браузеру нужно обновить содержимое web slice, он запрашивает нашу страницу целиком и выбирает из нее нужные данные. Логично, а откуда он их еще возьмет? И если на ваш сайт заходит пара сотен человек в день - на это можно смело не обращать внимание. А вот для тысяч посещений - это уже расточительство, по крайней мере, если вместе с web slices на странице выводится и другая информация (а значит и идут обращения к базе, выполняется серверный код и т.д.). Кроме того, размер страницы может быть очень большой и все это барахло содержимое браузеру приходится перетаскивать с сервера, чтобы просто понять, что данные изменились или отрисовать ваш фрагмент в выпадающем окне.

Для решения этой проблемы существует такая штука как "Alternative Update Source". Это указание браузеру запрашивать для обновления другой url, а не тот, на котором был найден web slice. То есть, мы добавляем к нашему фрагменту еще одну строку:
<a rel="feedurl" style="display:none" href="/WebSlices/LiveResultsUpdate.aspx"></a>
которая так же невидима для пользователя. LiveResultsUpdate.aspx - это страница, которая отдает только содержимое web slice, ее и будет запрашивать браузер для обновления.

Разбираемся дальше. Так как web slices являются частью "Windows RSS Platform", то по сути браузер воспринимает указанный url как RSS поток. То, что там расположен наш html с разметкой - удобная абстракция, которая позволяет программистам не заботиться о формировании XML с обновлениями. На самом деле страница LiveResultsUpdate.aspx может возвращать XML примерно такого вида:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005">
  <channel xmlns:cfi="http://www.microsoft.com/schemas/rss/core/2005/internal" cfi:lastdownloaderror="None">
    <title cf:type="text">Online-рузультаты футбольных матчей</title>
    <link>http://fannet.org/WebSlices/LiveResultsUpdate.aspx</link>
    <ttl>15</ttl>
    <item>
      <title xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" cf:type="text">Online-результаты</title>
      <link>http://fannet.org/live</link>
      <guid isPermaLink="false">c465d0e169db3b4eb0db5e1898224134</guid>
      <description>
        Тут расположено содержимое нашего web slice.
      </description>
    </item>
  </channel>
</rss>
И это будет лучше, так как в XML мы сможем явно указать различные параметры и избавим браузер от необходимости преобразования html в XML.

Из тегов канала (channel) нас интересует только "ttl", указывающий частоту обновления нашего фрагмента в минутах. 15 минут - минимальная частота, по умолчанию она равна 1 дню.

Значения остальных тегов: Результаты футбольных матчей FanNet.org
  • title - название web slice, будет отображаться на кнопке панели "Избранное"

  • link - url, на который мы перейдем, если кликнем на самую левую кнопку внизу окошка с web slice (вторая кнопка обновляет сдержимое самого окошка)

  • guid - значение, на основании которого браузер будет определять, изменилось ли содержимое web slice. Если оно обновилось, текст на кнопке с web slice должен стать жирным (хотя это можно отключить в настройках вашего браузера)

  • description - собственно содержимое web slice
Продолжаем разбираться с тонкостями. Кроме "Alternative Update Source" существует еще такая вещь как "Alternative Display Source". По сути, это еще один url вашего сайта. Если вы его зададите, в окошке с web slice будет отображаться содержимое именно этой страницы.

Перед тем как объяснить, зачем он нужен, хочу уточнить, что "alternative update source" и "alternative display source" не зависят друг от друга. Вы можете использовать только "alternative update source" или только "alternative display source" или оба вместе.

Так вот, "alternative display source" может оказаться полезным сразу по нескольким причинам:
  • Во-первых, по нажатию кнопки на панели web slice отобразиться в маленьком окне. Оно маленькое (по умолчанию 320 x 240), поэтому вы можете захотеть выводить содержимое web slice не так, как он выводиться на страницах вашего сайта. Например, убрать большой заголовок, сделать поменьше шрифт, убрать отступы. Поэтому "alternative display source" нужно использовать, когда вы хотите формировать html для web slice, заточенный для отображения в маленьком окошке.

  • Во-вторых, если мы используем "alternative display source", то в preview окне выводятся текущие, а не закешированные данные. Иначе там будет отображаться закешированная информация, которая обновляется с указаной вами периодичностью. И, в любом случае, этот период не может быть меньше 15 минут. Иногда это очень неудобно. Возьмем наш пример с результатами матчей. Данные на сайте обновляются примерно раз в две минуты. Если вы следите за ходом матча, то узнавать новости раз в 15 минут не совсем то, что вы хотели, верно? К сожалению, с ограниченим в 15 минут мы ничего не сделаем, но, по крайней мере, у нас будет возможность просматривать текущие результаты в preview окне, не открывая всю страницу.

  • Есть еще одна полезность "alternative display source". Мы помним, что содержимое web slice (неважно, взят он со страницы или формируется при помощи "alternative update source") воспринимается как RSS. Соответственно на содержимое такого web slice накладываются ограничения: в нем не поддерживаются скрипты, ActiveX компоненты, формы и кнопки с post-запросами. А вот в html от "alternative display source" все это использоваnm можно. Конечно, какие-то ограничния есть и там, но они мягче. Например, нельзя использовать всплывающие диалоги и не поддерживается инсталляция ActiveX (если он уже проставлен в браузере, использовать его можно).
Есть еще один момент, на который стоит обратить внимание. Если вы одновременно используете "alternative update source" и "alternative display source", то содержимое web slice, которое передается в "alternative update source" становиться ненужным. Для определения, обновились ли данные, лучше использовать guid в "alternative update source", а отображаться в окошке все равно будет html, который запрашивается у "alternative display source".

Таким образом, если вы хотите реализовать web slice совсем-совсем оптимально, лучше всего поступить так:
  • Выделяем участок страницы, который мы хотим отображать как web slice. Указываем там заголовок и ссылку на "alternative update source":
    <div id="liveRes" class="hslice">
      <div style="display:none">
        <span class="entry-title">Online-результаты</span>
        <a rel="feedurl" href="/WebSlices/LiveResultsUpdate.aspx"></a>
      </div>
      <common:LiveResults ID="lr" runat="server"/>
    </div>
  • Страница LiveResultsUpdate.aspx формирует RSS без самого контента, но с ссылкой на "alternative display source":
    <?xml version="1.0" encoding="utf-8"?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005">
      <channel xmlns:cfi="http://www.microsoft.com/schemas/rss/core/2005/internal" cfi:lastdownloaderror="None">
        <title cf:type="text">Online-рузультаты футбольных матчей</title>
        <link>http://fannet.org/WebSlices/LiveResultsUpdate.aspx</link>
        <ttl>15</ttl>
        <item>
          <title xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" cf:type="text">Online-результаты</title>
          <link>http://fannet.org/live</link>
          <guid isPermaLink="false">c465d0e169db3b4eb0db5e1898224134</guid>
          <atom:link xmlns:atom="http://www.w3.org/2005/Atom" href="http://fannet.org/WebSlices/LiveResultsDisplay.aspx" rel="entry-content"/>
          <atom:link xmlns:atom="http://www.w3.org/2005/Atom" href="http://fannet.org/WebSlices/LiveResultsUpdate.aspx" rel="alternate"/>
        </item>
      </channel>
    </rss>
  • Страница LiveResultsDisplay.aspx отдает html, оптимизированный для отображения в preview окне для web slice.

В результате, для автоматического обновления браузер будет запрашивать отдельный RSS, содержащий только guid и параметры web slice, а при нажатии кнопки в "Избранном" будет отображаться актуальный (незакешированный) html, который специально оптимизирован для отображения в маленьком окне.

Уф, мы почти добрались до конца, осталась пара изюминок, которые позволят довести ваш web slice до безумного совершенства :)

Web slices - взгляд третий

Scrolling

В документации по web slices рекомендуется создавать их таким образом, чтобы они нормально отображались в окошке размером 320 на 240 px. Именно в таком окне выведется web slice, когда пользователь нажмет кнопку на панели "Избранное" первый раз. Размер окна не подстраивается под размер web slice. Пользователь может растянуть его сам до определенных размеров, но сами вы никак не можете этим управлять.

Валюта online Мало того, это preview окно имеет одно неприятное свойство - если html в нем не помещаеться, вертикальной прокрутки (scrolling) в нем все равно не будет. Я так и не понял, объясняется ли это какими-то причинами или является просто ошибкой, но - прокрутки там нет. Т.е. если один и тот же html вы отобразите просто в IE - прокрутка есть, а в preview окне - нет.

Конечно, некоторые web slices имеют фиксированный размер, так что такое ограничение для них не проблема. Хороший пример - лоты на eBay. Фрагмент с описанием лота легко отобразить в небольшой зоне, которая прекрасно выводиться в preview.

Однако часто web slices представляют собой списки: последние новости, анонсы, музыка, товары, да мало ли. Иногда можно обойтись и тут - например отображать последние три анонса, выводя не более 300 символов текста для каждого + картинка фиксированного размера.

Но есть случаи, когда это не удобно. Например, нам нужно выводить весь текст, длину которого заранее мы не знаем. Или мы хотим вывести все элементы списка, а их количество постоянно меняется. Вот попробуйте зайти на страницу http://valuta.online.ua и добавить web slice с курсами валют. А теперь откройте окошко. Что, тоже крутите скроллер на мыши и ничего не получается, да? Мало того, если растянуть окно по максимуму, все строки все равно не влезут (ну разве что у вас о-очень большой дисплей).

Scrolling был нужен и для результатов матчей. Дело в том, что их количество постоянно меняется. Сегодня играют 10 - 15 игр, а завтра - одну или вообще ни одной. Выводить первых три не хотелось - даже основных матчей бывает много и выбирать из них только несколько - значить превратить web slice в простой баннер, а-ля "а вот у нас есть результаты матчей, заходите к нам!". Поэтому пришлось немного поэкспериментировать со стилями.

Сразу предупрежу, в верстке я разбираюсь "по-программистски", т.е. как-то конечно разбираюсь, но не в совершенстве :) Так что это только пример реализации, возможно опытный верстальщик посмотрит и скажет "ха, да тут все можно сделать одним аттрибутом". В этом случае мне будет приятно, если он поделиться своими мыслями в комментариях :)

Итак, html, который будет возвращаться в preview окне панели "Избранное", может выглядеть так:
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Online-рузультаты футбольных матчей</title>
    <style type="text/css">
      html { height: 100% }
      body { padding: 0px; margin: 0px; height: 100% !important; overflow: hidden; }
      #outer { overflow-x: hidden; overflow-y: auto; height: 100% }
      #inner { padding: 10px; }
    </style>
  </head>
  <body>
    <div id="outer">
      <div id="inner">
         <!-- Тут у нас размещен html нашего web slice -->
      </div>
    </div>
  </body>
</html>
Web slice with scrolling В результате наш html выводится с padding 10px от границ окна и при необходимости в нем появляется вертикальный скроллинг. Аттрибуты "overflow-x" и "overflow-y" уникальны для IE, но и web slices уникальны только для него же, так что проблемы не возникнет.

Ссылки в окне preivew

Если вы кликнете по какой-то ссылке в окне preivew, новая страница отобразиться там же. Вряд ли это то, что вы хотели, так как остальные страницы вашего сайта не предназначены для отображения в маленьком окошке. Для того, чтобы страница открылась в нормальном окне браузера, вам нужно добавить аттрибут target="_blank" ко всем вашим ссылкам (это, кстати, еще один повод использовать "alternative display source". Когда вы отображаете web slice на странице сайта такое поведение вам ни к чему).

Favorite icon

FanNet.org favorite icon Возможно это был какой-то локальный сбой, но! Добавляю web slice, он добавляется, но на кнопке выводиться картинка по умолчанию, а не favirite icon сайта. Мелочь - а неприятно. Причем, если web slice задан только при помощи html аттрибутов, без "alternative update source" - все ок, иконка есть. А если с "update source" - нет.

Прошелся по сайтам с web slices, у кого-то добавляется, у кого-то нет, но разницы понять не смог. После нескольких часов экспериментов получилось - для этого нужно было поместить favorite icon в корень сайта и назвать его стандартно "favicon.ico". В принципе, так и рекомендуется делать, но мне было приятнее собирать все изображения в папке "img", так что favicon жил у меня там. После этого иконка стала нормально отбражаться.

Возможно, сбой был из-за какой-то другой причины, которая исправилась незаметно от меня. Или это - ошибка беты IE и она будет исправлена в release. В любом случае, если у вас возникнут те же проблемы, проверьте сначала этот вариант.

Уф, вроде бы все. Естественно, любое описание не сможет заменить документации MSDN. И удачи вам в разработке!

P.S.

На сайте IE 8 есть галерея расширений, в том числе и web slices. А в RC1 на панели IE появилась кнопка "Get more Add-ons". Многие пользователи, проставившие IE (особенно после выхода релиза), заглянут на эту страницу, так что если вы добавите ваш web slice в галерею - это даст дополнительный трафик на ваш сайт.

блог сайта .NET: Записки программиста Подпишись на блог сайта .NET: Записки программиста



В избранное