Улучшения схемы форума обсуждений

Пожалуйста, оставьте URL-адрес на месте, даже если он заблокирован. Вы можете обсудить, имеет ли это смысл для ваших сценариев использования форума, но даже при заблокированном сканировании это может помочь в устранении неоднозначностей.

Это всё ещё просто вежливая просьба, и даже Google не всегда её уважает. Например, ссылки в Gmail позволяют Googlebot попасть туда сразу, а достаточное количество посещений приводит к индексации и появлению в результатах поиска.

Кроме того… мы/вы не знаем, как изменится ситуация в будущем. Если сейчас это исправлено, то беспокоиться об этом потом не нужно. Конечно, это требует времени, но так же как и инвестирование и обсуждение этого вопроса :smirking_face:

Теперь атрибут datePublished для DiscussionForumPosting на первой странице отличается от datePublished на страницах 2 и далее!

  • первая страница:
    2015-07-05T22:02:58Z
  • страницы 2+:
    2015-07-05T22:02:57Z

Я не думаю, что Google доверяет расходящимся данным и, возможно, решит, что эти два URL содержат разные DiscussionForumPosting, которые нельзя объединить.

Лучше использовать один и тот же источник данных на первой странице и на страницах 2+.
Например, всегда использовать datePublished из темы и никогда из первого сообщения?

search.google.com/test/rich-results для первой страницы
datePublished: 2015-07-05T22:02:58Z

search.google.com/test/rich-results для страницы 2
datePublished: 2015-07-05T22:02:57Z


PR:

Всегда использовать datePublished из темы и никогда из first_post. Это обеспечивает согласованность datePublished на первой странице и на страницах 2+.

Нет необходимости дублировать text на страницах 2+. Особенно не устанавливайте text на страницах 2+, если это лишь краткое содержание и, следовательно, не на 100% соответствует text на первой странице.
Непредвиденные результаты в Google Search Console: сохраняйте атрибут text на последующих страницах страницы 2+.

Скрыть пост «Закрыто x дней назад» из представления поискового робота

Если тема закрыта, к ней добавляется специальный пост:
Например, см. Google structured data for forums and profile pages - #15

Разумеется, у этого поста нет пустой атрибут text. См. validator.schema.org для …/t/-/286762 —> последний комментарий:

Отчёт в Google Search Console

Вывод

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

PR

Особый вид системных/объявительных постов исключается из представления поискового робота, так как они не содержат никакого контента.

Пустой контент вызывает некритическую проблему «Отсутствует поле “text” (в “comment”)» в Google Search Console.

Будет ли логичнее, если метаданные имени автора будут устанавливаться в полное имя из профиля, когда оно доступно? По крайней мере, на форумах, где отключена опция prioritize username in ux (хотя я считаю, что в любом случае поле URL всё равно обеспечивает однозначность).

Можно ли что-то сделать, чтобы это исправить, или команде Discourse нужно обновить ядро?

@rrlevering По поводу этого «отсутствия необходимости в атрибуте text на последующих страницах» / проверки IsExternalContent():

У меня есть этот тест-кейс на работающем домене:

Discourse реализует DiscussionForumPosting на …

  • первой странице - URL страницы: https://example.org/t/-/12345
    • атрибут url: https://example.org/t/-/12345
    • атрибут text: – установлен –
    • атрибут author: – установлен –
  • страница=2 - URL страницы: https://example.org/t/-/12345?page=2
    • атрибут url: https://example.org/t/-/12345
    • атрибут text: – не установлен вообще –
    • атрибут author: – установлен –

Результат: Google Search Console (живое тестирование)

  • первая страница:
    DiscussionForumPosting действительно
  • страница=2:
    DiscussionForumPosting недействительно
    • 1 критическая проблемаДолжен быть указан хотя бы один из атрибутов: "text", "image" или "video"

Таким образом, либо здесь нет проверки IsExternalContent(), либо проверка предполагает, что URL страницы равен атрибуту url для:

  • URL страницы:
    https://example.org/t/-/12345?page=2
  • атрибут url:
    https://example.org/t/-/12345

Пока что нам приходится дублировать атрибут text на последующих страницах, чтобы получить действительный DiscussionForumPosting в Google Search Console.

Неверная разметка схемы для DiscussionForumPosting — только для конкретных URL тем/сообщений

Затронутые темы: темы с общим количеством сообщений более 20
Затронутые URL: …/t/-/NNN/7…/t/-/NNN/20

Отчёт в «Google Rich Result Test»

URL …/t/-/NNN/11: разные темы с разным общим количеством сообщений (нажмите, чтобы открыть)

– Все примеры тем закрыты, чтобы общее количество сообщений не менялось. Сама ошибка также затрагивает открытые темы! –

URL …/t/-/16968/1 — …/t/-/16968/38: одна тема с текущим количеством 38 сообщений (нажмите, чтобы открыть)

Верная разметка схемы:
– У самой DiscussionForumPosting всё ещё есть ненужный атрибут position: 1. –

Неверная разметка схемы: отсутствуют author/datePublished

Снова верная разметка схемы: (здесь: @page > 1true):

Технические соображения

1. `@topic_view.prev_page` может быть не лучшим решением для определения, нужно ли отображать `author`/`datePublished`.

app/views/topics/show.html.erb#L53-L60

      <% if @topic_view.prev_page %>
        <meta itemprop='datePublished' content='<%= @topic_view.topic.created_at.to_formatted_s(:iso8601) %>'>
        <span itemprop='author' itemscope itemtype="http://schema.org/Person">
          <meta itemprop='name' content='<%= @topic_view.topic.user.username %>'>
          <link itemprop='url' href='<%= Discourse.base_url %>/u/<%= @topic_view.topic.user.username %>'>
        </span>
        <meta itemprop='text' content='<%= @topic_view.topic.excerpt %>'>
      <% end %>
2. Сама реализация `@topic_view.prev_page` может содержать ошибку.

lib/topic_view.rb#L113-L115
lib/topic_view.rb#L128-L130
lib/topic_view.rb#L193-L195

    @post_number = [@post_number.to_i, 1].max
# ---
    @page = @page.to_i > 1 ? @page.to_i : calculate_page
# ---
  def prev_page
    @page > 1 && posts.size > 0 ? @page - 1 : nil
  end

Есть ли здесь ошибка?
lib/topic_view.rb#L751-L755

  def calculate_page
    posts_count =
      is_mega_topic? ? @post_number : unfiltered_posts.where("post_number <= ?", @post_number).count
    ((posts_count - 1) / @limit) + 1
  end
  • Может ли calculate_page выдавать неожиданные результаты, так как использует текущий @post_number и каким-то образом некорректно работает для значений от 7 до 20?
  • Выражение ((posts_count - 1) / @limit) + 1 даёт результат вроде:
    ((7 - 1) / 20) + 1 = 1.3 = 1
  • Какое ожидаемое номер страницы? Возможно, нужно выполнять расчёты с нецелочисленными значениями, затем округлять число как задумано через floor/ceil и приводить к типу integer:
    (((posts_count - 1.0) / (@limit + 0.0)) + 1.0).floor.to_i
  • Возможно, стоит проверить unfiltered_posts.where("post_number <= ?", @post_number), так как @topic.posts может не содержать все сообщения, начиная с post_1, как задумано.

lib/topic_view.rb#L53-L55
lib/topic_view.rb#L119-L127
lib/topic_view.rb#L835-L841

  def self.chunk_size
    20
  end
# ---
    @chunk_size =
      case
      when @print
        TopicView.print_chunk_size
      else
        TopicView.chunk_size
      end

    @limit ||= @chunk_size
# ---
  def unfiltered_posts
    result = filter_post_types(@topic.posts)
    result = result.with_deleted if @guardian.can_see_deleted_posts?(@topic.category)
    result = result.where("user_id IS NOT NULL") if @exclude_deleted_users
    result = result.where(hidden: false) if @exclude_hidden
    result
  end

Вывод

В этом пограничном случае …

  • темы с общим количеством сообщений более 20
  • …/t/-/NNN/7…/t/-/NNN/20

… первое сообщение не входило в текущий просмотр, и @topic_view.prev_page не сработал, так как просмотр всё ещё находился на первой странице.

Таким образом, отсутствовали все атрибуты микроданных схемы DiscussionForumPosting, которые рендерились либо в контексте первого сообщения, либо при @topic_view.prev_page == true.

PR

Некоторые атрибуты микроданных схемы DiscussionForumPosting рендерятся в контексте первого сообщения. Убедитесь, что эти атрибуты также устанавливаются, если первое сообщение не входит в текущий просмотр.

Хм… Это неожиданно. Извините за неудобства. Похоже, проверка сравнения URL опускает параметры запроса. Я постараюсь как можно скорее выпустить исправление.

Есть какие-то новости по этому исправлению?

Я полагаю, что на этой неделе было выпущено исправление, учитывающее параметры запроса при проверке «является ли это внешней ссылкой». Таким образом, форумы, которые ссылаются на оригинальные посты (OP) с разных URL через параметры запроса (foo против foo?page=2), не будут вызывать ошибок в GSC.

Вероятно, исправление, выпущенное на этой неделе, учитывает параметры запроса при проверке «является ли это внешним URL»

@rrlevering На другой платформе форумов вы рекомендовали использовать вложенность в схеме comment - Schema.org Property для каждого сообщения в теме. Похоже, что Discourse этого не делает. Вы всё ещё рекомендуете это?

Discourse действительно встраивает схему Comment для каждого сообщения в теме. Перейдите по ссылке Schema Markup Validator, откройте объект DiscussionForumPosting и просмотрите вложенные комментарии.

Спасибо! Я упустил это, так как оно было вложено в DiscussionForumPosting.