mybb / mybb2

The repository for the MyBB 2 forum software. Not to be used on live boards.
https://www.mybb.com
BSD 3-Clause "New" or "Revised" License
112 stars 45 forks source link

Template hook system #303

Open euantorano opened 6 years ago

euantorano commented 6 years ago

Template hook system, allowing plugins and modules to easily output and modify template content without requiring edits to templates (removing the requirement for find_replace_templatesets). This should be less prone to error and make managing themes much easier (installing a new theme should mean that plugins just work).

1e4 commented 6 years ago

Is this still required? I'm willing to put something together if needed?

euantorano commented 6 years ago

It would be great, yeah. Currently our focus is on 1.10 where we will hopefully manage to backport this feature.

On 4 Dec 2017, at 16:34, Ian notifications@github.com wrote:

Is this still required? I'm willing to put something together if needed?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

1e4 commented 6 years ago

I built a hook system a few months back, pretty simple so I can create a PR when I get a chance.

euantorano commented 6 years ago

Sounds awesome, I'll quickly outline the kind of thing I'm hoping for 😄

{{ hook('header-welcomeblock_member_end') }}
$hookManager = app('template_hooks;); // Example of the hook manager's registered name in the DI
$hookManager->addHook('header-welcomeblock_member_end', function(\Twig_Environment $twig) {
    // do some stuff and return a rendered view here
    return $twig->render('foo');
});

I can't think of anything else at the moment - perhaps @Eric-Jackson or @justinsoltesz have some items on their wishlist (or anybody else out there - feel free to chime in with your wishes!). THe naming of things is always the hardest part I find, so feel free to use names other than TemplateHookManager and such :smile:

1e4 commented 6 years ago

Sounds good, below is what I hacked together a few months ago for a project, with a little tweaking and exposing the methods to Twig it should be golden. I need to add priority, basically just sort the array. I'll write a checklist at the end, if you can confirm then I can put it in MyBB

<?php

class HookContainer {

    /**
     * Object container all hooks that are enabled
     *
     * @var array
     */
    private $hooks;

    public function __construct()
    {

        // Get all the hooks and store them
        $this->hooks = Hooks::enabled();
    }

    /**
     * Run the hooks
     *
     * @param $location
     * @param array ...$args
     */
    public function run($location, ...$args)
    {

        $this->execute('hook_before', $args);
        $this->execute($location, $args);
        $this->execute('hook_after', $args);

    }

    /**
     * Wrapper for blade directives so we can show visible hooks
     *
     * @param $location
     * @param array ...$args
     */
    public function display($location, ...$args)
    {

        if(($debug = app('settings')->where('key', '=', 'debug')->first()) !== null)
        {
            if($debug->value === "1")
                echo view('partials.hook', [
                    'location'  =>  $location
                ]);
        }

        $this->execute('hook_before', $args);
        $this->execute($location, $args);
        $this->execute('hook_after', $args);
    }

    /**
     * Execute the hook location
     *
     * @param $location
     * @param array ...$args
     */
    public function execute($location, ...$args)
    {

        // Get hooks based on the location
        $hooks = $this->hooks;

        logDebug("Hook Location: {$location}");

        if(count($hooks) > 0) {
            // Loop through and execute each one
            foreach ($hooks as $hook) {
                foreach($hook->locations as $loc)
                {
                    if($loc->location !== $location)
                        continue;

                    $className = $loc->namespace;

                    // Find the class
                    $class = new $className(...$args);

                    // Add some friendly debug
                    logDebug([
                        "hook"=>[
                            "name"      =>  $hook->name,
                            "class"     =>  $className,
                            "location"  =>  $location,
                            "args"      =>  $args
                        ]
                    ], 'hooks');
                    $func = $loc->method;

                    // Allow the plugin to return a view or text or whatever
                    echo $class->$func();
                }

            }
        }
    }

}

I named it HookContainer as it contains all the hooks - this isn't limited to templates, I exposed it via IoC then wrapped a helper method so I could essentially do hook()->display('header') for example.

Is that correct?

1e4 commented 6 years ago

@euantorano Hope you don't mind the little bump

euantorano commented 6 years ago

Sorry, I somehow missed the notification for your reply @1e4!

Looks good to me. The only points I see are:

1e4 commented 6 years ago

No problem @euantorano, there are also no Facades. The Hooks::enabled() is a model with a static method. The hook() function simply get's the Hook instance from the Container. I'll try and carve some time out and get this in this week :)

1e4 commented 6 years ago

Afternoon @euantorano Christmas & New Year were busier than I expected, I'll look at making progress on it this week and keep you posted.

euantorano commented 6 years ago

Happy new year!

No problem, I know that feeling for sure 😀

On 2 Jan 2018, at 16:23, Ian notifications@github.com wrote:

Afternoon @euantorano Christmas & New Year were busier than I expected, I'll look at making progress on it this week and keep you posted.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

1e4 commented 6 years ago

Happy New Year @euantorano I hope MyBB 2 gets a BETA this year ^_^, hoping to contribute as much as I can to make this happen

euantorano commented 6 years ago

The current focus is upon 1.9, 1.10 and other incremental steps in the 1.x line due to community demand.

On 2 Jan 2018, at 16:42, Ian notifications@github.com wrote:

Happy New Year @euantorano I hope MyBB 2 gets a BETA this year ^_^, hoping to contribute as much as I can to make this happen

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.