CMS - Widgets
Creating your own Widget
## Introduction
---
**ABC Manager dashboard Widgets** is a CMS interface extension that allows you
to extend the application and global dashboard with your own set of view logic, supported
by CSS and JavaScript assets. Widgets are in fact simple HTTP controllers that
provide an api for a Vue JS template.
In this demonstration we will explain how to create a Widget based on the widget
called "CMS User Information", currently visible on the global CMS dashboard for "administrator" users.
Please read our [Widget](https://docs.angrybytes.com/p/abc-manager/6.0/docs/cms/widgets/index.html)
documentation chapter first.
![Widget](/bundles/demopublicationbundle/img/demo/widget.png)
*The end result*
This demonstration assumes you have already read the documentation about creating a Widget and will not explain the details in depth.
Note - all demonstrations occur in realtime! Open this project in your IDE to view and/or
modify the actual source code used in the demonstrations.
### The Widget
This Widget has been created for demonstration purposes only, but will show
you how to display possible useful information for administrators on an application
dashboard and does this based on live CMS user data.
It shows you an overview of CMS users. Security related information such as "account expiration date" is displayed
along each user.
We will now describe how the Widget has been created.
### The Widget Controller
Widgets are simple HTTP controllers. Each Widget extends the base class `Abc\BackendBundle\Widget`
and must implement the remaining Interface methods.
The Widget controller's main tasks are:
* create api data for the widget.
* providing a unique ID.
* setting a size (optional).
* setting a user role (optional).
Lets take a look at the controller first, which is `Demo\ContentBundle\BackendInterface\Widget\Admin\UserInfoWidget`
for our Widget.
The basic class structure looks as follows:
```php
// File: ./src/Demo/ContentBundle/BackendInterface/Widget/Admin/UserInfoWidget.php
namespace Demo\ContentBundle\BackendInterface\Widget\Admin;
use Abc\BackendBundle\Widget;
final class UserInfoWidget extends Widget
{
/**
* {@inheritDoc}
*/
public function getId(): string
{
return 'admin_user_info';
}
/**
* {@inheritDoc}
*/
public function getView(): string
{
return 'user_info';
}
/**
* {@inheritDoc}
*/
public function getSize(): string
{
return Widget::SIZE_LARGE;
}
/**
* {@inheritDoc}
*/
public function getRoleBasedAccessLevel(): int
{
return \Abc\AuthBundle\Access\RoleBased::LEVEL_ADMIN;
}
/**
* {@inheritDoc}
*/
public function dispatchGet(Request $request): Response
{
$resource = new Collection(...);
return $this->json(
$this->getFractalManager()->createData($resource)->toArray()
);
}
/**
* {@inheritDoc}
*/
public function dispatchPost(Request $request): Response
{
$resource = new Collection(...);
return $this->json(
$this->getFractalManager()->createData($resource)->toArray()
);
}
}
```
All other methods in the class are custom made for the Widget self. The methods
listed above are all you have to implement to fully customize your Widget.
The `getId()` method should provide a *unique id* for our Widget, used by our Widgets
collection. It is wise to prefix this with an application or bundle identifier so
there will be less chance for conflicts across bundles.
The `getView()` is used to match the name given when merging ABC widgets together
with your own custom widgets.
The method `getSize()` defines the Widget size. Valid options are: `Widget::SIZE_SMALL`,
`Widget::SIZE_MEDIUM` and `Widget::SIZE_LARGE`.
The method `getRoleBasedAccessLevel()` tells ABC Manager to display the Widget for
all users or *administrator* users only. Return the `Widget::ROLE_ADMIN` constant
if the latter is the case.
The `dispatchPost()` method is used a endpoint for the widget. This method handles
the GET request from the widget.
Finally, the `dispatchPost()` method is used a endpoint for the widget. This
method handles the POST request from the widget.
Take a look at all the other logic inside the Widget if you like. It handles
the CMS User data required by the Widget to be injected into the Twig template.
### Registration
When the controller is created, we can now register it in the service container
and the application's widget file so it will be displayed in the CMS.
First, lets register it in the service container:
```yaml
# File: ./src/Demo/ContentBundle/Resources/config/services/cms-widgets.yml
services:
# User info widget
demo.cms.widget.admin.user_info:
class: Demo\ContentBundle\BackendInterface\Widget\Admin\UserInfoWidget
arguments:
- '@cms.auth.user'
tags:
- name: abc.backend.widget
id: admin_user_info
```
Note that Widget is "tagged" with static name `cms.backend.widget` and provides
the Widget's ID value as well: `id: admin_user_info`, this is required as ABC Manager
uses the tag `name` to collect all Widgets for the `cms` application and
registers the Widget into the collection by its `id`.
Now that our Widget is tagged and exposed by the Bundle, we can create the YAML file
that defines which Widgets are loaded on the application dashboard.
Create a file named `widgets.yml` at `project/Resources/config/`.
The file defines Widgets in *multiple rows*, allowing you to group several Widgets
together:
```YAML
# File: ./project/Resources/config/widgets.yml
# CMS Global Dashboard Widgets.
widgets:
- id: admin_user_info
- id: ...
```
The Widget is hereby [visible](https://acc-cms.abc-demo.angrybytes.com/) on the global CMS dashboard.