Calling a plugin within a twig

I’ve created a plugin using the tutorial and screwing with admin and have the following:

latest.yaml :

   enabled: true
   theme: default

latest.php:

   <?php
namespace Grav\Plugin;

use Grav\Common\Page\Collection;
use Grav\Common\Plugin;

class LatestPlugin extends Plugin 
{
    public static function getSubscribedEvents() {
    return [
        'onPluginsInitialized' => ['onPluginsInitialized', 0],
    ];
} 

    public function onPluginsInitialized() {
        /** @var Uri $uri */
        $this->enable([
               'onPageInitialized' => ['onPageInitialized', 0]
            ]);
    }

    public function onPageInitialized()
    {
            $this->latestPages(1);
    }

    public function latestPages($count = 10)
    {
        /** @var Pages $pages */
        $pages = $this->grav['pages'];
        $latest = array();

        foreach ($pages->routes() as $url => $path) {
            $page = $pages->dispatch($url);
            if ($page && $page->routable()) {
                $latest[$page->route()] = ['modified' => $page->modified(), 'page' => $page];
            }
        }

        // sort based on modified
        uasort($latest, function ($a, $b) {
            if ($a['modified'] == $b['modified']) {
                return 0;
            }

            return ($a['modified'] > $b['modified']) ? -1 : 1;
        });

        // build new array with just pages in it
        // TODO: Optimized this
        $list = array();
        foreach ($latest as $item) {
            $list[] = $item['page'];
        }

        $this->grav['debugger']->addMessage(array_slice($list, 0, $count)[0]);

        return array_slice($list, 0, $count);
    }
}

As you can see here: http://qwyk.ly, the plugin is working (I get an array in the debugger)

My only problem is that in sidebar.html.twig (in user/themes/learn2/templates/partials) the following:

        <ul>
            <li>THE PLUGIN SHOULD SHOW DATA HERE </li>
            {% for posts in latestPages(1) %}
                <li>{{ posts.route }}</li>
            {% endfor %}
            <li>AND WOULD FINISH HERE</li>
        </ul>

Fails, returning nothing at posts … All help gratefully received

You are kinda doing it wrong. You should generate a latest_pages array, and add that to the Twig environment. Then in your sidebar you could loop over the latest_pages array and display stuff.

Pretty much every Grav plugin does this kinda of thing. Take a look at archives plugin for example.

So I pulled all that code from the admin plugin (latestPages) … Doesn’t latestPages return an array? It certainly seems to in the debugger. To be fair, I am brand new to PHP, so perhaps I am not understanding you right.

The problem here is not that the plugin doesn’t work (debugger shows that it does) more that I can’t get it to show on the page from the twig call…

Thanks again for help.

Admin calls admin.latestPages from the twig itself, thus getting the pages array directly. You could do like this

    public function onTwigSiteVariables() {
    $this->grav['twig']->latestPages = $this->latestPages(1);
}

and then

{% for posts in latestPages %}

example of a similar thing: https://github.com/getgrav/grav-plugin-comments/blob/develop/comments.php#L56-L64 (see other plugins code too)

Thanks - with a little tweaking I now have it working. I wasn’t calling the plugin with grav.twig.latestPages… That fixed things - Thanks!