Author Archive

Event Listings & Ticket Types

Listeo Booking Plus turns Listeo’s Event listing type into a real ticketing system. You can define multiple ticket types per event, set capacity per type, control sale rules, and (optionally) collect attendee details at checkout.

Defining ticket types

  1. Edit an Event listing.
  2. Scroll to the Ticket Types meta box.
  3. Click Add ticket type for each tier — for example: Adult, Child, VIP, Early Bird.
  4. For each tier set:
    • Label — what customers see (“Adult”, “VIP”).
    • Price — per-ticket price in your store currency.
    • Capacity — how many of this ticket type are available. Leave blank for “as many as the event capacity allows”.
    • Min & Max – set how many tickets user could buy at once.
    • Sales Start and Sales End date – when tickets will be available

How capacity works

Booking Plus respects two capacity limits at the same time: the per-ticket-type capacity (the cap you set on each tier) and the event total capacity (Core’s listing-level field). Whichever is reached first stops sales for that tier.

Example: an event with total capacity 100 and a “VIP — 20 tickets” tier. Once 20 VIP tickets are sold, the VIP tier shows as sold out even if total ticket sales are well below 100.

The front-end ticket selector

Customers see a quantity selector per ticket type. They can mix tiers in a single booking (2 Adult + 1 Child + 1 VIP), and the booking summary breaks each line out for transparency.

Collecting attendee names and emails

Toggle Collect attendee names and / or Collect attendee emails in Listeo Core  → Listeo Booking Plus Settings. When on, the confirmation step shows one name (and / or email) field per ticket. Names appear on the individual e-tickets; emails are stored against the booking so each attendee can be contacted directly.

 

Reservation holds

When a customer clicks “Book” and lands on the confirmation step, Booking Plus puts a temporary hold on the tickets they’ve selected. While the hold is active, those tickets are invisible to other customers — the inventory shows fewer seats, and the ticket selector won’t let anyone else buy them.

If the customer completes checkout, the hold becomes a real booking. If they abandon the page (or the timer runs out), the hold expires and the seats go back into inventory.

Configuration

  • Reservation hold time (minutes) — Listeo → Settings → Booking. Default: 15.
  • Raise it if your checkout requires a slow third-party step (a complex payment redirect, a manual approval).
  • Lower it on high-demand events where seats need to recycle quickly when checkout is abandoned.

What happens when a hold expires

The customer doesn’t get an aggressive error — when they submit the form, the system re-checks availability and tells them politely that their hold expired and to pick again. No silent overselling.

Individual ticket codes

When Generate individual ticket codes is on (default), Booking Plus creates one unique scannable code per ticket — not per booking. A family that buys 4 tickets gets 4 codes.

Where customers see their codes

  • In the booking confirmation email.
  • On the booking detail page in their dashboard.
  • Each code includes a QR for the door scanner.

Why per-ticket and not per-booking

Door scanning works ticket-by-ticket: each attendee can arrive separately, get their own code scanned, and the system marks just that ticket as used. With one code per booking, a single scan would either let the whole family in (no count) or block subsequent scans (annoying).

If you really do want per-booking codes (small private event, you trust the headcount), switch the setting off and the legacy single-code-per-booking behaviour comes back.

The Booking Popup – Appearance & Steps

The booking popup is the customer-facing modal used by every booking type — Services, Rentals and Events. Booking Plus replaces Listeo Core’s inline booking widget with this multi-step popup whenever the listing is configured to use Booking Plus features (resources or ticket types).

The steps

# Step When it appears
1 Resource  When the listing has resources attached. Picks which resource to book.
2 Date/time Always. Picks the date(s) and (for time-aware bookings) the time slot.
2 / 3 Tickets Event listings. Pick ticket types and quantities.
Last Confirm Always. Reviews the booking, collects guest info, optional attendee details.
Last+1 Success After a successful booking. Shows confirmation + next steps.

Customising appearance

Three colors in Listeo → Settings → Booking → Booking Popup Appearance control the look:

  • Popup sidebar — color — main sidebar background. Defaults to #2d2d32 (close to black).
  • Popup sidebar — gradient end (optional) — set this for a gradient sidebar; leave blank for solid.
  • Popup accent color — used for the dot before each section label, the active step number, the “Next” button, and selection highlights. Defaults to #3b82f6 (blue).

Values are injected as CSS custom properties before the popup paints — no flicker of the old color when the page loads.

Mobile behaviour

The popup goes full-screen on mobile and the multi-step navigation collapses to a top progress bar. Sidebar content moves to a collapsible header so the form always has the full screen width.

Overriding the templates in a child theme

Every step is a separate template file you can override (see  Customizing Templates):

  • templates/booking/modal.php — the popup shell.
  • templates/booking/modal-sidebar.php — the left sidebar.
  • templates/booking/modal-step-datetime.php
  • templates/booking/modal-step-resource.php
  • templates/booking/modal-step-confirm.php
  • templates/booking/modal-step-success.php

Services – Durations, Individual Services & Slot Spans

For Service listings,  Listeo Booking Plus adds two opt-in features that change how the booking widget interprets service selections.

Service durations

Off by default. Turn on with Enable service durations in Listeo Core → Booking.

When on, each bookable service on a listing gains a Duration field. Set a duration in minutes (e.g. 90 for a 90-minute massage), and when a customer picks that service the booking widget reserves enough consecutive slots to cover it.

Example with 30-minute slots:

  • Customer picks a 90-min service starting at 10:00.
  • Booking widget blocks 10:00, 10:30 and 11:00 — three consecutive slots.
  • No other customer can book any of those three slots, even though only one was “selected”.

This is the right model whenever a service is longer than your underlying booking grid.

Individual Services

Off by default. Turn on with Enable Individual Services in Listeo Core → Booking.

When on, each service has an Individual service toggle. The rule:

  • A customer can pick at most one Individual service per booking.
  • They can stack as many non-Individual services as they like on top — these act as add-ons.

The model: an Individual service is “the appointment” (haircut, massage, consultation); non-Individual services are “the add-ons you can tack on” (scalp treatment, hot towel, extra 15 min). This matches how most service businesses actually quote work.

If you don’t sell anything that fits the “main + add-on” pattern, leave this off – the regular Listeo Core behaviour applies and customers can pick any combination.

Slot spans

When service durations are on, the underlying mechanism is called slot spans — the booking record itself stores the span (start slot + number of slots) so that conflict checks, the calendar and emails all see one logical booking spanning multiple slots rather than several separate ones.

You don’t configure slot spans directly — they’re how durations get expressed under the hood. The main effect for you is that the bookings admin shows one row per booking (not one per slot), which keeps the list readable.

Pricing Extras & Repeatable Fees

Listeo Booking Plus extends Listeo Core’s pricing with repeatable fees — costs that scale with the booking instead of being a flat add-on.

What’s a repeatable fee?

Any cost that’s calculated per unit-of-something. Common examples:

  • Per-guest fee$5 per guest on a tour or event.
  • Per-night cleaning fee$25 per night on a rental.
  • Per-attendee surcharge — VIP service fee charged per ticket.

Compare to a flat fee (Listeo Core’s existing feature), which is the same regardless of party size or length of stay.

Adding a repeatable fee

  1. Edit the listing.
  2. In the pricing / extras section, find Repeatable Fees.
  3. Click Add fee and set:
    • Label (shown in the booking summary).
    • Amount per unit.
    • Unit — guest, night, ticket, hour, etc.
  4. Save.

Updating the Listeo Booking Plus

Normal updates

Once your license is activated, Booking Plus updates show up on Plugins → Updates like any other plugin. Click Update and you’re done.

Manual updates (license issues, staging environments)

  1. Download the latest .zip from your PureThemes license page.
  2. Plugins → Add New → Upload Plugin → pick the new zip.
  3. WordPress will detect that an older version exists and prompt to replace it. Confirm.
  4. The license re-syncs on the next admin page load.

The migration screen

Major releases sometimes need to migrate data — new database tables, new schema for ticket types, etc. Booking Plus runs migrations on first load after the update and shows a migration progress screen if there’s significant work to do.

Do not close the page while a migration is running. On most sites it completes in seconds. On sites with thousands of bookings it can take a minute or two. If it’s interrupted, reload the page and the migration resumes from where it stopped.

What to back up first

Before any major plugin update on a production site:

  1. A full database backup (UpdraftPlus, the host’s snapshot tool, or a manual mysqldump).
  2. The plugin folder (wp-content/plugins/listeo-booking-plus/).

You’d want both anyway, but specifically for Booking Plus: it stores resources, occurrences and ticket data in custom DB tables, so a database backup is the only way to roll back cleanly.

Customizing Templates in a Child Theme

Booking Plus follows the same child-theme override convention as Listeo Core: copy any template from the plugin’s `/templates/` folder into a matching path under your child theme, and Booking Plus loads your copy instead of its own.

Override path

wp-content/plugins/listeo-booking-plus/templates/<path-to-template>.php
wp-content/themes/your-child-theme/listeo-booking-plus/<path-to-template>.php

Most commonly overridden templates

Template What it controls
booking/modal.php The popup shell and step navigation.
booking/modal-sidebar.php The left sidebar inside the popup.
booking/modal-step-datetime.php The first step — date / time pickers.
booking/modal-step-resource.php The resource picker step.
booking/modal-step-confirm.php The confirmation step — guest info, attendee fields, summary.
booking/modal-step-success.php The “booking confirmed” screen.
booking/event-ticket-selector.php The multi-tier ticket quantity selector on Event listings.
booking/event-booking-summary.php The breakdown of selected tickets and totals.
single-listing/resources.php The Resources block on single-listing pages.
single-listing/resource-card.php A single resource card inside that block.
resource-submit.php / resource-list.php The front-end resource manager screens.
single/recurring-event-block.php The occurrence picker on a recurring event’s single page.

Things to know before you override

  • Templates can change between major versions. When you override, you’re taking responsibility for keeping your copy current. After a major update, diff your override against the new plugin version and pull in any changes — otherwise you’ll miss bug fixes and feature improvements.
  • Hooks first, overrides second. Many templates have do_action() / apply_filters() hooks. If you can achieve what you want by hooking into them from your child theme’s functions.php, do that — you’ll survive plugin updates without diffing anything.
  • Don’t override partials/ unless you know what depends on them. Several partials are included from multiple parent templates; overriding one partial changes its behaviour everywhere it’s used.

Resources – Employees, Rooms & Equipment

A Resource is anything that can only be booked by one customer at a time that can belong to a listing. Examples:

  • A hair stylist (a Service listing has multiple stylists; the customer picks one).
  • A specific hotel room.
  • An individual rental car or kayak inside a vehicle rental business.

When a listing has resources attached, Booking Plus reserves the resource – not just the listing. Two customers can book the same listing at the same time if they pick different resources, and conflicts are checked at the resource level.

When Manager Resources page is set, each Listings in My Listings page will have button “Add Resource”, that will open a submit form to create resources for listings.

In Listeo Booking Plus, “Resources” is the catch-all term for whatever bookable thing lives inside a listing — a room in a hotel, a stylist in a salon, a vehicle in a fleet, a court in a tennis club. Because that term doesn’t fit every business equally well, the plugin lets you rename it at three different levels: globally, per listing type, or per individual listing

When Listeo Booking Plus needs to print the label on a button, a heading, or in an email, it looks for the most specific override first and walks up to the default:

  1. Per-listing override (most specific) — set on the single listing.
  2. Per-listing-type label — set on the Listing Type in the Listeo editor.
  3. Plugin default — the literal words Resource / Resources.

If a listing has its own label, that wins. If it doesn’t, the listing’s type label wins. If neither is set, the generic default is used.

Level 1 — Plugin default

Out of the box, every label says Resource (singular) / Resources (plural). If your site is generic enough, you can leave it. Most sites won’t want to.

Level 2 — Per listing type (recommended starting point)

This is where 90% of sites should set the label. It applies to every listing of a given type — so all your Hotels say “Rooms,” all your Salons say “Professionals,” all your Tour businesses say “Guides.”

Where to set it:

  1. Go to Listeo Editor → Listing Types in wp-admin.
  2. Edit the listing type (e.g. Hotel, Service, Rental).
  3. Scroll to the Booking Resource Labels block.
  4. Fill in:
    • Singular Label — e.g. Room, Professional, Instructor, Vehicle.
    • Plural Label — e.g. Rooms, Professionals, Instructors, Vehicles.
  5. Save.

Level 3 — Per individual listing

Sometimes one specific listing inside a type needs a different word. A clinic listing type called “Practitioners” might still have one location that uses “Therapists.” A hotel called “Rooms” might have one boutique property where they’re called “Suites.”

There are two ways for that override to get set, depending on whether the listing is being managed in wp-admin or on the front-end.

A) The admin metabox (always available)

On the wp-admin listing edit screen, there’s a Resource Label Override section with two fields — singular and plural. Fill them, save, and they take precedence over the listing type’s label for this one listing only. Leave them blank to fall back to the listing-type label.

This works for every listing on every site without any extra setup.

[SCREENSHOT: Resource Label Override metabox on listing edit screen]

B) Front-end submit form (opt-in per listing type)

If you want the listing owner to be able to set the override themselves from the front-end (without giving them wp-admin access), you need to add the override fields to the submit form for that listing type using Listeo’s Submit Listing Editor.

  1. Go to Listeo → Submit Listing Editor
  2. Pick the listing type you want to enable the override on.
  3. Choose the section where you want the fields to appear (e.g. Basic information or a new section called Booking).
  4. Click Add Field and you’ll see two Booking Plus entries in the picker:
    • Resource Label (singular) — Booking Plus
    • Resource Label (plural) — Booking Plus
  5. Add both. Save the form.

From that point on, the listing’s owner sees the two fields in their submit / edit form and can fill them in. The values save to the listing as post meta and the booking UI picks them up immediately.

Creating a Resource from Admin side

Resources are a custom post type registered under your Listings menu in the WP admin.

  1. Go to Listings → Booking Resources → Add New.
  2. Give the resource a title (e.g. “Anna — Senior Stylist”, “Room 4”, “Kayak #12”).
  3. Add a description and a featured image — both appear on the front-end and in the booking popup.
  4. Save.

Assigning a Resource to a Listing

Edit a listing (Services, Rentals, Events all support it) and you’ll find a Resources section. Pick the resources that belong to this listing and save, or you can edit resource and select the listing to which it should be assigned

Display layout on the front-end

Resources appear on the single-listing page in either List (full-width stacked) or Grid (2-column cards) layout — switch in Listeo → Settings → Booking → Resources display layout.

When the listing has resources, listing-level booking settings act as defaults

Some configuration (availability calendar, certain pricing options) moves from the listing to the resource when resources are attached. The listing-level fields stay as defaults that new resources inherit, and the editor shows a notice telling you so — no need to re-enter everything for each resource. Basically if something is not set for resource, it inherits the setting from the listing.

Plugin Settings Overview

The Booking Plus options live on the Listeo > Settings > Booking tab, in two blocks near the bottom: Listeo Booking Plus Settings and Booking Popup Appearance. They live here rather than on a separate page because they extend Listeo Core’s booking behavior — keeping them together means one place to configure how bookings work site-wide.


Listeo Booking Plus Settings

Option What it does Default
Collect attendee names Adds a name field for each ticket on the booking confirmation form. Names appear on the individual e-tickets. Off
Collect attendee emails Adds an email field for each ticket on the confirmation form. Useful when each attendee should receive their own ticket. Off
Reservation hold time (minutes) How long tickets stay reserved in inventory while a user is on the confirmation page. Prevents two customers from buying the last seat at the same time. Lower it on high-traffic events; raise it for slower checkout flows. 15
Generate individual ticket codes One scannable code (with QR) per ticket. When disabled, one code per booking — legacy behavior, fine for small private events. On
Recurrence lookahead (months) How far in the future to generate occurrences for recurring events. The cron job extends the window as time passes. 12
Enable service durations Shows a "Duration" field on each bookable service. When set, the booking widget reserves enough consecutive time slots to cover it (e.g. a 90-min service blocks three 30-min slots). Off
Enable Individual Services Shows an "Individual service" toggle on each service. Customers can pick at most one Individual service per booking; non-Individual services act as add-ons that stack freely. Off
Resources display layout How resources appear on a single-listing page. List = stacked full-width rows. Grid = 2-column card grid, similar to the listings archive. List

Booking Popup Appearance

Option What it does Default
Popup sidebar — color Primary background of the popup’s left sidebar. #2d2d32
Popup sidebar — gradient end (optional) When set, the sidebar becomes a top-to-bottom gradient from the primary color to this one. Leave blank for a solid sidebar. (empty)
Popup accent color Drives the dot accent before section labels, the active step number, the primary "Next" button and selection highlights. #3b82f6
Example gradient

Note Changes apply on the next page load — the values are emitted as CSS custom properties before the popup paints, so there’s no flash of the old color.

Installation & License Activation

Up and running in 5 minutes!
Install Listeo Booking Plus like any WordPress plugin, activate your license key, and the advanced booking features unlock instantly – with automatic updates included.

⚠️ Requirements: Booking Plus requires the Listeo Core plugin to be installed and activated first – the plugin won’t boot without it. WooCommerce is also needed for bookings and checkout to work.


Installation
  1. Go to https://purethemes.net/license/ and download listeo-booking-plus.zip
    Enter your Listeo theme license there (for the free version) or your Listeo Booking Plus license (if you purchased the Pro version).
    You’ll need purchase key: How to find my license key?
  2. In WordPress admin, go to Plugins → Add New → Upload Plugin.
  3. Pick the zip, install, then click Activate.

If Listeo Core is missing or not active, you’ll see this notice – install/activate Listeo Core first, then come back:

Listeo Booking Plus – This plugin requires Listeo Core to be installed and activated. Please install Listeo Core first.


Enter your license key

Lost key or did not receive it after purchase? Send us an email at [email protected]

The free tier (the redesigned booking popup) works right after activation. All premium features – Resources, Event Ticketing and Recurring Events – stay locked until a valid license key is activated.

  1. Go to Settings → Booking Plus License.
  2. Paste your license key from your PureThemes account.
  3. Click Activate License.


You’ll see a green confirmation and a “Last verified” timestamp on success.

🔧 Activation failed? The most common reasons are:

1️⃣ The key has been used on too many sites – deactivate it on one of the others first.

2️⃣ The site URL doesn’t match what the license is registered against – typical after a domain change or moving from staging to production.

3️⃣ The server can’t reach the PureThemes license endpoint – check that your host isn’t blocking outbound HTTPS connections.


Invalid or expired license

With an invalid or expired license you’ll see a persistent admin notice on every page that links to the License page, and Booking Plus’s premium features remain disabled until activation succeeds.
Your data is not deleted – resources, tickets and bookings stay in the database; they just stop being surfaced until the plugin can boot again.


Automatic updates

Once activated, the license also enables automatic updates through the standard WordPress Dashboard → Updates and Plugins screens – no manual zip downloads needed for future versions.
See also: Updating the Listeo Booking Plus →


FAQ
  • Is there a free version of Booking Plus?

  • Where do I find my license key?

  • I'm moving from staging to production - what about the license?

  • What happens to my data if the license expires?

  • Do I get automatic updates?


Viewport Search

How it works?

If someone types a location in the search field, the geocoding service (Google Places API or OpenStreetMap Nominatim) returns not only the center coordinates but also a viewport – a rectangular bounding box that naturally represents the entire searched area.

When viewport search is enabled, Listeo uses these bounding box coordinates to find all listings within that rectangular area. For example:

  • Searching “California” returns all listings in the entire state
  • Searching “Brazil” returns all listings across the country
  • Searching “Europe” returns all listings on the continent

This works perfectly for large geographic areas where a circular radius search would be impractical.

Benefits:

  1. No radius selection needed for large areas – the natural bounds from the geocoding service are used automatically
  2. Faster database queries – simple coordinate range comparison instead of complex trigonometric calculations
  3. Better user experience – searching “Brazil” returns results from the entire country, not just a 50km radius from the center point
  4. Works with both Google Maps and OpenStreetMap – viewport data is included in both APIs at no extra cost


How to enable?

Viewport search uses the same geocoding API you’re already using for location search – there are no additional API costs. The viewport/bounding box data is already included in every geocoding response.

  1. Navigate to Listeo Core → Settings → Maps in your WordPress admin panel
  2. Find the “Location Search Method” setting
  3. Choose one of three modes:
    – Radius-based (current) – Traditional circular search using selected radius (default)
    – Viewport-based (recommended for large areas) – Uses rectangular bounding box from geocoding service
    – Auto (intelligent switching) – Automatically uses viewport for large areas (countries/regions) and radius for cities
  4. Configure optional settings:
    – Viewport Fallback Radius – When viewport data is unavailable (rare), use this radius value (default: 50)
    – Auto Mode Area Threshold – In Auto mode, if the viewport area exceeds this value in km², use viewport search (default: 50,000 km²)


Technical Details

Performance Comparison
Metric Radius Search Viewport Search
Database Query Haversine formula (trigonometry) Simple BETWEEN comparison
Query Speed (10k listings) 2-3 seconds 0.3-0.5 seconds
Indexable ❌ No ✅ Yes
Large Area Support ❌ Poor ✅ Excellent

API Costs

No additional costs – Viewport search uses the same geocoding API calls as radius search:

  • Google Places API: Same autocomplete session ($0.00283 per search)
  • OpenStreetMap Nominatim: FREE (no change)

The viewport/bounding box data is already included in every geocoding response – we’re just using data that was previously ignored.


When to Use Each Mode?

Use Viewport Mode:

  • Sites with listings across large geographic areas (states, countries, continents)
  • High-traffic sites with many listings (10,000+)
  • When users commonly search for broad locations
  • To eliminate the radius slider from search forms

Use Radius Mode:

  • Sites focused on local/neighborhood search
  • “Near me” functionality is important
  • Users expect circular search areas
  • Listings are concentrated in specific cities