From fe9219eaaf07f94f82c3e12d33618b933b36b705 Mon Sep 17 00:00:00 2001 From: Ian Dunn Date: Mon, 20 Nov 2023 13:57:37 -0800 Subject: [PATCH] Map: Merge event filters into main block In hindsight, it's much simpler to have this as part of the main block rather than having a second. This fixes a rendering bug that is caused by wrapping the main block, and prevents having to build support for block styles into the wrapper block. --- .../blocks/google-map-event-filters/README.md | 42 ------------ .../google-map-event-filters/src/block.json | 32 ---------- .../google-map-event-filters/src/index.js | 26 -------- mu-plugins/blocks/google-map/README.md | 64 +++++++++++++++++-- .../inc/event-filters.php} | 55 +++------------- mu-plugins/blocks/google-map/index.php | 12 ++++ mu-plugins/blocks/google-map/src/block.json | 12 ++++ mu-plugins/loader.php | 1 - 8 files changed, 91 insertions(+), 153 deletions(-) delete mode 100644 mu-plugins/blocks/google-map-event-filters/README.md delete mode 100644 mu-plugins/blocks/google-map-event-filters/src/block.json delete mode 100644 mu-plugins/blocks/google-map-event-filters/src/index.js rename mu-plugins/blocks/{google-map-event-filters/google-map-event-filters.php => google-map/inc/event-filters.php} (80%) diff --git a/mu-plugins/blocks/google-map-event-filters/README.md b/mu-plugins/blocks/google-map-event-filters/README.md deleted file mode 100644 index 3e16de5d8..000000000 --- a/mu-plugins/blocks/google-map-event-filters/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Google Map Event Filters - -This plugins creates the `wporg/google-map-event-filters` block, which displays a map and list of events that match a given filter during a given timeframe. Filters can be setup for anything, but some common examples are watch parties for WP anniversaries and the State of the Word. - -It uses the `wporg/google-map` block to display a searchable list and/or map of the selected events. - - -## Usage - -1. Setup the API key needed for the `wporg/google-maps` block. See its README for details. -1. Add a new filter to `get_events()` and/or `filter_potential_events()` if you're not using an existing one. You can use the `google_map_event_filters_{$filter_slug}` WP filter to register an event filter outside of this plugin. That can be useful in circumstances where the data is only used on a specific site, like WordCamp.org's `google_map_event_filters_city-landing-pages` filter. -1. Add the following to a pattern in your theme. `googleMapBlockAttributes` are the attributes that will be passed to the `wporg/google-map` block, see it's README for details. - - ```php - $filter_options = array( - 'filterSlug' => 'wp20', - 'startDate' => 'April 21, 2023', - 'endDate' => 'May 30, 2023', - - // This has to be an object, see `WordPressdotorg\MU_Plugins\Google_Map_Event_Filters\render()`. - 'googleMapBlockAttributes' => (object) array( - 'id' => 'wp20', - 'apiKey' => 'WORDCAMP_DEV_GOOGLE_MAPS_API_KEY', - ), - ); - - ?> - - - ``` - - Alternatively, you could take that JSON and manually put it in the post source like this: - - ```html - - - - - - ``` -1. View the page where the block is used. That will create the cron job that updates the data automatically in the future. -1. Run `wp cron event run prime_event_filters` to test the filtering. Look at each title, and add any false positives to `$false_positives` in `filter_potential_events()`. If any events that should be included were ignored, add a keyword from the title to `$keywords`. Run the command after those changes and make sure it's correct now. diff --git a/mu-plugins/blocks/google-map-event-filters/src/block.json b/mu-plugins/blocks/google-map-event-filters/src/block.json deleted file mode 100644 index 3c51abf84..000000000 --- a/mu-plugins/blocks/google-map-event-filters/src/block.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, - "name": "wporg/google-map-event-filters", - "title": "Event Filters for the Google Map block", - "icon": "nametag", - "category": "widgets", - "description": "Displays a map and/or list of a subset of events.", - "textdomain": "wporg", - "attributes": { - "filterSlug": { - "type": "string", - "default": "" - }, - "startDate": { - "type": "string", - "default": "" - }, - "endDate": { - "type": "string", - "default": "" - }, - "googleMapBlockAttributes": { - "type": "object", - "default": [] - } - }, - "supports": { - "inserter": false - }, - "editorScript": "file:./index.js" -} diff --git a/mu-plugins/blocks/google-map-event-filters/src/index.js b/mu-plugins/blocks/google-map-event-filters/src/index.js deleted file mode 100644 index 73e30507b..000000000 --- a/mu-plugins/blocks/google-map-event-filters/src/index.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * WordPress dependencies - */ -import { registerBlockType } from '@wordpress/blocks'; -import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; - -/** - * Internal dependencies - */ -import metadata from './block.json'; - -function Edit( { attributes } ) { - return ( -
- -
- ); -} - -registerBlockType( metadata.name, { - edit: Edit, -} ); diff --git a/mu-plugins/blocks/google-map/README.md b/mu-plugins/blocks/google-map/README.md index 9ab8626ab..11dd90ab1 100644 --- a/mu-plugins/blocks/google-map/README.md +++ b/mu-plugins/blocks/google-map/README.md @@ -2,22 +2,37 @@ Displays a Google Map with markers for each event. Markers will be clustered for performance and UX. Optionally, show a list of the same events, and a search feature. -Currently only supports programmatic usage in block theme templates etc. There's no UI available for adding markers. +Currently only supports programmatic usage in block theme templates etc. There's no UI available for selecting attributes and adding markers, but that can be added in the future. This doesn't currently utilize all the abilities of the `google-map-react` lib, but we can expand it over time. +You can pass markers directly to the block via the `markers` attribute, or use a pre-defined event filter to display events matching certain criteria. -## Usage -Place something like the following in a block or pattern. If you're pulling events from a database, a block is better because Gutenberg loads all patterns at `init` on all pages, regardless of whether or not they're used on that page. +## Map Setup + +```html + +``` + +`id` will be used in the HTML element that wraps the map/list. + +`apiKey` should be the _name_ of a constant, not the value. It's not private because it'll be exposed in the HTTP request to Google Maps, but it should still be stored in a constant in a config file instead of `post_content`. That allows for centralization, documentation, and tracking changes over time. It should be restricted in Google Cloud Console to only the sites where it will be used, to prevent abuse. + +Next, choose how you want to provide the markers. You can pass them directly from your code, or use a pre-defined event filter. See below for more. + + +## Passing Markers Directly + +Place something like the following in a block or pattern. If you'll be pulling events from a database, a block is better because Gutenberg loads all patterns at `init` on all pages, regardless of whether or not they're used on that page. ```php 'all-upcoming-events', + 'id' => 'my-map', 'apiKey' => 'MY_API_KEY_CONSTANT', - 'markers' => get_all_upcoming_events(), + 'markers' => get_my_markers() ); ?> @@ -25,8 +40,6 @@ $map_options = array( ``` -`apiKey` should be the _name_ of a constant, not the value. It's not private because it'll be exposed in the HTTP request to Google Maps, but it should still be stored in a constant in a config file instead of `post_content`. That allows for centralization, documentation, and tracking changes over time. It should be restricted in Google Cloud Console to only the sites where it will be used, to prevent abuse. - `markers` should be an array of objects with the fields in the example below. The `timestamp` field should be a true Unix timestamp, meaning it assumes UTC. The `wporg_events` database table is one potential source for the events, but you can pass anything. ```php @@ -42,3 +55,40 @@ If you have a small number of markers, you can manually json-encode them and the ```html ``` + + +## Passing Markers with Event Filters + +Instead of passing markers directly to the block, you can pass a `filterSlug` attribute, which corresponds to a pre-defined set of events. Some filters also support passing a start/end date, so you can restrict events to those dates. + +Filters can be setup for anything, but some common examples are watch parties for WP anniversaries and the State of the Word. + +1. If you're not using an existing filter, then add a new one to `get_events()` and/or `filter_potential_events()`. You can also use the `google_map_event_filters_{$filter_slug}` WP filter to register an event filter outside of this plugin. That can be useful in circumstances where the data is only used on a specific site, like WordCamp.org's `google_map_event_filters_city-landing-pages` filter. +1. Add the following to a pattern in your theme. + + ```php + $map_options = array( + 'id' => 'wp20', + 'apiKey' => 'WORDCAMP_DEV_GOOGLE_MAPS_API_KEY', + 'filterSlug' => 'wp20', + 'startDate' => 'April 21, 2023', + 'endDate' => 'May 30, 2023', + ); + + ?> + + + ``` + + Alternatively, you could take that JSON and manually put it in the post source like this: + + ```html + + + + + + ``` + +1. View the page where the block is used. That will create the cron job that updates the data automatically in the future. +1. Run `wp cron event run prime_event_filters` to test the filtering. Look at each title, and add any false positives to `$false_positives` in `filter_potential_events()`. If any events that should be included were ignored, add a keyword from the title to `$keywords`. Run the command after those changes and make sure it's correct now. diff --git a/mu-plugins/blocks/google-map-event-filters/google-map-event-filters.php b/mu-plugins/blocks/google-map/inc/event-filters.php similarity index 80% rename from mu-plugins/blocks/google-map-event-filters/google-map-event-filters.php rename to mu-plugins/blocks/google-map/inc/event-filters.php index 5e6c7ee2f..1d305902c 100644 --- a/mu-plugins/blocks/google-map-event-filters/google-map-event-filters.php +++ b/mu-plugins/blocks/google-map/inc/event-filters.php @@ -1,47 +1,22 @@ __NAMESPACE__ . '\render', - ) - ); -} - -/** - * Render the block content. - */ -function render( array $attributes, string $content, WP_Block $block ): string { - $attributes['startDate'] = strtotime( $attributes['startDate'] ); - $attributes['endDate'] = strtotime( $attributes['endDate'] ); - $wrapper_attributes = get_block_wrapper_attributes( array( 'id' => 'wp-block-wporg-google-map-event-filters-' . $attributes['filterSlug'] ) ); - - // The REST API doesn't support associative arrays, so this had to be defined as an object in this block. It - // needs to be an array when passed to the Google Map block though. - // See `rest_is_array()`. - $map_options = (array) $attributes['googleMapBlockAttributes']; - $map_options['markers'] = get_events( $attributes['filterSlug'], $attributes['startDate'], $attributes['endDate'] ); - - // This has to be called in `render()` to know which slug/dates to use. - $cron_args = array( $attributes['filterSlug'], $attributes['startDate'], $attributes['endDate'], true ); +function schedule_filter_cron( string $filter_slug, string $start_date, string $end_date ): void { + $cron_args = array( $filter_slug, $start_date, $end_date, true ); // Some custom filter slugs using `google_map_event_filters_{$filter_slug}` to pass data may need to run their // own cron to prime the cache. // See WordCamp's `themes/wporg-events-2023/inc/city-landing-pages.php` for an example. - $register_cron = apply_filters( 'google-map-event-filters-register-cron', true, $attributes['filterSlug'] ); + $register_cron = apply_filters( 'google-map-event-filters-register-cron', true, $filter_slug ); if ( $register_cron && ! wp_next_scheduled( 'prime_event_filters', $cron_args ) ) { wp_schedule_event( @@ -51,18 +26,6 @@ function render( array $attributes, string $content, WP_Block $block ): string { $cron_args ); } - - ob_start(); - - ?> - -
> - -
- - block_type->view_script_handles[0], $block->block_type->editor_script_handles[0] ); foreach ( $handles as $handle ) { diff --git a/mu-plugins/blocks/google-map/src/block.json b/mu-plugins/blocks/google-map/src/block.json index 2dfec3bbf..d2dedd225 100644 --- a/mu-plugins/blocks/google-map/src/block.json +++ b/mu-plugins/blocks/google-map/src/block.json @@ -16,6 +16,18 @@ "type": "string", "default": "" }, + "filterSlug": { + "type": "string", + "default": "" + }, + "startDate": { + "type": "string", + "default": "" + }, + "endDate": { + "type": "string", + "default": "" + }, "markers": { "type": "array", "default": [] diff --git a/mu-plugins/loader.php b/mu-plugins/loader.php index 2e061ab3a..cf0cdaafb 100644 --- a/mu-plugins/loader.php +++ b/mu-plugins/loader.php @@ -34,7 +34,6 @@ require_once __DIR__ . '/blocks/local-navigation-bar/index.php'; require_once __DIR__ . '/blocks/latest-news/latest-news.php'; require_once __DIR__ . '/blocks/link-wrapper/index.php'; -require_once __DIR__ . '/blocks/google-map-event-filters/google-map-event-filters.php'; require_once __DIR__ . '/blocks/navigation/index.php'; require_once __DIR__ . '/blocks/notice/index.php'; require_once __DIR__ . '/blocks/query-filter/index.php';