From 09e10d16ea78b01fafd8ca2a48156edea845ce5e Mon Sep 17 00:00:00 2001 From: Ole Vik Date: Thu, 17 Oct 2019 13:52:37 +0200 Subject: [PATCH] [RFR] Iterable Taxonomy (#2690) * Allow naive iterables in Taxonomy Currently, Taxonomy only supports one-level arrays in a Page's Taxonomy, so this works: ``` ---yaml title: XMark Test taxonomy: categories: academic tags: [xmark, link] author: - "Ole Vik" - "Ole Vik" - "Ole Vik" --- ``` But this does not: ```yaml --- title: XMark Test taxonomy: categories: academic tags: [xmark, link] author: - "Ole Vik" - "Ole Vik" - "Ole Vik" - name: "Ole Vik" email: "git@olevik.net" url: "https://olevik.me" --- ``` The change allows another level, to accommodate cases where the Taxonomy contains arrays of strings or hashes. This could potentially be expanded to recursively allow any amount of nesting of Taxonomies. In both the naive and expanded case, are there implications for finding and filtering by Taxonomies? I've not checked if that recurses through values as I'm not currently at my desktop, but I imagine more changes would be necessary. * Recursively iterate taxonomy fields * Accommodate findTaxonomy() by reducing to dot-notation * Remove superfluous conditional --- system/src/Grav/Common/Taxonomy.php | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php index e3236472b..84ac2680b 100644 --- a/system/src/Grav/Common/Taxonomy.php +++ b/system/src/Grav/Common/Taxonomy.php @@ -69,13 +69,40 @@ class Taxonomy foreach ((array)$config->get('site.taxonomies') as $taxonomy) { if (isset($page_taxonomy[$taxonomy])) { foreach ((array)$page_taxonomy[$taxonomy] as $item) { - $this->taxonomy_map[$taxonomy][(string)$item][$page->path()] = ['slug' => $page->slug()]; + $this->iterateTaxonomy($page, $taxonomy, '', $item); } } } } } + /** + * Iterate through taxonomy fields + * + * Reduces [taxonomy_type] to dot-notation where necessary + * + * @param PageInterface $page The Page to process + * @param string $taxonomy Taxonomy type to add + * @param string $key Taxonomy type to concatenate + * @param iterable|string $value Taxonomy value to add or iterate + * + * @return void + */ + public function iterateTaxonomy(PageInterface $page, string $taxonomy, string $key, $value) + { + if (is_iterable($value)) { + foreach ($value as $identifier => $item) { + $identifier = $key . '.' . $identifier; + $this->iterateTaxonomy($page, $taxonomy, $identifier, $item); + } + } elseif (is_string($value)) { + if (!empty($key)) { + $taxonomy = $taxonomy . $key; + } + $this->taxonomy_map[$taxonomy][(string) $value][$page->path()] = ['slug' => $page->slug()]; + } + } + /** * Returns a new Page object with the sub-pages containing all the values set for a * particular taxonomy.