diff --git a/src/Stache/Stores/TaxonomiesStore.php b/src/Stache/Stores/TaxonomiesStore.php index 365f7438be9..bc84fa59374 100644 --- a/src/Stache/Stores/TaxonomiesStore.php +++ b/src/Stache/Stores/TaxonomiesStore.php @@ -44,6 +44,8 @@ public function makeItemFromFile($path, $contents) ->title(Arr::get($data, 'title')) ->cascade(Arr::get($data, 'inject', [])) ->searchIndex(Arr::get($data, 'search_index')) + ->sortField(Arr::get($data, 'sort_by')) + ->sortDirection(Arr::get($data, 'sort_dir')) ->defaultPublishState($this->getDefaultPublishState($data)) ->sites($sites) ->previewTargets($this->normalizePreviewTargets(Arr::get($data, 'preview_targets', []))) diff --git a/src/Taxonomies/Taxonomy.php b/src/Taxonomies/Taxonomy.php index cef983535c7..88813672c2b 100644 --- a/src/Taxonomies/Taxonomy.php +++ b/src/Taxonomies/Taxonomy.php @@ -28,6 +28,7 @@ use Statamic\Facades\Site; use Statamic\Facades\Stache; use Statamic\Facades\URL; +use Statamic\Support\Arr; use Statamic\Support\Str; use Statamic\Support\Traits\FluentlyGetsAndSets; @@ -44,6 +45,8 @@ class Taxonomy implements Arrayable, ArrayAccess, AugmentableContract, ContainsQ protected $collection; protected $defaultPublishState = true; protected $searchIndex; + protected $sortField; + protected $sortDirection; protected $previewTargets = []; protected $template; protected $termTemplate; @@ -177,14 +180,32 @@ public function hasVisibleTermBlueprint() return $this->termBlueprints()->reject->hidden()->isNotEmpty(); } - public function sortField() + public function sortField($field = null) { - return 'title'; // todo + return $this + ->fluentlyGetOrSet('sortField') + ->getter(function ($sortField) { + return $sortField ?? 'title'; + }) + ->args(func_get_args()); } - public function sortDirection() + public function sortDirection($dir = null) { - return 'asc'; // todo + return $this + ->fluentlyGetOrSet('sortDirection') + ->getter(function ($sortDirection) { + if ($sortDirection) { + return $sortDirection; + } + + if ($this->sortField) { + return 'asc'; + } + + return 'asc'; + }) + ->args(func_get_args()); } public function queryTerms() @@ -290,6 +311,11 @@ public function fileData() 'layout' => $this->layout, ]; + $data = Arr::removeNullValues(array_merge($data, [ + 'sort_by' => $this->sortField, + 'sort_dir' => $this->sortDirection, + ])); + if (Site::multiEnabled()) { $data['sites'] = $this->sites; } diff --git a/tests/Data/Taxonomies/TaxonomyTest.php b/tests/Data/Taxonomies/TaxonomyTest.php index 05d685bb34f..b8726308880 100644 --- a/tests/Data/Taxonomies/TaxonomyTest.php +++ b/tests/Data/Taxonomies/TaxonomyTest.php @@ -182,6 +182,21 @@ public function it_gets_the_url_with_a_collection() $this->assertEquals('http://localhost/blog/tags', $taxonomy->absoluteUrl()); } + #[Test] + public function it_gets_sort_field_and_direction() + { + $taxonomy = new Taxonomy; + $this->assertEquals('title', $taxonomy->sortField()); + $this->assertEquals('asc', $taxonomy->sortDirection()); + + $taxonomy->sortField('foo'); + $this->assertEquals('foo', $taxonomy->sortField()); + $this->assertEquals('asc', $taxonomy->sortDirection()); + + $taxonomy->sortDirection('desc'); + $this->assertEquals('desc', $taxonomy->sortDirection()); + } + #[Test] public function it_gets_evaluated_augmented_value_using_magic_property() { @@ -308,6 +323,30 @@ public function it_get_terms_count_from_multi_sites() $this->assertEquals(3, $taxonomy->queryTerms()->pluck('slug')->unique()->count()); } + #[Test] + public function it_has_file_data() + { + $taxonomy = (new Taxonomy) + ->handle('tags') + ->title('Tags'); + + $this->assertEquals([ + 'title' => 'Tags', + 'inject' => [], + ], $taxonomy->fileData()); + + $taxonomy + ->sortField('foo') + ->sortDirection('desc'); + + $this->assertEquals([ + 'title' => 'Tags', + 'sort_by' => 'foo', + 'sort_dir' => 'desc', + 'inject' => [], + ], $taxonomy->fileData()); + } + #[Test] public function it_saves_through_the_api() { diff --git a/tests/Stache/Stores/TaxonomiesStoreTest.php b/tests/Stache/Stores/TaxonomiesStoreTest.php index b457a7cb45b..4fa8465f4da 100644 --- a/tests/Stache/Stores/TaxonomiesStoreTest.php +++ b/tests/Stache/Stores/TaxonomiesStoreTest.php @@ -67,6 +67,21 @@ public function it_makes_taxonomy_instances_from_files() $this->assertEquals('Example', $item->title()); } + #[Test] + public function it_hydrates_sort_field_and_direction() + { + $contents = <<<'YAML' +title: Tags +sort_by: foo +sort_dir: desc +YAML; + + $item = $this->store->makeItemFromFile($this->tempDir.'/tags.yaml', $contents); + + $this->assertEquals('foo', $item->sortField()); + $this->assertEquals('desc', $item->sortDirection()); + } + #[Test] public function it_normalizes_preview_target_url_into_format() {