Skip to content
This repository has been archived by the owner on Jul 10, 2023. It is now read-only.

Controllers for CPT Templates #86

Closed
codepuncher opened this issue May 25, 2018 · 6 comments
Closed

Controllers for CPT Templates #86

codepuncher opened this issue May 25, 2018 · 6 comments

Comments

@codepuncher
Copy link

I've done a lot of looking into this through the reported issues, Discourse and on Google but I can't seem to find an answer for what I'm looking for. Maybe this is a very specific case-scenario where I may not be able to achieve what I'm trying to do.

I have a Post Type event which allows user to choose which template they want to use:

  • single-event.blade.php (default)
  • single-event-featured.blade.php (Featured Event)
  • single-event-featured-bh.blade.php (Featured Event Red)

What I'm trying to achieve is to separate methods and code so that all Event Singles will load SingleEvent or at least the traits it needs. Then the "Featured" Event Singles that use that other template will use the same traits but also the extra featured event trait.

Now, assuming that the hierarchy will support this, I have setup 2 controllers SingleEvent and SingleEventFeatured and created 3 traits. SingleEvent loads 2 of them and SingleEventFeatured loads all 3 (3rd trait for specific "Featured Event" methods).

SingleEvent correctly loads on all Event Singles, regardless of template chosen. So I'm now stuck with how to get the specific featured code to load specifically only on my single-event-featured.blade.php template. I've used protected $template = 'single-event-featured'; but no luck. Only works when I do this:

class SingleEventFeatured extends Controller implements Tree
{
    use Events;
    use SingleEventTrait;
    use FeaturedEvent;

    protected $template = 'single-event';
...

but then of course that will load that controller on all Event singles.

Does anyone have some kind of approach that I could use for this? Maybe I am missing something, but I feel like this is something in the hierarchy that isn't taken account for.

Any help appreciated!

@darrenjacoby
Copy link
Member

darrenjacoby commented May 25, 2018

If you inspect the site, check the body classes ending with -data. Can you send them to me?

That's the hierarchy that Controllers will follow and any of those classes could be used.

@codepuncher
Copy link
Author

Ah, I did try using some of the body classes as controller names like EventTemplateSingleEventFeatured but couldn't get it working.

Here's what I have on body:

<body class="event-template event-template-views event-template-single-event-featured event-template-viewssingle-event-featured single single-event postid-1868 manchester-to-blackpool-bike-ride app-data index-data singular-data single-data single-event-data single-event-manchester-to-blackpool-bike-ride-data">

Is this something that Controller supports yet?

@d-a-v-e
Copy link

d-a-v-e commented May 29, 2018

I'm having the same issue with a CPT. my body tag is this:

class="wbspr_core_practice-template-default single single-wbspr_core_practice postid-117 logged-in admin-bar change-and-project-management app-data index-data singular-data single-data single-wbspr_core_practice-data single-wbspr_core_practice-change-and-project-management-data customize-support"

my controller

app/controllers/SingleWbsprCorePractice.php

<?php

namespace App\Controllers;

use Sober\Controller\Controller;

class SingleWbsprCorePractice extends Controller
{
    protected $acf = true;

    public function testText()
    {
        return 'the test text';
    }
}

the template

resources/views/single-wbspr_core_practice.blade.php

is rendered, but the ACF variables as well as the test variable $test_text aren't found, eg:

Notice: Undefined variable: test_text in /srv/www/example.com/current/web/app/uploads/cache/7b997eadd6b82b63a9290b30f1b890411e84658a.php on line

@d-a-v-e
Copy link

d-a-v-e commented May 30, 2018

Ah, figured out my issue from this closed ticket: #63

Should have read the original question for this ticket more closely, as I don't think my issue relates.

For anyone else having this problem though, cpt template files typically aren't found by the controller owing to the underscore_then-dash pattern. To get around this tell the controller which template to use by adding, for example:

protected $template = 'single-cpt_name';

or in my case

protected $template = 'single-wbspr_core_practice';

As per the documentation on template override https://github.com/soberwp/controller#template-override-option

@darrenjacoby
Copy link
Member

@codepuncher Controller uses https://github.com/Brain-WP/Hierarchy to determine the hierarchy (and therefore Controllers to load). You could raise an issue there regarding more granular control of post type templates. If updated there, Controller would work as expected above. I'm going to close for now as this could be considered edge case, but would recommend raising on their repo to see if we can get this working down the line.

@codepuncher
Copy link
Author

Opened issue @ Brain-WP/Hierarchy#14 (comment)

For those who stumble upon this looking for a solution, open filters.php, find this:

/**
 * Template Hierarchy should search for .blade.php files
 */
collect([
    'index', '404', 'archive', 'author', 'category', 'tag', 'taxonomy', 'date', 'home',
    'frontpage', 'page', 'paged', 'search', 'single', 'singular', 'attachment'
])->map(function ($type) {
    add_filter("{$type}_template_hierarchy", __NAMESPACE__.'\\filter_templates');
});

and add this before it

add_filter('single_template_hierarchy', function (array $templates) {
    $post = get_queried_object();
    if (! empty($post->post_type)) {
        $templateFile = get_page_template_slug($post);
        if ($templateFile && validate_file($templateFile) === 0) {
            if (strpos($templateFile, "single-{$post->post_type}-") !== false) {
                /** Remove .blade.php/.blade/.php from template names */
                $template = preg_replace('#\.(blade\.?)?(php)?$#', '', ltrim($templateFile));

                /** Remove partial $paths from the beginning of template names */
                if (strpos($template, '/')) {
                    $template = preg_replace("#^(" . implode('|', ['views']) . ")/#", '', $template);
                }
                array_unshift($templates, $template);
            }
        }
    }
    return $templates;
});

This allows me to use my template single-event-template-featured.blade.php with a controller named SingleEventTemplateFeatured.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants