Ядро Discourse теперь включает Markdown-эндпоинты для списков и просмотров тем

Discourse теперь поддерживает нативные Markdown-эндпоинты, что упрощает чтение контента форумов для ИИ-инструментов и других клиентов без необходимости парсить полные HTML-страницы.

Эта функция будет включена по умолчанию на всех хостинговых сайтах через систему Upcoming Changes. Администраторы, желающие отказаться от её использования, могут сделать это, отключив настройку сайта enable_markdown_endpoints.

Особая благодарность @benword за создание оригинального плагина Discourse to Markdown, который стал предшественником этой функции в ядре Discourse.


Markdown-вывод генерируется из отрендеренного («cooked») HTML постов, сохраняя контент, который видят читатели, включая раскрытые ссылки и обработанное форматирование. Специфичные для Discourse элементы, такие как цитаты, oneboxes, блоки кода, опросы и сворачиваемые секции, преобразуются обратно в Markdown. Ответы на темы включают метаданные и ссылки на пагинацию, а преобразованные тела постов кэшируются с использованием дайджеста содержимого, чтобы при редактировании создавался новый вывод.

Клиенты могут явно запрашивать Markdown через URL с расширением .md или отправляя заголовок Accept: text/markdown. Переговоры учитывают значения качества и выбирают Markdown, если он предпочтительнее HTML и JSON; явные запросы .md сохраняют свои форматы. Поддерживаемые HTML-страницы указывают на свой Markdown-эквивалент через HTTP-заголовок Link и элемент <link rel="alternate">.

20 лайков

Вы не могли бы уточнить, какие списки тем поддерживаются, а какие — нет?

Поскольку в настоящее время я использую оригинальный плагин Discourse-to-Markdown, нужно ли мне отключить и удалить его, чтобы избежать конфликтующих результатов? Прошу дать совет.

Работает нормально без плагина и включённой грядущей функции.

1 лайк

Один вопрос: для тех, кто использует прокси Cloudflare, кажется, возникает конфликт между функцией ядра и их инструментом конвертации. Вопрос в том: если я нахожусь за прокси, то из-за того, что эта функция доступна только подписчикам, они будут блокировать конвертацию заголовка из HTML в .md, или, поскольку клиент поддерживает конвертацию, она происходит независимо от этого?

Да. Если плагин останется включенным, он заменяет некоторые из основных конечных точек, поэтому мы рекомендуем отключить/удалить его, чтобы использовать функциональность, теперь встроенную в ядро.

В настоящее время поддерживаются следующие:

Поддерживается Примеры
Основные списки /latest.md, /hot.md, /top.md
Персональные списки, требующие аутентификации /new.md, /unread.md
Списки по умолчанию для категорий/подкатегорий /c/support/6.md, /c/parent/child/12.md
Списки по одному тегу /tag/example.md, /tag/example/123.md

Дополнительно /categories.md и /tags.md поддерживаются как каталоги. Определения маршрутов

Я не очень хорошо знаком с этой функцией Cloudflare, но насколько я могу судить, она перехватывает запрос Accept text/markdown до того, как он достигнет сервера, преобразует HTML и затем отдает его. Таким образом, похоже, что эта функция будет переопределять аналогичную функцию Discourse, если используется Cloudflare.

3 лайка

Если это включено, он будет переопределяться, верно? Я не нашёл в их блоге никакой информации о том, препятствуют ли они самой отправке этого заголовка с источника.

Я не могу сказать наверняка, но самый простой вариант — протестировать на живом сайте и сравнить вывод с тем, что выводит meta. Будут различия в том, какой контент включается. Если полученный вами ответ одинаков с включённой и выключенной функцией Cloudflare, значит, она учитывает Markdown, возвращаемый ядром Discourse.

1 лайк

Спасибо за подсказку, вот ответ по этому поводу:

  • X-Discourse-Route: topics/show: Показывает внутренний контроллер/действие Discourse (Ruby on Rails), обрабатывающее тему.
  • X-Runtime: 0.133969: Время, за которое приложение сгенерировало ответ (около ~133 мс).
  • Cf-Ray: ...-GRU: Запрос обработан краем Cloudflare в Гуарульюс/Сан-Паулу (GRU).
  • Cf-Cache-Status: DYNAMIC и Cache-Control: no-cache, no-store: Динамический контент, который не кэшируется на краевых узлах.
  • При проверке обычного HTML-URL без .json сервер отвечает:
    • Link: <https://segredin.com/t/conselhos-duvidosos/22054.md>; rel="alternate"; type="text/markdown"
    • X-Discourse-Crawler-View: true (показывает, что Discourse также предоставляет чистую версию в формате .md / нативный Markdown для веб-сканеров и читалок).

Заголовок Link, указывающий на альтернативную версию: Link: <https://segredin.com/t/conselhos-duvidosos/22054.md>; rel="alternate"; type="text/markdown"

Возвращает Vary: Accept от источника независимо от внешних функций на уровне DNS.

Если клиент выберет сделать запрос без .json, будет возвращена версия .md как стандартное преобразование.

HTTP/1.1 200 OK
Content-Type: text/markdown
Vary: Accept

Я сомневался, потому что получил 123 тысячи запросов от Claude, и большинство из них, с тех пор как я обновил Discourse с этой функцией ядра, не выросли в геометрической прогрессии. Буду наблюдать за этим в ближайшие недели.

Спасибо, я запутался, потому что сначала попробовал на списке тем, отфильтрованном по категории и тегу, и это не сработало. Я склонен выбирать неудачные примеры для тестирования.

Почему вы включили /new и /unread, но не /unseen?

1 лайк

Предполагает ли ядро, что блоки discourse-post-event должны иметь собственное представление в формате Markdown, так же как уже сейчас это реализовано для опросов, цитат, onebox-блоков и сворачиваемых секций? Технически, добавление такой функциональности в CookedProcessor выглядит вполне осуществимым: обнаружить div.discourse-post-event, прочитать его атрибуты data-* и заменить на сохранённый Markdown-блок до общего прохода ReverseMarkdown.

2 лайка

Спасибо за это предложение, оно реализовано в этом PR, который будет принят в ближайшее время.

2 лайка