[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
This commit is contained in:
Ole Vik 2019-10-17 13:52:37 +02:00 committed by Andy Miller
parent ef8e1c2fdf
commit 09e10d16ea

View File

@ -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.