Advanced dashboard API for Drupal

Installs: 206

Dependents: 0

Suggesters: 0

Stars: 1

Watchers: 10

Forks: 2

Open Issues: 7


1.0.3 2017-07-05 08:29 UTC


This initial version is a raw export of the ucms_dashboard from the Drupal module suite. Only namespaces have been changed, and a few utility functions moved from the ucms_contrib module.

It should be stable enough to use.


It depends heavily on makinacorpus/drupal-sf-dic, the easiest way to install is:

composer install makinacorpus/drupal-udashboard


Runtime configuration

Enable top toolbar

$conf['udashboard.context_pane_enable'] = true;

Enable context pane

$conf['udashboard.context_pane_enable'] = true;

Enable admin pages breadcrumb alteration

This is a very specific setting for usage with UCMS.

$conf['udashboard.breadcrumb_alter'] = true;

Display configuration

Disable custom CSS

If you wish to embed this module's CSS or custom LESS into your own custom theme, you might wish to disable CSS loading:

$conf['udashboard.disable_css'] = true;

Drupal seven theme fixes

By setting this to true, seven fixes will always be included:

$conf['udashboard.seven_force'] = true;

By setting it to false, the will be always dropped.

By removing the variable or setting it to null seven admin theme will be automatically detected at runtime and fixes will be loaded if necessary.



This module takes the philosophy from SOLID principles, for this to work, you will need to create:

  • a Controller
  • a DataSource
  • a twig template
  • possibly an ActionProvider

To demo this, we will replace the user administration from Drupal core.

Bind with Drupal

 * Implements hook_menu_alter().
function mymodule_menu_alter(&$items) {
  $items['admin/people']['page callback'] = 'sf_dic_page';
  $items['admin/people']['page arguments'] = [AccountController::class . '::accountList'];

The AccountController::actionListAction method will be called when hitting admin/people.



use MakinaCorpus\Drupal\Dashboard\Controller\PageControllerTrait;
use MakinaCorpus\Drupal\Sf\Controller;
use Symfony\Component\HttpFoundation\Request;

 * User admin
class AccountController extends Controller
     * Main list
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @return string
    public function accountListAction(Request $request)
        /** @var \MakinaCorpus\Drupal\Dashboard\Page\DatasourceInterface $datasource */
        $datasource = $this->get('mymodule.datasource.account');

        return $this
              'table' => 'module:mymodule:Page/page-account.html.twig',

As you can see, our controller depends on a datasource and a template.


A DefaultAccountDatasource is available and abstracts the main part of querying the users table, but you can add you own sorts for example


namespace MyModule\Page;

use MakinaCorpus\Drupal\Dashboard\Page\Account\DefaultAccountDatasource;
use MakinaCorpus\Drupal\Dashboard\Page\PageState;

 * Account Datasource
class AccountDatasource extends DefaultAccountDatasource
     * Add our own columns
     * @inheritdoc
    public function getSortFields($query)
        $sortFields = parent::getSortFields($query);

        $sortFields['m.myfield_value'] = "my field";

        return $sortFields;

    protected function applyFilters(\SelectQueryInterface $select, $query, PageState $pageState)
        $select->leftJoin('field_data_myfield', 'm', 'm.entity_id = u.uid');

It must be desclared in your

    public: true
    shared: false
    class: MyModule\Page\AccountDatasource
    arguments: ["@database", "@entity.manager"]


The template extends module:udashboard:views/Page/page.html.twig which provides the main components for display a table of items. All you have to do is override the columns and rows:

{% extends 'module:udashboard:views/Page/page.html.twig' %}

{%- block item -%}
    <tr class="separator">
        <td>{{ }}</td>
        <td>{{ item.myfield.und.0.value }}</td>
                {% for role in item.roles %}
                    {% if role != 'authenticated user' %}
                        <li>{{ role }}</li>
                    {% endif %}
                {% endfor %}
        <td>{{ item.created|date('d/m/Y H:i') }}</td>
        <td>{{ item.access|date('d/m/Y H:i') }}</td>
        <td>{{ item.status ? 'Yes'|t : 'No'|t }}</td>
        <td class="actions">{{ udashboard_primary(item) }}</td>
{%- endblock -%}

{% block item_list %}
    <table class="table table-striped table-condensed table-demandes">
            <th>My Field</th>
            <th>Member since</th>
            <th>Last access</th>
        {% for item in items %}
            {{ block('item') }}
        {% else %}
                <td colspan="9">
                    No account to display.
        {% endfor %}
{% endblock %}

Action provider

An action provider is not mandatory but it allows to add actions on items. Example for an account:


namespace MyModule\Action;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\user\User;
use MakinaCorpus\Drupal\Dashboard\Action\Action;
use MakinaCorpus\Drupal\Dashboard\Action\ActionProviderInterface;

 * Action provider for accounts
class AccountActionProvider implements ActionProviderInterface
    use StringTranslationTrait;

     * @inheritdoc
    public function getActions($item, $primaryOnly = false, array $groups = [])
        $ret = [];

        $ret[] = new Action($this->t("Edit"), 'user/'.$item->id().'/edit', null,'pencil', 0, true, false);
        $ret[] = new Action($this->t("Delete"), 'user/'.$item->id().'/cancel', null, 'trash', 2, true, false);

        return $ret;

     * {@inheritDoc}
    public function supports($item)
        return $item instanceof User;

It must be declared in your

    public: false
    class: MyModule\Action\AccountActionProvider
    tags: [{name: udashboard.action_provider}]