Installation:
composer require appaydin/pd-widget
Ensure Pd\WidgetBundle\PdWidgetBundle::class is enabled in config/bundles.php.
Configure Routing:
Add to config/routes.yaml:
widget:
resource: "@PdWidgetBundle/Resources/config/routing.yml"
Doctrine Mapping:
Update config/packages/doctrine.yaml to resolve UserInterface:
doctrine:
orm:
resolve_target_entities:
Pd\WidgetBundle\Entity\UserInterface: App\Entity\User
Optional Config:
Customize widget behavior in config/packages/framework.yaml:
pd_widget:
base_template: '@PdWidget/widgetBase.html.twig'
return_route: 'admin_dashboard'
Create a Widget Class:
// src/Widgets/HelloWidget.php
namespace App\Widgets;
use Pd\WidgetBundle\Builder\Item;
use Pd\WidgetBundle\Event\WidgetEvent;
class HelloWidget {
public function builder(WidgetEvent $event) {
$widgets = $event->getWidgetContainer();
$widgets->addWidget(
(new Item('hello', 3600))
->setGroup('demo')
->setName('hello_widget.name')
->setTemplate('widgets/hello.html.twig')
->setData(['message' => 'Hello, World!'])
);
}
}
Register the Widget:
# config/services.yaml
App\Widgets\HelloWidget:
tags:
- { name: kernel.event_listener, event: widget.start, method: builder }
Render the Widget:
{% extends 'base.html.twig' %}
{% block body %}
{{ pd_widget_render('demo') }}
{% endblock %}
Create the Template:
# templates/widgets/hello.html.twig
<div class="widget-hello">
<h3>{{ widget.data.message }}</h3>
</div>
Event-Driven Workflow:
widget.start event.WidgetEvent to access the container and add widgets dynamically.Grouping and Filtering:
admin, dashboard).{{ pd_widget_render('admin') }} {# All widgets in 'admin' group #}
{{ pd_widget_render('admin', ['user_info']) }} {# Only 'user_info' widget #}
Data Handling:
setData() to pass dynamic data to templates:
->setData(function () {
return ['userCount' => $this->userRepository->count()];
})
widget.data.Caching:
Item constructor:
(new Item('widget_key', 3600)) {# Cache for 1 hour #}
Dynamic Widgets:
setData():
->setData(function () use ($request) {
return ['active' => $request->isXmlHttpRequest()];
})
Role-Based Access:
->setRole(['ROLE_ADMIN'])
Reusable Templates:
{% extends pd_widget.base_template %}
{% block widget_content %}
{{ parent() }}
<div class="custom-styles">{{ widget.data.message }}</div>
{% endblock %}
Action Buttons:
@PdWidget/widgetAction.html.twig:
{% include '@PdWidget/widgetAction.html.twig' %}
Admin Panel Integration:
users, settings).Frontend Dashboards:
{{ pd_widget_render('dashboard', ['stats']) }}
Testing:
WidgetEvent in unit tests:
$event = $this->createMock(WidgetEvent::class);
$event->method('getWidgetContainer')->willReturn($container);
$widget->builder($event);
Doctrine UserInterface Mismatch:
resolve_target_entities in doctrine.yaml points to your actual User entity.Caching Issues:
php bin/console cache:clear
0 to test live updates.Template Overrides:
pd_widget_render() outputs nothing, verify:
widgets/userInfo.html.twig).isActive in Twig).Event Listener Registration:
tags: [kernel.event_listener] is present in services.yaml.Deprecated Properties:
setContent() for static text. Prefer setData() + template for flexibility.Log Widget Data: Add a debug dump in your widget builder:
public function builder(WidgetEvent $event) {
$widgets = $event->getWidgetContainer();
$widgets->addWidget((new Item('debug', 0))
->setData(function () {
return ['debug' => 'Widget loaded!'];
})
);
}
Check Active Widgets: In Twig, dump active widgets to verify rendering:
{{ dump(pd_widget_render('admin', [], true)) }} {# Show raw widget data #}
Event Dispatcher:
Ensure the widget.start event is dispatched. Add a listener to verify:
public function onKernelRequest(GetResponseEvent $event) {
$event->getRequest()->attributes->set('widgets_loaded', true);
}
Custom Base Template:
Override base_template in config to modify widget styling globally:
pd_widget:
base_template: 'custom_widget_base.html.twig'
Dynamic Widget Groups: Build groups dynamically based on user roles or permissions:
->setGroup($this->security->getToken()->getUser()->getRole())
Widget Actions:
Extend @PdWidget/widgetAction.html.twig to add custom buttons:
{# templates/widgets/custom_actions.html.twig #}
<button class="btn-edit">{{ 'widget.edit'|trans }}</button>
Internationalization: Use translation keys for widget names/descriptions:
->setName('widget.user_info.name')
Ensure translations are loaded in your Twig environment.
Performance:
setData():
->setData(function () {
return $this->expensiveService->getData(); // Load only when needed
})
setCacheDuration(0) for real-time widgets.How can I help you explore Laravel packages today?