Feeds and sitemaps

Feeds and sitemaps built from your own content

cms.feed.rss() turns a list you already know how to build in Twig into a valid feed, and every collection can publish an XML sitemap from a card on its edit form.

A feed is a list of things, and you already know how to build a list in Twig. cms.feed.rss() and cms.feed.atom() take two arguments — the feed's own details and the items — so which objects go in and how each one looks stays in the template, where filter, sortBy and map already live. Escaping, CDATA, RFC-2822 dates and the Atom self reference are handled for you. There is no XML boilerplate to copy and no layout to extend: the call is the template.

Add a podcast block to the feed details and to each item and the same feed gains the iTunes and Podcast Index tags that Apple Podcasts, Spotify and the open directories read. Apple's requirements are enforced rather than merely documented — without author, owner, image, category, explicit and the feed's own self URL the feed refuses to render, and a category that is not on Apple's list fails with the closest matches named. If your show uses the built-in podcast and podcast-episode schemas, cms.feed.podcast() fills the whole block in from those collections.

There is also a template-free endpoint at /feed/rss/{collection}. It maps fields by name, which is both its convenience and its ceiling: it cannot build a title out of two fields, and it cannot run a Markdown field through the markdown filter, so subscribers receive the raw asterisks. Use it when a collection already has a usable title and a plain-text summary; build the feed in Twig when you need control over either.

Sitemaps work the other way round — no template at all. Every collection has a Sitemap card on its edit form: a master toggle, which property supplies lastmod, change frequency, priority, and include and exclude filters. Opted-in collections appear in the index served at /sitemap.xml and publish their own /sitemap/{collection}; builder pages get /sitemap/-pages, with dynamic routes skipped because they cannot be enumerated. Collections that were never opted in are omitted from the index and return 404, so a private collection is not advertised by its own absence.

One rule ties both sitemaps together: any record whose SEO card has No Index turned on is skipped. A crawler told not to index a URL and then handed that same URL in a sitemap has received two contradictory instructions, so Total CMS only ever sends one.

What you get

The call is the template

Pass feed details and a mapped list. Escaping, CDATA, RFC-2822 dates and the Atom self link are handled, so there is no XML to hand-write.

Podcast tags included

A podcast block adds the iTunes and Podcast Index tags. Apple's required keys are validated, so a feed that would be rejected fails at render instead.

A no-template shortcut

/feed/rss/{collection} publishes a feed with no template at all, mapping fields by name — good enough when the collection already has a plain-text summary.

Sitemaps opt in

A card on the collection edit form sets the toggle, date property, frequency, priority and filters. Collections left off are omitted and return 404.

No Index wins

A page or object marked No Index on its SEO card is skipped by the sitemap too, so crawlers never get contradictory instructions.

In practice

One snippet

{{ cms.feed.rss(
	{
		title:       'Total CMS Releases',
		link:        cms.builder.canonicalUrl('changelog'),
		self:        cms.builder.canonicalUrl('changelog-rss'),
		description: 'New capabilities, refinements, and fixes.',
	},
	cms.collection.objects('changelog')|sortBy('date')|reverse|map(e => {
		title:   e.version ~ ' — ' ~ e.title,
		link:    cms.collection.canonicalObjectUrl('changelog', e),
		id:      e.id,
		date:    e.date,
		content: e.changelog|markdown,
	})
) }}

The entire template for a feed — a builder page whose route ends in /rss serves this as application/rss+xml.

FAQ

Common questions

Do I need a template to publish a feed?

Not always. /feed/rss/{collection} works with no template, mapping fields by name. Build the feed in Twig when you need a composed title or need to run a Markdown field through the markdown filter.

Can I publish a podcast feed?

Yes. A podcast block on the feed details and on each item adds the iTunes and Podcast Index tags. With the built-in podcast and podcast-episode schemas, cms.feed.podcast() fills that block in from the collections themselves.

Why is my collection missing from the sitemap?

Sitemaps are opt-in per collection. Until Include in Sitemap is turned on in the collection's Sitemap card, the collection is left out of the index and /sitemap/{collection} returns 404 — deliberately, so disabled collections stay off the public surface.

How do I keep one page or record out?

Turn on No Index on that record's SEO card and both sitemaps skip it. For collections other than builder pages, the schema's index array has to include seo, because the sitemap builders read the collection index rather than each object file.