# AA Events An approachable, theme‑friendly events plugin for WordPress. It adds an `Event` post type, useful taxonomies, ACF‑powered fields, and accessible front‑end templates (archive, single, and a calendar page template). Everything can be overridden from your theme when you need custom markup. ## What you get - Event post type with archive at `/events`. - Two taxonomies: `Event Types` (hierarchical) and `Event Tags` (non‑hierarchical). - Event details via ACF: occurrences, cost, location (online URL vs in‑person address). - Front‑end templates: archive list, single view, and a calendar page template. - Theme overrides for templates and styles with simple folder conventions. - Sensible defaults: the admin date column shows and sorts by the earliest normalized occurrence. --- ## Requirements - WordPress 5.8+ (uses modern APIs like `wp_date()` and template filters). - PHP 7.4+. - Advanced Custom Fields PRO is required for the event fields. **Occurrences** uses the Repeater field, which is an ACF PRO feature. The plugin will load without ACF PRO, but its built-in Event fields and related editing UI will not be available. --- ## Installation 1. Copy the `aa-events` folder into `wp-content/plugins/`. 2. (Required) Install and activate **Advanced Custom Fields PRO** so the Occurrences repeater is available. 3. In WordPress Admin → Plugins, activate “AA Events”. 4. Visit Settings → Permalinks and click Save if your events archive doesn’t appear (activation also flushes rewrites). --- ## Quick Start 1. Create events: Admin → Events → Add New. 2. Fill in the “Event Details” fields: - **Occurrences**: Add one row for each occurrence. A start date is required in every row; start time, end date, end time, and All Day are optional. - **Event Date & Time** (optional compatibility field only; use Occurrences when creating or editing event dates) - Event Cost (optional) - Online/In‑Person toggle (optional) - Event URL (required when Online) - Event Address (required when In‑Person) - Contact Email (optional; displayed on the single-event page) 3. View your list of events at `/events` and single event pages at their permalinks. 4. For a calendar view, create a new Page and choose the "Events Calendar" template, then publish. ### Event Occurrences The **Occurrences** repeater is the primary schedule editor. Each row describes one continuous occurrence: 1. Click **Add Occurrence** and enter its required Date. 2. Optionally add a Start Time. Add an End Date and/or End Time when the occurrence continues beyond its starting point; leaving the end blank is valid. 3. Enable **All Day** for an all-day occurrence. This hides the time controls, and saved time values are ignored. 4. Add another row when the event occurs again. Rows may freely mix single-day, multi-day, timed, and all-day occurrences; the plugin does not generate recurrence rules. For example, one event can have a row starting Friday at 6:00 PM and ending Sunday at 2:00 PM, plus a later row with a different date and **All Day** enabled. That is one continuous weekend occurrence followed by one separate all-day occurrence. **Backward compatibility:** Existing `event_dates` rows continue to work. The plugin also reads the optional legacy **Event Date & Time** (`event_datetime`) value and older standalone `date`/`start_time` fields when no occurrence rows are present. Saving a legacy-only event in the editor creates one equivalent occurrence row. No bulk migration is required, and later saves do not add duplicate rows. --- ## Content Model - Post type: `event` - Public, has archive (`/events`), supports title, editor, author, thumbnail. - Taxonomies - `event_type` (hierarchical, slug `event-type`) - `event_tag` (non‑hierarchical, slug `event-tag`) - Admin UX - Adds a “Date & Time” column on Events list, showing the earliest normalized occurrence and a count of additional occurrences; sorting uses the earliest occurrence. --- ## Front‑End Views - Archive: `/events` uses `templates/archive-event.php`. - Single: each event uses `templates/single-event.php`. - Calendar page: Page → Template → “Events Calendar” renders `templates/template-calendar.php` which includes `templates/calendar.php`. - Calendar navigation: query args `?aa_month=MM&aa_year=YYYY` change the visible month; “Today” jumps back to the current month. (`month`/`year` still work for legacy links.) - Archive and single templates show each occurrence as a formatted date or date/time range. - Single-event pages show a clickable Contact Email when a valid address is provided. - On desktop and tablet, visitors can switch between Calendar and List views. Calendar is the initial default; the visitor’s selection is saved in the browser and restored after month navigation and on later visits. - Calendar view uses a traditional month grid. Multi-day occurrences render as bars spanning each week they cross, with the event title repeated on each weekly segment. - At `640px` wide and below, the view switcher is hidden and the chronological List view is always used, regardless of any saved desktop preference. - Occurrences that cross into the visible month are included even when they start before it or end after it. - Calendar dates use the site timezone and the week layout respects Settings → General → “Start of week”. --- ## Theme Overrides The plugin is designed to be theme‑override friendly. Copy any template into your theme under `your-theme/aa-events/` and it will be used instead of the plugin version. - Templates you can override: - `archive-event.php` - `single-event.php` - `template-calendar.php` (page template) - `calendar.php` Example: to override the archive, create `your-theme/aa-events/archive-event.php`. Page template in a theme: the “Events Calendar” page template also respects theme overrides at `your-theme/aa-events/template-calendar.php`. An existing `your-theme/aa-events/calendar.php` remains authoritative. It does not automatically acquire the plugin template’s week-spanning bars, List markup, or desktop switcher. Theme authors can update overrides using `aa_events_get_occurrences()`, `aa_events_format_occurrence()`, and `aa_events_occurrence_time_markup()`. A CSS override must also cover any calendar, agenda, and switcher markup it adopts. --- ## Styling - Default CSS ships with the plugin and is enqueued automatically. - To replace it, add `your-theme/aa-events/aa-events.css`. If present, the theme stylesheet is loaded instead of the plugin’s, even when the theme does not override any templates. - Existing theme stylesheet overrides must add styles for the calendar utility row, view switcher, selected and focus states, hidden inactive view panel, and the forced List view at `640px` wide and below. Note: The bundled CSS is intentionally minimal. Use the override to match your theme. --- ## Developer Notes - Occurrence helpers: - `aa_events_get_occurrences( $post_id )` returns chronologically sorted, normalized rows from the occurrence repeater or a legacy fallback. Rows include `source`, `start_inferred`, and `end_inferred`; the inference flags identify legacy-derived starts and defaulted ends. - `aa_events_format_occurrence( $occurrence )` returns the localized visible range label. - `aa_events_occurrence_time_markup( $occurrence )` returns escaped, accessible `