🎯 Intelligent Dashboard für REDAXO CMS
Das Info Center ist ein intelligentes Dashboard-System für REDAXO CMS, das wichtige Informationen und Quick-Actions direkt im Backend und Frontend bereitstellt. Es bietet sowohl vorgefertigte Widgets als auch einen revolutionären Widget Builder für benutzerdefinierte Dashboards.
- 🔍 Search Widget - Livr-Suche mit Quick Actions
- 🏗️ Struktur-Navigation - Interaktiver Kategoriebaum mit Lazy Loading, Domain-Filterung und direkten Frontend-Links
- 📊 Performance Stats - Ladezeiten, Speicherverbrauch, DB-Queries
- ⏱️ TimeTracker - Arbeitszeit-Tracking mit Pausen und Berichten
- 📝 Artikel Widget - Zuletzt bearbeitete Inhalte mit direkten Links
- 🔗 URL Widget - URL2/YRewrite Datensätze verwalten
- 🛠️ Upkeep Integration - Wartungs-Status auf einen Blick
- ⚙️ System-Informationen - Server-Status und PHP-Infos
- 🔧 No-Code Widgets - Erstelle eigene Widgets ohne Programmierung
- 📊 YForm Integration - Beliebige YForm-Tabellen als Widgets
- 🎯 Feldauswahl - Wähle spezifische Felder oder lass das System entscheiden
- 🔍 Erweiterte Filter - SQL-basierte Filterung für präzise Ergebnisse
- 🔗 Flexible Verlinkung - YForm, URL Addon, YRewrite oder Custom URLs
- 👁️ Sichtbarkeits-Control - Backend-only, Frontend-only oder beide
- 🌍 Mehrsprachig - Deutsch und Englisch vollständig unterstützt
- 📱 Responsive Design - Optimal auf allen Geräten
- 🌙 Dark/Light Mode - Automatisch oder manuell wählbar
- 📍 Flexible Positionierung - Links oder rechts positionierbar
- 👤 Benutzer-spezifisch - Individuelle Widget-Konfiguration pro User
- 🔄 Auto-Refresh - Intelligente Aktualisierung der Daten
- REDAXO 5.18+
- PHP 8.1+
- YForm AddOn (für Widget Builder)
- AddOn hochladen und installieren
- Berechtigungen setzen (siehe Konfiguration)
- Widgets konfigurieren unter
AddOns → Info Center → Einstellungen - Custom Widgets erstellen mit dem Widget Builder
Der Widget Builder ist ein No-Code Tool, mit dem Administratoren eigene Dashboard-Widgets erstellen können - ohne eine Zeile Code zu schreiben!
✅ Widget-Name vergeben
✅ YForm-Tabelle auswählen
✅ Anzahl der Datensätze festlegen (1-50)
🔄 Felder werden automatisch nach Tabellen-Auswahl geladen
✅ Spezifische Felder auswählen oder alle verwenden
📋 System-Felder werden automatisch erkannt
-- Beispiele für Filter-Bedingungen:
status = 1
createdate >= CURDATE() - INTERVAL 30 DAY
status = 1 AND email LIKE '%@company.com'- 🔗 YForm Links - Direkte Bearbeitung (empfohlen)
- 🎨 URL Addon - Saubere URLs mit Schema
- 📝 YRewrite - Strukturierte URL-Generierung
- ⚙️ Custom URLs - Freie Platzhalter:
{id},{name}, etc. - 🚫 Keine Links - Nur Anzeige
- 🌐 Backend + Frontend - Überall sichtbar
- 🖥️ Nur Backend - Nur im REDAXO Backend
- 🌍 Nur Frontend - Nur im Frontend für Backend-User
- CSRF-Schutz - Automatische Token-Generierung
- Session-Management - Frontend-Backend-Verknüpfung
- Berechtigung-Prüfung - Sichere Zugriffskontrolle
- Artikel-Style - Wie "Zuletzt bearbeitet" Widget
- Meta-Informationen - Zusätzliche Feld-Anzeige
- Auto-ID-Loading - Automatische ID-Extraktion für Links
- Responsive Layout - Optimal auf allen Geräten
- Deutsche Oberfläche - Komplette deutsche Übersetzung
- English Interface - Full English translation support
- Dynamic Localization - Automatische Spracherkennung
Ein interaktiver Kategoriebaum direkt im Info Center - perfekt für schnelle Navigation durch komplexe REDAXO-Strukturen!
- Hierarchische Darstellung - Kategorien und Artikel in Baumstruktur
- Akkordeon-Navigation - Ein-/Ausklappbare Kategorien
- Auto-Expansion - Automatisches Öffnen zur aktuellen Position
- Sortierung - Unterkategorien zuerst, dann Artikel
- Status-Indikatoren - Farbcodierung (REDAXO Blau=Online, Grau=Offline, Rot=Gesperrt)
- Frontend-Preview - Direkter Link zur Seite im Frontend (👁️ Auge-Icon)
- Backend-Edit - Schneller Zugriff auf Bearbeitung (✏️ Stift-Icon)
- Target="_blank" - Frontend-Links öffnen in neuem Tab
- Smooth Transitions - Butterweiche Animationen beim Hover
- Kompaktes Layout - Optimale Platznutzung
- Für alle Elemente - Kategorien UND Artikel haben beide Buttons
- Echtzeit-Filter - 300ms Debounce für Performance
- Smart-Matching - Suche in Namen und IDs
- Parent-Expansion - Gefundene Elemente werden automatisch angezeigt
- Highlight-Effekt - Suchergebnisse werden hervorgehoben
- Domain-Switcher - Automatisch bei > 1 Domain mit Mountpoint
- Filter nach Domain - Zeige nur Struktur einer Domain
- "Alle Domains" - Standard-Ansicht zeigt alles
- Intelligente Erkennung - Nur echte Domains, keine Default-Entries
- Glassmorphism Design - Moderne Optik mit Backdrop-Blur
- Smooth Transitions - Butterweiche Animationen (cubic-bezier)
- Hover-Effekte - Action-Buttons erscheinen bei Hover
- Dark/Light Mode - Automatische Theme-Anpassung
- Responsive - Perfekt auf allen Bildschirmgrößen
- Keine IDs sichtbar - Nur bei Hover im Tooltip (saubere UI)
- Lazy Loading - API-basiertes Laden großer Strukturen (ab 100 Kategorien)
- Smart Caching - Intelligente Refresh-Logik
- Debounced Search - Optimierte Suche ohne Server-Last
- Permission-Check - Respektiert REDAXO Benutzerrechte
- Progressive Enhancement - Lädt nur sichtbare Elemente bei Bedarf
- 👁️ Frontend ansehen - Linker Button öffnet Seite im neuen Tab
- ✏️ Backend bearbeiten - Rechter Button öffnet Editor
- Tooltips - Zeigt Domain und ID bei Hover
- Für alle Elemente - Kategorien UND Artikel haben beide Buttons
- Kategorie-Klick - Öffnet Struktur-Seite
- Artikel-Klick - Öffnet Artikel im Edit-Modus
- Frontend-Button - Öffnet mit YRewrite oder rex_getUrl()
- Suchfeld - Live-Suche in Kategorien und Artikeln
- Domain-Dropdown - Filter nach YRewrite-Domain (bei Multi-Domain)
- Status-Filter - Visuell nach Online/Offline/Gesperrt
- REDAXO Blau (#4b9ad9) - Online/Veröffentlicht
- Grau (#6c757d) - Offline/Unveröffentlicht
- Rot (#ef4444) - Gesperrt/Status 2
Eine Spotlight-ähnliche Universalsuche direkt im Info Center - durchsuche alle wichtigen REDAXO-Inhalte mit einer Eingabe!
- Artikel - Durchsucht Namen, Titel und alle Content-Felder (value1-20)
- Kategorien - Findet Kategorien in der Struktur
- Module - Sucht in Modul-Namen und Code
- Templates - Durchsucht Template-Namen und Code
- Medien - Findet Bilder, Videos und andere Dateien im Mediapool
- 🧮 Rechner - Direkte Berechnung (z.B.
2+2,15*20%,(100+50)/2)- Automatisches Kopieren des Ergebnisses in die Zwischenablage
- 📚 Wikipedia - Suche mit Live-Vorschau (z.B.
wiki REDAXO)- REST API Integration mit 500 Zeichen Vorschau
- Öffnet vollständigen Artikel bei Klick
- 📖 Wörterbuch - Definition nachschlagen (z.B.
define CMS)- Wiktionary HTML API Integration mit echter Definition
- Zeigt erste Definition mit 500 Zeichen Vorschau
- 📝 Blindtext - Generator für Platzhaltertexte (z.B.
blindtext 500)- 8 verschiedene lustige deutsche Texte (kein Lorem Ipsum!)
- Automatisches Kopieren in Zwischenablage
- Intelligenter Schnitt am Satzende
- 🔗 URL-Erkennung - URLs werden automatisch erkannt und sind direkt öffenbar
- 📅 Datum-Filter
#modified:today- Heute geändert#modified:yesterday- Gestern geändert#modified:last-week- Letzte Woche geändert#modified:last-month- Letzter Monat geändert#modified:2024-12-05- An bestimmtem Datum geändert#created:today- Heute erstellt#created:last-week- Letzte Woche erstellt
- 👤 User-Filter
#author:username- Erstellt von User#editor:username- Bearbeitet von User
- 🎯 Kombinationen
Startseite #modified:today- "Startseite" heute geändert#author:admin #created:last-week- Von Admin letzte Woche erstellt#modified:yesterday #editor:admin- Gestern von Admin bearbeitet
- Bild-Thumbnails - 32x32px Vorschau, 200x200px bei Hover
- Video-Vorschau - Tooltip mit Autoplay bei Hover
- Code-Snippets - Zeigt Treffer-Kontext bei Modulen/Templates
- Optimierte Bilder - Nutzt Media Manager (rex_media_small)
- Berechtigungsprüfung - Respektiert User-Rechte für Struktur/Medien
- Extension Point -
INFO_CENTER_SEARCHfür AddOn-Integration - Keyboard-Navigation - ↑↓ für Navigation, Enter zum Öffnen, ESC zum Schließen
- ⌘K Shortcut - Schneller Zugriff via Tastenkombination
- Live-Suche - Sofortige Ergebnisse ohne Reload
REDAXO → Findet alle Inhalte mit "REDAXO"
template → Sucht in Templates und Modulen
logo.png → Findet Mediendateien
2+2 → Rechner: = 4 (kopiert in Zwischenablage)
15*20% → Rechner: = 3
wiki Berlin → Wikipedia mit Live-Vorschau
define CMS → Wörterbuch-Definition aus Wiktionary
blindtext 500 → Generiert 500 Zeichen deutschen Blindtext
https://... → URL wird erkannt und kann geöffnet werden
qr https:// → QRCODE in PNG oder SVG
#modified:today → Heute geänderte Inhalte
#created:yesterday → Gestern erstellte Inhalte
#author:admin → Von Admin erstellte Inhalte
#editor:username → Von User bearbeitete Inhalte
Startseite #modified:today → "Startseite" heute geändert
#author:admin #created:last-week → Von Admin letzte Woche erstellt
- ⌘K oder Ctrl+K - Search Widget fokussieren
- ↑/↓ - Durch Ergebnisse navigieren
- Enter - Ausgewähltes Ergebnis öffnen
- ESC - Suche schließen
Das Search Widget kann in den Einstellungen aktiviert/deaktiviert werden und unterstützt alle Standard-Widget-Optionen.
# Position des Info Centers
position: right # oder 'left'
# Theme-Modus
darkmode: auto # 'auto', 'light', 'dark'
# Widget-Aktivierung
widgets:
search: { enabled: true, prio: -10 } # Search Widget (NEU!)
article: { enabled: true, prio: 1 }
timetracker: { enabled: true, prio: 0 }
stats: { enabled: true, prio: 5 }
structure: { enabled: true, prio: 2 }
# ... weitere WidgetsJeder Benutzer kann individuell konfigurieren:
- ✅ Welche Widgets angezeigt werden
- ✅ Widget-Reihenfolge anpassen
- ✅ Persönliche Präferenzen
permissions:
info_center: "Info Center anzeigen"
info_center[config]: "Info Center konfigurieren"
info_center[admin]: "Widget Builder verwenden"- Backend-User im Frontend - Automatische Erkennung
- Session-Verknüpfung - Nahtlose Backend-Integration
- Responsive Design - Optimal auf allen Geräten
- Asset-Management - Automatisches CSS/JS Loading
/* Automatische Anpassung */
@media (max-width: 768px) {
/* Mobile Optimierung */
}
@media (min-width: 1200px) {
/* Desktop Volldarstellung */
}src/addons/info_center/
├── lib/
│ ├── InfoCenter.php # Hauptklasse - Singleton für Widget-Management
│ ├── AbstractWidget.php # Basisklasse für alle Widgets
│ ├── WidgetInterface.php # Interface-Definition für Widgets
│ ├── api_widget_builder.php # AJAX-API für Widget Builder
│ └── Widgets/
│ ├── ArticleWidget.php # Zuletzt bearbeitete Artikel
│ ├── TimeTrackerWidget.php # Arbeitszeit-Tracking
│ ├── CustomListWidget.php # Widget Builder Ausgabe
│ ├── StatsWidget.php # Performance-Statistiken
│ ├── SystemWidget.php # System-Informationen
│ ├── UpkeepWidget.php # Upkeep-Integration
│ └── UrlWidget.php # URL2/YRewrite-Management
├── pages/
│ ├── config.php # Konfigurationsseite
│ ├── index.php # Hauptübersicht
│ └── widget_builder.php # Widget Builder Interface
├── assets/
│ ├── css/
│ │ ├── info-center.css # Haupt-Styling
│ │ └── timetracker.css # TimeTracker-spezifische Styles
│ └── js/
│ ├── info-center.js # Haupt-JavaScript
│ └── timetracker.js # TimeTracker-Funktionalität
└── lang/
├── de_de.lang # Deutsche Übersetzungen
└── en_gb.lang # Englische Übersetzungen
Die zentrale Singleton-Klasse für das Widget-Management.
// Singleton-Instanz erhalten
InfoCenter::getInstance(): InfoCenter
// Widget registrieren
registerWidget(WidgetInterface $widget): void
// Alle registrierten Widgets abrufen
getWidgets(): array
// HTML-Output des kompletten Info Centers
get(): string
// Prüfen ob das Info Center gerendert werden soll
shouldRender(): boolAbstrakte Basisklasse für alle Widgets mit Standard-Implementierungen.
protected string $id; // Eindeutige Widget-ID
protected string $title; // Widget-Titel
protected float $priority; // Sortierung (niedrigere Zahl = höher)
protected bool $enabled; // Aktivierungs-Status
protected array $config; // Widget-Konfiguration
protected bool $supportsLazyLoading; // Lazy Loading Support// Eindeutige Widget-ID (automatisch aus Klassenname)
getId(): string
// Widget-Titel (aus Sprachdatei oder direkt)
getTitle(): string
// Priorität für Sortierung
getPriority(): float
setPriority(float $priority): void
// Aktivierungs-Status
isEnabled(): bool
setEnabled(bool $enabled): void
// Konfiguration
getConfig(string $key = null): mixed
setConfig(array $config): void
// Content in Widget-Container wrappen
wrapContent(string $content, array $attributes = []): string
// Lazy Loading Support
supportsLazyLoading(): bool
getInitialContent(): string // Muss implementiert werden wenn Lazy LoadingDefiniert die erforderlichen Methoden für alle Widgets.
interface WidgetInterface
{
public function getId(): string;
public function getTitle(): string;
public function getPriority(): float;
public function setPriority(float $priority): void;
public function isEnabled(): bool;
public function setEnabled(bool $enabled): void;
public function getConfig(string $key = null): mixed;
public function setConfig(array $config): void;
public function render(): string; // Haupt-Render-Methode
public function supportsLazyLoading(): bool;
public function getInitialContent(): string; // Für Lazy Loading
public function wrapContent(string $content, array $attributes = []): string;
}<?php
// Datei: src/addons/project/lib/InfoCenterWidgets/NewsWidget.php
namespace Project\InfoCenterWidgets;
use KLXM\InfoCenter\AbstractWidget;
use rex_i18n;
use rex_sql;
use rex_escape;
use rex_url;
class NewsWidget extends AbstractWidget
{
public function __construct()
{
parent::__construct();
$this->title = rex_i18n::msg('project_news_widget_title', 'Aktuelle News');
$this->priority = 15; // Nach System-Widgets, vor Custom Widgets
}
public function render(): string
{
// Daten aus der Datenbank holen
$sql = rex_sql::factory();
$sql->setQuery('
SELECT id, title, createdate, status
FROM rex_news
WHERE status = 1
ORDER BY createdate DESC
LIMIT 5
');
if (!$sql->getRows()) {
return $this->wrapContent(
'<p class="text-muted">' . rex_i18n::msg('project_no_news_found', 'Keine News gefunden') . '</p>'
);
}
$content = '<div class="info-center-list">';
foreach ($sql->getArray() as $row) {
$editUrl = rex_url::backendController([
'page' => 'content/articles',
'article_id' => $row['id'],
'clang' => 1
]);
$content .= sprintf(
'<div class="info-center-list-item">
<div class="item-title">
<a href="%s" title="%s">%s</a>
</div>
<div class="item-meta">
<span class="date">%s</span>
<span class="status status-%s">%s</span>
</div>
</div>',
$editUrl,
rex_escape($row['title']),
rex_escape($row['title']),
strftime('%d.%m.%Y', $row['createdate']),
$row['status'],
$row['status'] ? 'Online' : 'Offline'
);
}
$content .= '</div>';
return $this->wrapContent($content, [
'data-widget' => 'news',
'class' => 'widget-news'
]);
}
}<?php
// Datei: src/addons/project/boot.php
// Info Center Widget registrieren (nur wenn Info Center verfügbar ist)
if (rex_addon::get('info_center')->isAvailable()) {
// Widget nach Info Center Boot registrieren
rex_extension::register('PACKAGES_INCLUDED', function() {
$infoCenter = \KLXM\InfoCenter\InfoCenter::getInstance();
// News Widget registrieren
$newsWidget = new \Project\InfoCenterWidgets\NewsWidget();
$infoCenter->registerWidget($newsWidget);
// Weitere eigene Widgets...
}, rex_extension::LATE);
}// Datei: src/addons/project/lang/de_de.lang
project_news_widget_title = Aktuelle News
project_no_news_found = Keine aktuellen News vorhanden
// Datei: src/addons/project/lang/en_gb.lang
project_news_widget_title = Recent News
project_no_news_found = No recent news available<?php
namespace Project\InfoCenterWidgets;
use KLXM\InfoCenter\AbstractWidget;
class AdvancedStatsWidget extends AbstractWidget
{
protected bool $supportsLazyLoading = true;
public function __construct()
{
parent::__construct();
$this->title = 'Erweiterte Statistiken';
$this->priority = 8;
}
/**
* Schnell ladender Initial-Content
*/
public function getInitialContent(): string
{
return '<div class="loading-placeholder">Lade Statistiken...</div>';
}
/**
* Vollständiger Content (wird via AJAX geladen)
*/
public function render(): string
{
// Aufwändige Berechnungen hier
$stats = $this->calculateComplexStats();
$content = '<div class="stats-grid">';
foreach ($stats as $key => $value) {
$content .= sprintf(
'<div class="stat-item">
<span class="stat-label">%s</span>
<span class="stat-value">%s</span>
</div>',
rex_escape($key),
rex_escape($value)
);
}
$content .= '</div>';
return $this->wrapContent($content);
}
private function calculateComplexStats(): array
{
// Komplexe Statistik-Berechnungen...
return [
'Besucher heute' => '1.234',
'Artikel gesamt' => '456',
// ...
];
}
}<?php
namespace Project\InfoCenterWidgets;
use KLXM\InfoCenter\AbstractWidget;
class ConfigurableWidget extends AbstractWidget
{
public function __construct()
{
parent::__construct();
$this->title = 'Konfigurierbares Widget';
$this->priority = 20;
// Standard-Konfiguration
$this->setConfig([
'limit' => 10,
'show_date' => true,
'category' => 'all'
]);
}
public function render(): string
{
$limit = $this->getConfig('limit');
$showDate = $this->getConfig('show_date');
$category = $this->getConfig('category');
// Widget-Logik basierend auf Konfiguration...
return $this->wrapContent($content);
}
}
// Konfiguration in boot.php setzen:
$widget = new \Project\InfoCenterWidgets\ConfigurableWidget();
$widget->setConfig([
'limit' => 20,
'show_date' => false,
'category' => 'news'
]);
$infoCenter->registerWidget($widget);<?php
// In boot.php - Widgets nur unter bestimmten Bedingungen registrieren
rex_extension::register('PACKAGES_INCLUDED', function() {
$infoCenter = \KLXM\InfoCenter\InfoCenter::getInstance();
$user = rex::getUser();
// Widget nur für Administratoren
if ($user && $user->isAdmin()) {
$adminWidget = new \Project\InfoCenterWidgets\AdminWidget();
$infoCenter->registerWidget($adminWidget);
}
// Widget nur bei vorhandenem YForm
if (rex_addon::get('yform')->isAvailable()) {
$yformWidget = new \Project\InfoCenterWidgets\YFormWidget();
$infoCenter->registerWidget($yformWidget);
}
// Widget nur für bestimmte Benutzerrollen
if ($user && $user->hasPerm('project[editor]')) {
$editorWidget = new \Project\InfoCenterWidgets\EditorWidget();
$infoCenter->registerWidget($editorWidget);
}
}, rex_extension::LATE);- Verwende Lazy Loading für aufwändige Berechnungen
- Implementiere Caching für häufig abgerufene Daten
- Nutze Sprachdateien für alle Texte
- Prüfe Berechtigungen vor der Datenanzeige
- Escape alle Ausgaben für Sicherheit
- Verwende CSS-Klassen für konsistentes Styling
- Registriere Widgets in
PACKAGES_INCLUDEDmitrex_extension::LATE
- Keine schweren DB-Queries im Constructor
- Nicht ohne Berechtigung sensible Daten anzeigen
- Keine direkten rex_sql Ausgaben ohne Escaping
- Nicht ohne Fehlerbehandlung externe APIs aufrufen
- Keine Widgets direkt in boot.php registrieren (zu früh)
src/addons/project/
├── boot.php # Widget-Registrierung
├── lib/
│ └── InfoCenterWidgets/
│ ├── NewsWidget.php # News-Widget
│ ├── UserStatsWidget.php # Benutzer-Statistiken
│ └── CustomDashboardWidget.php # Benutzerdefiniertes Dashboard
├── pages/
│ └── info_center_config.php # Konfigurationsseite
├── assets/
│ └── info-center-project.css # Widget-spezifische Styles
└── lang/
├── de_de.lang # Deutsche Übersetzungen
└── en_gb.lang # Englische Übersetzungen
<?php
// src/addons/project/boot.php
// Info Center Integration (nur wenn verfügbar)
if (rex_addon::get('info_center')->isAvailable()) {
// CSS für eigene Widgets einbinden
if (rex::isBackend() && rex::getUser()) {
rex_view::addCssFile($this->getAssetsUrl('info-center-project.css'));
}
// Widgets nach vollständiger Initialisierung registrieren
rex_extension::register('PACKAGES_INCLUDED', function() {
$infoCenter = \KLXM\InfoCenter\InfoCenter::getInstance();
$user = rex::getUser();
if (!$user) return; // Nur für eingeloggte User
// 1. News Widget - für alle Benutzer
$newsWidget = new \Project\InfoCenterWidgets\NewsWidget();
$infoCenter->registerWidget($newsWidget);
// 2. User Stats Widget - nur für Admins und Redakteure
if ($user->hasPerm('project[editor]') || $user->isAdmin()) {
$userStatsWidget = new \Project\InfoCenterWidgets\UserStatsWidget();
$infoCenter->registerWidget($userStatsWidget);
}
// 3. Admin Dashboard - nur für Admins
if ($user->isAdmin()) {
$adminWidget = new \Project\InfoCenterWidgets\CustomDashboardWidget();
$infoCenter->registerWidget($adminWidget);
}
}, rex_extension::LATE); // LATE ist wichtig!
}// Widget Builder AJAX API
fetch('/redaxo/index.php?rex-api-call=widget_builder&action=get_table_fields&table_name=my_table')
.then(response => response.text())
.then(html => {
// Feldliste verarbeiten
});
// Lazy Loading für eigene Widgets
fetch('/redaxo/index.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
},
body: 'rex-api-call=info_center_lazy&widget_id=my_widget'
})
.then(response => response.text())
.then(html => {
document.querySelector('[data-widget="my_widget"] .widget-content').innerHTML = html;
});<?php
// YForm-Tabellen als Widget anzeigen
namespace Project\InfoCenterWidgets;
use KLXM\InfoCenter\AbstractWidget;
use rex_yform_manager_dataset;
class YFormDataWidget extends AbstractWidget
{
private string $tableName;
public function __construct(string $tableName)
{
parent::__construct();
$this->tableName = $tableName;
$this->title = 'YForm: ' . $tableName;
}
public function render(): string
{
// Prüfen ob YForm verfügbar ist
if (!rex_addon::get('yform')->isAvailable()) {
return $this->wrapContent('<p>YForm nicht verfügbar</p>');
}
// Daten über YForm Manager laden
$items = rex_yform_manager_dataset::query($this->tableName)
->limit(10)
->orderBy('id', 'DESC')
->find();
$content = '<div class="yform-widget-list">';
foreach ($items as $item) {
$content .= sprintf(
'<div class="yform-item">
<a href="/redaxo/index.php?page=yform/manager/data_edit&table_name=%s&data_id=%s">
%s
</a>
</div>',
$this->tableName,
$item->getId(),
$item->getValue('name') ?: 'ID: ' . $item->getId()
);
}
$content .= '</div>';
return $this->wrapContent($content);
}
}<?php
// Widget nur im Frontend für Backend-User anzeigen
namespace Project\InfoCenterWidgets;
use KLXM\InfoCenter\AbstractWidget;
use rex;
use rex_backend_login;
class FrontendOnlyWidget extends AbstractWidget
{
public function render(): string
{
// Nur im Frontend anzeigen, wenn Backend-User eingeloggt
if (!rex::isFrontend()) {
return '';
}
// Backend-User im Frontend prüfen
$user = rex_backend_login::createUser();
if (!$user) {
return '';
}
$content = '<div class="frontend-widget">';
$content .= '<h4>Frontend-Modus aktiv</h4>';
$content .= '<p>Du siehst diese Seite als: ' . $user->getLogin() . '</p>';
$content .= '</div>';
return $this->wrapContent($content);
}
}/* Eigene Widget-Styles in project/assets/info-center-custom.css */
/* News Widget Styling */
.widget-news .info-center-list-item {
border-left: 3px solid #007cba;
padding-left: 10px;
margin-bottom: 8px;
}
.widget-news .item-title a {
font-weight: bold;
color: #333;
text-decoration: none;
}
.widget-news .item-meta {
font-size: 0.85em;
color: #666;
margin-top: 2px;
}
.widget-news .status {
padding: 2px 6px;
border-radius: 3px;
font-size: 0.8em;
}
.widget-news .status-1 {
background: #d4edda;
color: #155724;
}
.widget-news .status-0 {
background: #f8d7da;
color: #721c24;
}
/* Loading Animation für Lazy Loading Widgets */
.loading-placeholder {
display: flex;
align-items: center;
justify-content: center;
height: 60px;
color: #666;
font-style: italic;
}
.loading-placeholder::after {
content: '';
width: 16px;
height: 16px;
margin-left: 10px;
border: 2px solid #ddd;
border-top: 2px solid #007cba;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}<?php
// Eigene Widgets konfigurierbar machen
// Datei: src/addons/project/pages/info_center_config.php
$content = '';
$addon = rex_addon::get('project');
// Konfiguration verarbeiten
if (rex_post('save', 'boolean')) {
$config = rex_post('config', 'array');
// News Widget Konfiguration
$addon->setConfig('info_center_news', [
'limit' => (int) $config['news_limit'],
'show_date' => (bool) $config['news_show_date'],
'category_filter' => $config['news_category']
]);
echo rex_view::success('Konfiguration gespeichert');
}
// Aktuelle Konfiguration laden
$newsConfig = $addon->getConfig('info_center_news', [
'limit' => 5,
'show_date' => true,
'category_filter' => ''
]);
// Formular
$formElements = [];
$n = [];
$n['label'] = '<label for="news_limit">Anzahl News anzeigen:</label>';
$n['field'] = '<input type="number" id="news_limit" name="config[news_limit]" value="' . $newsConfig['limit'] . '" min="1" max="20">';
$formElements[] = $n;
$n = [];
$n['label'] = '<label for="news_show_date">Datum anzeigen:</label>';
$n['field'] = '<input type="checkbox" id="news_show_date" name="config[news_show_date]" value="1"' . ($newsConfig['show_date'] ? ' checked' : '') . '>';
$formElements[] = $n;
$fragment = new rex_fragment();
$fragment->setVar('elements', $formElements, false);
$content .= $fragment->parse('core/form/form.php');
$content .= '
<fieldset>
<input type="submit" name="save" value="Speichern" class="btn btn-primary">
</fieldset>';
$content = '<form action="' . rex_url::currentBackendPage() . '" method="post">' . $content . '</form>';
echo $content;- ✅ Vollständige deutsche Übersetzung
- ✅ Technische Begriffe korrekt übersetzt
- ✅ Kontext-sensitive Hilfen
- ✅ Inline-Dokumentation
- ✅ Complete English translation
- ✅ Professional terminology
- ✅ Context-aware help texts
- ✅ Inline documentation
Das System erkennt automatisch die REDAXO Backend-Sprache und passt die Oberfläche entsprechend an.
- 🔄 Lazy Loading - Widgets werden nur bei Bedarf geladen
- 💾 Caching - Intelligente Zwischenspeicherung
- 📦 Asset-Optimierung - Minimierte CSS/JS-Dateien
- 🎯 Selective Loading - Nur aktive Widgets werden geladen
- 🛡️ CSRF-Schutz - Automatische Token-Validierung
- 👤 Berechtigungsprüfung - Mehrstufiges Rechtesystem
- 🔐 Session-Sicherheit - Sichere Frontend-Backend-Verknüpfung
- 🚫 Input-Validierung - SQL-Injection-Schutz
- ⏱️ Arbeitszeit tracken mit TimeTracker
- 📝 Schneller Zugriff auf zuletzt bearbeitete Artikel
- 🔍 Dashboard-Übersicht über wichtige Inhalte
- 📈 Performance-Monitoring mit Stats Widget
- 📋 Custom Dashboards mit Widget Builder
- 👥 Team-Übersicht mit benutzerdefinierten Widgets
- ⚙️ System-Monitoring mit technischen Widgets
- 🔧 Debug-Informationen auf einen Blick
- 🎨 Erweiterbare Architektur für eigene Widgets
- 👥 Kunden-spezifische Dashboards erstellen
- 📊 Projekt-Monitoring mit Custom Widgets
- 🎯 Maßgeschneiderte Lösungen ohne Programmierung
- GitHub Repository - https://github.com/klxm/info_center
- REDAXO Slack - #addons Channel
- Community Forum - REDAXO.org
- GitHub Issues für Bug-Reports
- Feature Requests via GitHub Discussions
- Pull Requests willkommen!
MIT License - Siehe LICENSE.md für Details.
Thomas Skerbis
KLXM Crossmedia GmbH
Entwickelt für REDAXO CMS - Das intelligente Dashboard-System für moderne Webentwicklung.
🎉 Viel Spaß mit dem Info Center - Ihrem intelligenten REDAXO Dashboard!