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

Installation

Add podcast_rss to your list of dependencies in mix.exs:

def deps do
  [
    {:podcast_rss, "~> 0.1.0"}
  ]
end

Quick 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:

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:

Testing

Run the test suite:

mix test

Documentation

Generate documentation:

mix docs

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Write tests for your changes
  4. Ensure all tests pass (mix test)
  5. Format your code (mix format)
  6. Commit your changes (git commit -am 'Add some feature')
  7. Push to the branch (git push origin my-new-feature)
  8. Create a new Pull Request

License

This project is licensed under the MIT License.

Acknowledgments