0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フィードの手書きに関して

Posted at

ウェブフィードを手書きすることに関しての雑多なメモです。

自動生成ならいざ知らず、一から書くとなると仕様の確認が必要です。ウェブフィードの形式はRDF Site Summary 1.0 (RSS 1.0)、Really Simple Syndication 2.0 (RSS 2.0)、Atom Syndication Formatが代表的でしょう。以降、この記事では基本的にAtomを題材にします。また、ウェブフィードのことを単にフィードを呼ぶことにします。

Atomの形式について、RFC以外で読みやすいところではFeed Validation Service - Atomというページもあります。

フィードはよくウェブサイトの更新を知らせるために使われていますが、そうでない用途でも使われることがあります。一方通行ではありますが、いわゆるマイクロブログのような使い方も見られます。私がこのような発想のものを初めて見たのはUnproductive Fun TimeRSS 2.0フィードだったと思います。

自分でAtomファイルを書くことを考えます。大枠としては以下になるでしょう。項目を追加するときは、/feed以下にentry要素を加えて、/feed/updatedを更新します。

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://FQDN/path/to/feed</id>
  <title>題名</title>
  <updated>2025-01-01T00:00:00+09:00</updated>
  <entry>
    <link href="https://FQDN/path/to/entry"/>
    <title>題名</title>
    <author><name>著者</name></author>
    <id>識別子</id>
    <updated>2024-01-01T00:00:00+09:00</updated>
  </entry>
  <!-- 以降も好きなだけentry要素を書く -->
</feed>

問題なのは、日時の形式が厳密に決まっているなど、毎回手入力するのが億劫なことです。これまでに3つの解決策を試してきました。

  • RubyでAtomフィードを生成する領域特化言語を作り、その言語を使って作成
  • AtomフィードでDocument Type Definition (DTD) による実体を定義
  • テキストエディタのスニペット機能を利用

領域特化言語を使うと、ソースファイルが見やすく、日付の扱いも楽になるでしょう。既定の振舞いを決めておくことで略記が捗ります。なお、スクリプトを走らせる一工程は要ります。

実体の定義の例は以下のような感じで、特に日時については時刻を決め打ちできます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE feed [
<!ENTITY time "T00:00:00+09:00">
<!ENTITY self "https://FQDN/path/to/feed#">
]>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://FQDN/path/to/feed</id>
  <title>題名</title>
  <updated>2025-01-01&time;</updated>
  <generator>手作り</generator>
  <entry>
    <link href="https://example.com"/>
    <title>題名</title>
    <author><name>著者</name></author>
    <id>&self;2024-01-01-foo</id>
    <updated>2024-01-01&time;</updated>
  </entry>
  <!-- ここに好きなだけentry要素を書く -->
</feed>

テキストエディタにスニペット機能がある場合、項目の追加が楽に行える可能性があります。ここではEmacsのYASnippetによる方法を示します。書き方はYet another snippet extension - Writing snippetsをご参照ください。

# -*- mode: snippet -*-
# name: new Atom entry
# key: entry
# --
<entry>
  <link href="$1"/>
  <title>$2</title>
  <author><name>$3</name></author>
  <id>&self;`(format-time-string "%Y-%m-%d")`-$4</id>
  <updated>`(format-time-string "%Y-%m-%dT%H:%M:%S+09:00")`</updated>
</entry>

上のスニペットでは、例えば以下の☆に地点があるとき、entry<TAB>とすると展開されます。

<feed xmlns="http://www.w3.org/2005/Atom">
  ...
  <updated>2024-01-01&time;</updated><entry>
...

展開後は以下。☆が展開後の地点です。入力し終わったら<TAB>とすることで★の位置に地点が移動していきます。

<feed xmlns="http://www.w3.org/2005/Atom">
  ...
  <updated>2025-01-01&time;</updated>
  <entry>
    <link href="☆"/>
    <title></title>
    <author><name></name></author>
    <id>&self;2024-01-01-★</id>
    <updated>2024-01-01T20:51:46+09:00</updated>
  </entry>
  <entry>
...

フィードを書いたら、それが正しい形式に従っているか確認する必要があります。これは、フィードを読む側でエラーになることを防ぐためです。XMLの構造的な検証の方法は色々あり、RELAX NGはその1つです。具体例として、フィードの形式を表すRELAX NGコンパクトスキーマファイルを入手し、EmacsのnXMLモードで設定する方法を示します。

AtomはRFCでRELAX NGコンパクトスキーマが付録されており、そこから抽出したファイルをatom-schemaのリリースアセットで配布しています。RSSは仕様を参考に作成途中のものがrss-schemaにあります。よろしければお使いください。nXMLのスキーマの配置場所の設定ファイルは次のようにします。

<?xml version="1.0"?>
<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
  <namespace uri="path/to/atom.rnc" ns="http://www.w3.org/2005/Atom" />
  <documentElement uri="path/to/rss2.rnc" localName="rss" />
</locatingRules>

少しだけフィードを手書きしやすくする工夫の紹介でした。


Copyright (c) 2025 gemmaro.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?