=== Luzid Content Scheduler === Contributors: luzidmedia Tags: scheduler, content, banner, shortcode, pagebuilder Requires at least: 6.0 Tested up to: 6.9 Requires PHP: 7.4 Stable tag: 1.4.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Show/hide frontend content blocks (banners, alerts, divs) with schedules, recurring rules and exceptions — via CSS class or shortcode. == Description == **Luzid Content Scheduler** controls *when* a specific frontend block is visible — and can also *output* the next scheduled date(s) via shortcode. This gives you two complementary ways to use a scheduler: 1. **Show / hide a block** (banner, alert, section, popup wrapper, …) Add the generated CSS class `luzid-cs-` to the element. The plugin adds body classes and a tiny frontend helper so the block is only displayed while the schedule is active. 2. **Display dates in the frontend** Use the shortcode to print the next event (or a list of upcoming events) anywhere in your content. = Typical Use Cases = * **Maintenance banners**: Show a "We're updating our systems" notice only during scheduled maintenance windows. * **Seasonal content**: Display holiday greetings, special offers, or seasonal menus during specific date ranges. * **Event announcements**: Print "Next event: Saturday, March 15th at 7 PM" dynamically on any page. * **Recurring schedules**: Show "Happy Hour specials" every Friday from 5 PM to 8 PM. * **Multi-stage visibility**: Use Event Classes to show a popup 4 days before an event, the full content 2 weeks before, and a menu item 11 days before — all independently controlled. * **Event calendars**: Generate a table of all upcoming events across multiple schedulers. = Core Concepts = * A scheduler becomes **active** when **at least one** rule matches (single dates/ranges *or* recurring rules). * **Exceptions override everything**: if "now" is inside an exception range, the block is hidden even if other rules match. * **Event Classes** (new in 1.4) allow multiple independent visibility windows with different offsets — each generating its own CSS class. * The shortcode reads the same event logic and outputs formatted dates with full control over separators and formatting. == Features == = Scheduling = * **Single dates & date ranges**: Define specific days or periods when content should be visible. * **Recurring rules**: Weekly (every Monday), Monthly (every 15th), Weekday in month (2nd Thursday), Yearly (February 14th). * **Exceptions**: Override all rules — content stays hidden during exception periods. * **Event Classes**: Create multiple CSS classes per scheduler, each with independent visibility offsets. = Shortcode Output = * **Flexible date/time formatting**: Choose from short, medium, long, or full date formats. * **Separators**: Control exactly what appears between date, time, and text parts. * **Lists**: Output multiple upcoming events with customizable separators. * **Event Table**: Generate a sortable table of all upcoming events from multiple schedulers. * **Time offset**: Shift the displayed time (e.g., "doors open 30 minutes before"). = Administration = * **Card-based UI**: Clean, modern interface for managing rules. * **Live preview**: See upcoming events and visibility windows instantly. * **Bilingual**: Full German and English support with one-click language switching. == Installation == 1. Upload the plugin folder to `/wp-content/plugins/` or install via the WordPress Plugins screen. 2. Activate **Luzid Content Scheduler**. 3. Go to **WP Admin → Luzid Content Scheduler**. 4. Create a scheduler, define rules, and save. 5. Add the generated CSS class `luzid-cs-` to your frontend block. == Usage == = Adding CSS Classes to Blocks = * **Gutenberg**: Select block → "Advanced" → "Additional CSS class(es)" → `luzid-cs-` * **Elementor**: Widget → "Advanced" → "CSS Classes" → `luzid-cs-` * **Divi/others**: Module settings → "CSS Class" → `luzid-cs-` = Basic Shortcode = `[luzid_cs slug="your-scheduler"]` Outputs: The next event date in the default format. = Shortcode Parameters = | Parameter | Default | Description | |-----------|---------|-------------| | `slug` | (required) | Scheduler slug | | `date` | (empty) | Date format: `short`, `medium`, `long`, `full` | | `time` | (empty) | Time format: `auto`, `raw`, `prefix`, `range`, `range_long` | | `list` | `false` | Output as list: `true` or `false` | | `count` | `10` | Number of events for lists (max 200) | | `text` | `false` | Include event text: `true` or `false` | | `sep1` | (space) | Separator between date and time | | `sep2` | (space) | Separator between time and text | | `sep3` | (empty) | Separator between list items | | `timeoffset` | `0` | Time offset in minutes (can be negative) | | `lang` | (current) | Force language: `de` or `en` | = Date Formats = | Value | Output Example | |-------|----------------| | `short` | 14.02.2026 | | `medium` | Sat, 14.02.2026 | | `long` | Saturday, 14.02.2026 | | `full` | Saturday, 14 February 2026 | = Time Formats = | Value | Output Example | |-------|----------------| | (empty) | No time output | | `raw` | 18:00 | | `prefix` | from 18:00 | | `range` | 18:00 to 20:00 | | `range_long` | from 18:00 to 20:00 | | `auto` | Intelligent format based on data | = Shortcode Examples = **Simple date output:** `[luzid_cs slug="maintenance" date="long"]` → Saturday, 15.03.2026 **Date with time:** `[luzid_cs slug="event" date="long" time="auto"]` → Saturday, 15.03.2026 from 18:00 to 20:00 **Only time output:** `[luzid_cs slug="event" time="raw"]` → 18:00 **Multi-line output:** `[luzid_cs slug="event" date="long" time="auto" text="true" sep1="
" sep2="
"]` → Saturday, 15.03.2026 from 18:00 to 20:00 Valentine's Dinner **List of next 5 events:** `[luzid_cs slug="concert" date="long" text="true" list="true" count="5" sep2="
" sep3="

"]` **With custom separators:** `[luzid_cs slug="event" date="long" time="raw" text="true" sep1=" | " sep2=" – "]` → Saturday, 15.03.2026 | 18:00 – Valentine's Dinner = Event Table Shortcode = `[luzid_cs_eventtable]` Outputs a table of all upcoming events from schedulers with "Include in Event Table" enabled. | Parameter | Default | Description | |-----------|---------|-------------| | `cols` | `date_medium,time_auto,text` | Columns (comma-separated) | | `count` | `30` | Maximum number of events | | `headers` | (automatic) | Custom column headers | | `noheaders` | `false` | Hide table headers | | `class` | (empty) | Additional CSS class | | `empty` | "No events" | Text when no events found | | `order` | `asc` | Sort order: `asc` or `desc` | **Available columns:** `date_short`, `date_medium`, `date_long`, `date_full`, `weekday_short`, `weekday_long`, `time_raw`, `time_auto`, `time_prefix`, `time_range`, `time_range_long`, `text`, `scheduler` **Example with custom columns:** `[luzid_cs_eventtable cols="weekday_short,date_short,time_range,text" count="10" headers="Day,Date,Time,Event"]` = Event Classes (New in 1.4) = Event Classes allow you to create multiple independent visibility windows for a single scheduler. Each class has its own CSS class and offset settings. **Example setup:** | Class | CSS Class | Days Before | Use Case | |-------|-----------|-------------|----------| | Standard | `.luzid-cs-dinner` | 14 | Main content | | popup | `.luzid-cs-dinner-popup` | 4 | Announcement popup | | menu | `.luzid-cs-dinner-menu` | 11 | Navigation menu item | This allows you to control when different elements appear, all based on the same event schedule. = CSS Hooks = **Shortcode output:** * `.luzid-cs` — Wrapper (plus `.luzid-cs--single` / `.luzid-cs--list`) * `.luzid-cs-item` — Single event in list * `.luzid-cs-date` — Date part * `.luzid-cs-time` — Time part * `.luzid-cs-text` — Event text * `.luzid-cs-sep` / `.luzid-cs-sep1` / `.luzid-cs-sep2` — Separators **Event table:** * `.luzid-cs-eventtable` — Table wrapper * `.luzid-cs-eventtable__head` / `__body` / `__row` / `__cell` **Body classes (for conditional CSS):** * `.luzid-cs-active-` — Added when scheduler is active * `.luzid-cs-active--` — Added when specific event class is active == Frequently Asked Questions == = How are multiple recurring rules combined? = They are combined with OR-logic: if **any** rule matches, the scheduler is considered active (unless an exception matches). = Do exceptions also affect the frontend, or only the preview? = Exceptions affect **everything** (frontend visibility, next event calculation, and preview). If "now" is inside an exception range, the block stays hidden. = What's the difference between Event Offset (old) and Event Classes (new)? = Event Classes replaced the old Event Offset feature in version 1.4. The key difference: you can now create **multiple classes** with independent offsets, allowing different content to appear at different times before/after an event. = Can I use multiple Event Classes for one block? = Each Event Class generates a separate CSS class. You can only apply one class per block, but you can have multiple blocks, each with a different Event Class. = Does the plugin require a specific theme? = No. It works with any theme/page builder that lets you set a custom CSS class on a block/element. = Can I output only the time without the date? = Yes! Use `[luzid_cs slug="your-slug" time="raw"]` to output only the time. Leave out the `date` parameter. = How do I create a line break between date and text? = Use `sep2="
"`: `[luzid_cs slug="event" date="long" text="true" sep2="
"]` == Screenshots == 1. Setup tab: Create a scheduler and copy the CSS class / shortcode. 2. Dates tab: Add single dates or date ranges with times and event text. 3. Recurring tab: Define weekly, monthly, or yearly patterns. 4. Exceptions tab: Block specific dates from showing content. 5. Event Classes tab: Create multiple CSS classes with independent visibility windows. 6. Preview tab: See all upcoming events at a glance. == License == This plugin is licensed under the **GNU General Public License v2.0 or later**. All code in this plugin is GPLv2-or-later compatible. Assets: * Luzid Logo and Flag icons are SVG assets shipped with the plugin (assets/img/). == Changelog == = 1.4.4 = * Fixed: List output with `list="true"` now works correctly again. * Fixed: Event Classes CSS generation now includes all custom classes (e.g., `.luzid-cs-slug-menu`), not just the standard class. * New: Date ranges for single dates — new "Date to" field allows multi-day events. * Improved: Shortcode `text="true"` now outputs only the event text without automatic date fallback. * Improved: Panel description updated to explain date range functionality. = 1.4.2 = * Fixed: Version number display in admin header. * Improved: Event Classes UI with copy button for CSS classes and consistent icon styling. = 1.4.1 = * Fixed: WordPress Plugin Check escaping warnings for Event Classes panel. = 1.4.0 = * **New: Event Classes** — Replace single Event Offset with unlimited named classes, each with independent visibility offsets. * New: Each Event Class generates its own CSS class (`luzid-cs--`). * New: Live preview of visibility windows per class. * New: Standard class (non-deletable) maintains backward compatibility. * Changed: Tab renamed from "Event-Offset" to "Event-Klassen". * Improved: Card-based UI consistent with other tabs. * Migration: Existing Event Offset settings are automatically converted to the new Event Classes structure. = 1.3.12 = * Fixed: Shortcode now outputs exactly what is specified — no hidden defaults. * Fixed: `date` parameter defaults to empty (not "long"). Only when neither `date` nor `time` is set, `date="long"` is used as fallback. * Fixed: Using only `time="raw"` now correctly outputs only the time, not date + time. = 1.3.11 = * Fixed: Auto-padding removed from separators. ` ` now outputs exactly one non-breaking space. = 1.3.10 = * Fixed: Single space separator handling — WordPress trims `sep1=" "`, now uses default fallback. = 1.3.9 = * **New: Separator system refactored** — `sep` replaced by `sep1`, `sep2`, `sep3` for precise control. * New: `sep1` controls separator between date and time. * New: `sep2` controls separator between time and text (or date and text if no time). * New: `sep3` controls separator between list items. * Changed: `time` parameter now defaults to empty (no time output unless explicitly requested). * Breaking: Old `sep` parameter removed. Use `sep1`/`sep2`/`sep3` instead. = 1.3.8 = * Fixed: Preview table now shows actual saved event text per date. = 1.3.7 = * Fixed: Yearly recurrence calculation for events spanning year boundaries. = 1.3.6 = * New: `[luzid_cs_eventtable]` shortcode for tabular event output. * New: "Include in Event Table" checkbox per scheduler. * New: Customizable columns, headers, and sorting for event tables. = 1.3.5 = * Improved: Card-based layout unified across all tabs. = 1.3.4 = * New: Dual-prefix system for Termine tab (CSS class prefix options). = 1.3.0 = * New: "Time to" field for time ranges (e.g., 18:00 – 20:00) in single dates and recurring rules. * New: Yearly recurring rule type (e.g., every February 14th at 16:00). * New: Card-based layout for Termine and Wiederholungen tabs. * Changed: Shortcode renamed from `[lz-cs]` to `[luzid_cs]` for WordPress.org compliance. * Changed: CSS classes renamed from `lz-cs-*` to `luzid-cs-*`. = 1.2.9 = * Changed: List wrapper from `` to `
` for better HTML structure. = 1.2.7 = * Fix: Prevent "phantom" events from incomplete recurring rules. * New: Preview table shows event source (Single vs Recurring). = 1.2.6 = * New: Shortcode output wrapped in styled span classes. * Improved: `sep` parameter can output `
` for line breaks. = 1.2.5 = * Fix: Separator spacing preserved correctly. * Improvement: Single dates sorted chronologically. * New: Optional event text for recurring rules. = 1.2.3 = * Added: Optional event text field for single dates. * Changed: Shortcode supports `list`, `count`, `text` and `sep` parameters. = 1.2.0 = * Initial release.