├── 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 |
15 |
16 | find($uri) ?>
17 | -
18 | title() ?>
19 | - date('j F Y') ?>
20 |
21 |
22 |
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 |
17 |
18 | find($uri); ?>
19 | - title() ?>
20 |
21 |
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 |
21 |
22 | find($uri); ?>
23 | - title() ?>
24 |
25 |
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 |
30 |
31 | find($uri); ?>
32 | -
33 | title(); ?>
34 | date('j F Y'); ?> - location(); ?>
35 |
36 |
37 |
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 |
--------------------------------------------------------------------------------