PodcastRSS
An Elixir library for generating podcast RSS feeds in RSS 2.0 format with iTunes and Podcast Index namespace support.
PodcastRSS provides a pipeline-friendly API for creating podcast feeds with sensible defaults and support for modern podcast features. It focuses on simplicity and readability while supporting all the core requirements for podcast distribution.
Features
- RSS 2.0 Compliant - Generates valid RSS feeds for podcast distribution
- iTunes Support - Built-in support for iTunes podcast tags
- Podcast Index - Support for modern Podcast Index namespace features
- Pipeline API - Clean, chainable functions for easy feed construction
- Fast XML Generation - Uses Saxy for efficient XML serialization
Installation
Add podcast_rss to your list of dependencies in mix.exs:
def deps do
[
{:podcast_rss, "~> 0.1.0"}
]
endQuick Start
alias PodcastRSS.Episode
# Create a podcast feed
channel = PodcastRSS.new()
|> PodcastRSS.title("Retro Gaming Chronicles")
|> PodcastRSS.link("https://example.com")
|> PodcastRSS.description("Exploring the golden age of video games")
|> PodcastRSS.self_link("https://feeds.example.com/rss")
|> PodcastRSS.image("https://example.com/cover.png")
|> PodcastRSS.language("en-us")
|> PodcastRSS.category("Technology")
# Create an episode (inherits channel namespaces)
episode = channel
|> PodcastRSS.new_episode()
|> Episode.title("The Birth of the NES")
|> Episode.description("How Nintendo revolutionized home gaming in 1985")
|> Episode.enclosure("https://example.com/episodes/nes-birth.mp3", 45678901, "audio/mpeg")
|> Episode.guid("retro-001-nes-birth")
|> Episode.chapter(0, "Introduction")
|> Episode.chapter(180, "Main Topic", url: "https://example.com")
|> Episode.chapter(365, "Bye")
feed_xml = channel
|> PodcastRSS.add_episode(episode)
|> PodcastRSS.to_xml()
IO.puts(feed_xml)Usage
Creating a Channel
The PodcastRSS.new/0 function creates a channel with useful defaults:
- Pre-registers common namespaces (iTunes, Podcast Index, Atom)
- Sets language to "en-us"
- Adds iTunes block and complete tags with sensible defaults
channel = PodcastRSS.new()
|> PodcastRSS.title("My Podcast")
|> PodcastRSS.description("A fascinating podcast about interesting topics")
|> PodcastRSS.link("https://example.com")
|> PodcastRSS.self_link("https://feeds.example.com/rss")
|> PodcastRSS.image("https://example.com/cover.jpg")Adding Episodes
Episodes are created using PodcastRSS.new_episode/1 which inherits the channel's namespaces:
alias PodcastRSS.Episode
episode = channel
|> PodcastRSS.new_episode()
|> Episode.title("Episode 1: Getting Started")
|> Episode.description("Our first episode covers the basics")
|> Episode.enclosure("https://cdn.example.com/episode1.mp3", 98765432, "audio/mpeg")
|> Episode.guid("episode-001")
channel = PodcastRSS.add_episode(channel, episode)
Episodes created this way automatically inherit the channel's registered namespaces, allowing immediate use of namespace-prefixed custom fields like itunes:duration or podcast:soundbite.
Categories
Set iTunes categories and subcategories:
channel = PodcastRSS.category(channel, "Arts")
# or with subcategory
channel = PodcastRSS.category(channel, "Arts", "Design")Custom Fields and Namespaces
Add custom fields for extended functionality:
channel = PodcastRSS.new()
|> PodcastRSS.register_namespace("dc", "http://purl.org/dc/elements/1.1/")
|> PodcastRSS.custom_field("dc:creator", "John Doe")Low-Level API
For more control, use the PodcastRSS.Channel module directly:
alias PodcastRSS.Channel
channel = Channel.new() # No defaults
|> Channel.title("My Podcast")
|> Channel.description("Custom channel")Architecture
PodcastRSS follows a clear separation between high-level convenience and low-level control:
PodcastRSS- High-level "batteries included" API with sensible defaultsPodcastRSS.Channel- Low-level channel API for direct controlPodcastRSS.Episode- Episode/item managementPodcastRSS.XML- XML generation using Saxy
Testing
Run the test suite:
mix testDocumentation
Generate documentation:
mix docsContributing
- Fork the repository
-
Create your feature branch (
git checkout -b my-new-feature) - Write tests for your changes
-
Ensure all tests pass (
mix test) -
Format your code (
mix format) -
Commit your changes (
git commit -am 'Add some feature') -
Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
License
This project is licensed under the MIT License.
Acknowledgments
- Built with Saxy for fast XML generation
- Inspired by podcast RSS standards and iTunes podcast requirements
- Supports modern Podcast Index namespace features