getherbert / herbert

The WordPress Plugin Framework:
http://getherbert.com/
634 stars 95 forks source link

Using controllers inside pages, or header/footer inside views? #13

Open mikehhhhhhh opened 9 years ago

mikehhhhhhh commented 9 years ago

I feel like either one of the above is necessary for the framework to be useful to me.

I'd prefer the latter, but could live with the former.

How should I be looking to do this?

ConnorVG commented 9 years ago

Hey @AardvarkMike, cheers for the feedback!

Controllers are used for single responses managed by the plugin, what you could do if you want a specific template rendered is add it to the api.

On this topic though, would it be preferred if you can {{ get_header() }} like in usual WP?

jasonagnew commented 9 years ago

Its worth checking out: http://getherbert.com/dev/api

Hopefully this answers your question:

Add an api method

class Api extends BaseController {

    public function callMyController($var)
    {
        return $this->controller->fetch('MyController@method', $var);
    }

}

Then in Wordpress template you could do:

<?php $myPluginApi->callMyController($var); ?>

You could also attach the Api method to a shortcode:

$plugin->shortcode->add('CallMyControllerShortcode', 'callMyController');

Then use that in the wordpress editor as:

[CallMyControllerShortcode var='some-value']

Or if you want to use your api in a view.

return $this->view->render('demo/example', [
    'api'   => $myPluginApi,
]);

Then in the view:

{{ api.callMyController('some-value') }}
mikehhhhhhh commented 9 years ago

Thats just what I was looking for, thank you.

I assume the render method just echos the parsed template and thus calling a controller that ends with a template render will simply result in the template to be rendered where it is.

ortegacmanuel commented 9 years ago

Is not possible just use something like this {{ get_header() }} ? Why?

bruno-barros commented 9 years ago

@kameleono Pay attention on fact the get_header() already echos out some HTML, so you can't echo twice. I use Blade engine with WordPress and some WP function I need to use <?php ?> because {{ }} is converted in <?php echo ?>, but I'm nor sure if it apply to Twig.

mikehhhhhhh commented 9 years ago

One assumes you could create a wrapper for get_header() with output buffering?

ConnorVG commented 9 years ago

That is something we should certainly look into, @AardvarkMike and @kameleono!

johnReeve commented 9 years ago

The other day I built an admin options page, and there were enough functions that needed buffering I went ahead and added a buffer method to my controller... I think it is a good general purpose solution:

private function buffer ($functionName = "", $settings = []) {
    ob_start();
    call_user_func_array($functionName, $settings);
    $buffer = ob_get_contents();
    ob_end_clean();
    return $buffer;
}

Then I ended up with a controller method like:

public function panel_generalSettings()
{
    return $this->view->render('admin/general', [
                'settings_field' => $this->buffer('settings_fields', ['mysettings']),
                'do_settings_field' => $this->buffer('do_settings_sections', ['mysettings]),
                'dev_mode' => get_option('dev_mode'),
                'submit_button' => get_submit_button()
    ]);
}
ConnorVG commented 9 years ago

How about a small class that allows for the buffering functionality, thoughts on that @johnReeve?

Sucks that WordPress makes us have to do this though! :laughing:

mikehhhhhhh commented 9 years ago

So, I made an attempt, and this seems to work;

{{ api.buffer('get_header')|raw }}
Test hello<br />
{{ test }}
{{ api.buffer('get_footer')|raw }}

I stole @johnReeve 's buffer function, so thanks for that.

The |raw bit is important if you're grabbing html, as twig seems to escape html by default.

briankelleher commented 8 years ago

@mikehhhhhhh did you have to do anything additional for getting the buffer function to work? I keep getting call_user_func_array() expects parameter 1 to be a valid callback when I call namespace.buffer('get_header') or with get_footer.