Best Practice / Resources for Blade

Thanks for the clarification.

I’l check out using static methods as a way of dealing with ACF data.


Hi all,

For those using Controller, please note that it is now a Sage dependency.

You can remove the mu-plugin and run composer require soberwp/controller:9.0.0-beta.3 from within the theme directory.

That’s all that’s needed.


Is it possible you would need to remove composer’s type “wordpress-muplugin”. Despite having run composer clear-cache, It installs in [sage]/wp-content/mu-plugins/… folder instead of vendor/soberwp/controller.

So sorry! that’s such an oversight, should be fixed now.


Can you please show an example how you use/not use sober? I’m usually using repeaters and flexible content alot, and it feels very weird and unefficient to loop over these fields in the controller, and then do the same in the view again.

Great tool none the less, thanks! :slight_smile:

1 Like

@intelligence for the most part, I still use the Advanced Custom Fields functions within the views, esp if within a loop. I will use Controller if I need to write some logic into the returned results though.

There are some good examples here though, esp the object syntax being used by @nathobson

I’ll see if I can write up some use-cases/examples down the line. I have been wanting to create nicer documentation with an easier way to consume, so will work on that.

EDIT: I may look at doing a Sober/Controller/Acf helper class. Could be useful and speed up templating when using acf a lot.


That would be awesome. I’m trying to do this right now and struggling a bit.

I was wundering if it’s possible to use a Trait used in the Sober controllers in a normal non-blade php file?

Let’s say I have a controller TemplateCustom.php where I want to use TraitA:

namespace App;
use Sober\Controller\Controller;

class TemplateCustom extends Controller {
	use TraitA;

	public function controlFields() {
		return (object) array (
			'posts' => TraitA::getPosts()

In my TraitA:

namespace App;

trait TraitA {

	/* Get all Posts  */
	public static function getPosts() {
		$postsObj = [];
		$posts   = get_posts([
			'post_type'      => 'post-type',
			'orderby'        => 'title',
			'order'          => 'ASC',
			'posts_per_page' => -1

		foreach ($posts as $post) {
			$postsObj[] = self::getPost($post->ID);

		return json_decode(json_encode($postsObj));

	/* Get Single Post */
	public static function getPost($id = null) {
		if ($id) {
			$post = get_post($id);
			$data = [
				'title' => get_the_title($id),
				'link'  => get_the_permalink($id),
				'slug'  => $post->post_name

			return json_decode(json_encode($data));

and a blade view template-custom.blade.php where I use the returned Trait data:

  Template Name: Custom Template


	@while(have_posts()) @php(the_post())
		@include('partials.content-post', array(
			'posts' => $control_fields->posts

This works great!
However, I think these traits are only available within the Sober Controllers?

What if I want to re-use the TraitA functions in a normal php class outside the blade controllers & views:

class TraitTest {
	use TraitA;

	public function __construct() {
		add_filter('some_filter', 'populatePosts', 10, 2);

	function populatePosts() {
		$posts = TraitA::getPosts();
		return $posts;

new TraitTest;

The above will result in an error:

Fatal error: Trait 'TraitA' not found

Is my Trait approach wrong here?

Any help is welcome, thanks!

1 Like

Can’t fully test right now, but my first feeling would be that the Trait is only included from Controller after your custom class is included.

My guess is because you didn’t import it and you’re not using the correct namespace. From the code you posted, it’s not TraitA, it’s App\TraitA


Thanks for your reply!
You mean in the Trait import line:

use App\TraitA

or in the function call:


Because both don’t work…

Do I need to declare the namespace App; in my php file too?
In both cases I still get the same error unfortunately:

Fatal error: Trait 'TraitA' not found

Am I doing something wrong?

Like @withjacoby said, your Trait probably hasn’t been loaded by the time you’re trying to call it–Controller loads the Classes and Traits for your data itself, they’re not autoloaded like most other classes in Sage.

If you have a Trait that you want to use in your controller and elsewhere, I’d probably do that by creating my Trait outside of the Controller ecosystem, and either load the file containing it manually (i.e. w/ functions.php) or set it up to use Composer’s autoloading. That way you can easily access it anywhere you want.


Maybe everyone else is on to something. Where did you place the TraitA file?

In the app/controllers/partials folder

1 Like

That’s probably the issue… PHP doesn’t know where to find the class because you’re not following the autoloading conventions.

Sage is autoloaded with PSR-4:

I would put that class in app/Traits, with the namespace App\Traits, and load it in other files use App\Traits\TraitA, which should get it autoloaded correctly. Just remember, PSR-4 basically means having your namespaces follow your folder structure.

1 Like

Doesn’t Controller suggest the use of the partials directory, though?

Yes, apparently SoberWP does… I’ll have to take a closer look…

Controller doesn’t require the use of PSR4 loading, anything within the controllers/ directory is included, and it will determine traits from classes, and then load the traits first.

I’ll do some testing re using traits outside of Controller and see what I can come up with, but I’m fairly confident it has to do with the order.

1 Like

Can I ask what the thought process is behind loading everything in the controllers folder and not following PSR-4? I apologize if this has been discussed previously, I’ve been busy the last couple months moving, haven’t been keeping up with Roots stuff, just starting to catch up now.

Possible related: I’ve run into an issue where Controller’s classes aren’t loaded when a Sage-based theme is installed via Composer.