Меня зовут Никита Неминущий, я ведущий инженер-программист финансового маркетплейса «Выберу.ру». В этой статьей я хотел бы рассказать, как на нашем сайте была реализована микроразметка и поделиться своим опытом ее доработки.

Пару слов о том, что такое микроразметка

Микроразметка сайта — это дополнительная (опциональная) разметка HTML-кода, которая помогает поисковым системам, таким как Google, Yandex, лучше понимать структуру и содержание веб-страниц. Она добавляет метаданные к контенту, чтобы поисковые системы могли более точно интерпретировать, что изображено на странице. Сама микроразметка не видна пользователю, но она значительно влияет на то, как сайт отображается в результатах поиска, так как поисковики включают данные из микроразметки в свою поисковую выдачу.

Другими словами, на полотне поисковой выдачи сайт с микроразметкой займёт больше места, чем сайт без нее, и вытеснит конкурентов. Также за счет выдачи ключевых частей контента страницы у такого сайта имеется больше шансов на то, чтобы захватить внимание пользователя и мотивировать его перейти по ссылке и открыть этот сайт.

Существуют два наиболее популярных словаря микроразметки и несколько их синтаксисов:

  1. Schema.org — это стандарт, который разработан Google, Bing, Yahoo и Yandex. То есть это та микроразметка, которая используется поисковыми системами;

  2. Open Graph — микроразметка, разработанная Facebook. Она используется для отображения информации в социальных сетях: определяет, как будет выглядеть пост: какое изображение, заголовок и описание будут показаны в случае, если вы поделитесь с кем-то ссылкой.

Мы сегодня поговорим о Schema.org.

Старое проблемное решение

На нашем портале прежде всего используется микроразметка из словаря Schema.org в двух вариантах синтаксиса: в меньшей степени “микроданные” и в большей “JSON-LD”.

Первый вариант менее удобный, так как данные микроразметки размазываются по HTML-разметке страницы, что засоряет её и усложняет поддержку такого кода для разработчиков.

Второй вариант представляет собой json, который вставляется в тег <script> в разделе <head> страницы. В итоге всё находится в одном месте, а значит, это легко найти, тяжело потерять и возможно, сделав раз, забыть.

Каждый объект json’а представляет собой краткое отображение представленных на странице сущностей. Например, если на странице представлен некий продукт, то для его описания существует соответствующий тип https://schema.org/Product. Все типы Schema.org включены в иерархию, а для их свойств четко определено, объекты какого типа они поддерживают.

"Ошибаться можно - врать нельзя" (с) Андрей Белоусов

Не будем греха таить и честно признаемся, что на нашем портале иногда встречаются спорные решения. И одним из таких решений была реализация микроразметки (создание json’а) путем склеивания строк.

Большими недостатками данного решения является следующее:

  • разработчик должен хорошо разбираться в правилах, установленных словарём микроразметки;

  • разработчик может легко ошибиться, размещая те типы данных и в таких местах, которые не предназначены для этого;

  • разработчик может легко сломать уже созданный код генерации микроразметки, потеряв где-либо скобочку или кавычку.

В 2010 году с российским с ракетой-носителем "Протон-М" произошёл инцидент: ракета разбилась из-за неверно установленного гироскопа. Ракета должна была вывести на орбиту три спутника системы ГЛОНАСС, но после старта ракета отклонилась от курса, развернулась на 180 градусов и в итоге упала в Тихий океан неподалеку от Гавайских островов.

Гироскоп, использовавшийся для управления ориентацией ракеты, был вставлен вверх ногами, что привело к тому, что система управления, полагая, что ракета со всей дури несется вниз, сделала всё, чтобы исправить её курс и направить на путь истинный. А всё из-за того, что инженеры, собиравшие ракету, испытывали трудность в размещении гироскопа на своей позиции и в итоге, воспользовавшись напильником и подточив защиту у крепления, они таки смогли его туда воткнуть.

Так вот, продолжать этот  путь не хотелось и чтобы случайно не впихнуть “невпихуемое”, и был произведен поиск альтернатив. Альтернатива была найдена достаточно быстро, и из доступного в нашем стеке технологий dotNET ей оказался nuget пакет Schema.NET, который мы и решили задействовать на нашем ресурсе.

Работа строго по словарю, или как не получить ложкой в глаз

Nuget пакет Schema.NET поддерживает все основные типы и свойства словаря Schema.org, и предоставляет возможность создания микроразметки путем заполнения данных в подготовленных к сериализации моделях. Все эти модели для nuget пакета Schema.NET генерируются автоматически по заданным правилам, которые строго соответствуют словарю, и описанным в этом многостраничном документе.

То есть чтобы разработчику получить подобную JSON-LD микроразметку:

{
    "@context":"https://schema.org",
    "@type":"WebSite",
    "alternateName":"An Alternative Name",
    "name":"Your Site Name",
    "url":"https://example.com"
}

Ему достаточно написать следующий код:

WebSite website = new()
{
    AlternateName = "An Alternative Name",
    Name = "Your Site Name",
    Url = new Uri("https://example.com")
};
string jsonLd = website.ToString();

Благодаря тому, что каждому полю задан свой тип, разработчику тяжелее ошибиться, “попав ложкой себе в глаз”. Но ошибиться всё же можно, так как некоторые свойства многотипные, то есть могут содержать в себе более одного варианта типа данных. А так как C# строго типизированный язык, то реализация этой возможности имеет определенные ограничения. Чтобы их обойти, Schema.NET реализует вспомогательные типы, такие как структура Values<T1, T2>.

Вот так, например, выглядит свойство Brand в типе Product:

[JsonPropertyName("brand")]
[JsonPropertyOrder(110)]
[JsonConverter(typeof(ValuesJsonConverter))]
public Values<IBrand, IOrganization> Brand { get; set; }

Из кода видно, что свойство может принимать все модели, реализующие либо интерфейс IBrand, либо интерфейс IOrganization. Этот факт, конечно, является документацией сам по себе, но дабы сделать заполнение моделей удобным, а код наглядным: структура Values<T1, T2> реализует множество вариантов неявных приведений типов.

Одно такое неявное приведение типа выглядит таким образом:

public static implicit operator Values<T1, T2>(object[] array) => new(array);

Это позволяет вонзить в него произвольный массив и с ходу не заметить, что” бутерброд” то” без масла". На этапе выполнения никакой ошибки не будет, просто в итоговом json’е свойство окажется незаполненным.

Еще одним недочетом Schema.NET является тот факт, что все содержащиеся в нем типы данных расположены в одном и том же пространстве имен. Из-за этого, к примеру, в Schema.NET напрочь отсутствует тип PaymentCard как финансовый продукт, зато есть PaymentCard как способ оплаты. И если посмотреть на описание этого типа https://schema.org/PaymentCard в словаре, то можно заметить, что их два с одним и тем же именем, но от разных наследников.

Благо в Schema.NET все типы данных не являются закрытыми от наследования и по примеру можно создать нужный вам тип. А в остальном, прекрасная маркиза, всё хорошо, всё хорошо…

Руки в ноги — подводим итоги

Использование nuget пакета Schema.NET позволило нам:

  • унифицировать механизм добавления микроразметки к страницам сайта;

  • ускорить добавление этой самой микроразметки;

  • снизить порог вхождения разработчиков в данную технологию;

  • повысить отказоустойчивость кода.

Комментарии (0)