Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x] Allow taxonomies and terms to specify a template and layout #8372

Merged
merged 9 commits into from
Dec 13, 2023
3 changes: 3 additions & 0 deletions resources/lang/en/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@
'tabs_instructions' => 'The fields in each section will be grouped together into tabs. Create new fields, reuse existing fields, or import entire groups of fields from existing fieldsets.',
'taxonomies_blueprints_instructions' => 'Terms in this taxonomy may use any of these blueprints.',
'taxonomies_collections_instructions' => 'The collections that use this taxonomy.',
'taxonomy_configure_layout_instructions' => 'Set this taxonomy\'s default layout. Terms can override this setting with a `layout` field.',
'taxonomy_configure_template_instructions' => 'Set this taxonomy\'s default template.',
'taxonomy_configure_term_template_instructions' => 'Set this taxonomy\'s default template. Terms can override this setting with a `template` field.',
'taxonomies_preview_targets_instructions' => 'The URLs to be viewable within Live Preview. Learn more in the [documentation](https://statamic.dev/live-preview#preview-targets).',
'taxonomies_preview_target_refresh_instructions' => 'Automatically refresh the preview while editing. Disabling this will use postMessage.',
'taxonomy_configure_handle_instructions' => 'Used to reference this taxonomy on the frontend. It\'s non-trivial to change later.',
Expand Down
30 changes: 29 additions & 1 deletion src/Http/Controllers/CP/Taxonomies/TaxonomiesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ public function edit($taxonomy)
'collections' => $taxonomy->collections()->map->handle()->all(),
'sites' => $taxonomy->sites()->all(),
'preview_targets' => $taxonomy->basePreviewTargets(),
'term_template' => $taxonomy->termTemplate(),
'template' => $taxonomy->template(),
'layout' => $taxonomy->layout(),
];

$fields = ($blueprint = $this->editFormBlueprint($taxonomy))
Expand Down Expand Up @@ -162,7 +165,10 @@ public function update(Request $request, $taxonomy)

$taxonomy
->title($values['title'])
->previewTargets($values['preview_targets']);
->previewTargets($values['preview_targets'])
->termTemplate($values['term_template'] ?? null)
->template($values['template'] ?? null)
->layout($values['layout'] ?? null);

if ($sites = array_get($values, 'sites')) {
$taxonomy->sites($sites);
Expand Down Expand Up @@ -308,6 +314,28 @@ protected function editFormBlueprint($taxonomy)
],
],
],
'templates' => [
'display' => __('Templates'),
'fields' => [
'template' => [
'display' => __('Template'),
'instructions' => __('statamic::messages.taxonomy_configure_template_instructions'),
'type' => 'template',
'placeholder' => __('System default'),
],
'term_template' => [
'display' => __('Term Template'),
'instructions' => __('statamic::messages.taxonomy_configure_term_template_instructions'),
'type' => 'template',
'placeholder' => __('System default'),
],
'layout' => [
'display' => __('Layout'),
'instructions' => __('statamic::messages.taxonomy_configure_layout_instructions'),
'type' => 'template',
],
],
],
]);

return Blueprint::makeFromTabs($fields);
Expand Down
5 changes: 4 additions & 1 deletion src/Stache/Stores/TaxonomiesStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ public function makeItemFromFile($path, $contents)
->searchIndex(array_get($data, 'search_index'))
->defaultPublishState($this->getDefaultPublishState($data))
->sites($sites)
->previewTargets($this->normalizePreviewTargets(array_get($data, 'preview_targets', [])));
->previewTargets($this->normalizePreviewTargets(array_get($data, 'preview_targets', [])))
->termTemplate(array_get($data, 'term_template', null))
->template(array_get($data, 'template', null))
->layout(array_get($data, 'layout', null));
}

protected function getDefaultPublishState($data)
Expand Down
12 changes: 8 additions & 4 deletions src/Taxonomies/LocalizedTerm.php
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,17 @@ public function toResponse($request)
public function template($template = null)
{
if (func_num_args() === 0) {
$defaultTemplate = $this->taxonomyHandle().'.show';
if ($template = $this->get('template')) {
return $template;
}

$template = $this->taxonomy()->termTemplate();

if ($collection = $this->collection()) {
$defaultTemplate = $collection->handle().'.'.$defaultTemplate;
$template = $collection->handle().'.'.$template;
}

return $this->get('template', $defaultTemplate);
return $template;
}

return $this->set('template', $template);
Expand All @@ -387,7 +391,7 @@ public function template($template = null)
public function layout($layout = null)
{
if (func_num_args() === 0) {
return $this->get('layout', 'layout');
return $this->get('layout') ?? $this->taxonomy()->layout();
}

return $this->set('layout', $layout);
Expand Down
52 changes: 44 additions & 8 deletions src/Taxonomies/Taxonomy.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class Taxonomy implements Arrayable, ArrayAccess, AugmentableContract, Contract,
protected $revisions = false;
protected $searchIndex;
protected $previewTargets = [];
protected $template;
protected $termTemplate;
protected $layout;
protected $afterSaveCallbacks = [];
protected $withEvents = true;

Expand Down Expand Up @@ -249,6 +252,9 @@ public function fileData()
'title' => $this->title,
'blueprints' => $this->blueprints,
'preview_targets' => $this->previewTargetsForFile(),
'template' => $this->template,
'term_template' => $this->termTemplate,
'layout' => $this->layout,
];

if (Site::hasMultiple()) {
Expand Down Expand Up @@ -354,20 +360,50 @@ public function get($key, $fallback = null)
return $fallback;
}

public function template()
public function termTemplate($termTemplate = null)
{
$template = $this->handle().'.index';
return $this
->fluentlyGetOrSet('termTemplate')
->getter(function ($termTemplate) {
if ($termTemplate ?? false) {
return $termTemplate;
}

if ($collection = $this->collection()) {
$template = $collection->handle().'.'.$template;
}
$termTemplate = $this->handle().'.show';

return $template;
return $termTemplate;
})
->args(func_get_args());
}

public function layout()
public function template($template = null)
{
return 'layout';
return $this
->fluentlyGetOrSet('template')
->getter(function ($template) {
if ($template ?? false) {
return $template;
}

$template = $this->handle().'.index';

if ($collection = $this->collection()) {
$template = $collection->handle().'.'.$template;
}

return $template;
})
->args(func_get_args());
}

public function layout($layout = null)
{
return $this
->fluentlyGetOrSet('layout')
->getter(function ($layout) {
return $layout ?? 'layout';
})
->args(func_get_args());
}

public function searchIndex($index = null)
Expand Down
39 changes: 39 additions & 0 deletions tests/Data/Taxonomies/TaxonomyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,45 @@ public function if_saving_event_returns_false_the_taxonomy_doesnt_save()
Event::assertNotDispatched(TaxonomySaved::class);
}

/** @test */
public function it_gets_and_sets_the_layout()
{
$taxonomy = (new Taxonomy)->handle('tags');

// defaults to layout
$this->assertEquals('layout', $taxonomy->layout());

// taxonomy level overrides the default
$taxonomy->layout('foo');
$this->assertEquals('foo', $taxonomy->layout());
}

/** @test */
public function it_gets_and_sets_the_template()
{
$taxonomy = (new Taxonomy)->handle('tags');

// defaults to taxonomy.index
$this->assertEquals('tags.index', $taxonomy->template());

// taxonomy level overrides the default
$taxonomy->template('foo');
$this->assertEquals('foo', $taxonomy->template());
}

/** @test */
public function it_gets_and_sets_the_term_template()
{
$taxonomy = (new Taxonomy)->handle('tags');

// defaults to taxonomy.show
$this->assertEquals('tags.show', $taxonomy->termTemplate());

// taxonomy level overrides the default
$taxonomy->termTemplate('foo');
$this->assertEquals('foo', $taxonomy->termTemplate());
}

/** @test */
public function it_cannot_view_taxonomies_from_sites_that_the_user_is_not_authorized_to_see()
{
Expand Down
38 changes: 38 additions & 0 deletions tests/Data/Taxonomies/TermTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,4 +288,42 @@ public function it_gets_preview_targets()
['label' => 'Show', 'format' => 'http://preview.com/{locale}/tags/{slug}?preview=true', 'url' => 'http://preview.com/de/tags/das-foo?preview=true'],
], $termDe->previewTargets()->all());
}

/** @test */
public function it_gets_and_sets_the_layout()
{
$taxonomy = tap(Taxonomy::make('tags'))->save();
$term = (new Term)->taxonomy('tags');

// defaults to layout
$this->assertEquals('layout', $term->layout());

// taxonomy level overrides the default
$taxonomy->layout('foo');
$this->assertEquals('foo', $term->layout());

// term level overrides the origin
$return = $term->layout('baz');
$this->assertEquals($term, $return);
$this->assertEquals('baz', $term->layout());
}

/** @test */
public function it_gets_and_sets_the_template()
{
$taxonomy = tap(Taxonomy::make('tags'))->save();
$term = (new Term)->taxonomy('tags');

// defaults to taxonomy.show
$this->assertEquals('tags.show', $term->template());

// taxonomy level overrides the default
$taxonomy->termTemplate('foo');
$this->assertEquals('foo', $term->template());

// term level overrides the origin
$return = $term->template('baz');
$this->assertEquals($term, $return);
$this->assertEquals('baz', $term->template());
}
}
Loading