Using Custom Tags in Feed2Fedi

Feed2Fedi supports extracting custom or non-standard tags from RSS/Atom feeds and making them available in post templates. This feature is useful when feeds contain tags that aren't part of the standard RSS/Atom specification, or when you want to use alternative tags instead of the standard ones.

Table of Contents

Use Case Example

A common use case is when a feed uses non-standard tags that provide better information for Fediverse posts. For example:

  • A media library feed has <link> tags pointing directly to MP4 video files
  • The same feed also has custom <websiteUrl> tags pointing to HTML pages where the videos can be played
  • Mastodon and other Fediverse platforms embed HTML pages better than direct video links
  • With custom tag mappings, you can use {website_url} in your template instead of {link}

Without custom tags: - Template uses {link} (points to MP4 file) - Result: Mastodon shows a plain video link without preview

With custom tags: - Template uses {website_url} (points to HTML page) - Result: Mastodon shows a rich preview with title, description, and thumbnail

Configuration

To use custom tags, add a tag_mappings section to your feed configuration in config.json:

{
  "feeds": [
    {
      "url": "https://example.com/feed.xml",
      "prefix": "Example Feed",
      "tag_mappings": {
        "website_url": "websiteUrl",
        "duration": "duration",
        "categories": "tags",
        "rating": "contentRating"
      },
      "post_template": "{title}\n\nWatch here: {website_url}\n\nDuration: {duration}"
    }
  ]
}

How it Works

  1. Mapping Definition: The tag_mappings dictionary maps template variable names (left) to feed tag names (right)
  2. Tag Extraction: Feed2Fedi extracts the specified tags from the feed
  3. Template Variables: The extracted values become available as template variables
  4. Template Usage: Use the variables in your post_template with curly braces: {variable_name}

Key Points

  • Case Insensitivity: Feed tag names are case-insensitive in the mapping because feedparser (the underlying library) lowercases all tag names
  • Optional Feature: The tag_mappings field is optional - omit it or set it to null if you don't need custom tags
  • Feed-Specific: Each feed can have its own tag mappings

Tag Value Handling

Feed2Fedi handles different types of tag values automatically:

Single Values

Simple tags with a single value are converted to strings:

<websiteUrl>https://example.com/page</websiteUrl>

Becomes: "https://example.com/page"

Arrays of Strings

Multiple tags with the same name are joined with commas:

<category>News</category>
<category>Technology</category>
<category>Python</category>

Becomes: "News, Technology, Python"

Arrays of Dictionaries (Standard RSS Categories)

Standard RSS categories are stored as dictionaries with term fields:

<category>News</category>
<category>Technology</category>

Feedparser stores these in the tags field as [{"term": "News"}, {"term": "Technology"}]

Feed2Fedi extracts the term values and joins them: "News, Technology"

Missing Tags

If a mapped tag isn't found in the feed, the template variable is set to an empty string ("").

Examples

Example 1: Media Library Feed

{
  "url": "https://mediathek.example.com/feed.xml",
  "prefix": "Media Library",
  "tag_mappings": {
    "website_url": "websiteUrl",
    "duration": "duration",
    "categories": "tags",
    "rating": "contentRating"
  },
  "post_template": "{title}\n\nWatch here: {website_url}\n\nDuration: {duration}\nRating: {rating}\nCategories: {categories}"
}

With this RSS feed:

<item>
  <title>Documentary: The Future of Technology</title>
  <link>https://mediathek.example.com/videos/documentary.mp4</link>
  <websiteUrl>https://mediathek.example.com/watch/documentary</websiteUrl>
  <duration>PT1H30M</duration>
  <contentRating>PG-13</contentRating>
  <category>Documentary</category>
  <category>Technology</category>
  <category>Science</category>
</item>

The post would be:

Media Library - Documentary: The Future of Technology

Watch here: https://mediathek.example.com/watch/documentary

Duration: PT1H30M
Rating: PG-13
Categories: Documentary, Technology, Science

Example 2: Podcast Feed with Custom Tags

{
  "url": "https://podcast.example.com/feed.rss",
  "tag_mappings": {
    "episode_number": "episodeNumber",
    "season": "season",
    "transcript_url": "transcriptUrl",
    "guests": "guest"
  },
  "post_template": "S{season}E{episode_number}: {title}\n\nListen: {link}\nTranscript: {transcript_url}\nGuests: {guests}"
}

Example 3: News Feed with Multiple Categories

{
  "url": "https://news.example.com/feed.atom",
  "tag_mappings": {
    "topics": "category",
    "region": "region",
    "importance": "priority"
  },
  "post_template": "{title}\n\n{link}\n\nTopics: {topics}\nRegion: {region}\nPriority: {importance}"
}

Troubleshooting

Tag Not Found in Template

Problem: You get a KeyError when formatting the template.

Solution: Check that: 1. The tag name in tag_mappings matches the tag in the feed (case-insensitive) 2. The template variable name matches the key in tag_mappings 3. The tag actually exists in the feed (some feeds may not include all tags for all items)

Empty Values

Problem: Template variables are empty even though tags exist in the feed.

Solution: 1. Check the actual tag name in the feed XML 2. Remember that feedparser lowercases all tag names 3. Verify the feed actually contains the tag for the specific item

Array Values Not Joined Correctly

Problem: Array tags (like multiple categories) show as Python list representation instead of joined strings.

Solution: This usually means feedparser is storing the tags differently than expected. Check: 1. For standard RSS <category> tags, map to "tags" not "category" 2. The actual structure feedparser uses (enable icecream_enable for debugging)

Case Sensitivity Issues

Problem: Tag mappings don't work with mixed-case tag names.

Solution: Remember that feedparser lowercases all tag names. Map using lowercase:

"tag_mappings": {
  "website_url": "websiteurl",  // Not "websiteUrl" or "WebsiteUrl"
  "custom_tag": "customtag"     // Not "customTag" or "CustomTag"
}

Advanced Usage

Combining with Filters

Custom tags work alongside the existing filter system. You can use custom tags in filter checks by accessing them through item["params"] in custom filter implementations.

Dynamic Templates

You can create conditional templates using the new conditional syntax {[prefix]variable[suffix]}:

"post_template": "{title}{[ by ]author}\n\n{link}{[Duration: ]duration}{[Rating: ]rating}"

Where: - {[ by ]author} shows " by Author" only when author exists - {[Duration: ]duration} shows "Duration: 1h30m" only when duration exists - {[Rating: ]rating} shows "Rating: PG-13" only when rating exists

The prefix and suffix (inside square brackets) are only shown when the variable has a non-empty value. This syntax works with both standard variables ({title}, {author}, etc.) and custom tags mapped via tag_mappings.

Examples: - {[Title: ]title} → "Title: ActualTitle" or empty string - {[ / by]author} → " / by Author" or empty string - {author[ / by]} → "Author / by" or empty string - {[ by ]author[.]} → " by Author." or empty string

This is especially useful for templates like DESCRIPTION [PUBLISHER{[ / by]author}] which shows "DESCRIPTION [PUBLISHER / by Author]" when author exists, or just "DESCRIPTION [PUBLISHER]" when author is empty.

Nested Tags

Feed2Fedi currently doesn't support extracting values from nested XML structures. For complex nested tags, consider using a pre-processing script or requesting the feed provider to flatten the structure.