Roots Discourse

Best practice to run (SoberWP)Controllers in admin section

I would like to run Controllers directly inside the admin_init hook. Sage 9 works with SoberWP which automatically populates the Controllers based on the frontend view.

I would like to run Controllers directly in the admin section as well.

Currently I’ve obtained this by adding the following rule inside the app/admin.php.

add_action(‘init’, function() {
//add new controller
$questions = new Questions();
}, 1);

What would be a better and more sustainable way of working?

I recommend taking a look at Acorn. In Sage 10 and Clover, Acorn will replace Controller with View Composers. They work a bit different than Controller, you can read about them on the blog:

Instead of Controllers being mapped to the template hierarchy, with View Composers need to explicitly loaded into your Acorn-powered theme or plugin’s config, then you can specify which views you want the composer to be called for. This is great since you can run the same composer for multiple views (an array or even a glob pattern).

Anyway, with Acorn, you can render a view like this:

Roots\view('admin.path.to.template', ['title' => 'Hello, World']);

An example of a custom admin page might look like this:

// Some plugin file

use function Roots\view;

add_action('admin_menu', function () {
    add_menu_page(
        __('My Plugin Settings', 'my-plugin'),
        __('My Plugin Settings', 'my-plugin'),
        'manage_options',
        'my-plugin-options',
        function () {
            // uses resources/views/admin/options.blade.php
            // resources/views is an example path for the views
            view('admin.pages.options', $associative_array_for_the_view);
        },
    );
});

An example of the corresponding View Composer:

<?php

namespace App\Composers;

use Roots\Acorn\View\Composer;
use Illuminate\Support\Str;

class AdminPage extends Composer
{
    /**
     * List of views served by this composer.
     *
     * @var array
     */
    protected static $views = ['admin.pages.*'];

    /**
     * Data to be passed to view before rendering.
     *
     * @param  array $data
     * @param  \Illuminate\View\View $view
     * @return array
     */
    public function with($data, $view)
    {
        return [
          // will be available in the template as $title
          'title' => Str::title($data['title']);
        ];
    }
}

Bear in mind that Acorn is still in development, so if you choose to use it right now, there won’t be a ton of support from the community. Hopefully in the future with the introduction of Clover — our plugin boilerplate — we can provide a simpler workflow for creating admin pages + UI.