RFC 3339 DateTime in Kirby for Atom feed?

I’m trying to build my own atom feed from scratch via a template and I’ve pretty much gotten everything to pass validation except for the timestamps.

Here is a screenshot of the Atom validator:

It says the date must be in RFC-3339 format which looks like this:

1985-04-12T23:20:50.52Z

From my research, PHP has predefined constants:

date(DATE_RFC3339);
date(DATE_ATOM);

I just can’t figure out how to display this format in Kirby.

I also have my atom feed setup at /feed, but it would be nice if I could have it work as /feed.atom. Is there a straightforward way to add the .atom extension at the end for this url?

Here’s my code for this page in case it helps:

Appreciate any help! :folded_hands:

Welcome to the Kirby forum!

<?= $item->date()->toDate(DATE_RFC3339); ?>

See also: $field->toDate() | Kirby CMS

In future posts, please post code as code snippets between three backticks, like so:

.

Thank you!

Thank you! I will use the code tag next time. I did try your solution initially and thought it wasn’t working because this is the result I get:

<updated>2025-0-28\</updated>

I’m assuming I need to do something else to deal with the escaped character?

Hoping for an answer on this one! :folded_hands:

Hm, don’t know and can’t test, because just on phone until Monday

Can you try it with "Y-m-d\\TH:i:sP"? The toDate method expects a string so maybe that’s what fails when passing the constant.

I think I know why this is happening. I have a date set for my posts, but no time. :man_facepalming: I will try to get that sorted and report back. Sorry!

Ok I added the time as well, but still having the same issue.

This is now in my txt files:

Date: 2025-04-04 00:00:00

Here are the pages I’m filtering for the atom feed:

<?php
	$blog = $pages->find('blog')->children()->listed()->sortBy(function ($page){return 	$page->date();}, 'asc')->limit(10);
	$kirby->response()->type('application/atom+xml');
?>

If I just use this:

<updated><?= $blog->last()->date(); ?></updated>

Here is the output:

<updated>2025-04-04 00:00:00</updated>

If I do this (or : “Y-m-d\TH:i:sP”)

<updated><?= $blog->last()->date()->toDate(DATE_RFC3339); ?></updated>

Here is the output:

<updated>2025-0-4\</updated>

Hm, I suspect you are using the date.handler option with the intl value, which then makes Kirby use PHP’s Intl extension for internationalized date formatting. This would explain why some parts of the date are formatted (with different values) and the backslash survives the formatting into the output.

You can either switch to the basic PHP date handler, or use the following format with intl:

<updated><?= $blog->last()->date()->toDate("y-MM-dd'T'HH:mm:ssxxx"); ?></updated>

You can find more about this in the reference:

1 Like

That seems to be it! Thank you!

Date formatting

I’m using this in my Atom and JSON feed templates:

$published = $page->content()->get('published')->toDate();
echo date(DateTimeInterface::W3C, $published);

The DateTimeInterface::W3C constant is defined like this:

public const string W3C = "Y-m-d\\TH:i:sP";

.atom extension in URL

I also have my atom feed setup at /feed, but it would be nice if I could have it work as /feed.atom. Is there a straightforward way to add the .atom extension at the end for this url?

You can use Content representations.

On my own site I’ve implemented this by having a content/feed/feed.txt page, and then creating the following templates:

  • site/templates/feed.php ← not used but required!
  • site/templates/feed.json.php ← renders a JSON Feed
  • site/templates/feed.xml.php ← renders an Atom feed

The feed.php template is empty:

<?php
/**
 * This template has to exist so that the content representation templates
 * (feed.xml.php and feed.json.php) are used by Kirby.
 * More info: https://getkirby.com/docs/guide/templates/content-representations
 */
  • Loading /feed.json will render the content/feed/feed.txt page with the site/templates/feed.json.php template.
  • Loading /feed.xml will render the content/feed/feed.txt page with the site/templates/feed.xml.php template. (I believe you could use any extension, so .atom instead of .xml might work too.)
  • Loading /feed will render the content/feed/feed.txt page with the site/templates/feed.php template, i.e. it will render a blank page. You could create a redirect in your site’s routes or even from the template itself to redirect to /feed.atom instead.

I think I’m using the default text/xml content-type for /feed.xml, but I could add some code to send a content-type: application/atom+xml header instead.

Adding to that: You can also create a feed.atom.php template (instead of feed.xml.php) to create a content representation at /feed.atom.

To set the content type header, use:

$kirby->response()->type('application/atom+xml');

See: