How do I get all pages of a certain type in PHP (in a plugin)?

Hey everybody,

I feel this should be simple, but I can’t make it work. In my Simple Events plugin, I would like to add the option to automatically remove past events. To this intent, I need a collection of pages of the Event type in PHP, so that I can then check the date of each page and delete it if it’s in the past.

I have tried a few things:

$collection = new Collection();
$collection->ofType('event')->order('header.start', 'asc');

returns an empty array.

$ev = $collection->ofType('event')->dateRange('01/01/1970', 'today');

empty as well.

$ev = $collection->setParams(['items' => '@root.descendants'])->ofType('event')->dateRange('01/01/1970', 'today');

empty again…

Seems to me like I’m not telling PHP to get me all pages in the right way, so all the filtering afterwards sifts through emptiness. :confused:

$pages = Grav::instance()['pages']->all();

returns all pages, which is nice and I will use that and iterate over it if I have to… but it seems to me there should be a simpler way? Can somebody help me out here?

Thanks for reading!

@Netzhexe, First a few notes on your attempts:

  • $collection = new Collection();
    
    This creates an empty collection, which means that all your samples based on ‘$collection’ will return an empty collection…
  • $collection->setParams(['items' => '@root.descendants'])
    
    According the sourcecode, setParams() only merges the given parameter with existing params for the collection and returns the collection. It does not create a new collection nor filters it.

Working samples on ‘Blog Site’ skeleton:

$pages = $this->grav['pages'];
$collection = $pages->all();  // size: 12
$collection = $pages->all()->ofType('item');  // size: 9
$collection = $pages->all()->ofType('item')->dateRange('2017-06-01', 'today');   // size: 7
$collection = $pages->getCollection(['items' => ['@taxonomy.tag' => 'photography']]); // size: 5

$page = $this->grav['page'];
$collection = $page->evaluate(['@taxonomy.tag' => 'photography']); // size: 5

Hope these examples give you a starting point for your own use-case…

Hello there, thank you so much! This really helped me understand things better, and I quickly built a lovely two line solution:

    $pages = $this->grav['pages'];
    $collection = $pages->all()->ofType('event')->dateRange('01/01/1970', 'today', 'header.start');

This gets me all pages of type event with their header.start set in the past. Exactly what I wanted. :+1:

@Netzhexe, It seems your code is a little off…

$pages = $this->grav['pages'];
$collection = $pages->all()->ofType('event')->dateRange($myvar);

This will select all pages of type ‘event’, with a date bigger than the value of$myvar .

By the way, any reason why you cannot use the standard frontmatter fields ‘publish_date’ and ‘unpublish_date’? When using these two frontmatter values in each event, Grav will automatically set published: false for a page when the current date falls outside of ‘publish_date’ and ‘unpublish_date’.

You can then filter the collection as follows:

$pages = $this->grav['pages'];
$collection = $pages->all()->ofType('event')->published();

Hey there,

that is a fair question! I wasn’t fully aware of the unpublish_date especially. The thing is, these events can potentially have an end date… also I have set up an extra tab with only the relevant fields to fill out, to make it easier for my clients who are very usually not tech savvy at all. I guess I could repurpose the publish_date field for the start date, but it might result in some confusion. And setting the unpublish_date just adds an extra field to fill out with the same data as the start date.

– But I might repurpose the unpublish_date field as the start date, now that would be something! That would save a bit of date checking in the templates. I will think about that for a bit; it sounds like a good idea for my use cases, but other people might have different requirements. Still, thank you for telling me about it! :slight_smile:

(And if you happen to know how to actually delete pages, that question is still unanswered…)