Beach
| Day | Opening Hours |
|---|---|
| Sat, Jun 13 | 10:00 am – 8:30 pm |
| Sun, Jun 14 | 10:00 am – 8:30 pm |
| Mon, Jun 15 | 10:00 am – 8:30 pm |
Bar
| Day | Opening Hours |
|---|---|
| Sat, Jun 13 | 8:30 pm – 12:00 am |
| Sun, Jun 14 | Closed |
| Mon, Jun 15 | 8:30 pm – 12:30 am |
Mall
| Day | Opening Hours |
|---|---|
| Sat, Jun 13 | Renovation (Closed) |
| Sun, Jun 14 | Renovation (Closed) |
| Mon, Jun 15 | Renovation (Closed) |
Core Features
🗺️ Multi-Location Management
Create unlimited locations via a dedicated custom post type. Each location is a self-contained entity with its own hours, timezone, and contact details — perfect for chains, franchises, or any business with multiple branches.
⏰ Per-Day Schedules with Multiple Time Slots
Break your day into as many opening blocks as needed (e.g., 9:00–12:00 and 14:00–18:00). No more cramming everything into a single “open–close” pair. Each weekday is independently configurable with add/remove slot controls.
🔄 Date-Based Exceptions & Overrides
Holidays, special events, bad weather days, maintenance closures — define any date range with a reason label. Override regular hours entirely (full-day closure) or supply custom time slots just for that period. Overrides automatically take precedence and display with a
clear visual reason banner on the frontend.
🌍 Per-Location Timezone
Each location gets its own timezone from the complete IANA database (all ~400 zones). The “open now” check is always computed in the location’s local time — no more timezone math headaches.
🌱 Seasonal Operation Mode
Define a season window (start date → end date) for seasonal businesses. Outside the window a configurable “Out of season” notice replaces the schedule — all automatically. Season ranges support year-spanning windows (e.g., November through April for winter resorts).
⚡ Real-Time Open/Closed Status
An AJAX-powered badge shows “Open now” / “Closed now” in real time. Green when open, red when closed, with a loading skeleton while it resolves. Animated and keyboard-accessible via aria-live.
📅 3-Day Look-Ahead
The public display always shows today plus the next two days, respecting overrides and seasons for each day independently. Today’s row is highlighted and marked with aria-current=”date”.
────────────────────────────────────────────────────────────────────────────────
Integration & Delivery
📌 Shortcode
| Day | Opening Hours |
|---|---|
| Sat, Jun 13 | Closed |
| Sun, Jun 14 | Closed |
| Mon, Jun 15 | Closed |
Location not found.
— drop opening hours anywhere on your site. Attributes control location selection, live status badge visibility, and location title display.🧩 Native WordPress Widget
Drag a location into any widget area via the standard Widgets screen. Per-instance settings for widget title, location picker dropdown, and status badge toggle — no shortcode memorization needed.
🔌 REST API Ready
All location post types are exposed to the WordPress REST API (show_in_rest: true). Block editor, headless frontend, mobile app — consume your opening hours data however you want.
────────────────────────────────────────────────────────────────────────────────
Admin Experience
🎛️ Smart Time Selectors
Dropdown-based time pickers that auto-detect whether your site uses 12-hour or 24-hour format (based on WordPress time format setting). No free-text time fields to validate — it’s correct by construction.
🖱️ Dynamic, jQuery-Powered Interface
Add/remove time slots per day with a click. Toggle individual days to “Closed” with a single checkbox. Exception rows auto-populate with tomorrow’s date. All inputs are re-indexed on the fly so the form always submits clean arrays.
📋 Three Organized Meta Boxes
– Opening Hours — the main weekly schedule grid
– Exceptions & Overrides — table of date range exceptions, sorted newest-first
– Location Details — sidebar box for season window, timezone, address, and phone
────────────────────────────────────────────────────────────────────────────────
Engineering Quality
🛡️ Security-First Data Handling
WordPress nonce verification on every save. Capability checks (current_user_can). Proper sanitization via sanitize_text_field, sanitize_textarea_field, and absint throughout. No raw $_POST usage without validation.
🧹 Clean Architecture
Object-oriented PHP split by responsibility — post type registration, meta box rendering/saving, shortcode rendering, widget registration, helper utilities, and admin asset loading. Each class has a single init() entry point. PSR-4-friendly structure ready for extension.
♿ Accessibility Built In
aria-live=”polite” on the live status badge (screen readers announce open/closed changes). aria-current=”date” on today’s row. screen-reader-text table captions and headers with proper scope attributes. Keyboard-operable admin controls.
🌐 Translation-Ready
Full i18n with textdomain open-status. POT files provided in /languages. Every user-facing string is wrapped in __() or _e().
🧽 Clean Uninstall
All location posts (any status) and plugin settings are removed on uninstall. No orphaned data left behind.
────────────────────────────────────────────────────────────────────────────────
Summary Checklist
┌───────────────────────────────────────────┬────────┐
│ Capability │ Status │
├───────────────────────────────────────────┼────────┤
│ Unlimited locations │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Multiple daily time slots │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Date-range exceptions with reason labels │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Per-location timezone │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Seasonal operation with year-span support │ ✅ │
├───────────────────────────────────────────┼────────┤
│ AJAX live open/closed badge │ ✅ │
├───────────────────────────────────────────┼────────┤
│ 3-day look-ahead schedule table │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Shortcode + Widget output │ ✅ │
├───────────────────────────────────────────┼────────┤
│ 12h/24h auto-detected time inputs │ ✅ │
├───────────────────────────────────────────┼────────┤
│ REST API enabled │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Nonce + capability security │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Screen reader + keyboard accessible │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Translation-ready (i18n/l10n) │ ✅ │
├───────────────────────────────────────────┼────────┤
│ Clean uninstall │ ✅ │
├───────────────────────────────────────────┼────────┤
│ OOP, single-responsibility classes │ ✅ │
└───────────────────────────────────────────┴────────┘
────────────────────────────────────────────────────────────────────────────────