PodcastRSS.Channel (Podcast RSS v0.3.0)
View SourceLow-level API for creating podcast RSS channels.
This module provides direct control over all channel properties without any defaults.
For most users, PodcastRSS module provides a more convenient API with useful defaults.
The Channel struct contains the core RSS 2.0 required fields for a valid podcast feed.
Summary
Functions
Add an episode to the channel.
Set the podcast category.
Set the podcast category with subcategory.
Add a custom field to the channel.
Set the channel description.
Set the podcast cover image URL.
Set the podcast language.
Set the channel link (website URL).
Create a new empty channel.
Create a new episode that inherits this channel's namespaces.
Register a namespace for use in custom fields.
Set the canonical RSS feed URL.
Set the channel title.
Set the type of show.
Types
@type t() :: %PodcastRSS.Channel{ category: String.t() | {String.t(), String.t()} | nil, custom_fields: %{required(String.t()) => custom_field()}, description: String.t() | nil, episodes: [PodcastRSS.Episode.t()], feed_url: String.t() | nil, image_url: String.t() | nil, language: String.t() | nil, link: String.t() | nil, namespaces: %{required(String.t()) => String.t()}, title: String.t() | nil, type: :episodic | :serial | nil }
Functions
@spec add_episode(t(), PodcastRSS.Episode.t()) :: t()
Add an episode to the channel.
Episodes are prepended to the list, so the most recently added episode will appear first in the RSS feed.
Set the podcast category.
The category must be a valid Apple Podcasts category. This function validates the category against Apple's official category list.
Examples
iex> Channel.new() |> Channel.category("Technology")
%Channel{category: "Technology", ...}
Set the podcast category with subcategory.
Both the category and subcategory must be valid Apple Podcasts categories. This function validates both against Apple's official category list.
Examples
iex> Channel.new() |> Channel.category("Health & Fitness", "Nutrition")
%Channel{category: {"Health & Fitness", "Nutrition"}, ...}
Add a custom field to the channel.
Namespace Handling
If the field name contains a colon (e.g., "itunes:block"), the namespace prefix
must be registered first using register_namespace/3, or you can use the
:namespace_uri option for one-shot registration.
Options
:attributes- A map of XML attributes for the field (default: %{}):cdata- Whether to wrap content in CDATA (default: false):namespace_uri- URI for one-shot namespace registration (extracts prefix from field name)
Examples
# Method 1: Explicit registration (recommended for multiple fields)
channel = Channel.new()
|> Channel.register_namespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd")
|> Channel.custom_field("itunes:block", "no")
|> Channel.custom_field("itunes:explicit", "no")
# Method 2: One-shot registration (convenient for single usage)
channel = Channel.new()
|> Channel.custom_field("itunes:block", "no",
namespace_uri: "http://www.itunes.com/dtds/podcast-1.0.dtd")
|> Channel.custom_field("podcast:locked", "no",
namespace_uri: "https://podcastindex.org/namespace/1.0")
|> Channel.custom_field("itunes:explicit", "no") # Uses registered namespace
# Non-namespaced fields
channel
|> Channel.custom_field("language", "en-us")
|> Channel.custom_field("copyright", "© 2024 My Podcast", attributes: %{"type" => "legal"})
Set the channel description.
Set the podcast cover image URL.
Set the podcast language.
The language should be specified using ISO 639 language codes (e.g., "en-us", "de", "fr").
Set the channel link (website URL).
@spec new() :: t()
Create a new empty channel.
@spec new_episode(t()) :: PodcastRSS.Episode.t()
Create a new episode that inherits this channel's namespaces.
The returned episode will have all of the channel's registered namespaces available, allowing immediate use of namespace-prefixed custom fields without requiring explicit namespace registration.
Examples
episode = channel
|> Channel.new_episode()
|> Episode.title("Episode Title")
|> Episode.custom_field("itunes:duration", "00:15:30") # Works immediately
Register a namespace for use in custom fields.
This allows you to use namespaced field names (e.g., "itunes:block") without having to specify the namespace URI every time.
Examples
channel = Channel.new()
|> Channel.register_namespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd")
|> Channel.custom_field("itunes:block", "no") # Uses registered namespace
|> Channel.custom_field("itunes:explicit", "no") # Uses registered namespace
Set the canonical RSS feed URL.
Set the channel title.
Set the type of show.
The type of show determines how Apple Podcasts presents your episodes to listeners. According to Apple's iTunes specifications:
Episodic (default): Episodes are intended to be consumed without any specific order. Apple Podcasts will present newest episodes first and display the publish date of each episode. If organized into seasons, the newest season will be presented first - otherwise, episodes will be grouped by year published, newest first. For new subscribers, Apple Podcasts adds the newest, most recent episode in their Library.
Serial: Episodes are intended to be consumed in sequential order. Apple Podcasts will present the oldest episodes first and display the episode numbers of each episode. If organized into seasons, the newest season will be presented first and episode numbers must be given for each episode. For new subscribers, Apple Podcasts adds the first episode to their Library, or the entire current season if using seasons.
Examples
iex> Channel.new() |> Channel.type(:episodic)
%Channel{type: :episodic, ...}
iex> Channel.new() |> Channel.type(:serial)
%Channel{type: :serial, ...}