Per-feed content filters: HTML sanitization, category allow/block lists, image stripping, and summary truncation.
The sanitizer (sanitize_html: true, the default) removes the tags listed
in drop_tags, the attributes listed in drop_attrs, every on* event
handler attribute, and any URL-bearing attribute (href, src, srcset,
action, formaction, poster, xlink:href) whose URL
scheme is not http, https, or mailto (relative URLs are kept).
It is a defense-in-depth measure for feed content, not a guarantee — if
you render feed HTML in a security-sensitive context, consider pairing it
with a dedicated sanitizer such as html_sanitize_ex.
To delegate sanitization entirely, configure an Exoplanet.Sanitizer
adapter:
config :exoplanet, sanitizer_adapter: MyApp.FeedSanitizerWhen set (and sanitize_html is true), the adapter replaces the built-in
sanitize step. strip_images and excerpt_length still apply, after the
adapter. See Exoplanet.Sanitizer.
Category filters
allow_categories accepts a list of strings or :all (no allowlist
constraint). block_categories accepts a list of strings or :none (no
blocklist constraint). The empty list [] is equivalent to :all /
:none respectively and remains supported. Atoms are normalized to []
internally; see normalize_categories/1. The inverses
(allow_categories: :none, block_categories: :all) raise
ArgumentError — drop the feed entirely if you want zero posts.
Summary
Functions
Applies the merged filter map to a list of Exoplanet.Post structs.
Built-in default filter map. Used by Exoplanet.Config as the baseline
for default_filters and as the starting point that user-supplied
default_filters are merged onto.
Merges a per-feed filter map onto a default filter map.
Normalizes the category-filter atoms in a filter map.
Types
Functions
@spec apply([Exoplanet.Post.t()], t()) :: [Exoplanet.Post.t()]
Applies the merged filter map to a list of Exoplanet.Post structs.
Returns the filtered list. Posts dropped by category filters are removed
entirely. The sanitize_html and strip_images filters modify each post's
:body and :summary. The excerpt_length filter modifies only :summary.
Sanitization runs first, then image stripping, then excerpt generation.
When both built-in HTML filters are enabled they share a single tree walk;
with a sanitizer_adapter configured, sanitization and image stripping run
as separate passes.
@spec defaults() :: t()
Built-in default filter map. Used by Exoplanet.Config as the baseline
for default_filters and as the starting point that user-supplied
default_filters are merged onto.
Merges a per-feed filter map onto a default filter map.
allow_categories and block_categories REPLACE the default value when
the per-feed map sets them to a list. Other keys override field-by-field.
Per-feed keys set to nil leave the default in place.
Defaults are normalized first, then the merged result is normalized,
so callers may use allow_categories: :all or block_categories: :none
on either side. Invalid atoms (allow_categories: :none,
block_categories: :all, or any unrecognized atom) raise ArgumentError.
Normalizes the category-filter atoms in a filter map.
Replaces allow_categories: :all with [] and block_categories: :none
with []. Lists pass through unchanged. Keys that are missing stay
missing (no defaults are inserted). Raises ArgumentError for any
other atom value, including allow_categories: :none and
block_categories: :all (both nonsensical — drop the feed instead).
Called automatically by merge/2 and Exoplanet.Config.from_file/1,
so consumers rarely need to invoke it directly.