Zum Hauptinhalt springen

Elementor Widget Development

Entwickler-Guide: Erstellen Sie Custom Elementor Widgets mit CockpitOS API-Integration.

Überblick

CockpitOS Elementor Widgets sind spezialisierte UI-Komponenten, die Live-Daten vom CockpitOS Dashboard laden und in WordPress/Elementor anzeigen.

Widget-Architektur

Widget-Kategorien

  • Content Widgets: Shops, Events, News, Angebote
  • Layout Widgets: Hero-Sections, Grids, Slider
  • Contact Widgets: Kontaktformulare, Öffnungszeiten
  • Navigation Widgets: Menüs, Breadcrumbs

Widget-Struktur:

class CockpitOS_My_Widget extends \Elementor\Widget_Base {
// Widget-Metadaten
public function get_name() { return 'cockpit-my-widget'; }
public function get_title() { return 'CockpitOS My Widget'; }
public function get_categories() { return ['cockpit-os']; }

// Elementor Controls (Schema-basiert)
protected function register_controls() { /* ... */ }

// Widget-Rendering
protected function render() { /* ... */ }

// API-Integration
private function get_data_from_api() { /* ... */ }
}

Widget erstellen

Schritt 1: Widget-Klasse definieren

<?php
class CockpitOS_Events_List_Widget extends \Elementor\Widget_Base {

public function get_name() {
return 'cockpit-events-list';
}

public function get_title() {
return 'CockpitOS Events Liste';
}

public function get_icon() {
return 'eicon-calendar';
}

public function get_categories() {
return ['cockpit-os'];
}

public function get_keywords() {
return ['events', 'calendar', 'cockpit', 'shopping center'];
}
}

Schritt 2: Elementor Controls (Schema-basiert)

protected function register_controls() {
// Content Section
$this->start_controls_section('content_section', [
'label' => 'Inhalt',
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]);

$this->add_control('events_count', [
'label' => 'Anzahl Events',
'type' => \Elementor\Controls_Manager::NUMBER,
'default' => 6,
'min' => 1,
'max' => 20,
]);

$this->add_control('show_images', [
'label' => 'Bilder anzeigen',
'type' => \Elementor\Controls_Manager::SWITCHER,
'default' => 'yes',
]);

$this->add_control('layout', [
'label' => 'Layout',
'type' => \Elementor\Controls_Manager::SELECT,
'default' => 'grid',
'options' => [
'grid' => 'Grid',
'list' => 'Liste',
'slider' => 'Slider',
],
]);

$this->end_controls_section();

// Style Section
$this->start_controls_section('style_section', [
'label' => 'Style',
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]);

$this->add_control('title_color', [
'label' => 'Titel-Farbe',
'type' => \Elementor\Controls_Manager::COLOR,
'default' => 'var(--cockpit-primary-color)',
'selectors' => [
'{{WRAPPER}} .event-title' => 'color: {{VALUE}}',
],
]);

$this->end_controls_section();
}

Schritt 3: Widget-Rendering

protected function render() {
$settings = $this->get_settings_for_display();
$events = $this->get_events_from_api($settings['events_count']);

if (empty($events)) {
echo '<p>Keine Events verfügbar.</p>';
return;
}

echo '<div class="cockpit-events-list layout-' . $settings['layout'] . '">';

foreach ($events as $event) {
echo '<div class="event-item">';

if ($settings['show_images'] === 'yes' && !empty($event['image'])) {
echo '<div class="event-image">';
echo '<img src="' . esc_url($event['image']) . '" alt="' . esc_attr($event['title']) . '">';
echo '</div>';
}

echo '<div class="event-content">';
echo '<h3 class="event-title">' . esc_html($event['title']) . '</h3>';
echo '<div class="event-date">' . date('d.m.Y', strtotime($event['date'])) . '</div>';
echo '<div class="event-description">' . wp_trim_words($event['description'], 20) . '</div>';
echo '</div>';

echo '</div>';
}

echo '</div>';
}

Schritt 4: API-Integration

private function get_events_from_api($limit = 6) {
// Cache-Key für Performance
$cache_key = 'cockpit_events_' . $limit;
$cached_events = get_transient($cache_key);

if ($cached_events !== false) {
return $cached_events;
}

try {
// CockpitOS API Client verwenden
$api_client = new CockpitOS_API_Client();
$response = $api_client->get_events(['limit' => $limit]);

if ($response['success'] && !empty($response['data'])) {
$events = $response['data'];

// Cache für 5 Minuten
set_transient($cache_key, $events, 5 * MINUTE_IN_SECONDS);

return $events;
}

} catch (Exception $e) {
error_log('CockpitOS Events Widget Error: ' . $e->getMessage());
}

return [];
}

Widget-Styling

CSS für Theme-Integration:

/* Widget nutzt CSS-Variablen vom Dashboard */
.cockpit-events-list {
font-family: var(--cockpit-body-font);
}

.cockpit-events-list .event-title {
color: var(--cockpit-primary-color);
font-family: var(--cockpit-heading-font);
}

.cockpit-events-list .event-date {
color: var(--cockpit-secondary-color);
}

/* Responsive Grid Layout */
.cockpit-events-list.layout-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}

.cockpit-events-list.layout-list .event-item {
display: flex;
margin-bottom: 1rem;
padding: 1rem;
border: 1px solid #e2e8f0;
}

/* Mobile Responsive */
@media (max-width: 768px) {
.cockpit-events-list.layout-grid {
grid-template-columns: 1fr;
}
}

Widget-Registry-System

Widget registrieren:

// Widget-Registry für bessere Organisation
class CockpitOS_Widget_Registry {
private static $widgets = [];

public static function register($widget_class, $config = []) {
self::$widgets[$widget_class] = array_merge([
'category' => 'cockpit-os',
'themes' => ['all'],
'version' => '1.0.0'
], $config);

// Widget bei Elementor registrieren
add_action('elementor/widgets/widgets_registered', function($widgets_manager) use ($widget_class) {
$widgets_manager->register_widget_type(new $widget_class());
});
}

public static function get_widgets_by_theme($theme_id) {
return array_filter(self::$widgets, function($config) use ($theme_id) {
return in_array('all', $config['themes']) || in_array($theme_id, $config['themes']);
});
}
}

// Widgets registrieren
CockpitOS_Widget_Registry::register('CockpitOS_Events_List_Widget', [
'category' => 'content',
'themes' => ['hbb-standard', 'smg-standard'],
'version' => '1.0.0'
]);

Dynamic Tags Integration

Event-Title Dynamic Tag

class CockpitOS_Event_Title_Tag extends \Elementor\Core\DynamicTags\Tag {

public function get_name() {
return 'cockpit-event-title';
}

public function get_title() {
return 'Event Titel';
}

public function get_group() {
return 'cockpit-events';
}

public function get_categories() {
return [\Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY];
}

protected function register_controls() {
$this->add_control('event_id', [
'label' => 'Event ID',
'type' => \Elementor\Controls_Manager::TEXT,
]);
}

public function render() {
$event_id = $this->get_settings('event_id');

if (empty($event_id)) {
echo 'Event Titel';
return;
}

$api_client = new CockpitOS_API_Client();
$event = $api_client->get_event($event_id);

if ($event && !empty($event['title'])) {
echo esc_html($event['title']);
} else {
echo 'Event nicht gefunden';
}
}
}

Best Practices

1. Performance-Optimierung

// Caching verwenden
$cache_key = 'widget_data_' . md5(serialize($settings));
$data = get_transient($cache_key);
if ($data === false) {
$data = $this->get_api_data();
set_transient($cache_key, $data, 5 * MINUTE_IN_SECONDS);
}

2. Error-Handling

try {
$data = $api_client->get_data();
} catch (Exception $e) {
error_log('Widget Error: ' . $e->getMessage());
echo '<p>Daten konnten nicht geladen werden.</p>';
return;
}

3. Responsive Design

@media (max-width: 768px) {
.my-widget { font-size: 14px; }
}

4. Accessibility

echo '<img src="' . $image . '" alt="' . esc_attr($title) . '">';
echo '<h3 role="heading" aria-level="3">' . $title . '</h3>';

Ihr Elementor Widget ist jetzt bereit für CockpitOS Integration!

Das Widget lädt automatisch Live-Daten vom Dashboard und nutzt center-spezifische Theme-Anpassungen.

Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /developer-guide/wordpress-themes/widget-development