Project

General

Profile

Bug #4080

Events Calendar: Allow sites to embed calendars from groups (perhaps via BP group blog)

Added by Matt Gold over 4 years ago. Updated over 3 years ago.

Status:
Resolved
Priority name:
Normal
Assignee:
Category name:
Events
Target version:
Start date:
2015-05-23
Due date:
% Done:

0%

Estimated time:

Description

Following up from our last Subcommittee meeting in Spring 2015 is this suggestion from Luke:

Allow sites to embed calendars from groups (perhaps via BP group blog)


Related issues

Related to CUNY Academic Commons - Feature #4908: Create shortcode for embedding group calendarsResolved2015-11-16

History

#1 Updated by Boone Gorges about 4 years ago

  • Assignee changed from Boone Gorges to Raymond Hoh
  • Target version set to 1.9

Lotsa questions about UX and options here. What does the workflow look like? It's especially complex if we don't limit to groupblog connections.

My initial suggestion is to have a Group Events widget. The widget controls would allow a site user to select one of his groups, and the widget would display the next five (or whatever) events from the group, as a list. If the site is associated with a group via groupblog, the associated group would be the default value for the widget.

Technical note: The ability to have a calendar on subsites will require that EO and BPEO are network-activated. This is potentially problematic in the case of EO, since activating EO automatically adds a bunch of UI to the Dashboard. Quick, dumb idea: if

! is_plugin_active( 'event-organiser' ) include '/path/to/event-organiser-bootstrap';
, though that might have to be a custom bootstrap that tells EO to point to the root blog's tables. When EO is in active use on the current site, we'll have to swap out table references on the fly. It's going to be pretty complicated.

Ray, do you have thoughts about this?

#2 Updated by Raymond Hoh about 4 years ago

I'm thinking of something more like an embeddable widget.

Group users will be able to see some form of wizard that will generate some IFRAME html code that they can embed on external sites. Or maybe this is just a shortcode that they can embed within Commons sites?

This way, we bypass having to network activate EO / BPEO.

#3 Updated by Boone Gorges about 4 years ago

Yeah, an iframe is maybe a better idea, though it'll mean we have to write our own plugin to handle it. (We would've had to write our own plugin anyway :) ) We could still potentially frame this as a regular WP widget, but the markup it created would be an iframe.

Adding Samantha as a watcher. Sam, do you have any thoughts about how this might best work, from a user's point of view?

#4 Updated by Samantha Raddatz about 4 years ago

I got the sense from Luke that he was interested in having a full 'events' page on a group site that mirrors the group's Commons events calendar, which I think would be the case where the iframe would come into play. I can also imagine a lot of use of a widget that displays 5 upcoming events and appears on all pages of a site. I take it that we need to pick one or the other, at least for a first implementation?

Am I correct that the two options we're discussing are:
  1. a widget that's an option in the widgets area of WP. It displays the next 5 events from that group's Commons calendar.
  2. a code that you find on your Commons group event's calendar page that can be copied and pasted into any external webpage to embed the full calendar (rather than a list)?

#5 Updated by Boone Gorges about 4 years ago

I don't think it's either-or. Once we've built the basic functionality - say, the ability to embed specific calendar content using an iframe - it's trivial to implement it a widget, as a shortcode, or both. My only concern was going whole-hog in terms of interface on the first version: IMO, shortcodes, while flexible, are not very user-friendly, so I was somewhat wary of making them the first user-facing version of this feature. If we're going to launch with shortcodes, I think it's probably wise to do it alongside, rather than instead of, the widget.

#6 Updated by Matt Gold about 4 years ago

Agreed, Boone. I do think that both a whole-page view (in iframe) and sidebar widget would be useful

#7 Updated by Boone Gorges about 4 years ago

Yes, I agree that everything would be useful (all the features!!) but we should think about the user experience of the feature when initially released. I just don't want it to be too complicated. Happy to go forward with whatever the team thinks is best.

#8 Updated by Samantha Raddatz about 4 years ago

I agree that the widget is probably the way to start on this one. My only concern is how we surface that it's available to the groups; is there a way to make it obvious on the event calendar that it can be added to their blog? Or do they have to know to search for it in the WordPress Plugins?

As far as layout for the widget, I think list-style with the following information would be useful:

Event title (link to full event info if it's a public group?)
Date/time
Location

The list section of this site's sidebar is a good example of what I mean: http://posmanbooks.com/events/

#9 Updated by Boone Gorges about 4 years ago

My only concern is how we surface that it's available to the groups; is there a way to make it obvious on the event calendar that it can be added to their blog? Or do they have to know to search for it in the WordPress Plugins?

I don't think we'll require a plugin to be activated. We'll just make the widget available on every site (maybe through an mu-plugin - we already do this for one or two widgets, I think). Site admins would need to know to go to Appearance > Widgets to add it (as they'd need to know for any widget); I figure we can let them know about the new feature through the Codex and other documentation.

#10 Updated by Matt Gold almost 4 years ago

Hi All,

I'm writing to introduce Hannah Aizenman, who is a new GC Digital Fellow from our Computer Science program. Hannah is interested in this issue and is willing to pitch in on it. Has there been any movement on this since the last update? Is there any way that Hannah can help? She has been added as a watcher here.

#11 Updated by Boone Gorges almost 4 years ago

Hi Hannah - welcome to Redmine and to CAC!

I think Ray is going to handle the initial implementation - it'll involve building a custom router and display interface for EO, which can be invoked via iframe, plus the network-activated widget plugin that will generate the iframe markup.

Hannah, we'd be happy to have some help, but I want the help to match your skill level and interests. Are you interested in working on a few wireframes for us? For instance, you could mock up how you think the widget output might structured; or how you think the widget control (in the Dashboard > Appearance > Widgets panel) should look; or what values should be user-configurable (the group, of course, but perhaps also the number of items to show?). It'd likely make Ray's job more straightforward if we had this kind of starting place. Or, if you're interested in helping out with some more technical tasks, let me know about that and I'll see how I can guide you.

#12 Updated by Hannah Aizenman almost 4 years ago

Hi, sorry I missed the email about the update

For instance, you could mock up how you think the widget output might structured; or how you think the widget control (in the Dashboard > Appearance > Widgets panel) should look; or what values should be user-configurable (the group, of course, but perhaps also the number of items to show?).

I think I'd want to meet with Raymond to clarify what you'd want that differ from the typical calendar interface.

Or, if you're interested in helping out with some more technical tasks, let me know about that and I'll see how I can guide you.

Hmm, my skill set definitely lends itself more to backend stuff than UX. I've done wireframes a handful of times, but it's not my strong suite.

#13 Updated by Raymond Hoh almost 4 years ago

Thanks Hannah for wanting to get involved.

I can handle getting the calendar displayed without the header and footer (eg. example.com/groups/GROUP/events/?embed=true ~ example.com/groups/GROUP/events/upcoming/?embed=true ) and then, perhaps, you can tackle writing the actual widget code with the iframe output?

If that sounds okay, I can walk you through some tips when you're writing the widget code.


Update: I've written the code to remove the header and footer for group event calendars. For those with access to CDEV, this is now available for testing there.

Use the following URLs to see it in action:
- cdev.gc.cuny.edu/groups/GROUP/events/?embed=true
- cdev.gc.cuny.edu/groups/GROUP/events/upcoming/?embed=true

What's left is the widget plugin. Let me know if you are interested in taking this on, Hannah.

#14 Updated by Hannah Aizenman almost 4 years ago

What's left is the widget plugin. Let me know if you are interested in taking this on, Hannah.

Sorry it took so long to get back to you, but yeah still interested in taking this on. Can you point me towards any documentation for/examples of doing this sorta thing?

#15 Updated by Raymond Hoh almost 4 years ago

Sorry it took so long to get back to you, but yeah still interested in taking this on. Can you point me towards any documentation for/examples of doing this sorta thing?

Cool, glad to have you onboard, Hannah!

I've written a guide below on how to get set up with WordPress and how to go about writing the widget plugin.

Let me know if you encounter any issues if a certain section isn't clear!


(1) Set up

WordPress: Event Organiser: BP Event Organiser: BuddyPress:
  • Install BuddyPress - https://wordpress.org/plugins/buddypress/
  • Activate BuddyPress from the Network Admin dashboard - https://codex.wordpress.org/Network_Admin_Plugins_Screen
  • Activate the Groups component from the Network Admin dashboard (Network Admin > Settings > BuddyPress)
  • Create a group (Network Admin > Groups and click on the "Add New" button or via example.com/groups/create/)
  • Once you've created your group, navigate to the group on the frontend (example.com/groups/ and click on the group you just created).
  • There should be an "Events" tab in the group. Click on it. You should now see an empty event calendar.
  • You should see a "New Event" button. Click on it and create an event.

You are set up! Now we will start writing the plugin.


(2) Writing the plugin

Since we will be bundling the widget plugin with BP Event Organiser, let's start by creating a blank file in /wp-content/plugins/bp-event-organiser/bp-event-organiser-embed-widget.php.

Open the file in your preferred editor. Now we'll start writing the plugin. A plugin starts with a file header. Copy the header contents from the link below and modify it to suit our needs :
https://developer.wordpress.org/plugins/the-basics/header-requirements/

Since we will be writing a widget plugin, let's take a look at the Widgets API codex article:
https://codex.wordpress.org/Widgets_API

I'll also outline an example of the "Pages" widget that comes bundled with WordPress. Let's see how that works.

Navigate to the WP admin dashboard and navigate to "Appearance > Widgets". Next, find the "Pages" widget and drag it to the sidebar. The contents of the widget should now expand. Fill in the "Title" field and save. Now navigate to the frontend of the site to see the widget in action in the sidebar. That's basically what we are going to accomplish, but with our group event calendar being embedded.

Now, let's see how that "Pages" widget is written:
https://core.trac.wordpress.org/browser/tags/4.3.1/src/wp-includes/default-widgets.php#L9

You can copy that class over to our file and change the WP_Widget_Pages reference to something like BPEO_Group_Widget. Then we'll modify the class methods to suit our needs.

Here's a brief summary of the class methods:

  • __construct(): is used to set up the admin widget title and the description for the most part
  • widget(): used to display the contents of the widget on the frontend
  • update(): used to update the admin widget form for saving
  • form(): displays the form that we saw under "Appearance > Widgets"
For the form() method, this is what we want to accomplish:
  • Show a "Title" field so a user can customize the title of the widget
  • Show a "Select a group to embed events for" field, which will display a <select> list of the logged-in user's BuddyPress groups.

Something like:

<select name="<?php echo esc_attr( $this->get_field_name( 'group_id' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'group_id' ) ); ?>">
<option value="NUMERIC_ID_OF_GROUP">GROUP NAME</option>
</select>

The groups_get_groups() function will be handy here:
https://buddypress.trac.wordpress.org/browser/tags/2.3.4/src/bp-groups/bp-groups-functions.php#L670

Make sure to pass the user ID of the logged-in user with get_current_user_id().

  • Add a radio option to select whether the user wants to embed a calendar or list of upcoming events for that group.
  • Add input field options for "Width" and "Height" to control those options for the IFRAME

For the update() method, we want to make sure our fields are saved, so make sure the form names from the form() method are mirrored here.

For the display() method, this is what we want to accomplish:
  • Output the "title" from the form
  • Embed the group's event calendar using an IFRAME.

For the IFRAME link, we want something that resembles this:

  • example.com/groups/GROUP/events/?embedded=true - to embed the event calendar
  • example.com/groups/GROUP/events/upcoming/?embedded=true - to embed upcoming events

To do this, we'll need to fetch the group:

$group = groups_get_group( array(
    'group_id' => GROUP_ID_FROM_FORM,
    'populate_extras' => false, // this is so we do not need to query for other group items
) );

Then, we can grab the group permalink with bp_get_group_permalink():
https://buddypress.trac.wordpress.org/browser/tags/2.3.4/src/bp-groups/bp-groups-template.php#L1040

// for group calendar
$link = bp_get_group_permalink( $group ) . 'events/?embedded=true';

// for upcoming events
$link = bp_get_group_permalink( $group ) . 'events/upcoming/?embedded=true';

(3) Registering the widget

We have now written our widget, but we still need to register it with WordPress.

At the end of the plugin, let's register our widget. To do that, we'll follow the register_foo_widget() example from the codex article:
https://codex.wordpress.org/Widgets_API#Example

We'll need to modify that code example to suit our needs.

First, rename the function so it's more reflective of our widget. Second, change the 'Foo_Widget' call to our widget's class name - 'BPEO_Group_Widget'.

Thirdly, in our widget, since we are using some BuddyPress plugin functions, we must make sure that the BuddyPress plugin is active before calling register_widget(). Otherwise, we will get a PHP fatal error and we do not want that!

A simple way of determining if BuddyPress is active is by doing a function_exists( 'buddypress' ) call:

// Do not proceed if BuddyPress is not available
if ( false === function_exists( 'buddypress' ) ) {
    return;
}

Since our widget also depends on the BP Event Organiser plugin being active on the main (first) site, we should also check to see if BP Event Organiser is activated on that site.

This is how I would go about this:

- Grab the active plugins list from the first site
- Check if the BP Event Organiser plugin is active
- If not, we bail from registering the widget.

To grab the active plugins list from the first site, you can do this:

$active_plugins = get_blog_option( bp_get_root_blog_id(), 'active_plugins' );

This will return an array of relative plugin filepaths for all activated plugins on the main site.

Now, you can use in_array() to search for BP Event Organiser's filepath - bp-event-organiser/bp-event-organiser.php - as the needle.

If our filepath doesn't exist, bail from registering the widget.

And, that should be it! Now, let's test the plugin.


(4) Testing the plugin

Navigate to the secondary site's admin dashboard and go to the "Plugins" page. You should see your plugin. Activate it.

Next, go to "Appearance > Widgets" in the dashboard and find the widget you just created and test it out.

#16 Updated by Matt Gold almost 4 years ago

Wow. Huge thanks for putting so much time and care into this, Ray.

#17 Updated by Raymond Hoh almost 4 years ago

Hi Hannah,

Have you had a chance to work on this? If not, and you do not have time in the upcoming weeks to work on this, don't worry about it as I can take care of this ticket before our next milestone.

#18 Updated by Hannah Aizenman almost 4 years ago

Have you had a chance to work on this?

Hi, so sorry that I totally dropped the ball on this. While I probably have time to work on this in the upcoming weeks, I figure that you can get it finished orders of magnitude more quickly.

#19 Updated by Raymond Hoh almost 4 years ago

Hi, so sorry that I totally dropped the ball on this.

No problem, Hannah. Thanks for getting back to me.


I've coded the group widget plugin. It's available for testing on cdev.

To test:
1. Navigate to one of your sites and enable the BP Event Organiser - Group Widget plugin.
2. Next, go to "Appearance > Widgets" and select the Group Events widget.
3. Configure the widget:

4. Lastly, visit the site to view the widget in action.

Some notes:
- The group events widget only allows events for public groups to be embedded.
- I've named the widget "(BuddyPress) Group Events" because I didn't want to go with something like "(BP Event Organiser) Group Events". Could use some feedback here with the naming. Also let me know if the plugin name should be changed to something that community members will find more recognizable.
- As of right now, the calendar embed type requires a large widget area. The current version of Event Organiser doesn't have great responsive styles. However, the upcoming version of Event Organiser (v3.0) will.
- We could add other widget options for styling purposes down the road, but I've added what I feel are the bare minimum options at the moment. Feel free to chime in with feedback here.

#20 Updated by Boone Gorges almost 4 years ago

Pretty slick, Ray!

I see why you've packaged the groups widget plugin the way that you have for the purposes of bp-event-organizer. But for the purposes of CAC, I think we should just network activate it.

Widget name seems fine to me.

It would be a cool feature (though not critical for now) if, when adding the widget, the bp-groupblog-associated group were the default selection. I assume that a majority of use cases for the widget will involve bp-groupblog.

#21 Updated by Raymond Hoh almost 4 years ago

But for the purposes of CAC, I think we should just network activate it.

For sure!

It would be a cool feature (though not critical for now) if, when adding the widget, the bp-groupblog-associated group were the default selection.

I've updated the group widget so it should select the bp-groupblog-associated group when the group selection is empty.

#22 Updated by Boone Gorges almost 4 years ago

  • Status changed from Assigned to Testing Required
  • Assignee changed from Raymond Hoh to Samantha Raddatz

Whee! Thanks, Ray. Passing this over to Sam to make sure it passes muster.

#23 Updated by Samantha Raddatz almost 4 years ago

This is so great, Ray!

A couple minor settings things:
- When configuring the widget, can it say 'Calendar From Group' rather than just 'Calendar'?
- Can the height field be auto-filled with 300 and then editable rather than blank to start?

I assume the width is managed by the theme... is there any way to give the user control over that as well, or is there a relatively standard width that we can design the calendar view for? The scrolling L/R is a little strange (see attached screenshot from TwentyTwelve theme).

#24 Updated by Raymond Hoh almost 4 years ago

- When configuring the widget, can it say 'Calendar From Group' rather than just 'Calendar'?
- Can the height field be auto-filled with 300 and then editable rather than blank to start?

This is done and is available for testing on cdev.

I assume the width is managed by the theme... is there any way to give the user control over that as well, or is there a relatively standard width that we can design the calendar view for?

As mentioned above, the current styles for the calendar plugin we are using (Event Organiser) are not responsive. However, the upcoming version of Event Organiser will fix this. See:
https://github.com/stephenharris/Event-Organiser/issues/296

Perhaps we might want to hide the "Calendar from group" option until Event Organiser is updated? Or add some type of help text in the widget options? (I did add some tooltip text, but that might not be visible enough.)

#25 Updated by Samantha Raddatz almost 4 years ago

Looks good. Thanks, Ray!

I'd be into hiding 'Calendar from group' until Event Organiser is updated -- it's just a bit too wonky on the front-end for my liking right now. But the list format works great!

#26 Updated by Matt Gold almost 4 years ago

Hi Ray,

Many thanks for your work on this. I have a query that may move things in an additional direction, and I'm not sure whether it is a small or large shift:

My understanding is that the plugin you created will allow sites to include a list of upcoming events in the sidebar. This great and is desired functionality from users.

But is it (or could it) also be possible to embed a group calendar on a blog page? Here's one example -- I would love to embed a group calendar from this group, which collects events from multiple organizations -- http://commons.gc.cuny.edu/groups/gc-events-and-workshops/events/ -- on this particular organizational page -- http://gcdi.commons.gc.cuny.edu/events-landing/

If I should start a new ticket for this, please let me know. Thanks!

#27 Updated by Raymond Hoh almost 4 years ago

But is it (or could it) also be possible to embed a group calendar on a blog page?

Yes, it's possible. I could implement a shortcode if desired.

Something like:
[bpeo-group-events url="http://commons.gc.cuny.edu/groups/gc-events-and-workshops/events/"]

I should note that the approach I'm using only works for public groups, not private or hidden ones.

#28 Updated by Boone Gorges almost 4 years ago

Yeah, I think a shortcode would be great, but let's handle it as a separate ticket. Ideally, the shortcode would be accompanied by a UI button for the Visual editor that would give users a fairly easy way to select the relevant group (as you've got in the widget controls).

#30 Updated by Raymond Hoh almost 4 years ago

I'd be into hiding 'Calendar from group' until Event Organiser is updated -- it's just a bit too wonky on the front-end for my liking right now. But the list format works great!

Done! When we upgrade to Event Organiser 3, the group widget will automatically add the "Calendar from group" option back for selection.

#31 Updated by Raymond Hoh over 3 years ago

  • Status changed from Testing Required to Resolved
  • Assignee changed from Samantha Raddatz to Raymond Hoh

Thanks everyone for your feedback on this ticket.

Marking as resolved for 1.9.

Additional work will continue in #4908 for group calendar embedding.

Also available in: Atom PDF