Sorting pages by "published on" date in the panel

Hello! I would greatly appreciate any help with this problem I’m currently facing: I have a “news index” page, which displays children “news” pages inside of it. I’ve sorted the news pages by num:published, and this works for when I call for them in my newsindex.php. However, in the panel itself, the news pages are still appearing in what seems to be alphabetical order, rather than in order of publication date.

My newsindex.yml looks like this:

title: News Index
  
num: published

options:
  title: false
  status: false
  move: false
  duplicate: false
  delete: false
  changeSlug: false

sections:
  drafts:
    headline: Drafts
    type: pages
    status: draft
    image:
      ratio: 5/4
      cover: true
    template: news
    info: "{{page.published}}, {{page.type}}"
  published:
    headline: Published
    type: pages
    layout: cards
    status: published
    image:
      ratio: 5/4
      cover: true
    template: news
    info: "{{page.published}}, {{page.type}}"
    min: 1
    search: true

And my news.yml looks like this:

title: News

num: published

columns:
    - width: 1/2
      sections:
          info:
              type: fields
              fields:
                  Title:
                      type: text
                      required: true
                  published:
                    label: Published on
                    type: date
                    default: now

So, in my newsindex.php, when I try to display all the news pages in reverse chronological order of their “published on” dates via $news = $page->children()->listed()->sortBy('published', 'desc'); , they sequence correctly.

However, in the panel itself, they appear in alphabetical order, despite the num: published stipulation. I also noticed that in the actual content folder itself, the news folders are being prepended with (1_, 2_, 3_) instead of the 0_ that they originally generated with (I’m not sure what caused this; I’ve tried manually renaming the folder back to all starting with 0_, but they’ve reverted to numerical sequencing again).

On a related note, is there a way to append the date set by “published on” to the url/folder name of a page? I’ve tried to do so through models/news.php, but what I have so far only prepends the date of when I set the page status from draft to published (so, in other words, “today”), rather than the “published on” date that I manually set, which could be years in the past:

<?php

use Kirby\Cms\Page;
use Kirby\Toolkit\Str;

class NewsPage extends Page
{
    public static function create(array $props): Page
    {
        // Get the 'published' field from content props
        $published = $props['content']['published'] ?? null;

        // Format the published date (make sure it's valid)
        if ($published) {
            $date = date('Y-m-d', strtotime($published));
        } else {
            // $date = date('Y-m-d'); // fallback to now if field is missing
        }

        // Append the date to the slug
        if (!empty($props['slug'])) {
            $props['slug'] = $props['slug'] . '-' . $date;
        }

        return parent::create($props);
    }
}

num: published published is invalid, see numbering schemes: Page blueprint | Kirby CMS. And also, this determines what number gets prepended to the page slug when a page is published.

Sorting in the Panel, however, is done in the section where you display them, in that case in newsindex.yml in the published section, see docs: Pages section | Kirby CMS

Thank you for your reply!

I modified my news.yml according to the Page blueprint documentation you shared, and now it’s prepending the custom “published on” date to the folder name correctly. Is there a way to also prepend this date to the page url itself?

title: News

num: '{{ page.published.toDate("Ymd") }}'

In my newsindex.yml, I also changed it to sortBy: published, which fixed my sorting issue in the panel! Though, perhaps this is redundant now that the folder names are being prepended with the published dates?

title: News Index
 
sections:
  published:
    headline: Published
    sortBy: published
    flip: true
    type: pages
    layout: cards
    status: published
    image:
      ratio: 5/4
      cover: true
    template: news
    info: "{{page.published}}, {{page.type}}"
    min: 1
    search: true

Possible, yes, but needs a combination of a page model that overwrites the url method and a route that catches these type of url and returns the correct page.

Okay! I started off with a page model, site/models/news.php, which I based off of this post.

<?php
use Kirby\Cms\Page;

class NewsPage extends Page {

    public static function create(array $props): Page
        {
            $page = new Page($props);
            $date = $page->published()->toDate('Ymd');

            $props['slug'] = $props['slug'] . '-' . $date;
            
            
            return parent::create($props);
        }
}

However, this appends the date when the page status is set from “Draft” to “Published” (e.g., “Today”), rather than the custom published on date that I’m retrieving in the news.yml via num: '{{ page.published.toDate("Ymd") }}'. Do you know how I can set it to append the correct date?

Also, could you say more about why I would need to use a route to return the correct page? Wouldn’t the URL with the date appended already be the correct page?

Ok, if you append the date to the slug, then you don’t need a route/url method. I was thinking of doing this purely virtually, without changing the slug.

For your approach, you don’t actually need the model, but can create the slug via the create option in the blueprint, if you add the date field to the create dialog.

create:
  slug: "{{ page.title.slug }}-{{ page.published.toDate('Ymd') }}"
  fields:
    - published

This worked, thank you!

Hi so actually, I have a couple followup questions I would appreciate your help with:

  1. If I later change the “published on” date for a news entry, is there a way to then automatically also update the slug to reflect the change? Or would I need to update that manually through “Change URL”?
  2. Is there a way to add a sort of help tagline in the news.yml page creation options under published, so as to inform users of the importance of setting the date upfront? I tried the following and some variations, but they all produced an error:
create:
  slug: "{{ page.title.slug }}-{{ page.published.toDate('Ymd') }}"
  fields:
    - published
    - help: "Make sure you pick the correct published date now, as this will be appended to the page url"
 

Well, the question is rather if that is a clever move, considering that indexed pages in Google Search etc. will stop working after you change the slug. Why do you need the date in the url in the first place if that date can be modifiable?

You cannot add help text there. If you add help text to the field itself, it will also appear in the dialog.

Oh! I didn’t think about that, thank you for pointing that out. I had thought that appending the date in the url would be helpful for situations where multiple entries share the same title but are published on different dates, e.g., “exhibition_20260617” and “exhibition_20020509.” Without appending the date in the URL, when I try to create a page that shares a title with another, the panel will forbid the action saying that a page with the same name / url already exists.

Thank you for your answer about the help text as well!

Right, but then again, at least from a SEO-perspective, naming multiple posts just “exhibition” doesn’t sound convincing or exciting?

Yeah, no disagreement there :sweat_smile: For more context, I’m doing this on behalf of a client who doesn’t really care about SEO and wants to spend as little time thinking about naming and file organization as possible. (They probably won’t literally name a page “exhibition,” but it’s very possible they could have multiple entries all titled “Talk at [Same Location]” or something similar.) So I’m just trying to think of ways to automatically remove any hiccups they might encounter when trying to publish a new page (in this case, reducing the possibility of duplicate names for entries), while also keeping some consistency in the naming system throughout.

Buuuut if it’s technically complicated to automatically update the slug after publishing, and this also does no favors for SEO, then maybe I can try to persuade the client to just be more strategic in their naming… :melting_face:

Anything is technically possible. You could rename the slug via a page.update:after hook, but if you do that while still on the page in the Panel, the current page will become invalid, and you have to go back and open the page again under its new link to continue editing.

Fair enough, if the website is not intended to reach as many people as possible.

Thank you for your reply! Hmmm, that also sounds like more trouble than my client likely would want … in which case I’ll just try to persuade them to name their pages with more pizzaz and specificity from the get-go. Thank you for all your help with this!