Freeslot Calendar

Description

Freeslot Calendar is a lightweight WordPress plugin that publishes a clean monthly availability view on any page or post. It’s built for freelancers, designers, photographers, consultants, and small studios who want visitors to see at a glance which days are open and which are busy, without exposing a full booking system.

Events live in your WordPress admin like any other content. The public calendar reads from them and paints each day as Free, Partially busy, or Fully busy based on your working hours.

Key features

  • Drop-in shortcode[igcal_availability] renders the calendar anywhere.
  • Bilingual out of the box — Bulgarian and English, per-event title and note translations, automatic locale switching.
  • Working-hours aware — partial vs. full busy status is computed from your actual day, not a guess.
  • Recurring events — daily, weekly, monthly, with an end date.
  • Per-event color, image, and category for richer day-detail cards.
  • Customizable Contact CTA — label, colors, size, and the URL it links to.
  • Customizable header — change the calendar’s title and subtitle per language, or pass a title="..." shortcode attribute.
  • Accessible — full keyboard navigation (arrows, Home/End, PageUp/Down), ARIA roles, screen-reader announcements on month change.
  • Mobile responsive — two-stage breakpoints, dense list view on phones.
  • AJAX month navigation with skeleton loader and cross-fade transitions.
  • Cached — each month grid is cached per language and invalidated automatically when events or settings change.
  • No tracking, no external calls — your data stays on your site.

Shortcode attributes

  • months — number of months to render (default 1).
  • langauto (follow site locale), bg, or en.
  • title — override the header title for this instance.
  • show_legend1 or 0.
  • show_cta — show the bottom Contact CTA bar (1 or 0).

Example:

[igcal_availability lang="en" months="3" show_cta="0"]

Installation

  1. Upload the freeslot-calendar folder to /wp-content/plugins/ (or install via Plugins Add New Upload).
  2. Activate the plugin through the Plugins screen.
  3. Go to Freeslot Calendar Settings to set working hours, language, colors, and the Contact CTA.
  4. Go to Freeslot Calendar Events to add busy events.
  5. Drop [igcal_availability] on any page or post.

FAQ

Does this plugin accept bookings?

No. It’s intentionally read-only — visitors see your availability and contact you through whatever channel you configure (email, form, Calendly link, etc.). This keeps the plugin small, fast, and easy to reason about.

Does it support languages other than Bulgarian and English?

Out of the box the calendar ships with bg_BG and en_US translations. The plugin is fully internationalized (Text Domain: freeslot-calendar), so additional locales can be added via standard .po/.mo files.

Can I have multiple calendars on different pages?

Yes — the shortcode can be placed on any page or post. All instances share the same event pool and settings (there is currently one global calendar, not multiple separately-managed ones).

Does it work with my caching plugin?

Yes. Month grids are cached via WordPress transients with automatic invalidation on event save and settings change. Page-level cache plugins work fine because the AJAX month-nav endpoint is unauthenticated and idempotent.

Will it slow down my site?

Assets (CSS / JS / fonts) only load on pages that actually contain the shortcode. The initial month is server-rendered; subsequent months are fetched via a single small AJAX call.

Is the public calendar keyboard-accessible?

Yes. Tab into the grid, then use arrow keys to move between days, Home/End for first/last day of the visible month, and PageUp/PageDown to jump between months. Today’s cell is marked with aria-current="date" and month changes are announced via an ARIA live region.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Freeslot Calendar” is open source software. The following people have contributed to this plugin.

Contributors

Translate “Freeslot Calendar” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

1.7.19

  • Removed Author URI from the plugin header (the WordPress.org review team requires domain-ownership verification when an Author URI is set, and the simplest path was to drop the line). Author credit “Krasimir Ignatov” is unchanged.

1.7.18

  • Renamed plugin to “Freeslot Calendar” (slug freeslot-calendar) at the request of the WordPress.org review team, who flagged the previous name as too generic. Text domain, language files, and folder name updated to match.

1.7.17

  • Removed Plugin URI from the plugin header — WordPress.org rejects submissions where Plugin URI and Author URI point to the same site. Author URI (https://ignatovdesigns.com/) stays.

1.7.16

  • Renamed the leftover ignatov_calendar_force_assets filter to igcal_force_assets so the hook name matches the plugin’s prefix (caught by Plugin Check after the rename).
  • Updated Contributors: field in readme.txt to krasimirignatov (matches the WordPress.org account that will own the plugin).

1.7.15

  • Fix: post-activation welcome notice now displays in English when the admin locale is English. The main message string was missing from the .po files entirely, and the “Add your first event ” string had an arrow inside the gettext call that didn’t match the .po msgid. Both are now in sync.

1.7.14

  • Added Author URI header so the author name on the Plugins screen links to https://ignatovdesigns.com/.

1.7.13

  • Renamed the plugin to “Freeslot Calendar”; author credit updated to Krasimir Ignatov.

1.7.12

  • Mobile / tablet: added 20px right margin to the Today button so it no longer hugs the right edge of the month-nav pill.

1.7.11

  • Fix: on tablet and phone the Today button is now actually pinned to the right edge of the month-nav. The 1.7.9 rule was being overridden by the base margin-left: 8px rule because of CSS source-order; bumped with !important so the mobile override wins.

1.7.10

  • Day-detail close button: removed the grey hover background — only the icon color darkens on hover now.

1.7.9

  • Empty-state banner icon switched from brand-orange to ink (matches the calendar’s other dark icons). On tablet and phone the month-nav pill (prev / month / next / Today) now stretches to the full calendar width with the Today button pinned to the right edge, so the header and grid line up visually on narrow screens.

1.7.8

  • Cleaned up the surrounding chrome: month nav, empty-state banner, and day-detail panel are now transparent (no cream / peach fill), all using the same grey border. Empty-state banner’s drop-shadow was dropped since a shadow on a transparent element looks odd.

1.7.7

  • Clicking a day now leaves a visible “selected” marker on the grid — a semi-transparent green inset ring — so the visitor can see which day they just opened in the detail panel. Distinct from today’s solid-green ring; works for both grid clicks and list-view row clicks.

1.7.6

  • Calendar grid is now wrapped in a single bordered card with rounded corners and a soft drop-shadow. Day cells sit edge-to-edge inside the card with shared 1px separators (no gaps), the weekday header row sits at the top of the same card with a subtle tinted background. Today’s cell now uses an inset green ring (so it stays inside the shared-edge grid). Status pills use a soft tinted background with matching text color instead of solid white-on-color. Cleaned up legacy !important overrides that were forcing the older sharp-corner / solid-pill look.

1.7.5

  • Apple-style calendar refresh: each day cell is now its own soft card (larger border-radius, resting drop-shadow, wider gap between cells), and the status text (“Свободно” / “Частично заето” / “Напълно заето”) is rendered as a tinted pill instead of plain text. Empty-month banner picks up the same soft shadow. Off-month and empty cells stay flat as before.

1.7.4

  • Calendar header restyled: title and subtitle now both use Roboto; the second word of the default title is no longer italicized or accent-colored. Added Roboto to the bundled Google Fonts request.

1.7.3

  • Converted the remaining meta_query / meta_key phpcs:ignore markers into proper phpcs:disable / phpcs:enable blocks so Plugin Check fully recognizes them as intentional. Runtime behavior unchanged.

1.7.2

  • Second Plugin Check compliance pass: normalized all ABSPATH guards to the PCP-recognized form (no leading backslash), switched calendar arithmetic from date() to gmdate() (timezone-safe), set an explicit IGCAL_VERSION on Google Fonts enqueues (PCP rejected false), added translators: comment for the slot-length string, escaped the language-radio flag emoji, marked the pre-rendered month-grid / month-list HTML echoes as intentional (built upstream by escaping templates), switched image_id sanitization to absint( wp_unslash() ), dropped deprecated suppress_filters from the uninstall query.
  • Bumped “Tested up to” to WordPress 6.9.

1.7.1

  • Plugin Check compliance pass: explicit input sanitization on all $_POST reads, justified phpcs:ignore markers for legitimate direct DB / meta_query / read-only $_GET patterns, explicit false version on external Google Fonts enqueues.
  • Removed deprecated load_plugin_textdomain() call — WordPress 4.6+ auto-loads translations from the plugin’s /languages/ folder.
  • Trimmed plugin short description to fit WordPress.org’s 150-character limit.

1.7.0

  • Renamed all internal prefixes from 2-letter ic_ / IC_ to 5-letter igcal_ / IGCAL_ for WordPress.org compliance (uniqueness rule).
  • Renamed shortcode from [availability_calendar] to [igcal_availability].
  • Accessibility: added aria-current="date" on today, aria-live="polite" on the month label and empty-state banner, role="region" with label on the calendar root, and full keyboard navigation inside the grid (arrows, Home, End, PageUp, PageDown).

1.6.3

  • Added Settings fields to customize the calendar’s header title and subtitle per language (BG / EN). Empty falls back to the translated default; the shortcode title attribute still takes priority.
  • Removed leftover theme attribute card from the Shortcode reference section.

1.6.2

  • Fixed: a few admin-side strings (Publication section, status labels) were not translating to English.
  • Tightened spacing in the month navigation header (chevron / Today button gap).

1.6.0

  • Added per-event Contact CTA customization: label per locale, background and text colors, size variants (small / medium / large). Uses CSS custom properties so customizations always win over theme overrides.

1.5.0

  • Added event thumbnails / images, category tags, improved typography hierarchy in day-detail cards.

1.4.0

  • Mobile responsiveness pass: two-stage breakpoints (720 px tablet, 480 px phone), compact list view on phones.

1.0.0

  • Initial release.