├── templates ├── bydate-basic.php ├── bydate-years.php ├── bydate-months.php └── bydate-options.php ├── plugins └── bydate.php └── README.md /templates/bydate-basic.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 |

Sorry, nothing to show.

11 | 12 | 13 | 14 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /templates/bydate-years.php: -------------------------------------------------------------------------------- 1 | 'year')); 6 | ?> 7 | 8 | 9 | 10 |

Sorry, nothing to show.

11 | 12 | 13 | 14 | $uris): ?> 15 |

16 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /templates/bydate-months.php: -------------------------------------------------------------------------------- 1 | 'month')); 6 | ?> 7 | 8 | 9 | 10 |

Sorry, nothing to show.

11 | 12 | 13 | 14 | $months): ?> 15 | 16 |

17 | $uris): ?> 18 | 19 |

20 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /templates/bydate-options.php: -------------------------------------------------------------------------------- 1 | '2012-12-31', 9 | 'min' => '2012-01-01', 10 | 'order' => 'asc', 11 | ); 12 | 13 | // If we want all pages with dates in the site, we can do: 14 | $eventUris = pagesByDate($pages, $myOptions); 15 | 16 | // If instead we want to limit ourselves to content in a "content/events" folder… 17 | // (We can't just use $pages->find('events') because it doesn't return a set of pages) 18 | // $src = $pages->find('events')->children(); 19 | // $events = pagesByDate($src, $myOptions); 20 | // ); 21 | ?> 22 | 23 | 24 | 25 |

Sorry, no event planned yet.

26 | 27 | 28 | 29 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /plugins/bydate.php: -------------------------------------------------------------------------------- 1 | c::get('bydate.order', 'desc'), 16 | 'limit' => c::get('bydate.limit', 100), 17 | 'offset' => c::get('bydate.offset', 0), 18 | 'max' => c::get('bydate.max', time()), 19 | 'min' => c::get('bydate.min', 0), 20 | 'group' => c::get('bydate.group', 'none') 21 | ); 22 | $options = is_array($userOptions) ? array_merge($defaults, $userOptions) : $defaults; 23 | 24 | // Normalize some options 25 | if (!is_int($options['limit'])) $options['limit'] = $defaults['limit']; 26 | if (!is_int($options['offset'])) $options['offset'] = $defaults['offset']; 27 | if (is_string($options['max'])) $options['max'] = strtotime($options['max']); 28 | if (is_string($options['min'])) $options['min'] = strtotime($options['min']); 29 | 30 | // Order source content 31 | $source = $source->sortBy('date', $options['order']); 32 | 33 | // We'll return $results in the end 34 | $temp = array(); 35 | $results = array(); 36 | 37 | // 1. Validate each page based on status metadata and integer dates 38 | foreach ($source as $page) { 39 | $status = $page->status() ? strtolower($page->status()) : 'unknown'; 40 | $date = $page->date(); // false when no date, integer timestamp otherwise 41 | if ( 42 | $status !== 'archive' && $status !== 'draft' && $status !== 'ignore' 43 | && $date !== false && $date >= $options['min'] && $date <= $options['max'] 44 | ) { 45 | $temp[] = $page; 46 | } 47 | } 48 | 49 | // 2. Apply offset/limit on the validated pages 50 | $temp = array_slice($temp, $options['offset'], $options['limit']); 51 | 52 | // 3. Populate $results with page URIs 53 | 54 | if ($options['group'] == 'year' || $options['group'] == 'month') { 55 | // Grouping by year, or by year then by month 56 | foreach ($temp as $page) { 57 | $year = $page->date('Y'); 58 | $month = $page->date('m'); 59 | if (!array_key_exists($year, $results)) { 60 | $results[$year] = array(); 61 | } 62 | if ($options['group'] == 'year') { 63 | $results[$year][] = $page->uri(); 64 | } 65 | if ($options['group'] == 'month') { 66 | if (!array_key_exists($month, $results[$year])) { 67 | $results[$year][$month] = array(); 68 | } 69 | $results[$year][$month][] = $page->uri(); 70 | } 71 | } 72 | return $results; 73 | } 74 | else { 75 | // Returning URIs from page objects in $temp as-is. 76 | foreach ($temp as $page) { 77 | $results[] = $page->uri(); 78 | } 79 | return $results; 80 | } 81 | } 82 | 83 | ?> 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DEPRECATED: Kirby bydate plugin 2 | =============================== 3 | 4 | I originally made this plugin because Kirby 1 had slightly limited tools for filtering page collections, sorting efficiently by date, getting all descendants of a page, etc. This is not the case anymore in Kirby 2.x, and using Kirby’s native API is arguably easier than using this plugin, so consider it deprecated. 5 | 6 | In Kirby 2.x you have all the tools you need to do the kind of filtering that this plugin does. 7 | 8 | See: https://getkirby.com/docs 9 | And in particular: https://getkirby.com/docs/solutions/filtering 10 | 11 | --- 12 | 13 | ## Legacy documentation 14 | 15 | Kirby plugin that helps working with dated pages, such as blog posts. Provides a pagesByDate function for your templates. Tested on Kirby 1 and 2. 16 | 17 | ### Install 18 | 19 | 1. Get [bydate.php](plugins/bydate.php) and put it in the `site/plugins` folder of your Kirby-powered site. 20 | 21 | 2. Optional: [Download or copy example templates](templates/). Some can be included as-is in your templates, but you’ll probably want to copy the relevant examples and customize them in your own templates. 22 | 23 | ### pagesByDate function 24 | 25 | Function which returns an array of Kirby page URIs, or nested arrays when grouping by year or month. 26 | 27 | The feature set for this function is: 28 | 29 | - *Only* returns URIs for pages with a valid `date` or `Date` metadata field. 30 | - Set limit dates, and by default do not return pages with a future date. 31 | - … Which allows you to set pages to be [published in the future](#future-publishing). 32 | - Exclude pages with a `status` metadata key set to either `draft`, `archive` or `ignore`. Pages with a different `status` or with no `status` metadata will be included. 33 | - Option to group by year or year then month, for instance if you want to ouput titles with years or months before the relevant posts. 34 | - Use `limit` and `offset` options to limit the number of results and perhaps do some semi-manual pagination (sorry, no Kirby pagination object). 35 | 36 | #### Usage 37 | 38 | The `pagesByDate` function may take two arguments: 39 | 40 | 1. Source (required): A kirby Pages object which represents the set of pages to work with. Use `$pages` for all pages in the site. Or use any Kirby Pages object, such as the ones returned by `$page->children()` and `$page->siblings()`. 41 | 42 | 2. Options (optional): An array of options. [See below for available options](#option-documentation). You can also set options for this plugin [in your Kirby config files](#set-options-in-config). 43 | 44 | If you want to work on all child pages of a given folder, you could use: 45 | 46 | ```php 47 | $postUris = pagesByDate($pages->find('myfolder')->children()); 48 | ``` 49 | 50 | Note that we need to use `->children()`, since `$pages->find()` will return a unique page, and we need a set of pages instead. 51 | 52 | To set some custom options: 53 | 54 | ```php 55 | $postUris = pagesByDate($pages, array('order'=>'asc')); 56 | ``` 57 | 58 | See the option documentation below for available options. 59 | 60 | #### How to use in templates 61 | 62 | Here's a basic example: 63 | 64 | ```php 65 | 66 | find($postUri); ?> 67 |

68 | title(); ?> 69 | - date('j F Y'); ?> 70 |

71 | 72 | ``` 73 | 74 | (Make sure you put `bydate.php` in your `site/plugins` folder first.) 75 | 76 | See complete examples: 77 | 78 | - [Simple example](templates/bydate-basic.php) 79 | - [Example with custom options](templates/bydate-options.php) 80 | - [Example with results grouped by year](templates/bydate-years.php) 81 | - [Example with results grouped by month](templates/bydate-months.php) 82 | 83 | #### Recursive listing 84 | 85 | Right now if you’re trying to list all dated pages from different folders and at different levels, it can prove a bit tricky in Kirby 1. `pagesByDate()` used to have a `recursive` option but it was a hack with several issues so I removed it. 86 | 87 | In Kirby 2, you should be able to use `$pages->index()`: 88 | 89 | ```php 90 | // URIs for all pages in your site 91 | $postUris = pagesbyDate( $pages->index() ); 92 | 93 | // URIs for all child and descendant pages in a 'blog' folder 94 | $postUris = pagesbyDate( $pages->get('blog')->index() ); 95 | ``` 96 | 97 | #### Exclude pages with `status` metadata 98 | 99 | If you want to exclude pages from what `pagesByDate()` returns, you can add a `Status` metadata field to your pages with any of those values: 100 | 101 | - `draft` 102 | - `archive` 103 | - `ignore` 104 | 105 | These three values are hardcoded in bydate.php. In a future version I might offer an option to change them. 106 | 107 | Note that Kirby 2 also has `$pages->filter()` and `$pages->filterBy()` which could allow you to do the same thing with any metadata key or value(s). 108 | 109 | #### Future publishing 110 | 111 | If you write a post with a date in the future: 112 | 113 | Title: Is HTML5 Ready Yet? 114 | ---- 115 | Date: 2020-04-01 116 | ---- 117 | Text: … 118 | 119 | With default options, `pagesByDate` will not return this page's URI until the current server date is beyond the page’s date (even if only by a few seconds). One gotcha: if you only specify a date and not the exact publishing time, this defaults to 00:00 in the morning. If you want your post to go live at 8:00 in the morning, you could use `2020-04-01 8:00`. 120 | 121 | Warning: the function currently doesn’t manage time zones in any way! 122 | 123 | Let’s be clear about posts “going live”: we only mean that any place you used `pagesByDate` with the default `max` setting will not show a page with a date in the future. So the lists of posts, archives, and RSS/Atom feeds in your site all use `pagesByDate`, that makes your content almost invisible. Almost, because you can still see it if you go to the post’s own URL (unless you write some date-based logic of your own in the template that handles showing your posts). 124 | 125 | #### Group results by year 126 | 127 | ```php 128 | $postUris = pagesByDate($pages, array('group'=>'year')); 129 | ``` 130 | 131 | will return an array of page URIs that may look like (pseudocode): 132 | 133 | [ 134 | "2013" => ["blog/some-post", "work/recent-project", "blog/another-one"], 135 | "2012" => ["work/older-project", "blog/yet-another-post"], 136 | … 137 | ] 138 | 139 | where each item in the child arrays is a Kirby page URI. 140 | 141 | See [Example with results grouped by year](templates/bydate-years.php) for relevant templating code. 142 | 143 | #### Group results by month 144 | 145 | ```php 146 | $postUris = pagesByDate($pages, array('group'=>'month')); 147 | ``` 148 | 149 | will return an array of page URIs that may look like (pseudocode): 150 | 151 | [ 152 | "2013" => [ 153 | "05" => ["blog/some-post", "work/recent-project"], 154 | "03" => ["blog/another-one"] 155 | ], 156 | "2012" => [ 157 | "11" => ["work/older-project"], 158 | "01" => ["blog/yet-another-post"] 159 | ], 160 | … 161 | ] 162 | 163 | where each item in the deepest arrays is a Kirby page URI. 164 | 165 | See [Example with results grouped by month](templates/bydate-months.php) for relevant templating code. 166 | 167 | #### Set options in config 168 | 169 | We're using the same option keys, prefixed with 'bydate.' 170 | 171 | For instance, adding these lines to your `site/config/config.php` would set the same thing as the default values: 172 | 173 | ```php 174 | c::set('bydate.order', 'desc'); 175 | c::set('bydate.limit', 100); 176 | c::set('bydate.offset', 0); 177 | c::set('bydate.max', time()); 178 | c::set('bydate.min', 0); 179 | c::set('bydate.group', 'none'); 180 | ``` 181 | 182 | Values set in an option array passed to the `pagesByDate` will take precedence over site config. 183 | 184 | ### Option documentation 185 | 186 | order: Sort order: 'asc' (oldest first) or 'desc' (newest first). 187 | Defaults to 'desc'. 188 | 189 | limit: Integer. Max number of posts to return. 190 | Defaults to 100. 191 | 192 | offset: Integer. Number of posts to skip. Use this and limit for 193 | manual pagination. 194 | Defaults to 0. 195 | 196 | max: Integer (timestamp) or string (date). 197 | Posts from after this date won't be included. 198 | Defaults to the current timestamp (time()). 199 | 200 | min: Integer (timestamp) or string (date). 201 | Posts from before this date won't be included. 202 | Defaults to UNIX epoch time (0 or roughly '1970-01-01'). 203 | 204 | group: Should the posts be grouped by year or month? 205 | When grouped by year, we will return an array of arrays, 206 | each child array containing the URI strings for a given year, 207 | with the year as the child array's key (e.g. '2011'). 208 | When grouped by month, we will group by year first, then 209 | by month, so that means child and grandchild arrays. 210 | Month arrays have keys looking like '01', '02', …, '12'. 211 | Use var_dump to look at the resulting array's structure, 212 | or look at the templating examples. 213 | --------------------------------------------------------------------------------