Event Duplicator: duplicate calendar events/topics into a new time period

:information_source: Summary Lets authorized users duplicate calendar events/topics (created via Discourse Calendar and Events ) into a new time period. Works on a single topic or a whole tagged series (e.g. every topic tagged `grand-prix`), with a review step to edit proposed dates before committing.
:hammer_and_wrench: Repository Link GitHub - louking/discourse-event-duplicator: discourse plugin to duplicate events · GitHub
:open_book: Install Guide How to install plugins in Discourse

Summary

This plugin was built for a running-club community whose calendar is largely the same events happening every year on a shifted date. Recreating each event’s topic by hand every season meant duplicating the [event ...] block, fixing the title, and hunting down which ones were already redone. That was tedious and error-prone. Event Duplicator automates it: pick a source event, or a whole tagged series of them, get a proposed new date, review or edit it, and confirm.

See docs/USAGE.md for a full user-facing walkthrough: who can use it, duplicating a series vs. a single topic, how the review step works.

Features

  • Series duplication: pick a category and one or more tags (e.g. grand-prix, signature-race; matches are OR’d and deduplicated, so a topic with multiple matching tags only shows up once), optionally restricted to a source date range, then review proposed next-occurrence dates before confirming.
  • Single-event duplication: the same review-and-confirm flow for one topic at a time, from that topic’s admin menu (wrench icon).
  • Editable review step: each row shows the original start date next to a proposed new one you can edit (day granularity), plus an editable title. The end date is always derived automatically from the source event’s own duration, so it can’t drift out of sync with an edited start date.
  • Two pluggable date-shift strategies, selectable per run with a configurable default:
    • Same calendar date: shift forward by the configured number of months.
    • Nth weekday of month: preserve e.g. “3rd Saturday of the month” even when the shift lands in a different month.
  • Configurable shift amount: shift forward by any number of months (12, i.e. one year, by default), not just annually. Useful for monthly, quarterly, or other recurring cadences. Overridable per run, with a site-wide default via a new setting (below).
  • “Date TBD” flagging: for events whose real-world date isn’t settled yet, flag a row. A configurable annotation (default (date TBD)) gets appended to both the topic title and the event name.
  • Duplicate tracking: prevents re-duplicating the same event twice (relevant since a topic can carry more than one series tag). Already-duplicated topics are flagged and unselected by default in review, with an explicit re-check-the-box override to force it anyway. Deleting a duplicate topic automatically frees its source up for re-duplication, and undeleting re-locks it.
  • Post-duplication feedback: successfully duplicated rows turn into a link to the new topic right in the review table. Genuine failures are reported per row instead of aborting the whole batch.

Requirements

  • discourse-calendar must be installed and enabled. This plugin duplicates events by going through discourse-calendar’s own [event ...] post markup and DiscoursePostEvent::Event model instead of inventing separate date storage.
  • Tested against Discourse 2026.7.0. Not verified on earlier releases.

Configuration

All settings are under Admin → Settings → Plugins, search for event_duplicator:

Setting Default Description
event_duplicator_enabled off Enables the plugin.
event_duplicator_allowed_groups staff Groups (in addition to normal per-category topic-creation permission) allowed to duplicate events. Note: an empty list means nobody, not everyone. Add the “everyone” group to fully open this up.
event_duplicator_default_date_strategy Same calendar date Default date-shift rule; overridable per run.
event_duplicator_default_shift_months 12 Default shift amount, in months; overridable per run.
event_duplicator_tbd_annotation (date TBD) Text appended to a duplicated topic’s title/event name when flagged TBD in review. Leave blank to disable the annotation feature entirely.

Authorization is an AND of three checks: normal Discourse category permissions, membership in event_duplicator_allowed_groups, and discourse-calendar’s own permission to create [event] posts at all.

Known limitations

  • The review step’s date editing is day-granularity only (no time-of-day editing). That’s a deliberate scope decision: the target use case is recurring race/event dates, not times.

Source / issues

Updated 2026-08-01: v1.1.0 adds configurable month-based shifting, see below

4 Likes

Nice work! And thank you for sharing it with others. It effectively plugs a gap in the calendar-and-events functionality.

I do wonder if it might be better called “Yearly Event Duplicator” instead, as it doesn’t appear designed for monthly duplications.

Would you be open to extending it to cover a monthly use case?

We have a lot of monthly, bi-monthly, and tri-monthly (i.e. quarterly) events, which fall on the Xth Monday (etc.) of the month. They carry a significant amount of documentation / uploads, which makes them inappropriate for the core recurring events mechanism.

At present, this requires quite a bit of manual handling, and errors do get made!!

Due to the more compressed timeframes, to make this work it would probably need some sort of prompt (such as a PM to the Topic owner +/- admins) once the current event is complete (if it is tagged).

1 Like

Maybe. One possibility would be to have the duplicate events view have a “shift (months)” control, the default value of which would be a new setting. Is this about what you’re looking for?

I’ve added add n months shift support · Issue #19 · louking/discourse-event-duplicator · GitHub to track this. I have some other work on my plate, so I’m not sure what the priority will be. On the surface, though, it seems like it’d be a pretty quick mod.

This part I’m less interested in doing, frankly. If the events were in a series (i.e., tagged a certain way) the plugin would have to remember which was the last in the tagged events, notice if a new event was tagged at the end of the series, etc. I expect the needs for this notification would be diverse and I don’t think I could cover all possibilities.

1 Like

Sweet - thank you.

Understandable! It could be quite easily achieved by a simple bookmark anyway now I think a bit more about it.

@nathank Shift (months) shipped in v1.1.0.

The review page now has a Shift (months) field next to the Date rule dropdown. It defaults to 12, same behavior as before, but you can override it per run. There’s also a new event_duplicator_default_shift_months site setting if you want a different site-wide default.

It works with both date rules. A monthly or quarterly series that needs a specific weekday still gets the “same weekday of month” treatment, just at whatever month interval you set instead of a fixed year.

Update to v1.1.0 to get it (rebuild if your app.yml pins a specific tag). Issue #19 has the implementation details if you’re curious.

I think it makes sense to also update the OP. I’ll get to that by tomorrow, probably.