From 673c20ca6e552e4edc221cd7d67551369af65d77 Mon Sep 17 00:00:00 2001 From: Steven Dufresne Date: Wed, 6 Dec 2023 09:46:23 +0900 Subject: [PATCH] Events: Use a showcase like approach for the events list/archive (#1124) * Try using a php block that queries. * Example query filtering. * add block build script. * Add the patterns * Hook in another filter. * Rename template. * Some minor updates. * Add the month filter * Add in Past Events template * update menu links * pass filter values to map block * Add map block. Isn't yet connected to country list. * Update copy. * Harmonize spacing. * Make font size smaller for past events. * Update post title spacing. * Update search layout. * fix upcoming spacing. * Update the filters to show the item count on archives. * Fix the template widths. * Update event list UI. * Update the menu text based on designs. * combine build/watch scripts for convenience * use get_events for filtering and caching * add missing template part * update upcoming events slug * add country filter values * add all months * schedule crons to prime cache * apply coding standards --------- Co-authored-by: Ian Dunn --- .../themes/wporg-events-2023/functions.php | 178 +++++++++++++++++- .../themes/wporg-events-2023/package.json | 6 +- .../parts/event-filters.html | 7 + .../patterns/events-list-filters.php | 18 ++ .../patterns/front-cover.php | 12 +- .../patterns/front-events.php | 4 +- .../patterns/page-organize-events.php | 2 +- .../page-upcoming-see-past-events.php | 16 ++ .../postcss/blocks/wporg-google-map.pcss | 6 +- .../wporg-events-2023/postcss/page/misc.pcss | 4 + .../src/event-list/block.json | 35 ++++ .../wporg-events-2023/src/event-list/edit.js | 20 ++ .../wporg-events-2023/src/event-list/index.js | 16 ++ .../src/event-list/index.php | 117 ++++++++++++ .../src/event-list/style.scss | 0 .../templates/page-past-events.html | 16 ++ .../templates/page-upcoming.html | 22 +++ .../wporg-events-2023/templates/search.html | 20 ++ 18 files changed, 484 insertions(+), 15 deletions(-) create mode 100644 public_html/wp-content/themes/wporg-events-2023/parts/event-filters.html create mode 100644 public_html/wp-content/themes/wporg-events-2023/patterns/events-list-filters.php create mode 100644 public_html/wp-content/themes/wporg-events-2023/patterns/page-upcoming-see-past-events.php create mode 100644 public_html/wp-content/themes/wporg-events-2023/src/event-list/block.json create mode 100644 public_html/wp-content/themes/wporg-events-2023/src/event-list/edit.js create mode 100644 public_html/wp-content/themes/wporg-events-2023/src/event-list/index.js create mode 100644 public_html/wp-content/themes/wporg-events-2023/src/event-list/index.php create mode 100644 public_html/wp-content/themes/wporg-events-2023/src/event-list/style.scss create mode 100644 public_html/wp-content/themes/wporg-events-2023/templates/page-past-events.html create mode 100644 public_html/wp-content/themes/wporg-events-2023/templates/page-upcoming.html create mode 100644 public_html/wp-content/themes/wporg-events-2023/templates/search.html diff --git a/public_html/wp-content/themes/wporg-events-2023/functions.php b/public_html/wp-content/themes/wporg-events-2023/functions.php index 4606d8508b..c5e663d3ec 100644 --- a/public_html/wp-content/themes/wporg-events-2023/functions.php +++ b/public_html/wp-content/themes/wporg-events-2023/functions.php @@ -5,10 +5,19 @@ require_once __DIR__ . '/inc/city-landing-pages.php'; +// Block files. +require_once __DIR__ . '/src/event-list/index.php'; + add_action( 'after_setup_theme', __NAMESPACE__ . '\theme_support' ); add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_assets' ); add_filter( 'wporg_block_navigation_menus', __NAMESPACE__ . '\add_site_navigation_menus' ); +add_filter( 'wporg_query_filter_options_format_type', __NAMESPACE__ . '\get_format_type_options' ); +add_filter( 'wporg_query_filter_options_event_type', __NAMESPACE__ . '\get_event_type_options' ); +add_filter( 'wporg_query_filter_options_month', __NAMESPACE__ . '\get_month_options' ); +add_filter( 'wporg_query_filter_options_country', __NAMESPACE__ . '\get_country_options' ); +add_action( 'wporg_query_filter_in_form', __NAMESPACE__ . '\inject_other_filters' ); +add_filter( 'query_vars', __NAMESPACE__ . '\add_query_vars' ); /** * Register theme supports. @@ -36,13 +45,174 @@ function add_site_navigation_menus( $menus ) { return array( 'local-navigation' => array( array( - 'label' => __( 'All Events', 'wordcamporg' ), - 'url' => '/upcoming-events/', + 'label' => __( 'Upcoming events', 'wordcamporg' ), + 'url' => '/upcoming/', ), array( - 'label' => __( 'Organize an Event', 'wordcamporg' ), - 'url' => '/organize-an-event/', + 'label' => __( 'Organize an event', 'wordcamporg' ), + 'url' => '/organize-events/', ), ), ); } + +/** + * Sets up our Query filter for country. + * + * @return array + */ +function get_country_options( array $options ): array { + global $wp_query; + $selected = isset( $wp_query->query['country'] ) ? (array) $wp_query->query['country'] : array(); + + $countries = wcorg_get_countries(); + + // Re-index to match the format expected by the query-filters block. + $countries = array_combine( array_keys( $countries ), array_column( $countries, 'name' ) ); + + return array( + 'label' => __( 'Country', 'wporg' ), + 'title' => __( 'Country', 'wporg' ), + 'key' => 'country', + 'action' => home_url( '/upcoming/' ), + 'options' => $countries, + 'selected' => $selected, + ); +} + +/** + * Sets up our Query filter for event_type. + * + * @return array + */ +function get_event_type_options( array $options ): array { + global $wp_query; + $selected = isset( $wp_query->query['event_type'] ) ? (array) $wp_query->query['event_type'] : array(); + $count = count( $selected ); + $label = sprintf( + /* translators: The dropdown label for filtering, %s is the selected term count. */ + _n( 'Type %s', 'Type %s', $count, 'wporg' ), + $count + ); + + return array( + 'label' => $label, + 'title' => __( 'Type', 'wporg' ), + 'key' => 'event_type', + 'action' => home_url( '/upcoming/' ), + 'options' => array( + 'meetup' => 'Meetup', + 'wordcamp' => 'WordCamp', + ), + 'selected' => $selected, + ); +} + +/** + * Sets up our Query filter for format_type. + * + * @return array + */ +function get_format_type_options( array $options ): array { + global $wp_query; + $selected = isset( $wp_query->query['format_type'] ) ? (array) $wp_query->query['format_type'] : array(); + $count = count( $selected ); + $label = sprintf( + /* translators: The dropdown label for filtering, %s is the selected term count. */ + _n( 'Format %s', 'Format %s', $count, 'wporg' ), + $count + ); + + return array( + 'label' => $label, + 'title' => __( 'Format', 'wporg' ), + 'key' => 'format_type', + 'action' => home_url( '/upcoming/' ), + 'options' => array( + 'online' => 'Online', + 'in-person' => 'In Person', + ), + 'selected' => $selected, + ); +} + +/** + * Sets up our Query filter for month. + * + * @return array + */ +function get_month_options( array $options ): array { + global $wp_query; + $selected = isset( $wp_query->query['month'] ) ? (array) $wp_query->query['month'] : array(); + $count = count( $selected ); + $label = sprintf( + /* translators: The dropdown label for filtering, %s is the selected term count. */ + _n( 'Month %s', 'Month %s', $count, 'wporg' ), + $count + ); + + $months = array(); + + for ( $i = 1; $i <= 12; $i++ ) { + $month = strtotime( "2023-$i-1" ); + $months[ gmdate( 'm', $month ) ] = gmdate( 'F', $month ); + } + + return array( + 'label' => $label, + 'title' => __( 'Month', 'wporg' ), + 'key' => 'month', + 'action' => home_url( '/upcoming/' ), + 'options' => $months, + 'selected' => $selected, + ); +} + +/** + * Add in our custom query vars. + */ +function add_query_vars( $query_vars ) { + $query_vars[] = 'format_type'; + $query_vars[] = 'event_type'; + $query_vars[] = 'month'; + $query_vars[] = 'country'; + + return $query_vars; +} + + +/** + * Add in the other existing filters as hidden inputs in the filter form. + * + * Enables combining filters by building up the correct URL on submit, + * for example sites using a tag, a category, and matching a search term: + * ?tag[]=cuisine&cat[]=3&s=wordpress` + * + * @param string $key The key for the current filter. + */ +function inject_other_filters( $key ) { + global $wp_query; + + $query_vars = array( 'event_type', 'format_type', 'month', 'country' ); + + foreach ( $query_vars as $query_var ) { + if ( ! isset( $wp_query->query[ $query_var ] ) ) { + continue; + } + + if ( $key === $query_var ) { + continue; + } + + $values = (array) $wp_query->query[ $query_var ]; + + foreach ( $values as $value ) { + printf( '', esc_attr( $query_var ), esc_attr( $value ) ); + } + } + + // Pass through search query. + if ( isset( $wp_query->query['s'] ) ) { + printf( '', esc_attr( $wp_query->query['s'] ) ); + } +} diff --git a/public_html/wp-content/themes/wporg-events-2023/package.json b/public_html/wp-content/themes/wporg-events-2023/package.json index a5b1ca5f63..fb5a9f54f6 100644 --- a/public_html/wp-content/themes/wporg-events-2023/package.json +++ b/public_html/wp-content/themes/wporg-events-2023/package.json @@ -4,6 +4,7 @@ "description": "Description: Includes templates for the homepage, event archives, etc", "license": "GPL-2.0-or-later", "devDependencies": { + "@wordpress/scripts": "^26.18.0", "cssnano": "^6.0.1", "postcss": "^8.4.31", "postcss-cli": "^10.1.0", @@ -13,8 +14,9 @@ }, "scripts": { "start": "npm run watch", - "watch": "npm run build -- --watch", - "build": "postcss postcss/style.pcss postcss/editor.pcss --dir . --ext css", + "watch": "wp-scripts start & npm run build:css -- --watch", + "build": "wp-scripts build && npm run build:css", + "build:css": "postcss postcss/style.pcss postcss/editor.pcss --dir . --ext css", "lint:js": "echo 'There is no JS, but this is required to make the `linter.yml` workflow pass. See https://github.com/yarnpkg/yarn/issues/6739, https://github.com/yarnpkg/yarn/issues/6894.'", "lint:css": "wp-scripts lint-style 'postcss/*.pcss'" } diff --git a/public_html/wp-content/themes/wporg-events-2023/parts/event-filters.html b/public_html/wp-content/themes/wporg-events-2023/parts/event-filters.html new file mode 100644 index 0000000000..b5594be408 --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/parts/event-filters.html @@ -0,0 +1,7 @@ + +
+ + + + +
diff --git a/public_html/wp-content/themes/wporg-events-2023/patterns/events-list-filters.php b/public_html/wp-content/themes/wporg-events-2023/patterns/events-list-filters.php new file mode 100644 index 0000000000..3949ae7905 --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/patterns/events-list-filters.php @@ -0,0 +1,18 @@ + + + +
+ +
+ +
+ + +
diff --git a/public_html/wp-content/themes/wporg-events-2023/patterns/front-cover.php b/public_html/wp-content/themes/wporg-events-2023/patterns/front-cover.php index 384072c9f1..da374f160d 100644 --- a/public_html/wp-content/themes/wporg-events-2023/patterns/front-cover.php +++ b/public_html/wp-content/themes/wporg-events-2023/patterns/front-cover.php @@ -8,8 +8,8 @@ ?> -
-
+
+

Meet the community behind WordPress

@@ -25,8 +25,8 @@
- -
+ +
@@ -46,9 +46,9 @@
- +
- + \ No newline at end of file diff --git a/public_html/wp-content/themes/wporg-events-2023/patterns/front-events.php b/public_html/wp-content/themes/wporg-events-2023/patterns/front-events.php index b4e0ab092f..436cc8999a 100644 --- a/public_html/wp-content/themes/wporg-events-2023/patterns/front-events.php +++ b/public_html/wp-content/themes/wporg-events-2023/patterns/front-events.php @@ -13,11 +13,13 @@

Upcoming events

+ + diff --git a/public_html/wp-content/themes/wporg-events-2023/patterns/page-organize-events.php b/public_html/wp-content/themes/wporg-events-2023/patterns/page-organize-events.php index a07e7fbc37..10b3450dd7 100644 --- a/public_html/wp-content/themes/wporg-events-2023/patterns/page-organize-events.php +++ b/public_html/wp-content/themes/wporg-events-2023/patterns/page-organize-events.php @@ -165,7 +165,7 @@
diff --git a/public_html/wp-content/themes/wporg-events-2023/patterns/page-upcoming-see-past-events.php b/public_html/wp-content/themes/wporg-events-2023/patterns/page-upcoming-see-past-events.php new file mode 100644 index 0000000000..dd0f1a407d --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/patterns/page-upcoming-see-past-events.php @@ -0,0 +1,16 @@ + + + +

+ + See past events + +

+ diff --git a/public_html/wp-content/themes/wporg-events-2023/postcss/blocks/wporg-google-map.pcss b/public_html/wp-content/themes/wporg-events-2023/postcss/blocks/wporg-google-map.pcss index 8e6e106351..c706af9eb7 100644 --- a/public_html/wp-content/themes/wporg-events-2023/postcss/blocks/wporg-google-map.pcss +++ b/public_html/wp-content/themes/wporg-events-2023/postcss/blocks/wporg-google-map.pcss @@ -36,13 +36,17 @@ } .wporg-marker-list-item__title { + margin: 0; font-family: var(--wp--preset--font-family--inter); font-size: var(--wp--preset--font-size--normal); line-height: var(--wp--custom--body--typography--line-height); - --wp--preset--spacing--30: 0; } + .wporg-marker-list-item__title a { + text-decoration: none; + } + .wporg-marker-list-item__date-time { @media (--medium) { display: block; diff --git a/public_html/wp-content/themes/wporg-events-2023/postcss/page/misc.pcss b/public_html/wp-content/themes/wporg-events-2023/postcss/page/misc.pcss index a0ab6e5e05..8e16be144d 100644 --- a/public_html/wp-content/themes/wporg-events-2023/postcss/page/misc.pcss +++ b/public_html/wp-content/themes/wporg-events-2023/postcss/page/misc.pcss @@ -8,3 +8,7 @@ display: none; } } + +body .is-layout-flex.page-upcoming-title-past-wrapper { + align-items: baseline; +} diff --git a/public_html/wp-content/themes/wporg-events-2023/src/event-list/block.json b/public_html/wp-content/themes/wporg-events-2023/src/event-list/block.json new file mode 100644 index 0000000000..e90c17ef3b --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/src/event-list/block.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "wporg/event-list", + "version": "0.1.0", + "title": "WordPress Events List", + "category": "design", + "icon": "list-view", + "description": "List of WordPress Events", + "textdomain": "wporg", + "attributes": { + "events": { + "type": "string", + "default": "all-upcoming" + } + }, + "supports": { + "align": true, + "color": { + "background": true, + "text": true + }, + "spacing": { + "margin": [ "top", "bottom" ], + "padding": true, + "blockGap": false + }, + "typography": { + "fontSize": true, + "lineHeight": true + } + }, + "editorScript": "file:./index.js", + "style": "file:./style-index.css" +} diff --git a/public_html/wp-content/themes/wporg-events-2023/src/event-list/edit.js b/public_html/wp-content/themes/wporg-events-2023/src/event-list/edit.js new file mode 100644 index 0000000000..1fb41ab1ee --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/src/event-list/edit.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ + +import { Disabled } from '@wordpress/components'; +import ServerSideRender from '@wordpress/server-side-render'; +import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; + +export default function Edit( { attributes, name } ) { + return ( +
+ + + + + + +
+ ); +} diff --git a/public_html/wp-content/themes/wporg-events-2023/src/event-list/index.js b/public_html/wp-content/themes/wporg-events-2023/src/event-list/index.js new file mode 100644 index 0000000000..5d6da2ae24 --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/src/event-list/index.js @@ -0,0 +1,16 @@ +/** + * WordPress dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import Edit from './edit'; +import metadata from './block.json'; +import './style.scss'; + +registerBlockType( metadata.name, { + edit: Edit, + save: () => null, +} ); diff --git a/public_html/wp-content/themes/wporg-events-2023/src/event-list/index.php b/public_html/wp-content/themes/wporg-events-2023/src/event-list/index.php new file mode 100644 index 0000000000..2f20dd6ba3 --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/src/event-list/index.php @@ -0,0 +1,117 @@ + __NAMESPACE__ . '\render', + ) + ); +} + +/** + * Render the block content. + * + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. + * + * @return string Returns the block markup. + */ +function render( $attributes, $content, $block ) { + $facets = array( + 'search' => sanitize_text_field( get_query_var( 's' ) ?? '' ), + 'type' => sanitize_text_field( get_query_var( 'event_type' ) ?? '' ), + 'format' => sanitize_text_field( get_query_var( 'format_type' ) ?? '' ), + 'month' => absint( get_query_var( 'month' ) ?? 0 ), + 'country' => sanitize_text_field( get_query_var( 'country' ) ?? '' ), + ); + + $events = get_events( $attributes['events'], 0, 0, $facets ); + schedule_filter_cron( $attributes['events'], 0, 0, $facets ); + + // Get all the filters that are currently applied. + $filtered_events = array_slice( filter_events( $events ), 0, 10); + + // loop through events output markup using gutenberg blocks. + $content = '
    '; + + foreach ( $filtered_events as $event ) { + $content .= '
  • '; + $content .= '

    ' . esc_html( $event->title ) . '

    '; + $content .= '
    ' . esc_html( $event->location ) . '
    '; + $content .= '
    ' . esc_html( $event->timestamp ) . '
    '; + $content .= '
  • '; + } + + $content .= '
'; + + $wrapper_attributes = get_block_wrapper_attributes( array( + 'class' => 'wp-block-wporg-google-map', + ) ); + return sprintf( + '
%2$s
', + $wrapper_attributes, + do_blocks( $content ) + ); +} + +/** + * Get a list of the currently-applied filters. + * + * @return array + */ +function filter_events( array $events ): array { + global $wp_query; + + $taxes = array( + 'map_type' => 'map_type', + ); + $terms = array(); + + // Get the terms. + foreach ( $taxes as $query_var => $taxonomy ) { + + if ( ! isset( $wp_query->query[ $query_var ] ) ) { + continue; + } + + $values = (array) $wp_query->query[ $query_var ]; + foreach ( $values as $value ) { + $terms[] = $value; + } + } + + if ( empty( $terms ) ) { + return $events; + } + + $filtered_events = array(); + foreach ( $events as $event ) { + // Assuming each event has a 'type' property. + if ( isset($event->type) && in_array($event->type, $terms) ) { + $filtered_events[] = $event; + } + } + + return $filtered_events; +} diff --git a/public_html/wp-content/themes/wporg-events-2023/src/event-list/style.scss b/public_html/wp-content/themes/wporg-events-2023/src/event-list/style.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public_html/wp-content/themes/wporg-events-2023/templates/page-past-events.html b/public_html/wp-content/themes/wporg-events-2023/templates/page-past-events.html new file mode 100644 index 0000000000..cd1efd0c4c --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/templates/page-past-events.html @@ -0,0 +1,16 @@ + + + +
+ +
+ + + +
+ +
+ + + diff --git a/public_html/wp-content/themes/wporg-events-2023/templates/page-upcoming.html b/public_html/wp-content/themes/wporg-events-2023/templates/page-upcoming.html new file mode 100644 index 0000000000..8f93a5028a --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/templates/page-upcoming.html @@ -0,0 +1,22 @@ + + + +
+ +
+ +
+ + +
+ + + + +
+ +
+ + + diff --git a/public_html/wp-content/themes/wporg-events-2023/templates/search.html b/public_html/wp-content/themes/wporg-events-2023/templates/search.html new file mode 100644 index 0000000000..1541f2ae92 --- /dev/null +++ b/public_html/wp-content/themes/wporg-events-2023/templates/search.html @@ -0,0 +1,20 @@ + + + +
+ + + +
+ +
+ + + +
+ +
+ + +