
---
title: "Sometimes It’s Faster to Build the Damn Thing"
id: "527"
type: "post"
slug: "building-a-lightweight-wordpress-event-calendar"
published_at: "2026-03-26T18:40:00+00:00"
modified_at: "2026-10-21T18:46:27+00:00"
url: "https://compiledrogue.com/articles/building-a-lightweight-wordpress-event-calendar/"
markdown_url: "https://compiledrogue.com/articles/building-a-lightweight-wordpress-event-calendar.md"
excerpt: "A client needed a simple way to browse upcoming events in WordPress. After hours of evaluating oversized calendar plugins, I built a lightweight date filter that worked with the existing event archive."
taxonomy_category:
  - "Selected Work"
taxonomy_post_tag:
  - "Custom Development"
  - "Event Calendars"
  - "JavaScript"
  - "Plugin Evaluation"
  - "WordPress"
---

March 26, 2026Selected Work

## Sometimes It’s Faster to Build the Damn Thing

# A WordPress event calendar, a few hours of plugin research, and the value of solving exactly the problem in front of you.

I spent a few hours trying not to build this.

[Laura Alzubi](https://www.linkedin.com/in/lauraalzubi/)
 at [Scrub Studio Soaps](https://scrubstudiosoaps.com/)
 had what sounded like a small request: add a calendar to the sidebar of the events page so customers could browse upcoming dates.

Not a booking engine. Not ticket sales. Not a recurring-event management platform. Just a month-at-a-glance calendar that lets someone click a date and see the events happening that day.

It seemed straightforward. Which, in WordPress, is sometimes a warning sign.

## The request was smaller than the available solutions

The site already had an events archive. Each event needed its own content, imagery, and details, presented as a proper card in the listing. The calendar wasn’t supposed to replace that content. It was supposed to help people navigate it.

My first instinct was Google Calendar. But that would have introduced a second place to manage events, and the presentation wasn’t right for the job. I’ve seen what happens when you try to squeeze meaningful content into tiny calendar cells. It rarely ends well.

Then I looked at the built-in WordPress calendar widget. At a glance, it seems close: a grid of dates, with days containing content highlighted. But the WordPress widget is built around **date archives**, not filtering an existing set of event cards. Clicking a date takes you somewhere else. The interaction model was wrong.

So I did the reasonable thing: I started looking for a plugin.

## A few hours of installing, testing, and removing

The plugin ecosystem has no shortage of event calendars. That wasn’t the problem.

Most of what I found was designed for a much larger scope: bookings, ticketing, recurring schedules, separate event-management interfaces, dashboards, and a long list of settings for scenarios this client didn’t have.

And the admin experience? A steady parade of upsells, banners, nags, and upgrade prompts. Blech.

The closest fit was [Pie Calendar](https://piecalendar.com/)
. It supported custom post types and offered filtering functionality, so it was much closer to the interaction we needed. But it still introduced more machinery than the request justified.

This is a recurring problem with general-purpose software. To serve as many use cases as possible, a tool accumulates features and abstractions. That’s useful when you actually need those features. When you don’t, you’re left working around the tool rather than solving the original problem.

Eventually, it became obvious that I was spending more time trying to avoid writing code than the code itself was likely to take.

So I stopped looking and built the damn thing.

## What I actually built

The implementation is intentionally small. It has three responsibilities:

1. **Use the existing event content.** Events remain normal WordPress content, with an event date and all the imagery and details the archive already displays.
2. **Show a small calendar.** Only dates that actually have events are interactive.
3. **Filter the existing listing.** Clicking a date shows matching event cards; clicking it again clears the filter.

That’s it. The calendar doesn’t need to own the events, build a separate listing, or introduce another content-management interface.

## The useful part is the boundary

The JavaScript reads dates from event cards already rendered on the page. Each card exposes its event date through a `data-event-date` attribute, using a stable `YYYYMMDD` key.

From there, the component builds a map of days that have events:

mini-calendar-filter.js — event dates

```
function buildActiveDateMap() {
  const map = {};

  document.querySelectorAll('.event-listing .entry-event').forEach(el => {
    const ymd = el.getAttribute('data-event-date');
    if (!ymd) return;

    map[ymd] = (map[ymd] || 0) + 1;
  });

  return map;
}
```

The calendar uses that map to decide which days are interactive. Days without events are just date labels; days with events are buttons. Selecting an active day passes the same date key to a callback that filters the cards.

mini-calendar-filter.js — filter wiring

```
function applyEventFilter(ymdOrNull) {
  document.querySelectorAll('.event-listing .entry-event').forEach(el => {
    const match = !ymdOrNull || el.getAttribute('data-event-date') === ymdOrNull;
    el.style.display = match ? '' : 'none';
  });
}

const cal = new MiniCalendar('#mini-cal', {
  weekStartsOn: 1,
  getActiveMap: buildActiveDateMap,
  onDateClick: applyEventFilter
});
```

There’s a little more to the calendar component itself—month navigation, date-grid rendering, and selected-day state—but the architectural idea is contained in those two snippets.

The full [MiniCal JavaScript gist](https://gist.github.com/hypergeneric/612cd87e5bf2f730b627a4680a76916c)
 is public if you want to see how the pieces fit together.

**Note**This is a filter for events **already rendered on the page**, not a universal events engine. If the requirements later involve server-side pagination, event retrieval across an entire database, complex recurring schedules, or booking workflows, the architecture would need to grow. Those weren’t the requirements here.

That limitation isn’t something to apologize for. It’s the point of keeping the implementation proportional to the problem.

## The result

The original event cards remain the presentation layer, with their imagery and details intact. The calendar gives visitors a quick overview of the month and a direct way to narrow the listing to the date they care about.

Laura later commented on the original LinkedIn post that the calendar made the events easier to navigate and gave customers the zoomed-out monthly view she was looking for. That’s a better measure of success than how many settings the solution has.

You can [see the events page at Scrub Studio Soaps](https://scrubstudiosoaps.com/events/)
 and [read the implementation gist](https://gist.github.com/hypergeneric/612cd87e5bf2f730b627a4680a76916c)
.

## The lesson isn’t that plugins are bad

I use plugins all the time. A good plugin can save enormous amounts of work, especially when the feature involves real complexity: payments, bookings, permissions, recurrence rules, integrations, or ongoing maintenance across a wide range of edge cases.

But a plugin isn’t automatically the simpler solution just because someone else wrote it.

There is a cost to learning its configuration, fitting it around your existing content model, dealing with its markup, accommodating its assumptions, and keeping it maintained. Sometimes that cost is entirely justified. Sometimes it’s larger than the feature you were trying to add.

For this project, the useful abstraction wasn’t **an event-management system**. It was **a date filter on an existing event archive**.

That’s a much smaller thing to build, test, and understand.

And after spending a few hours trying not to write it, it turned out to be the right thing to build.
