=== Eventward ===
Contributors: omniswp
Tags: events, calendar, event calendar, recurring events, tickets
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.5.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

The complete events calendar, free: recurring events, six views, maps, tickets and RSVP with no platform fee. No Pro version, nothing locked.

== Description ==

Eventward is a complete events calendar for WordPress, and all of it is free. Recurring events, six calendar views, maps, venues, organizers, tickets and RSVP come in one plugin. There is no Pro version, no add-on store, no licence key and no feature held back for a paid tier.

It is built for sites that need to stay fast and correct: event dates live in their own indexed table, repeating schedules are expanded by a real iCalendar engine, and paid tickets go straight to your own Stripe account with no fee from us.

= What makes Eventward different =

* **Everything is in the free plugin.** Recurring events, every view, maps, filters, tickets and RSVP. Most event plugins sell these as add-ons; here there is nothing to upgrade to.
* **Built on a proper date index.** Each event date is stored as a row in one small indexed table, instead of being searched out of post meta. Month, week and list views stay quick as a calendar grows into thousands of dates, and every event keeps its real post ID, so other plugins and page builder loops work with it normally.
* **Recurring events that get the details right.** Schedules follow the iCalendar standard (RRULE), with skipped and extra dates. Each event has its own timezone, and a 7pm weekly event stays at 7pm when the clocks change.
* **Tickets with no platform fee.** Free tickets work as an RSVP. Paid tickets use Stripe Checkout on your own Stripe account: buyers pay you directly and you only pay Stripe's standard processing fees.
* **Search engine friendly by design.** Every event page carries schema.org Event data for Google. Calendar navigation cannot turn into an endless crawl: dated calendar pages are noindex, navigation links are nofollow and empty far-future months return 404.
* **An easy move from The Events Calendar.** Event, venue, organizer, month and day URLs follow the same patterns, and the `[tribe_events]` shortcode keeps working, so existing links and pages survive the switch.

= Calendar and views =

* **Six views:** month, week, list, photo, map and day, as a block you can place anywhere, plus ready-made templates for block themes. Classic themes are supported too.
* **Search and filters** by keyword, category, venue and organizer, applied in place without reloading the page.
* **Mobile friendly.** On small screens the month view becomes an easy-to-read agenda.
* **Light on your pages.** Styles and scripts only load where events are shown, and moving between months and views updates the calendar in place.

= Recurring events and time zones =

* Daily, weekly, monthly ("the second Tuesday", "the last Friday") and yearly schedules, with intervals, end dates, counts, skipped dates and extra dates.
* A custom option for anything else the iCalendar standard can describe.
* A timezone per event, with correct local times across daylight saving changes.
* Each date of a repeating event has its own page and its own entry in Google's event data.

= Venues, organizers and maps =

* Create venues and organizers inline while editing an event. Each gets its own page listing its upcoming events.
* **Maps without API keys.** OpenStreetMap maps for the calendar, venues and events, with clustered pins, bundled with the plugin.
* Venue addresses are turned into map locations automatically when you save, and you can always place the pin by hand.

= Tickets and RSVP =

* Free RSVP and paid tickets, several ticket types per event, with capacity per type and per date.
* Stripe Checkout in test and live mode. Connect your Stripe account in one click, or paste a restricted API key.
* Seats are held while a buyer pays and released automatically if they do not finish, so a date does not oversell.
* Confirmation emails with ticket codes, an attendee list with check-in, CSV export, one-click refunds and resending confirmations.
* An optional Stripe webhook for instant confirmations. Without it, payments are still confirmed when buyers return and by a background check.
* Bookings are included in WordPress's personal data export and erasure tools.

= Themes, blocks and page builders =

* Native blocks and Site Editor templates for block themes.
* Shortcodes for the calendar, event details, single fields (date, venue, cost and more), tickets and maps, for Bricks, Divi, Elementor and other builders.
* A sortable "next date" field for page builder query loops.

= Sharing and SEO =

* schema.org Event data on every event: status, attendance mode, location, organizer, price and availability.
* Add to calendar links for Google Calendar, Apple Calendar, Outlook and Microsoft 365, plus subscribable iCal feeds for the whole calendar or any category.
* Event status for cancelled, postponed, rescheduled and moved online events, shown on the page and sent to Google.

= Fair by default =

* No upsells, no admin banners, no ads and no tracking. Every external service Eventward can use is listed below, with what it sends and when.
* Your data stays yours: deactivating never deletes anything, and uninstalling only removes events if you ask it to.
* Translation ready.

Eventward is made by OmnisWP, the team behind Siteward.

== Installation ==

1. Install and activate Eventward from Plugins > Add New.
2. Go to Events > Add Event. Set the date, time and repeat options in the editor sidebar, and add a venue and organizer if you like.
3. Your calendar is live at /events/. To show it anywhere else, add the Events Calendar block, or the `[eventward]` shortcode in a page builder.
4. To take bookings, turn on "Take bookings for this event" in the Tickets and RSVP panel. Free tickets work straight away; for paid tickets, connect Stripe under Events > Payments.
5. Adjust views, slugs, maps and more under Events > Settings.

== Frequently Asked Questions ==

= Is there a Pro version? =

No. Every feature is in this plugin, free.

= Will it slow my site down? =

Eventward only loads its styles and scripts on pages that show events, and stores event dates in an indexed table built for date-range lookups.

= Do you take a fee on ticket sales? =

No. Payments go directly from the buyer to your own Stripe account. You only pay Stripe's standard processing fees.

= Do I need a Stripe account? =

Only for paid tickets. Free tickets (RSVP) work without Stripe or any other service.

= I use The Events Calendar. Will my links break if I switch? =

Eventward uses the same URL patterns for events, venues, organizers and calendar pages, and supports the `[tribe_events]` shortcode, so existing links and pages keep working.

= Does it work with my theme or page builder? =

Yes. Block themes get native blocks and templates, classic themes are supported, and shortcodes cover Bricks, Divi, Elementor and other builders.

= Does Eventward contact any outside services? =

Only the ones listed under External services below, each for a clear reason (map tiles, address lookups for venues, and Stripe when you sell paid tickets). There is no tracking or usage reporting.

= Which recurrence rules are supported? =

Daily, weekly, monthly and yearly rules with intervals, weekdays, "nth weekday" and "last weekday" patterns, end dates and counts. The custom option accepts iCalendar RRULEs using FREQ, INTERVAL, COUNT, UNTIL, BYDAY, BYMONTHDAY, BYMONTH, BYSETPOS and WKST.

== External services ==

Eventward works on your own site, except for the services below:

* **OpenStreetMap Nominatim (geocoding).** Used to turn venue addresses into map locations. Your site contacts https://nominatim.openstreetmap.org when a venue is saved with a new or changed address, when you press "Find on map", and in an hourly background check that looks up to 10 venues that have never been looked up (for example imported ones). Venues whose coordinates you typed yourself are never looked up. Each request sends the venue's address (street, city, region, postcode, country), your site's address (in the User-Agent, as Nominatim's policy requires) and your site's language. Nothing about your visitors is sent. You can turn this off under Events > Settings > Maps. Usage policy: https://operations.osmfoundation.org/policies/nominatim/ Privacy policy: https://osmfoundation.org/wiki/Privacy_Policy
* **OpenStreetMap map tiles.** Pages that show a map load map images from https://tile.openstreetmap.org in the visitor's browser (only once the map scrolls into view). The visitor's IP address and the page address are visible to that server, as with any image. Tile usage policy: https://operations.osmfoundation.org/policies/tiles/ Privacy policy: https://osmfoundation.org/wiki/Privacy_Policy You can switch to another tile provider under Events > Settings > Maps.
* **Add to calendar links** (Google Calendar, Outlook.com, Microsoft 365) are ordinary links: nothing is sent unless a visitor clicks one.
* **Stripe (payments).** Only when you sell paid tickets. Your site talks to https://api.stripe.com to create Stripe Checkout sessions, confirm payments and make refunds. The buyer's name, email, the tickets and their prices are sent to Stripe; card details are entered on Stripe's own page and never touch your site. If you add the optional webhook in your Stripe Dashboard, Stripe also sends payment and refund notices to your site. Stripe terms: https://stripe.com/legal Privacy policy: https://stripe.com/privacy
* **OmnisWP connection service.** Only if you choose "Connect with Stripe" instead of pasting an API key. Stripe's app login needs a secret held by OmnisWP, so https://omniswp.com/wp-json/omnis-connect/v1 is contacted only when an admin presses "Connect with Stripe" (your site first checks the service is available for that mode), and while connected, by a background check every 30 minutes that renews the short-lived access token. When connecting, the admin's browser takes the mode (test or live), a one-time challenge and the address of your site's Payments screen to omniswp.com, and your site then sends the one-time claim code and its matching secret to collect the tokens. When renewing, your site sends the mode and the refresh token. Like any WordPress request, these carry your site's address in the User-Agent. The service never sees payments or buyer details, and keeps nothing after handing the tokens to your site. Terms: https://omniswp.com/terms/ Privacy policy: https://omniswp.com/privacy-policy/

== Third-party libraries ==

* Leaflet 1.9.4, BSD 2-Clause licence, https://github.com/Leaflet/Leaflet (bundled in assets/vendor/leaflet, minified build from the official npm package)
* Leaflet.markercluster 1.5.3, MIT licence, https://github.com/Leaflet/Leaflet.markercluster (bundled in assets/vendor/leaflet-markercluster)

== Changelog ==

= 0.5.1 =
* Fix: With Rank Math or Yoast SEO active, dated, paged and filtered calendar pages stay noindex and each date of a repeating event keeps its own canonical link. Those plugins print their own robots and canonical tags, which had replaced Eventward's.

= 0.5.0 =
Review release ahead of the WordPress.org submission.

* Fix: Paid checkout offers card payments (including Apple Pay and Google Pay) only, and a payment that arrives after a booking lapsed is confirmed if seats are still free or refunded automatically, with the buyer and admin told. A buyer can no longer be charged without getting tickets.
* Fix: Orders are only expired when Stripe says the checkout expired, never because Stripe was briefly unreachable.
* Fix: Prices such as "1,000" are no longer read as 1 or turned into a free ticket: a price that cannot be read clearly is not sold and the editor says why. Three-decimal currencies (KWD, BHD, JOD, OMR, TND) are charged correctly.
* Fix: Moving an event's date or time moves its bookings with it. Tickets left on a date that was removed are flagged on the Attendees screen.
* Fix: Refunds made in the Stripe Dashboard are matched correctly, including several partial refunds.
* Fix: Test-mode bookings no longer count against live capacity.
* Fix: Password-protected events no longer show their content, online link or booking form anywhere (lists, feeds, Google data, REST API) until the password is entered.
* Fix: Shortcodes only show published events.
* Fix: Changing the site timezone rebuilds event dates; long repeating series with an end date or count keep extending; the iCal feed no longer stops at 2000 dates.
* Fix: Several accessibility, contrast and translation improvements in the calendar, booking form, editor and admin screens.
* Change: The Payments screen no longer contacts omniswp.com when it loads; the connection service is only contacted when you press "Connect with Stripe".
* Change: Visitors see a general message when payment is unavailable; the Stripe detail is shown to admins on the Payments screen.

= 0.4.4 =
* Fix: When a buyer cancels on Stripe's payment page, the Stripe checkout is closed too, so a copy left open in another tab cannot take payment for seats that were released.

= 0.4.3 =
* Change: Test-mode bookings are clearly labelled "Test payment, no money taken" on the confirmation.

= 0.4.2 =
* New: Optional Stripe webhook you add by hand in your Stripe Dashboard (Events, Payments). Payments, expired checkouts and refunds made in Stripe then show up instantly instead of within 10 minutes. Every request is checked against the endpoint's signing secret.
* Fix: A booking confirmed at the same moment by the return page and the background check can no longer send two confirmation emails.

= 0.4.1 =
* Fix: The booking button now uses the theme's primary colour instead of blending into the background.
* Change: Paid tickets show as not on sale online until Stripe is connected, instead of showing a form that cannot take payment.
* Change: Events with a single ticket type start the quantity at one.

= 0.4.0 =
* New: Tickets and RSVP. Add ticket types to any event (free ones are an RSVP), with capacity per date, a booking form on the event page, and confirmation emails with ticket codes.
* New: Paid tickets through Stripe Checkout with your own Stripe account, in test and live mode. Connect in one click through the Eventward Stripe app, or paste a restricted API key. No fee from Eventward.
* New: Attendees screen with filters, check-in, CSV export, order details, refunds and resending confirmations.
* New: Seats are held for 30 minutes while a buyer pays, then released if they do not finish. Refunds made in the Stripe Dashboard cancel the tickets here.
* New: Personal data export and erasure for bookings (Tools, Export or Erase Personal Data).
* New: [eventward_tickets] shortcode for page builder templates.
* Change: Google event data uses real ticket prices and shows sold-out dates as sold out.

= 0.3.3 =
* Fix: A calendar with navigation turned off (an upcoming-events widget) no longer changes when another calendar on the same page is navigated.
* Fix: A calendar placed on a static front page kept showing after you moved between months or views. Before, the front page switched to the blog listing.
* Change: Dated and filtered calendar addresses are marked noindex on every page that shows a calendar, not only on the events page.

= 0.3.2 =
* Fix: The calendar's view switcher wraps instead of running off the edge in narrow columns and on phones.

= 0.3.1 =
* Fix: Map tiles no longer show "Access blocked" on hosts that send a strict Referrer-Policy header (common on CloudPanel and with security plugins).

= 0.3.0 =
* New: Week, photo and map views, and a setting to choose which views visitors can switch between.
* New: Search and filters (keyword, category, venue, organizer) above the calendar, applied in place.
* New: OpenStreetMap maps with clustered pins on the map view, venue pages and event pages. No API key needed.
* New: Venue addresses are looked up automatically on save, with a "Find on map" button in the venue editor. Addresses with floors or units ("Level 2/182 Vivian St") are cleaned up first, and coordinates you type yourself are never overwritten.
* New: Shortcodes for page builders: [eventward], [eventward_event_details], [eventward_field] and [eventward_map], plus [tribe_events] compatibility.
* New: Each event keeps its next date in the _eventward_next field, so builder query loops can sort and filter upcoming events.
* New: Setting to stop event details being added automatically when a builder template places them.

= 0.2.0 =
* New: Events Calendar block with month, list and day views, in-place navigation and a mobile agenda layout.
* New: Event Details block with date, venue, organizers, cost, map link, add-to-calendar menu and other dates of repeating events.
* New: Templates for block themes (calendar, single event, event category) and support for classic themes.
* New: Each date of a repeating event has its own address, e.g. /event/quiz-night/2026-10-13/.
* New: schema.org Event data for Google, one entry per date.
* New: iCal downloads and subscription feeds (/events/ical/), with correct timezones.
* New: Venue and organizer pages list their upcoming events.
* New: Settings for the default calendar view, events per page and currency code.
* Change: Addresses match The Events Calendar, including /events/month/, /events/list/, /events/today/ and ?ical=1.

= 0.1.0 =
* New: Events, venues, organizers and event categories.
* New: Recurring events with skipped and extra dates, previewed live in the editor.
* New: Per-event timezones, all-day events, event status and online or hybrid attendance.
* New: Duplicate an event from the Events list.
* New: Settings for addresses, how far ahead to plan recurring events, and prices.
