Booking source copy during the coordinated GitLab transition.
  • PHP 81.4%
  • JavaScript 13.4%
  • Shell 2.4%
  • SCSS 2.1%
  • CSS 0.7%
Find a file
2026-09-22 22:56:59 +02:00
circumflex-booking Add silent expiry for overdue requests 2026-09-22 19:42:12 +02:00
circumflex-booking-airspace Update Airspace browser test harness 2026-09-21 14:11:17 +02:00
circumflex-booking-meeting-rooms Protect add-on wording boundaries 2026-09-21 13:29:48 +02:00
releases Record Corebooking candidate deployment 2026-09-22 22:56:59 +02:00
wordpress-org Refine booking identity and Airspace icon 2026-09-22 06:25:17 +02:00
.editorconfig Initial public source import 2026-07-24 02:02:24 +02:00
.gitattributes Initial public source import 2026-07-24 02:02:24 +02:00
.gitignore feat: add independently packaged meeting-room profile 2026-09-13 23:35:24 +02:00
.gitlab-ci.yml Balance plugin checks across shared environments 2026-09-22 12:26:19 +02:00
.markdownlint.json Initial public source import 2026-07-24 02:02:24 +02:00
.wp-env.release.json Prepare Circumflex Booking 1.5.11 release candidate 2026-08-25 08:25:23 +02:00
.wp-env.wordpress-org.json Prepare coordinated free plugin releases 2026-09-16 23:39:51 +02:00
ADDON-DEVELOPMENT.md Add silent expiry for overdue requests 2026-09-22 19:42:12 +02:00
AGENTS.md Track CI efficiency follow-ups 2026-09-22 07:01:39 +02:00
AIRSPACE-IMPLEMENTATION.md Clarify Airspace public description 2026-09-19 06:41:55 +02:00
AUTHENTICATION-HARDENING-PLAN.md Prepare coordinated free plugin releases 2026-09-16 23:39:51 +02:00
AUTHENTICATION-PLAN.md Record verified combined authentication and room-first candidate 2026-09-14 23:20:07 +02:00
BOOKING-ADDONS-PUBLICATION-TODO.md Record Core 1.6.8 publication 2026-09-21 17:08:12 +02:00
components.json Prepare coordinated free plugin releases 2026-09-16 23:39:51 +02:00
MEETING-ROOMS-ADMIN-PLAN.md Integrate booking authentication and room-first administration 2026-09-14 23:06:52 +02:00
MEETING-ROOMS-EXECUTION.md Integrate booking authentication and room-first administration 2026-09-14 23:06:52 +02:00
MEETING-ROOMS-GUIDE.md Prepare coordinated free plugin releases 2026-09-16 23:39:51 +02:00
MEETING-ROOMS-PLAN.md docs: keep product documentation tool-neutral 2026-09-14 06:11:36 +02:00
mise.toml Optimize development and release workflow 2026-07-28 22:10:19 +02:00
PRO-BRANDING-OVERVIEW.md Present booking add-ons and Pro options 2026-09-21 13:07:27 +02:00
PUBLIC-RELEASE-PLAN.md Add silent expiry for overdue requests 2026-09-22 19:42:12 +02:00
README.md Add silent expiry for overdue requests 2026-09-22 19:42:12 +02:00
RELEASE.md Prevent releases from unmerged branches 2026-09-20 15:56:45 +02:00
ROOM-BOOKING-HOURS-PLAN.md Prepare coordinated free plugin releases 2026-09-16 23:39:51 +02:00
ROOM-FINDER-PLAN.md Prepare coordinated free plugin releases 2026-09-16 23:39:51 +02:00
SECURITY.md Refactor booking profiles and harden configuration lifecycle 2026-08-22 07:35:42 +02:00
todo.txt Record Camiskin release verification 2026-09-22 22:05:10 +02:00
WORKFLOW.md Balance plugin checks across shared environments 2026-09-22 12:26:19 +02:00

Circumflex Booking

Circumflex Booking is a self-hosted scheduling and appointment plugin for WordPress. Its default profile can let customers choose either one service or one or more services, a practitioner or the first available practitioner, and an available time. Validated add-ons can register other predefined workflows without forking the reservation engine. New bookings reserve the time while they await manual approval unless a compatible Pro workflow confirms them automatically.

Core 1.6.9 is the current published release and is available from the WordPress.org Plugin Directory. Airspace 1.0.2 is published in its separate WordPress.org listing. Meeting Rooms 1.0.1 is published in its separate WordPress.org listing. Pro is distributed separately through the Circumflex customer platform.

Airspace 1.0.2 explains the plugin's flight-training purpose, planned quiet periods and support for spreading activity across several exercise areas in clearer public language.

Core 1.6.10 is the current development candidate. It lets authorized staff close a past request that was never confirmed without sending notifications. The dedicated action releases the reservation, stops unsent Core and compatible add-on notifications, records the outcome as Expired and retains the ordinary terminal-data privacy lifecycle.

The current compatible published free set is Core 1.6.9 / extension API 21, Airspace 1.0.2 and Meeting Rooms 1.0.1. All three have independent WordPress.org listings. Pro remains a separately versioned and distributed optional add-on. See the public release plan.

The next candidate adds a location-aware room finder with browser-local home and favorites, exact available times and a single confirmation screen. See the room-finder verification record and meeting-room guide. The subsequent authentication hardening record documents the six review fixes and the replacement candidate packages. Existing OIDC clients must register their new connection-specific callback URLs. The follow-up authentication UX candidate forwards directly when one provider is enabled and resumes the original booking automatically after sign-in. Authenticated room-booking users can also open a compact list of their upcoming reservations. The list is scoped on the server to the verified booking identity; anonymous self-service continues through the secure email link. See the authenticated-booking verification record.

The candidate adds a separate meetings domain with capacity, admin-defined facilities, optional city/building/floor navigation and tailored public room selections. Duration has minute precision independently of start steps; full-day and consecutive daily-session bookings retain one shared room calendar. See the meeting-room guide and implementation evidence. Public entrances are not private customer organizations or an authentication system.

The authentication development candidate adds optional Pro customer sign-in through configurable OIDC providers. Core API 21 retains and enforces access rules independently of Pro. See the authentication contract.

Features

  • Configurable services, optional expandable groups with one shared customer description and a one-or-several choice rule, duration, preparation buffer, optional price, and a per-service choice to show or hide treatment minutes from customers
  • Configurable one-service or multiple-service policy for the default appointments profile; vertical add-ons retain their own bounded policy
  • Configurable policy for whether buffers must fit inside opening hours while always retaining the full buffer for conflict prevention
  • One or more practitioners with service-specific availability
  • Weekly schedules with drag ordering and one date-exception editor that can close or add extra opening hours for one practitioner or every practitioner across an inclusive date period, plus manual time blocks
  • Two-step permanent deletion for inactive catalog and schedule configuration, with booking history retained; inactive resources may remain archived without assignments, while deletion is blocked if an active resource would lose its final service
  • Public booking without requiring a customer account
  • A compact treatment, practitioner, date and time summary on the final contact step, with direct change actions and no repeated review screen for standard appointments
  • Adaptive date selection: a today-only window shows available times directly, two to seven available dates use compact date cards, and longer booking windows retain the calendar and list views
  • A booking horizon of zero for today-only booking, with configurable horizons for longer booking windows
  • Manual approval, rejection, rescheduling, completion, no-show and silent expiry workflows for past unconfirmed requests
  • One administrative planning calendar with ordinary day/week time grids, a prominent all-or-one resource filter, bookings across services, free capacity and controlled-public-availability holds; month view stays booking-only
  • Customer email notifications and secure self-service links
  • Configurable site identity in responsive HTML email headers
  • Progressive disclosure for email templates and service-specific scheduling overrides, with effective values kept visible in the collapsed summary
  • Empty optional detail rows are omitted from both plain-text and HTML emails
  • Shortcode, dynamic Gutenberg block, and optional Elementor widget
  • Configurable booking and cancellation deadlines
  • Local data retention, WordPress privacy tools, and audit logging
  • Honeypot and rate limiting, with optional Cloudflare Turnstile
  • Bounded, customer-data-free extension points for separately installed add-ons
  • A site-wide selector for validated vertical booking profiles, with a safe Core fallback
  • A guarded return from an active add-on profile to Core's default workflow, with the default choice collapsed until deliberately opened and confirmed
  • An API 14 date–service–resource–time workflow for vertical add-ons, with optional aggregate context and bounded presentation controls that cannot replace Core availability checks
  • API 15 opt-in participant input policies with browser guidance, normalization and matching server enforcement; the default appointments profile is unchanged
  • API 16 registration of trusted extension text domains through the selected profile's same bounded administration terminology document
  • Review-before-save email-template presets supplied by validated booking profiles
  • A provider-neutral contact-verification boundary with WordPress email in Core Free; Core includes no SMS provider
  • Translation-ready, with complete Norwegian runtime catalogs bundled in the release archive and the source available to WordPress language packs

Payment processing is outside the plugin's scope.

The separately installed Circumflex Booking Pro add-on adds optional sign-in and access control, automation, additional notification channels, follow-up, anonymous insight into the booking journey, official Pro updates and email support. The free plugin remains fully usable without Pro. The agreed public feature presentation and its maintenance rule are recorded in PRO-BRANDING-OVERVIEW.md. Every new or materially changed Pro capability must explicitly update that overview or document why it remains outside the concise public presentation.

The development tree also contains the separately installed circumflex-booking-airspace/ profile. It maps services to session types and practitioners to exercise areas without changing Core's reservation model. Administrators select it explicitly under Booking settings. It can run without contact verification or use email verification; SMS delivery and channel registration remain outside Free and owned by Pro. Once an add-on profile is selected, Core keeps the default appointments profile behind a deliberate return control and confirms the site-wide workflow change before saving it. A temporary fallback never replaces the retained add-on selection merely because the add-on is unavailable. Airspace also owns an optional public upcoming-reservation calendar with a privacy-safe neutral default, explicit visibility choices for additional reservation details, and browser-side filters for individual exercise areas. Through Core API 16 it also uses a date, optional session type, exercise area and start-time sequence. The area overview keeps areas neutral and in the administrator-configured public order, previews exact start availability with a compact segmented line, shows only bounded planned-minute aggregates and hands time selection and booking back to Core. Its required aircraft registration / call-sign field is normalized to uppercase and limited to seven letters and digits, with one optional formatting separator.

Core and add-ons

Core owns the generic reservation, availability, workflow, notification, privacy and audit engine. Vertical domains are separate add-ons that register a complete predefined profile; they do not fork Core and administrators do not maintain arbitrary word-replacement rules. Pro remains separately responsible for SMS delivery and automatic confirmation.

  • ADDON-DEVELOPMENT.md defines the versioned profile, terminology, email, verification, lifecycle and security contract.
  • AIRSPACE-IMPLEMENTATION.md records the Airspace product decisions, current implementation and deferred questions.
  • SECURITY.md documents the threat model, controls and review checklist.

The architecture, Airspace behavior and Meeting Rooms behavior described here are implemented in this repository. Both add-ons have their own WordPress.org listings. The cross-repository candidate, test-site and public publication order is defined in RELEASE.md.

Meeting-room development is tracked in MEETING-ROOMS-PLAN.md and MEETING-ROOMS-EXECUTION.md. The separately installed circumflex-booking-meeting-rooms/ is the published 1.0.1 WordPress.org release. It keeps the booking behavior from the tagged 1.0.0 release while improving public copy and adding the maintained Norwegian add-on catalog. The execution log distinguishes earlier verified candidates from subsequent capabilities. The room-first administration iteration is documented in MEETING-ROOMS-ADMIN-PLAN.md; the current usage guide is MEETING-ROOMS-GUIDE.md. Meeting Rooms 1.0.1 requires Core 1.6.0 or newer with extension API 20.

Requirements

  • WordPress 6.8 or newer
  • PHP 8.3 or newer
  • Tested and supported database baseline: MySQL 8.0 or MariaDB 10.11 and newer
  • A working WordPress mail setup; an SMTP plugin is recommended

The database versions follow WordPress's recommended production baseline and the plugin's compatibility test matrix. Older database versions may work, but they are not tested or supported; the plugin reports them as a warning rather than treating the version alone as proof of incompatibility.

Install the free add-ons on a clean site

The free add-ons require Core 1.6.0. Install Core first, then install Airspace or Meeting Rooms through Plugins → Add Plugin.

For a local development installation, upload and activate the generated archives in this order:

  1. build/circumflex-booking.zip
  2. build/circumflex-booking-airspace.zip
  3. build/circumflex-booking-meeting-rooms.zip when testing that profile

The Core release archive contains the maintained Norwegian PHP and JavaScript runtime catalogs. A Norwegian site therefore does not depend on the timing of a matching WordPress.org language pack for the installed Core version.

When replacing an existing manual installation before the WordPress.org listings are live, upload the new ZIP and choose WordPress's option to replace the installed plugin. Do not uninstall first: Core uninstallation may remove data when permanent data removal is enabled, and keeping an add-on installed preserves a continuous, validated profile transition.

Embed the booking form

Circumflex Booking does not create or reserve a predefined booking URL. Create or edit a normal WordPress page, add one of these integrations, and publish the page:

  • Shortcode: [circumflex_booking]
  • Gutenberg block: Circumflex Booking
  • Elementor widget: Circumflex Booking

The Elementor integration is optional. Core booking functionality does not depend on Elementor. Share the WordPress page's URL with customers as the booking URL.

Measure successful booking submissions

After the server accepts a public booking, the receipt remains visible in the booking form and the page URL gains booking-received=1 without reloading. For example, /book-an-appointment/ becomes /book-an-appointment/?booking-received=1.

The recommended Google Tag Manager setup is:

  1. Create a Custom Event trigger named circumflex_booking_received.
  2. Use that trigger for a GA4 Event tag that sends Google's recommended generate_lead event.
  3. Mark generate_lead as a key event in Google Analytics when a completed booking request is a key event for the site.

The data-layer signal contains only its fixed event name and schema version. It is emitted once after an accepted server response and is not repeated when the receipt is restored, the URL is opened directly, or a submission fails. The plugin only pushes to an existing window.dataLayer; it never creates or loads Google Tag Manager. Non-Google integrations can instead listen for the bubbling circumflex-booking:received DOM event, whose detail is only { version: 1 }.

As a simpler page-view alternative, enable GA4 page views based on browser history events and create generate_lead from page_view when page_location contains booking-received=1. That alternative can observe a repeated page view if the customer refreshes the receipt, so use the dedicated custom event when an exact submission count matters.

The marker and measurement events contain no booking reference, status, service, or customer data. Circumflex Booking does not load an analytics service or transmit analytics itself; the site owner remains responsible for its separately installed analytics, consent configuration, and key-event settings.

Development

The plugin source is in circumflex-booking/.

cd circumflex-booking
composer install
npm ci
npm run build
npm run check

Check the separately installed Airspace reference add-on with:

cd ../circumflex-booking-airspace
bin/check.sh

Create its deterministic release archives with bin/package.sh. The command writes the integration archive plus an immutable, versioned public archive, their SHA-256 sidecars and extracted-content manifests to the repository's top-level build/ directory. Build the same source twice and require every artifact to be identical; the full Core pipeline enforces this and publishes them as CI artifacts. The public release workflow sends the exact approved artifacts to their independent WordPress.org repositories; see RELEASE.md.

Create the deterministic WordPress.org ZIP archive with:

npm run plugin:zip

For compatibility with existing manual-install workflows, the same verified content can also be emitted under the standalone archive name:

npm run plugin:zip:standalone

This first verifies the WordPress.org archive and then creates build/circumflex-booking-standalone.zip. Both Core archives contain the same maintained Norwegian PHP and JavaScript runtime catalogs. Airspace includes its own complete Norwegian runtime translation in its separate archive.

The build requires Composer, Node.js, npm, Docker, and a recent WordPress CLI environment. Exact dependency versions are recorded in the lock files.

Working task list

Open product tasks may be added to todo.txt. During an active work session, check the file when starting, before choosing the next task, periodically during longer sessions, and before handoff. Keep a task in the file until its implementation and relevant verification are complete, then remove it as part of the same change. Do not remove a task merely because it was read, discussed, or deferred.

A release checklist is the exception: keep its unresolved public and manual gates until the release is published or explicitly superseded. Store permanent candidate hashes, pipeline links, deployment/restore evidence and final public verification under releases/ and link the short checklist to that record.

At an agent handoff, start with the Resume protocol in todo.txt. Re-read live Git status and the private operations pause marker before acting. Do not repeat a frozen release gate merely because the conversation, process, or network connection restarted.

todo.txt is a lightweight inbox, not a background monitor. It can only be checked while someone is actively working in this repository; it is not monitored between work sessions.

Keep each todo entry short, decision-oriented and verifiable. Do not paste personal contact details, credentials or full correspondence into the task file. Distill the requirement and link to a maintained design document when the context is longer; include the unresolved decision and the check that will show when the task is complete.

When code changes are ready to be checked in, the handoff must include a concise, concrete suggestion for the Git commit message. Do not create the commit unless the user explicitly asks for it.

WordPress.org releases

The plugin is published in the WordPress.org Plugin Directory. Releases are promoted from verified Git tags to the WordPress.org Subversion repository.

A protected semantic-version Git tag runs the complete test matrix and an anonymous WordPress.org SVN preflight. The resulting wordpress-org-release job remains manual and requires a second confirmation before it can update trunk/, copy the release from trunk to tags/<version>/, publish the reviewed directory artwork under top-level assets/, and commit the changes atomically.

Each component job accepts only its configured WordPress.org repository and the public WordPress.org username sutregutt. Its only secret is the account's separate SVN password, supplied as the protected, masked, hidden WPORG_SVN_PASSWORD GitLab variable with environment scope wordpress.org. No WordPress.org password belongs in Git, artifacts, job definitions, or job logs.

Data and external services

Booking and contact data are stored in the WordPress database. Circumflex Booking does not transmit telemetry.

Cloudflare Turnstile is disabled by default. If a site administrator explicitly enables it, the public booking form contacts Cloudflare to verify submissions. Administrators should describe that service in their privacy notice.

Email is sent through WordPress wp_mail() and therefore uses the mail transport configured by the site owner.

Public information

Support is provided through the WordPress.org support forum.

License

Circumflex Booking is licensed under GPL-2.0-or-later.

Felles bookingtider for møterom (utviklingskandidat)

Nye møterom følger felles bookingtider, som starter med hele døgnet / alle dager. By, bygg og etasje kan overstyre regelen. Eksisterende rom beholdes og kan velges samlet under Bookingtider for å følge stedets regler. Anbefalt møtedag og «Hel dag» er normalt 08:00–16:00, uavhengig av når rommet kan bookes. Se møteromveiledningen og vurderingen og implementeringsplanen.