Setting up a controller for ACF fields

Hi all,

I’m trying to figure out the best strategy for retrieving and calling ACF data for my views, I’ve been reading ACF variables in blade template and related threads about creating controllers but I don’t quite get it.

I have a custom post type nomination and I’m using archive-nomination.blade.php as my view and this file is just in resources/views. I wanted to create a controller for this view in app/controllers called nomination, currently it looks like this

<?php

namespace App;

use Sober\Controller\Controller;

class nomination extends Controller
{
    public function description(){
        return get_field('nomination_description');
    }
}

I thought that I would be able to just access description using $description as per https://github.com/soberwp/controller explanation. It doesn’t seem to work for me though and I’m sure it’s because I am not making the controller accessible to the view, but this is the bit I don’t understand. I think that this is where I would use add_filter(), but where do I put that and what would my path be? Can anyone explain this in simple terms please?

Many thanks
Kevin

Controller uses the WordPress template loading hierarchy, converted to CamelCase, to find the correct class names. You’ve named your class “nomination” which won’t match anything. If you want it to display on archives for your nomination post type, then you need to name your class file’s name to ArchiveNomination.php and your class’s ArchiveNomination.

If you’re using an up-to-date version of Controller, you also need to use the namespace App\Controllers.

Thanks, creating that class works now. I still don’t really get it though because regardless of what namespace I use in the controller - App\Controllers or App or even Controllers, they all work! The only thing that doesn’t work is if I remove the namespace from the controller altogether.

What if I want to use the same controller on a different view, say a different archive or single view for other post types, how would I go about that?

Appreciated the help greatly!
Kevin

Without knowing which version of Controller you’re using, it’s difficult to answer your question about namespacing. I would stick with App\Controllers because that’s what @withjacoby has in the Controller readme, and it seems most inline with proper namespacing for Sage.

In general controllers should be unique to views. If you want to have a generic “Archive” controller, then you could change your class name and file name to Archive. Otherwise I’d recommend just creating a new controller. Controllers are matched like Blades using the content of the body class that WordPress generates, so in theory you can create a controller that matches any class in that filter. Just remember that Controller is using PSR-4 to load controllers, so your file names and class names need to match, and need to conform to PSR-4 standards (which mostly means they need to be CamelCase—i.e. page-template-contact would be PageTemplateContact).

Also: Updated versions of Controller now support ACF fields natively.

OK I think I’m startng to get it! With the support for ACF fields, I added…

protected $acf = true;

…to the controller, so according to the readme that should pass on all of the acf field data to the view. But how do I actually access that on the view? Say I have a field short_description should I ge able to just use

{{$short_description}}

on my blade template? I did just try this and I’m getting an undefined variable error. Maybe I need to update Controller? How to I tell which version I have?

Kevin

As far as I can see my Controller version is 9.0.0-beta.4 - does that make sense?

You can update your Controller version by changing the version value in your composer.json. Yours probably looks like this right now:

"soberwp/controller": "9.0.0-beta.4"

I believe that the ACF functionality was added in 2.0.0, so you could change it to:

"soberwp/controller": "^2.0.0"

Then run composer update.

3 Likes

Hmm… tried that but now I’m getting…

Fatal error: Uncaught ReflectionException: Class App\Controllers\app does not exist in /Users/kevin.price-ward/Sites/jewson_bbc/web/app/themes/bbc/vendor/soberwp/controller/src/Loader.php on line 119

Any ideas?
Kevin

Class App\Controllers\app makes it look like you aren’t naming your classes correctly. Specifically, this suggests that you used lower-case for your class name. You need to follow the PSR-4 standard. In this particular case, your App.php file should look like this:

<?php

namespace App\Controllers;

use Sober\Controller\Controller;

class App extends Controller
{
   // Whatever stuff you want to do in this controller...
}

Brilliant… thanks @alwaysblank, I had to change the namespace and rename the file on both app.php and front-page.php but working now!

Glad it worked for you. :slight_smile: If you can, please mark the post that solved it for you as the solution.

2 Likes

Hi,
I’ve been following this thread and hope it’s okay to add my problem in here.

I’ve updated my Controller version from 9.0.0-beta.4 to 2.0.0. The namespaces of my controllers were App so I’ve changed these to App\Controllers. I’m still getting the fatal error:

Fatal error: Uncaught ReflectionException: Class App\Controllers\front-page does not exist in /srv/www/mysite.co.uk/current/web/app/themes/my-theme/vendor/soberwp/controller/src/Loader.php on line 119

All I have in the controller front-page.php is:
<?php

namespace App\Controllers;

use Sober\Controller\Controller;

class FrontPage extends Controller
{
 
}

Can anyone help? I feel really clueless about this.

The filename of the file containing your front page class needs to have the same name as the class; in this case, your file should be FrontPage.php. Controller uses the PSR-4 spec to autoloader files, which determines how files should be named and organized. You can read the details here: https://www.php-fig.org/psr/psr-4/

I renamed the files to App.php and FrontPage.php, changed line 3 to be ‘namespace App\Controllers;’, and I’m still getting a ReflectionException error:

Fatal error: Uncaught ReflectionException: Class App\Controllers\App does not exist in /srv/www/.../vendor/soberwp/controller/src/Loader.php on line 119

You’ll need to provide some more information about your setup for us to try and help. What version of Controller are you using? What is the rest of your code in App.php?

Controller is ^2.0.0. App.php is just the default file that ships with Sage, it just has a siteName and title method. All I did was change line three. The folder structure is /app/controllers/App.php FrontPage.php. This is a Trellis/Bedrock/Sage site, and I really haven’t touched anything other than the composer.json file. The Call Stack says it fails during the __contruct() in the Loader.php file.

Thanks @alwaysblank. I’m getting closer to getting it working now. I’ve renamed:
app.php to App.php
front.page.php to FrontPage.php
page.php to Page.php
I’ve taken all the code I added out of the above pages so there’s nothing there to sully them.

I can now see my dashboard which is definite progress. However when I try to look at the site I get an error to do with name spacing. I’ve been debugging the site having followed A Sage 9 + ACF debugging technique

I’ve now got two errors:
Symfony\Component\Debug\Exception\FatalThrowableError Class 'Sober\Controller\Module\Debugger' not found

Class 'Sober\Controller\Module\Debugger' not found (View: /srv/www/mysite.co.uk/current/web/app/themes/mytheme/resources/views/partials/page-header.blade.php)

page-header.blade.php contains:

@php
if ($_SERVER['WP_ENV'] == 'development') {
  $controller = new \Sober\Controller\Module\Debugger(get_defined_vars(), 'Debugger');
  $fields = get_fields();
  PC::debug($controller);
  PC::debug($fields);
}
@endphp

I really am trying to work it out for myself but I really need help with this bit to help me understand it all.

It looks like the namespace for the debugger has changed to Sober\Controller\Debugger as per the source found here: https://github.com/soberwp/controller/blob/2.0.0/src/Debugger.php

Errors about “Class ‘SomeClass’ not found” or about “ReflectionError” frequently mean that the namespace or class name is wrong either where a class is being instantiated, or in the original definition of that class. If you’re struggling with namespaces, this post I wrote attempting to explain how they work may be helpful: Controller namespace issue, different behavior on localhost and development server