Стилизуй свой RSS

Перевод статьи «Style your RSS feed», Darek Kay

RSS не умер. Это не мейнстрим, но это все еще процветающий протокол, особенно среди технарей. Многие не знают, что такое RSS-лента и как им пользоваться.

Большинство браузеров отображают RSS как сырые XML-файлы, что не помогает пользователям понять, в чём суть:

Пример необработанных XML-файлов RSS-лент

В этой статье я расскажу, как оформлять RSS-ленты и одновременно обучать читателей.

XSL (T) приходит на помощь

Вот как выглядит RSS-лента этого блога:

Пример необработанных XML-файлов RSS-лент

Чтобы стилизовать XML-файл в браузере, необходимо предоставить информацию о стилях. Это можно сделать, добавив инструкцию обработки xml-stylesheet в RSS-ленту:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/rss.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:media="http://search.yahoo.com/mrss/">
  ...
</feed>

Атрибут href указывает URL-адрес допустимого XSL-файла. Вы можете ознакомиться с моим примером. Вот суть:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:atom="http://www.w3.org/2005/Atom">
  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
      <title>
        RSS Feed | <xsl:value-of select="/atom:feed/atom:title"/>
      </title>
      <link rel="stylesheet" href="/assets/styles.css"/>
    </head>
    <body>
      <p>
        This is an RSS feed. Visit
        <a href="https://aboutfeeds.com">About Feeds</a>
        to learn more and get started. It’s free.
      </p>
      <h1>Recent blog posts</h1>
      <xsl:for-each select="/atom:feed/atom:entry">
        <a>
          <xsl:attribute name="href">
            <xsl:value-of select="atom:link/@href"/>
          </xsl:attribute>
          <xsl:value-of select="atom:title"/>
        </a>
        <xsl:value-of select="atom:summary"/>
        Last updated:
        <xsl:value-of select="substring(atom:updated, 0, 11)" />
      </xsl:for-each>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Этот код вдохновлен pretty-feed-v3, но я адаптировал его под спецификацию Atom.

XSL-файл преобразует XML-ленту в валидный HTML-документ, который любой браузер может отобразить. Вы можете использовать любую информацию из XML-файла и поместить её в новую структуру разметки. Вы даже можете отобразить контент, который не является частью XML-ленты. Идеальный пример использования — добавить заметку о том, что такое RSS-ленты и как их использовать (как показано в примере выше).

Вы можете определить встроенные CSS-стили с помощью обычного элемента <style>, но также можно импортировать внешние CSS-файлы. Я импортировал основной CSS-файл своего блога, поэтому мне не пришлось писать новый код, чтобы RSS-лента соответствовала дизайну моего блога.

Кроме того, можно использовать функции XSLT для изменения значений. Вот как я обрезаю временную метку, чтобы отображалась только дата:

<!-- Full timestamp -->
<xsl:value-of select="atom:updated" />

<!-- Date only -->
<xsl:value-of select="substring(atom:updated, 0, 11)" />

Поддержка браузером XSL-трансформаций отличная; неподдерживаемые браузеры вернутся к поведению по умолчанию (прогрессивное улучшение).

Примеры

Вот несколько стилизованных RSS-лент, которые вы можете посмотреть для вдохновения:

XSL-файлы публичны, так что можно посмотреть, как эти всё реализовано.

Sitemap

XSL-файлы можно применять к любому XML-файлу. Ещё один пример использования стилизованных XML-файлов — это карта сайта. Хотя карты сайта предназначены для обработки роботами (например, краулерами), их можно стилизовать с минимальными усилиями. Посмотрите мою карту сайта и соответствующий XSL-файл в качестве примера. Вот суть:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9">
  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
      <body>
        <h1>Sitemap</h1>
        <xsl:for-each select="/sitemap:urlset/sitemap:url">
          <a>
            <xsl:attribute name="href">
              <xsl:value-of select="sitemap:loc"/>
            </xsl:attribute>
            <xsl:value-of select="sitemap:loc"/>
          </a>
          Last updated:
          <xsl:value-of select="substring(sitemap:lastmod, 0, 11)" />
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Предостережение

Что произойдёт, если пользователь захочет сохранить стилизованный XML-файл? Интересно, что ответ зависит от браузера. Chrome и Safari сохранят оригинальный XML-файл, а Firefox сохранит стилизованную HTML-страницу. Большинство RSS-ридеров ожидают URL-адрес ленты, поэтому это поведение не имеет значения. Однако я бы был осторожен с XML-файлами, которые предназначены для загрузки, например, OPML-файлами. Спасибо Robb Knight за это наблюдение.

Заключение

Я люблю RSS, и, согласно моей статистике, многие мои читатели тоже его любят. С учётом всех закрытых экосистем социальных сетей, я надеюсь, что RSS станет более популярным. Создавая собственный XSL-файл, вы можете сделать свою RSS-ленту привлекательной и добавить информацию о том, что такое RSS на самом деле.


Про этот сайт и что сделал я 

Мне понравилась идея. Я захотел сделать не отдельную «красивую страницу» самого RSS, а как бы «вписать» RSS-страницу в общее оформление сайта — ну вот чтобы и шапка и подвал и вообще весь контекст.

Получилось вот так: https://sglazov.ru/notes/feed/

К сожалению, даты локализовать я не смог. И меня несколько смущает вот этот вид «18.04.2024», но это всё же лучше, чем просто xml-файл или отсутствие даты.

Мой файл rss-style.xsl повторяет разметку файла layout.njk всей темы этого сайта.

Единственный момент — понадобилось написать простую функцию, чтобы HTML-разметка там, где надо преобразовалась в xHTML — где-то закрывать теги и всё такое:

export default function html2xhtml(content) {
  return content.toString()
    .replace(/(<(img|source)[^>]*?) *\/?>/g, '$1 />')
    .replace('itemscope', 'itemscope=""')
    .replace('&copy;', '&#169;')
    .replace('&nbsp;', '&#160;')
}

В неё целиком я оборачиваю какие-то include-конструкции. Карта сайта сделана также.