class

Hwaro::Content::Seo::Feeds

Inherits Reference < Object

Constants

DEFAULT_FILENAMES = {"rss" => "rss.xml", "atom" => "atom.xml", "json" => "feed.json"}

[feeds] type values the writer knows, and the file each one publishes when filename is left empty.

FEED_TEMPLATE_KEYS = {"rss" => "rss.xml", "atom" => "atom.xml", "json" => "feed.json"}

User template keys that override the built-in feed output, per feed type. templates/rss.xml.jinja loads under the key "rss.xml" (template keys strip only the final template extension).

Class methods

build_template_context(pages : Array(Models::Page), config : Models::Config, feed_type : String, filename : String, is_text : Bool, feed_title : String, base_path : String, language : String | Nil, *, kind : String, section_url : String | Nil, taxonomy : String | Nil, term : String | Nil) : Hash(String, Crinja::Value)

Template context for user feed templates. Everything a feed body needs is precomputed here with the same helpers the programmatic generators use (URLs absolute + percent-encoded, dates normalized and preformatted), so a template never has to re-derive feed semantics — XML escaping via the xml_escape filter is the template author's job.

Source
dedupe_by_output_url(pages : Array(Models::Page)) : Array(Models::Page)

Keep the page the build actually wrote when two pages collide on one URL (path-sort-first winner, matching render.cr#compute_output_url_winners). Used for main, section, language, and taxonomy feeds so no surface advertises a loser.

A page the build refused to write at all (output_suppressed: a URL that traverses out of the output directory, a collision loser already flagged upstream) is dropped first — its URL is unique, so the URL dedupe alone let /posts/../../escape/ into every section and taxonomy feed while sitemap/search/llms correctly omitted it.

Source
feed_language(config : Models::Config, language : String | Nil) : String | Nil

The language a feed declares (RSS <language>, Atom xml:lang, JSON language): a non-default language's code. Default-language feeds declare none, like the main site feed, so section and term feeds under /ko/ say ko exactly as /ko/rss.xml does.

Source
feed_output_dir_for(output_dir : String, url : String) : String | Nil

Safe subdirectory under output_dir for a section/lang/taxonomy feed. Returns nil (and warns) when the URL escapes the public tree.

Source
generate(pages : Array(Models::Page), config : Models::Config, output_dir : String, verbose : Bool = false, skip_if_unchanged : Bool = false, templates : Hash(String, String) | Nil = nil, renderer : Renderer | Nil = nil) : Array(String)

Returns every feed file this build publishes: the ones written, or, when skipped as unchanged, the ones already on disk (published_outputs).

Source
generate_atom(pages : Array(Models::Page), config : Models::Config, filename : String, is_text : Bool, feed_title : String, base_path : String, language : String | Nil = nil) : String
Source
generate_json(pages : Array(Models::Page), config : Models::Config, filename : String, is_text : Bool, feed_title : String, base_path : String, language : String | Nil = nil) : String

JSON Feed 1.1 (https://www.jsonfeed.org/version/1.1/). Same inputs and helpers as the RSS/Atom writers: summary mirrors RSS <description>, and the body follows Atom's <content> choice — content_html for full HTML, content_text when full_content is off or truncate > 0 (an item must carry one of the two).

Source
generate_rss(pages : Array(Models::Page), config : Models::Config, filename : String, is_text : Bool, feed_title : String, base_path : String, language : String | Nil = nil) : String
Source
process_feed(pages : Array(Models::Page), config : Models::Config, output_dir : String, custom_filename : String, feed_title : String, base_path : String = "", verbose : Bool = false, language : String | Nil = nil, templates : Hash(String, String) | Nil = nil, renderer : Renderer | Nil = nil, kind : String = "main", section_url : String | Nil = nil, taxonomy : String | Nil = nil, term : String | Nil = nil) : String
Source
published_outputs(pages : Array(Models::Page), config : Models::Config, output_dir : String) : Array(String)

Every main, section and per-language feed file the current config and page set publish. The builder claims these whether generate wrote them or skipped as unchanged, so a warm --cache build (or a serve rebuild) removes a feed an earlier config published: [feeds] disabled, generate_feeds turned off on a section, a language's generate_feed dropped, a renamed feed file. Planned by the same each_feed the writer walks, so the two cannot drift. Taxonomy feeds are claimed by the taxonomy generator.

Source
safe_feed_filename(custom_filename : String, feed_type : String) : String

Config feeds.filename and empty custom names resolve to a single basename under the feed's output directory.

Source

Nested types