Widgets

Widget extensions control dashboard widget configuration, data, and output.

Widget Extension

This section will go over the \Anomaly\DashboardModule\Widget\Extension\WidgetExtension class.

WidgetExtension::$view

The view property defines the widget's content view.

protected $view = 'anomaly.extension.xml_feed_widget::view';

The default value is null and will default to looking for resources/views/content.twig.

WidgetExtension::$wrapper

The wrapper property defines the outer wrapper view for the widget output. The default value is the wrapper included in the Dashboard module:

protected $wrapper = 'anomaly.module.dashboard::admin/widgets/widget';
WidgetExtension::load()

The load method is responsible for loading the data into the widget for display later.

Returns: void
Arguments
Key Required Type Default Description
$widget true `WidgetInterface` none The widget entry instance.
WidgetExtension::content()

The content method is responsible for setting the content on the widget. This method normally won't need overriding in your own extensions.

Returns: void
Arguments
Key Required Type Default Description
$widget true `WidgetInterface` none The widget entry instance.
WidgetExtension::output()

The output method returns the rendered widget output including the wrapper. This method runs the load and content methods before returning the rendered output. You can override this method to inject additional processing before output.

Returns: string
Arguments
Key Required Type Default Description
$widget true `WidgetInterface` none The widget entry instance.

Writing Widgets

This section will show you how to write your own custom dashboard widget.

Creating the extension

The first thing we need to do is to use the make:addon command to create our extension:

php artisan make:addon anomaly.extension.xml_feed_extension
Extending the widget extension

The extension you create must extend the \Anomaly\DashboardModule\Widget\Extension\WidgetExtension class:

<?php namespace Anomaly\XmlFeedWidgetExtension;

use Anomaly\DashboardModule\Widget\Contract\WidgetInterface;
use Anomaly\DashboardModule\Widget\Extension\WidgetExtension;
use Anomaly\XmlFeedWidgetExtension\Command\LoadItems;

class XmlFeedWidgetExtension extends WidgetExtension
{

    /**
     * This extension provides the "Recent News"
     * widget for the main dashboard.
     *
     * @var string
     */
    protected $provides = 'anomaly.module.dashboard::widget.xml_feed';

    /**
     * Load the widget data.
     *
     * @param WidgetInterface $widget
     */
    protected function load(WidgetInterface $widget)
    {
        $this->dispatch(new LoadItems($widget));
    }
}

You must define the provides property as anomaly.module.dashboard::widget.your_widget_slug so that it's picked up as a supported extension.

Defining extension configuration

Most every widget and even extension will likely need configuration to differentiate it from other same instances. In this example we want to allow users to define a custom XML feed URL if desired. Create a resources/config/configuration.php file to define your fields for the Configuration module:

<?php

return [
    'url' => [
        'type'   => 'anomaly.field_type.url',
        'config' => [
            'default_value' => 'http://www.pyrocms.com/posts/rss.xml',
        ],
    ],
];
Load widget data

The primary task of any widget is loading data into the widget in order to display it later. In this example we will use a command thats dispatched within the load method:

protected function load(WidgetInterface $widget)
{
    $this->dispatch(new LoadItems($widget));
}

Our LoadItems command is responsible for loading the data:

<?php namespace Anomaly\XmlFeedWidgetExtension\Command;

use Anomaly\ConfigurationModule\Configuration\Contract\ConfigurationRepositoryInterface;
use Anomaly\DashboardModule\Widget\Contract\WidgetInterface;
use Illuminate\Contracts\Cache\Repository;

class LoadItems
{

    /**
     * The widget instance.
     *
     * @var WidgetInterface
     */
    protected $widget;

    /**
     * Create a new LoadItems instance.
     *
     * @param WidgetInterface $widget
     */
    public function __construct(WidgetInterface $widget)
    {
        $this->widget = $widget;
    }

    /**
     * Handle the widget data.
     *
     * @param \SimplePie                       $rss
     * @param Repository                       $cache
     * @param ConfigurationRepositoryInterface $configuration
     */
    public function handle(\SimplePie $rss, Repository $cache, ConfigurationRepositoryInterface $configuration)
    {
        $items = $cache->remember(
            __METHOD__ . '_' . $this->widget->getId(),
            30,
            function () use ($rss, $configuration) {

                $rss->enable_cache(false);

                $rss->set_feed_url(
                    $configuration->value(
                        'anomaly.extension.xml_feed_widget::url',
                        $this->widget->getId(),
                        'http://www.pyrocms.com/posts/rss.xml'
                    )
                );

                // Make the request.
                $rss->init();

                return $rss->get_items(0, 5);
            }
        );

        $this->widget->addData('items', $items);
    }
}
**Note:** Learn more about using the [Configuration module](/documentation/configuration-module).
Define the content view

The content view will display your widget content using the data loaded prior. By default the content view is defined as resources/views/content.twig within your extension:

{% for item in widget.data.items %}

    <div class="media">

        <div class="media-left">
            <i class="fa fa-calendar fa-lg text-faded"></i>
        </div>

        <div class="media-body">

            <h3 class="media-heading">
                <a href="{{ item.get_permalink() }}" target="_blank">
                    {{ item.get_title() }}
                </a>

                <br>

                <small class="text-muted">
                    {{ item.get_date()|date('F j, Y') }}
                </small>
            </h3>

            {{ item.get_description()|striptags }}

        </div>

    </div>

    {% if not loop.last %}
        <hr>
    {% endif %}

{% endfor %}