Events Plugin 📆

(Angus McLeod) #125

Did you upgrade to the latest version of the plugin? That url generated by the google calendar button looks like the old version.

(Chris Beach) #126

Thanks @Angus, all fixed. Really appreciate your continued support of these plugins.

(tran) #127

thx!!!@angus The update problem .Everything’s OK now!!!

(Andreas Dorfer) #128

That is great! Thanks a lot!

(Chris Beach) #129

Another minor bug (sorry @Angus).

The multi-day event (shown in pink below) should end in October, but this isn’t the case in the Calendar view:

The event: Horniman Exhibition: Colour: The Rainbow Revealed - Events - SE23 Forum | Forest Hill & Honor Oak

(Angus McLeod) #130

Thanks, multi-month events will work properly now.

Example: The 262 day challenge - Events - Angus' Sandbox
Calendar: Events - Angus' Sandbox

(tran) #131

Hi,I met a problem.I don’t want all the users’ topics to be created in the category on a calendar, and I just want to know each user’s agenda. I just has an idea: when the category slug is personal, calendar and agenda are not displayed in the category. For it’s personnal, it’s just showed in the personal page. You have your own agenda but everyone can read it。

This is just my imagination

(Angus McLeod) #132

While that’s an interesting idea, it’s a little bit outside the scope of this plugin at the moment. One thing I don’t want to do is build something that overlaps with the functionality of existing calendars.

Could you explain more about why you want calendars for individual people in Discourse itself, as opposed to just using Google Calendar or a similar personal calendar product for this?

(Tobias Eigen) #133

Maybe you could simply extend the events plugin so it can also work with personal messages - so discourse groups can have calendars and users can set up events with one or more other users. This could be pretty amazing for organizing AMAs (we’re doing an AMA next week - let’s brainstorm some seed questions here on xyz date), PM conversations (let’s meet here in this message tomorrow at 5 to talk over xyz), webinars or other community-level events without turning to google calendar and outlook, and all the hilarity and confusion that still results from doing that with people you don’t schedule meetings with on a regular basis.

But bike shedding, scope creep and all that. This is what you get for creating a nifty plugin.

(Tom Newsom) #134

:Clasped-hands: Pretty please! Feed delay is of no concern for my use, but this feature is the last thing I’m waiting for before installing…

(Angus McLeod) #135

I’ve added full ical feed support (site and category calendars) and upgraded the rss support to include categories.

There’s now a ‘Subscribe’ button on the right above site and category calendars. Clicking this presents the iCal and RSS feed urls for this calendar localised to whatever timezone you’re currently in.


Example urls:


  • ical: webcal://
  • rss:


  • ical: webcal://
  • rss:

These urls can be used in any Calendar or RSS client, e.g. Google Calendar.



Must say I love how this is evolving into such a great plugin @angus Thank you!

I cannot wait to get our forum upgraded from stable in order to take advantage of all the new features and calendar you have added recently!

(Chris Beach) #137

Hi @Angus,

I’ve recently started seeing internal server errors across my forum which caused the following pages to return errors to all users:

  • /unread
  • /new
  • /topics/private-messages/[username]

I disabled the plugin and all is well.

The stacktrace is below.

In case it’s relevant, I had just deleted a long-term member of the forum (on their request) - so possibly some data gremlins?

/var/www/discourse/plugins/discourse-events/plugin.rb:294:in `block in event_ics'
/var/www/discourse/plugins/discourse-events/plugin.rb:293:in `each'
/var/www/discourse/plugins/discourse-events/plugin.rb:293:in `event_ics'
/var/www/discourse/plugins/discourse-events/plugin.rb:255:in `calendar_ics'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:422:in `block in inverted_lambda'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:177:in `block (2 levels) in halting_and_conditional'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:177:in `each'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:177:in `all?'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:177:in `block in halting_and_conditional'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:507:in `block in invoke_before'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:507:in `each'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:507:in `invoke_before'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:130:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/abstract_controller/callbacks.rb:19:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_controller/metal/rescue.rb:20:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/notifications.rb:166:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/notifications.rb:166:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_controller/metal/params_wrapper.rb:252:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/railties/controller_runtime.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/abstract_controller/base.rb:124:in `process'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionview-5.1.4/lib/action_view/rendering.rb:30:in `process'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-mini-profiler-0.10.7/lib/mini_profiler/profiling_methods.rb:76:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_controller/metal.rb:189:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_controller/metal.rb:253:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/routing/route_set.rb:31:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/journey/router.rb:50:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/journey/router.rb:33:in `each'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/journey/router.rb:33:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/routing/route_set.rb:834:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-protection-2.0.0/lib/rack/protection/frame_options.rb:31:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/conditional_get.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:149:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/cookies.rb:613:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:97:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/callbacks.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/logster-1.2.9/lib/logster/middleware/reporter.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:36:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:26:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:16:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:29:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/request_id.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/executor.rb:12:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-mini-profiler-0.10.7/lib/mini_profiler/profiler.rb:171:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/message_bus-2.1.2/lib/message_bus/rack/middleware.rb:63:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:166:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/engine.rb:522:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/railtie.rb:185:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/railtie.rb:185:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:606:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:701:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:142:in `start'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.4.0/bin/unicorn:126:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.4.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.4.0/bin/unicorn:23:in `<main>'

(Tobias Eigen) #138

Nice work. With the ical feed support, looks like you’ve addressed just about every single one of my suggestions above. Wow! :rocket: Thank you!

This one you did not do, but perhaps intentionally/not worth the effort.

Also, I have yet to install it on my instance so can’t tell if this has been done. I know you allow events across categories, but I don’t know about limiting the ability to add event dates to staff or by trust level.

I thought I had asked somewhere about a calendar nav and don’t recall you responding. Something along the lines of TODAY PREVIOUS MONTH NEXT MONTH - like the screenshot below from google calendar. It’s easy to get lost in a calendar and such links can be a big help to orient oneself.


And finally, I think I might have noticed a minor bug. When you select “x more” it opens up a lovely full view for the day. Select on “x more” on another day and it stays open. Close one of them and it closes all of them. Seems to me that when you select “x more” on another day the previously opened day should close.

** edit ** also just noticed that the SUBSCRIBE button doesn’t work until you log in. Is that intentional or a bug? On that note, it occurs to me that subscribing to private categories will probably not work, right? The URL would have to include some sort of API key.

(Angus McLeod) #139

Thanks for the report. Should work regardless of any data irregularities now.

@tobiaseigen Thanks for the feedback.

Yeah this one is TBD as I think it’s a relatively marginal use case.

This is not literally possible yet (you could achieve a version of this through category-level permissions), but the more I think about it, the more I like it. I’ll take a crack at it soon.

Yes, this has been on my mind. Will add this too.

Yup that’s a bug, will fix.

Yes, that was intentional. I think it’s not necessary now however. I’ll remove the check for a current user.

Yup, that’s right. It’s not currently possible to subscribe to calendars in categories with restricted ‘see’ permissions.

(Chris Beach) #140

Thanks for the fix @angus. I’ve scheduled it to upgrade at a quiet time overnight.

(tran) #141

THX for replying.

Individual people‘s calendar makes the list of a specific category clear at a glance.I want to know clearly that everyone continues to update or punch in this category.The specific category is based on a wide range of community purposes.For it is different from other categories, and its content is even one of the highlights of your discourse.

Embedding Google Calendar in discourse, As far as I know,to allow all visitors to see your calendar, you have to make the calendar’s access authority public.That means all your private agendas will be exposed.That’s terrible.

(Tobias Eigen) #142

Good stuff all around.

Makes sense. So maybe remove/suppress the subscribe button from private categories?

(Angus McLeod) #143

This has been added:


This restriction has been added to the guardian and, if used, will apply regardless of how the event is created (e.g. via client or api)

Full nav has been added and subscribe button visibility has been fixed. The subscribe button will appear for guests, but won’t appear in categories with restricted view permissions.

The year selector contains the current, previous and next years.

This has been fixed:

(Chris Beach) #144

That has successfully fixed the problem I was seeing. Thanks for the speedy turnaround @angus