Developer API
Booking Hub is built to be themed: the CP handles service configuration and reservation management, while the public booking form is a set of theme templates a developer wires up against the plugin's services and Twig helpers.
Frontend templates
Booking Hub registers its own frontend template root (bookinghub/...) with
starter templates under templates/frontend/services/ — an index (service
picker / booking flow), summary, and success page, plus a customer
account tab (templates/frontend/customer/account/reservations.twig) when
customer account integration is enabled.
These ship intentionally minimal — they extend the shared yui/layouts/*
layout and load the plugin's compiled CSS via the craft.getCssStyleContent()
helper, but the actual booking UI (service list, date/slot picker, form
markup) is left for the site's theme to build against the plugin's services
below. Read more on the shared theme structure at
craftdocs.yui.sk/docs/frontend/theme-structure.
The site routes behind these templates — booking-hub/services,
booking-hub/services/reserve, the per-service get-dates availability
endpoints, and so on — are only registered while the plugin itself is
enabled (Booking Hub → Settings → General). With the plugin disabled,
those routes 404 and the theme's booking pages have nothing to call. The
YSCP account routes (booking-hub/account/*) are the one exception — they're
registered whenever YSCP support is on,
independent of that toggle.
Twig variable and helpers
Booking Hub attaches a craft.bookinghub behavior
(Yui\BookingHub\web\twig\CraftVariableBehavior) to the global craft
variable, plus a small extension registered directly on Twig:
{# Inline/minified CSS for a compiled asset path or a raw CSS string #}
{{ craft.getCssStyleContent(bookingServicesCssUrl)|raw }}
{# The configured store address, as an array or a formatted string #}
{% set address = craft.bookinghub.getStoreAddress(true) %}
{# Renders a settings-configured agreement text with a {link} placeholder
swapped for the linked entry's URL #}
{{ craft.bookinghub.getAgreementLabel(agreementText, agreementPageId) }}
{# Minutes -> human-readable duration, e.g. "90" -> "1h 30min" #}
{{ 90|formatDuration }}
{{ formatDuration(90) }}
{# Whether the nystudio107 Minify plugin is installed and active #}
{% if isMinifyEnabled() %}...{% endif %}
Service types and availability
Every service is one of two types, each with its own service class under
Yui\BookingHub\services\types:
EventService—getAvailableDates(int $eventId, string $date = null)returns the remaining bookable occurrences/seats for a fixed-schedule event;getParticipantsById(int $id)lists who has already reserved a seat.AppointmentService—getAvailableSlots(int $appointmentId, string $date = null)returns the open time slots for a given day, generated from the service's duration and the business hours/lunch break/holiday configuration in Settings;generateAppointmentTimeSlots()(re)builds the slot set when a service's schedule changes.
Both funnel into ReservationService, the shared entry point for creating
and querying bookings regardless of type — used by the CP and the customer
account tab alike:
use Yui\BookingHub\Plugin;
$reservationService = Plugin::getInstance()->getReservation();
// Reservations for the logged-in customer / a guest by email
$mine = $reservationService->getCustomerReservations($customerId);
$guest = $reservationService->getGuestReservations($email);
// Upcoming vs already-happened bookings
$active = $reservationService->getActiveReservations();
$past = $reservationService->getPastReservations();
// Save a new booking (validates availability/overlaps before saving)
$reservationService->save($reservationModel);
$reservationService->cancelReservation($reservationId);
Cancellation rules
Each event/appointment service can define whether it's cancellable and, if
so, a cutoff window before the start time. ReservationService::getCancellationMinutes()
returns how many minutes remain before that cutoff for a given
reservation's start date, so a theme can show or hide a "Cancel" button
without duplicating the rule.
Console commands
Two reservation reminder jobs are meant to run on a schedule (cron), and one diagnostic command:
# Reminder shortly before a reservation, per the lead time in Settings
* /15 * * * * /path/to/craft bookinghub/reservations/send-notifications
# Optional "reminder before a future/recurring event" pass
0 6 * * * /path/to/craft bookinghub/reservations/send-future-notifications
# Verify the plugin is installed, its tables exist, and report status
./craft bookinghub/plugin/validate
Both notification commands accept an optional --siteId for multi-site
installs and log failures through the plugin's own error log
(Plugin::error()) rather than failing the cron run.
Editions and licensing
Booking Hub ships three editions — small, medium, enterprise — gating
feature availability by license tier. License validation and the CP
license screen reuse the shared yui\craftcore license infrastructure (see
the platform's own developer docs for the general license/entitlement
model); Booking Hub's LicenseService is the plugin-specific entry point
into it.