Когда я опубликовал предыдущий пост и решил добавить ссылку на него в Google+, я обратил внимание на то, что Google выбирает не тот текст со страницы, который я хотел бы видеть. Ну кому интересно каждый раз смотреть на облако тегов?
В итоге я решил разобраться и попытаться указать гуглу (а может и еще кому) нужный кусок. С гуглом получилось, с другими пока нет. И заодно я поднял целый пласт недостающих знаний по HTML5, а именно Microdata. Я, конечно, не раз встречал это слово в спецификации, но никак не мог сообразить, где именно это может использоваться.
Итак, представляю вашему вниманию HTML Microdata. Эта спецификация отвечает за дополнительную семантическию разметку страницы. Но для начала разберемся, что такое семантическая разметка. Как подсказывает нам википедия, семантика — серия научных дисциплин и концепций о смысловой интерпретации в различных символьных системах. Таким образом, семантическая разметка — это способ придания смысла кускам страницы.
Как вы, должно быть, знаете, в HTML5 появился целый набор специальных тегов для семантичекой разметки. Например, header
пригодится, чтобы объявить кусок страницы заголовком, а article
— статьей, новостью или чем-то подобным. Но что, если нам нужно точнее указывать значение элементов на странице? Например, вот это — имя автора статьи, рядом список ключевых слов, а потом еще какая-то информация, которая к статье относится весьма опосредованно. Зачем? Ну мы-то визуально всё это различим, а вот поисковики и скрипты на всяких сайтах наверняка нет. И вот в этом случае придется иметь дело с Microdata.
По спецификации у нас есть буквально несколько дополнительных атрибутов для тегов — itemscope
, itemtype
и itemprop
. Но сами по себе эти атрибуты никакой семантики не добавляют. Создатели спецификации решили, что не дело им указывать какие типы/значения могут быть у контента. Оно и правильно, пусть другие этим занимаются. Так ведь нашлось кому заняться: в 2011 году Google, Bing и Yahoo объединились, чтобы создать список типов данных на странице, а еще через некоторое время к ним присоединился Яндекс. Так что теперь у нас есть Schema.org, прошу любить и жаловать.
Теперь можно со спокойной душой добавить всякой семантической красоты на свою страницу и наслаждаться жизнью. Практически весь специализированный вывод на страницах результатов поисковиков получается благодаря этой разметке. Скажу честно, это не единственный способ, есть еще microformats, но, по утверждению того же Google, предпочтительно использовать Microdata, т.к. этот формат гораздо более гибкий. Кстати, у Google и Яндекса есть инструменты для тестирования подобной разметки: раз и два.
Ладно, может, это всё и никому не нужная ерунда, но по крайней мере у меня получилось указать Google+, какая именно часть страницы является статьей и что нужно показывать.
А еще хочется бросить камень в огород сказать пару слов по поводу Facebook. Эти ребята решили выделиться: для поддержки Facebook нужно использовать свой формат данных — Open Graph. И использовать его нужно только одним заранее определенным способом: с помощью добавления тегов meta
в заголовок страницы. Придется, видимо, подумать, как это сделать, если я хочу красивое описание у ссылок на мой сайт в Facebook.
Пример использования Microdata можно посмотреть прям тут (Ctrl+U в хроме или Firefox). Вопросы и пожелания — добро пожаловать в комментарии.
Антон весьма оперативно выложил запись подкаста с моим участием в сеть. Предлагаю всем послушать и насладиться.
И опять я оказался на записи подкаста IT_Ground, на этот раз в обновленной студии. Теперь всё модно и красиво, есть куча проводов и даже микшер. Приглашаю всех полюбоваться.
Делюсь с вами кусочком из своей практики, который может кому-нибудь пригодиться. Лично я был бы рад найти подобный пост на просторах интернета, когда столкнулся с этой проблемой.
Итак, задача: с помощью XmlHttpRequest получать бинарные данные с сервера. Ну как-то так получилось, что нужно скачивать сжатый с помощью gzip xml-файл с сервера и выбирать из него некоторый набор данных.
Первая важная вещь, которая понадобится, — это метод overrideMimeType
у объекта XMLHttpRequest. Этот метод позволяет переопределить тип получаемых с сервера данных. И даже существует специальная кодировка, которая специально была задумана для приема бинарных данных — x-user-defined
(мы помним, что XMLHttpRequest автоматически преобразует все принятые данные в юникод). Поэтому простое добавление следующей строчки должно сделать большую часть работы.
xhr.overrideMimeType('text/plain; charset=x-user-defined');
Мозг, натренированный jQuery, выдает кусок кода практически сразу:
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.overrideMimeType(
'text/plain; charset=x-user-defined'
);
},
success: successHandler,
error: errorHandler
});
А вот с Google Closure Library не всё так просто. Там нет никаких beforeSend
, и если посмотреть в документацию, то нужная функция выглядит следующим образом:
goog.net.XhrIo.send(url, opt_callback, opt_method, opt_content, opt_headers, opt_timeoutInterval)
Только один callback, который срабатывает на complete, данные, заголовки, таймаут. Не густо. Но если посмотреть в код этой функции, то можно обнаружить, что на самом деле это прокси для объекта goog.net.XhrIo
. Но goog.net.XhrIo
тоже не конструирует XMLHttpRequest. Вместо этого использует фабрику для создания запросов, что, кстати, логично, но больше Java-way чем JS-way. Ну да ладно. Получается, чтобы вклинить вызов overrideMimeType
, нужно сделать свою фабрику с блекджеком, например, вот так:
my.net.BinaryXmlHttpFactory = function () {
goog.base(this);
};
goog.inherits(my.net.BinaryXmlHttpFactory, goog.net.DefaultXmlHttpFactory);
my.net.BinaryXmlHttpFactory.prototype.createInstance = function () {
var xhr = goog.base(this, "createInstance");
xhr.overrideMimeType('text/plain; charset=x-user-defined');
return xhr;
};
Теперь дело осталось за малым: инициализировать goog.net.XhrIo
c новой фабрикой и выполнить запрос:
var xhrIo = new goog.net.XhrIo(new my.net.BinaryXmlHttpFactory());
goog.events.listen(xhrIo, goog.net.EventType.SUCCESS, successHandler);
goog.events.listen(xhrIo, [goog.net.EventType.ERROR, goog.net.EventType.ABORT], errorHandler);
xhrIo.send(url);
Вот и всё. Сразу оговорюсь, что всё это не будет работать в Internet Explorer, т.к. там нужна своя особая магия для получения бинарных данных, в отличие от остальных, где остаток действий выглядит довольно просто:
var res = '';
for (var i = 0; i < data.length; ++i) {
var code = data.charCodeAt(i);
res += String.fromCharCode(code & 0xff);
}
Надеюсь, что кому-то этот пост поможет и направит мысли в правильную сторону.
Сегодня я обратил внимание на такую конструкцию в JavaScript: void 0
. И вдруг понял, что я не знаю, для чего на самом деле нужно слово void
. То, что void 0
используется как эквивалент undefined
, я догадывался, но не более. Так вот, раскрываю всем (и в том числе себе) глаза. Оператор void
используется для изменения результата любого выражения на undefined
. Как-то так получилось, что сейчас применений для этого слова почти не осталось, кроме сокращения записи undefined на целых 3 байта. Хотя на MDN написано, что void
может использоваться в URI-схеме 'javascript:
', чтобы избежать замены станицы результатом выполнения этого выражения. Да, так и есть. Проверил: если сделать ссылку <a href=”javascript: ‘Hello world’”>Click!</a>
, то после нажатия на нее, вся страница будет заменена на «Hello world». Но не во всех браузерах: Chrome выпилил этот пережиток прошлого из своих исходников, так что полагаться на эту возможность нельзя.
Вот и получаем в итоге два практически бесполезных куска знаний: void
и принцип работы схемы javascript:
.