Kapazitätsanzeige-Plugin hinzugefügt und juconnect-strict-theme-v3 aktualisiert

This commit is contained in:
2026-02-15 11:33:18 +01:00
parent 28b5061650
commit 60cade23b2
5 changed files with 437 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
.juconnect-capacity-indicator {
display: inline-flex;
align-items: center;
gap: 10px;
margin: 0 0 var(--s3, 14px) 0;
max-width: 100%;
border-radius: 999px;
border: 1px solid var(--line, #d7dee5);
background: var(--surface, #ffffff);
color: var(--text2, #3c4a58);
padding: 8px 12px;
font-size: var(--fs-s, 0.92rem);
line-height: 1.35;
}
.juconnect-capacity-indicator .pill__dot {
width: 10px;
height: 10px;
flex: 0 0 auto;
border-radius: 999px;
background: var(--juconnect-capacity-dot, #2f855a);
}
.hero__inner > .juconnect-capacity-indicator {
margin-top: 0;
}
.juconnect-capacity-indicator--limited {
--juconnect-capacity-dot: #b7791f;
}
.juconnect-capacity-indicator--full {
--juconnect-capacity-dot: #c53030;
}
.juconnect-capacity-indicator--paused {
--juconnect-capacity-dot: #2b6cb0;
}

View File

@@ -0,0 +1,385 @@
<?php
/**
* Plugin Name: JuConnect Kapazitaetsanzeige
* Description: Zeigt im Hero eine konfigurierbare Kapazitaetsanzeige im Stil der JuConnect-Pills an.
* Version: 0.2.0
* Author: JuConnect
*/
if (!defined('ABSPATH')) {
exit;
}
const JUCONNECT_CAPACITY_VERSION = '0.2.0';
const JUCONNECT_CAPACITY_OPTION_KEY = 'juconnect_capacity_settings';
function juconnect_capacity_default_settings() {
return [
'enabled' => 1,
'placement' => 'front_page',
'status' => 'available',
'text' => 'Kapazitaeten frei',
'dot_color' => '#2f855a',
];
}
function juconnect_capacity_status_options() {
return [
'available' => __('Kapazitaeten frei', 'juconnect'),
'limited' => __('Wenige Kapazitaeten frei', 'juconnect'),
'full' => __('Aktuell keine Kapazitaeten frei', 'juconnect'),
'paused' => __('Aufnahme pausiert', 'juconnect'),
];
}
function juconnect_capacity_placement_options() {
return [
'front_page' => __('Nur auf der Startseite', 'juconnect'),
'all_hero' => __('Auf allen Seiten mit Hero', 'juconnect'),
];
}
function juconnect_capacity_get_settings() {
$settings = get_option(JUCONNECT_CAPACITY_OPTION_KEY, []);
if (!is_array($settings)) {
$settings = [];
}
return wp_parse_args($settings, juconnect_capacity_default_settings());
}
function juconnect_capacity_default_color_for_status($status) {
$status_colors = [
'available' => '#2f855a',
'limited' => '#b7791f',
'full' => '#c53030',
'paused' => '#2b6cb0',
];
return $status_colors[$status] ?? '#2f855a';
}
register_activation_hook(__FILE__, function () {
if (false === get_option(JUCONNECT_CAPACITY_OPTION_KEY, false)) {
add_option(JUCONNECT_CAPACITY_OPTION_KEY, juconnect_capacity_default_settings());
}
});
function juconnect_capacity_sanitize_settings($input) {
if (!is_array($input)) {
$input = [];
}
$defaults = juconnect_capacity_default_settings();
$statuses = juconnect_capacity_status_options();
$placements = juconnect_capacity_placement_options();
$sanitized = [];
$sanitized['enabled'] = empty($input['enabled']) ? 0 : 1;
$placement = isset($input['placement']) ? sanitize_key($input['placement']) : $defaults['placement'];
$sanitized['placement'] = array_key_exists($placement, $placements) ? $placement : $defaults['placement'];
$status = isset($input['status']) ? sanitize_key($input['status']) : $defaults['status'];
$sanitized['status'] = array_key_exists($status, $statuses) ? $status : $defaults['status'];
$text = isset($input['text']) ? sanitize_text_field($input['text']) : '';
$sanitized['text'] = '' === $text ? $statuses[$sanitized['status']] : $text;
$dot_color = isset($input['dot_color']) ? sanitize_hex_color($input['dot_color']) : '';
if (!$dot_color) {
$dot_color = juconnect_capacity_default_color_for_status($sanitized['status']);
}
$sanitized['dot_color'] = $dot_color;
return $sanitized;
}
add_action('admin_init', function () {
register_setting('juconnect_capacity_settings_group', JUCONNECT_CAPACITY_OPTION_KEY, [
'type' => 'array',
'sanitize_callback' => 'juconnect_capacity_sanitize_settings',
'default' => juconnect_capacity_default_settings(),
]);
add_settings_section(
'juconnect_capacity_main_section',
__('Kapazitaetsanzeige', 'juconnect'),
function () {
echo '<p>' . esc_html__('Steuert die Kapazitaetsanzeige im oberen Bereich des Hero-Blocks.', 'juconnect') . '</p>';
},
'juconnect-capacity-settings'
);
add_settings_field(
'juconnect_capacity_enabled',
__('Anzeige aktiv', 'juconnect'),
'juconnect_capacity_render_enabled_field',
'juconnect-capacity-settings',
'juconnect_capacity_main_section'
);
add_settings_field(
'juconnect_capacity_placement',
__('Platzierung', 'juconnect'),
'juconnect_capacity_render_placement_field',
'juconnect-capacity-settings',
'juconnect_capacity_main_section'
);
add_settings_field(
'juconnect_capacity_status',
__('Status', 'juconnect'),
'juconnect_capacity_render_status_field',
'juconnect-capacity-settings',
'juconnect_capacity_main_section'
);
add_settings_field(
'juconnect_capacity_text',
__('Textinhalt', 'juconnect'),
'juconnect_capacity_render_text_field',
'juconnect-capacity-settings',
'juconnect_capacity_main_section'
);
add_settings_field(
'juconnect_capacity_dot_color',
__('Punktfarbe', 'juconnect'),
'juconnect_capacity_render_dot_color_field',
'juconnect-capacity-settings',
'juconnect_capacity_main_section'
);
});
add_action('admin_menu', function () {
add_options_page(
__('JuConnect Kapazitaetsanzeige', 'juconnect'),
__('Kapazitaetsanzeige', 'juconnect'),
'manage_options',
'juconnect-capacity-settings',
'juconnect_capacity_render_settings_page'
);
});
function juconnect_capacity_render_settings_page() {
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html__('JuConnect Kapazitaetsanzeige', 'juconnect'); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields('juconnect_capacity_settings_group');
do_settings_sections('juconnect-capacity-settings');
submit_button();
?>
</form>
</div>
<?php
}
function juconnect_capacity_render_enabled_field() {
$settings = juconnect_capacity_get_settings();
?>
<label>
<input
type="checkbox"
name="<?php echo esc_attr(JUCONNECT_CAPACITY_OPTION_KEY); ?>[enabled]"
value="1"
<?php checked(1, (int) $settings['enabled']); ?>
/>
<?php echo esc_html__('Kapazitaetsanzeige im Hero anzeigen', 'juconnect'); ?>
</label>
<?php
}
function juconnect_capacity_render_placement_field() {
$settings = juconnect_capacity_get_settings();
$options = juconnect_capacity_placement_options();
?>
<select name="<?php echo esc_attr(JUCONNECT_CAPACITY_OPTION_KEY); ?>[placement]">
<?php foreach ($options as $value => $label) : ?>
<option value="<?php echo esc_attr($value); ?>" <?php selected($settings['placement'], $value); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
function juconnect_capacity_render_status_field() {
$settings = juconnect_capacity_get_settings();
$options = juconnect_capacity_status_options();
?>
<select name="<?php echo esc_attr(JUCONNECT_CAPACITY_OPTION_KEY); ?>[status]">
<?php foreach ($options as $value => $label) : ?>
<option value="<?php echo esc_attr($value); ?>" <?php selected($settings['status'], $value); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
function juconnect_capacity_render_text_field() {
$settings = juconnect_capacity_get_settings();
?>
<input
type="text"
class="regular-text"
name="<?php echo esc_attr(JUCONNECT_CAPACITY_OPTION_KEY); ?>[text]"
value="<?php echo esc_attr($settings['text']); ?>"
/>
<p class="description">
<?php echo esc_html__('Freier Text fuer die Anzeige. Wenn leer, wird der Status-Standardtext genutzt.', 'juconnect'); ?>
</p>
<?php
}
function juconnect_capacity_render_dot_color_field() {
$settings = juconnect_capacity_get_settings();
?>
<input
type="color"
name="<?php echo esc_attr(JUCONNECT_CAPACITY_OPTION_KEY); ?>[dot_color]"
value="<?php echo esc_attr($settings['dot_color']); ?>"
/>
<?php
}
function juconnect_capacity_should_inject() {
$settings = juconnect_capacity_get_settings();
if (empty($settings['enabled'])) {
return false;
}
if (is_admin() && !wp_doing_ajax()) {
return false;
}
if (defined('REST_REQUEST') && REST_REQUEST) {
return false;
}
if (is_feed() || is_embed()) {
return false;
}
if ('front_page' === $settings['placement'] && !is_front_page()) {
return false;
}
return true;
}
function juconnect_capacity_render_indicator_markup() {
$settings = juconnect_capacity_get_settings();
if (empty($settings['enabled'])) {
return '';
}
$status_options = juconnect_capacity_status_options();
$status = $settings['status'];
if (!array_key_exists($status, $status_options)) {
$status = 'available';
}
$text = trim((string) $settings['text']);
if ('' === $text) {
$text = $status_options[$status];
}
$status_class = sanitize_html_class('juconnect-capacity-indicator--' . $status);
$dot_color = sanitize_hex_color($settings['dot_color']);
$style_attr = $dot_color ? ' style="--juconnect-capacity-dot:' . esc_attr($dot_color) . ';"' : '';
$dot_style_attr = $dot_color ? ' style="background-color:' . esc_attr($dot_color) . ';"' : '';
return '<div class="juconnect-capacity-indicator pill ' . esc_attr($status_class) . '" role="status" aria-live="polite"' . $style_attr . '>'
. '<span class="pill__dot" aria-hidden="true"' . $dot_style_attr . '></span>'
. '<span>' . esc_html($text) . '</span>'
. '</div>';
}
add_shortcode('juconnect_capacity_status', function () {
return juconnect_capacity_render_indicator_markup();
});
add_filter('render_block', function ($block_content, $block) {
static $inserted = false;
if ($inserted || !juconnect_capacity_should_inject()) {
return $block_content;
}
if (!is_array($block) || empty($block['blockName']) || 'core/group' !== $block['blockName']) {
return $block_content;
}
$class_name = $block['attrs']['className'] ?? '';
if (!is_string($class_name) || '' === trim($class_name)) {
return $block_content;
}
$target_classes = ['hero__inner', 'pagehead__left', 'pagehead'];
$matched_target_class = '';
foreach ($target_classes as $target_class) {
if (false !== strpos(' ' . $class_name . ' ', ' ' . $target_class . ' ')) {
$matched_target_class = $target_class;
break;
}
}
if ('' === $matched_target_class) {
return $block_content;
}
$indicator = juconnect_capacity_render_indicator_markup();
if ('' === $indicator) {
return $block_content;
}
$inserted = true;
$target_pattern = preg_quote($matched_target_class, '/');
$injected = preg_replace(
'/(<div[^>]*class="[^"]*' . $target_pattern . '[^"]*"[^>]*>)/i',
'$1' . $indicator,
$block_content,
1
);
if (is_string($injected) && '' !== $injected) {
return $injected;
}
return $indicator . $block_content;
}, 10, 2);
add_action('wp_enqueue_scripts', function () {
$settings = juconnect_capacity_get_settings();
if (empty($settings['enabled'])) {
return;
}
$css_rel_path = 'assets/css/juconnect-capacity-status.css';
$css_abs_path = plugin_dir_path(__FILE__) . $css_rel_path;
if (!file_exists($css_abs_path)) {
return;
}
$css_ver = (string) filemtime($css_abs_path);
if ('' === $css_ver) {
$css_ver = JUCONNECT_CAPACITY_VERSION;
}
wp_enqueue_style(
'juconnect-capacity-status',
plugin_dir_url(__FILE__) . $css_rel_path,
[],
$css_ver
);
});

View File

@@ -4,6 +4,7 @@ if (!defined('ABSPATH')) exit;
function juconnect_setup() { function juconnect_setup() {
add_theme_support('title-tag'); add_theme_support('title-tag');
add_theme_support('post-thumbnails'); add_theme_support('post-thumbnails');
add_theme_support('site-icon');
add_theme_support('custom-logo', [ add_theme_support('custom-logo', [
'height' => 120, 'height' => 120,
'width' => 120, 'width' => 120,
@@ -18,6 +19,19 @@ function juconnect_setup() {
} }
add_action('after_setup_theme', 'juconnect_setup'); add_action('after_setup_theme', 'juconnect_setup');
/**
* Fallback favicon when no Site Icon is set in WordPress.
*/
function juconnect_favicon_fallback() {
if (has_site_icon()) {
return;
}
$icon_url = get_template_directory_uri() . '/assets/img/juconnect_icon.svg';
echo '<link rel="icon" href="' . esc_url($icon_url) . '" type="image/svg+xml" />' . "\n";
}
add_action('wp_head', 'juconnect_favicon_fallback');
function juconnect_assets() { function juconnect_assets() {
$theme_ver = wp_get_theme()->get('Version'); $theme_ver = wp_get_theme()->get('Version');
$style_ver = filemtime(get_stylesheet_directory() . '/style.css'); $style_ver = filemtime(get_stylesheet_directory() . '/style.css');