From f8eca142768fb28ff32ec7d6f9fb98e4026e2769 Mon Sep 17 00:00:00 2001 From: Maud Leray Date: Tue, 12 Nov 2024 11:31:16 +0100 Subject: [PATCH] PLANET-7614 Add categories filter to News & Stories page (#2422) Other listing pages shouldn't have it --- assets/src/js/listing_pages.js | 25 +++++++++++++++++ assets/src/scss/layout/_forms.scss | 35 ++++++++++++------------ assets/src/scss/pages/_listing-page.scss | 12 ++++++++ functions.php | 18 ++++++++++++ src/ListingPage.php | 26 ++++++++++++++++++ templates/listing-page-filters.twig | 17 ++++++++++++ templates/listing-page.twig | 6 +++- 7 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 templates/listing-page-filters.twig diff --git a/assets/src/js/listing_pages.js b/assets/src/js/listing_pages.js index 4c1be338e5..151243b938 100644 --- a/assets/src/js/listing_pages.js +++ b/assets/src/js/listing_pages.js @@ -1,4 +1,5 @@ export const setupListingPages = () => { + // Setup behaviour for list/grid toggle. const listViewToggle = document.querySelector('.list-view-toggle'); const gridViewToggle = document.querySelector('.grid-view-toggle'); @@ -17,4 +18,28 @@ export const setupListingPages = () => { listViewToggle.onclick = switchViews; gridViewToggle.onclick = switchViews; + + // Setup filters for the News & Stories page. + const filters = document.querySelector('.listing-page-filters'); + if (!filters) { + return; + } + + // Functions and constants. + const CATEGORY_FILTER = 'category'; + + const updateFilter = event => { + const {target: {id, value}} = event; + const newUrl = new URL(window.location.href.split('/page/')[0]); + + if (value) { + newUrl.searchParams.set(id, value); + } else { + newUrl.searchParams.delete(id); + } + window.location.href = newUrl.href; + }; + + // Category filter. + document.getElementById(CATEGORY_FILTER).onchange = updateFilter; }; diff --git a/assets/src/scss/layout/_forms.scss b/assets/src/scss/layout/_forms.scss index 66644b7988..627bfe414c 100644 --- a/assets/src/scss/layout/_forms.scss +++ b/assets/src/scss/layout/_forms.scss @@ -25,7 +25,7 @@ position: relative; cursor: pointer; display: inline-block; - padding-inline-start: 36px; + padding-inline-start: $sp-4x; a { color: inherit; @@ -41,7 +41,7 @@ border-radius: 2px; left: 0; position: absolute; - top: calc((100% - 20px) / 2); + top: calc((100% - $sp-4x) / 2); html[dir="rtl"] & { right: 0; @@ -62,14 +62,14 @@ transform: rotate(-45deg) scale(-1, 1); border-bottom: 2px solid var(--grey-900); border-right: 2px solid var(--grey-900); - top: calc(((100% - 20px) / 2) + 5px); - left: 4px; + top: calc(((100% - $sp-2x) / 2) + 5px); + left: $sp-x; height: 8px; width: 12px; html[dir="rtl"] & { left: auto; - right: 4px; + right: $sp-x; } } } @@ -109,7 +109,7 @@ font-family: var(--font-family-paragraph-secondary); position: relative; cursor: pointer; - padding-inline-start: 36px; + padding-inline-start: $sp-4x; a { color: inherit; @@ -125,7 +125,7 @@ border-radius: 50%; left: 0; position: absolute; - top: calc((100% - 20px) / 2); + top: calc((100% - $sp-2x) / 2); html[dir="rtl"] & { right: 0; @@ -160,7 +160,7 @@ background-color: var(--white); border: 1px solid var(--grey-500); color: var(--color-text-body); - padding: 0 16px; + padding: 0 $sp-2; &::placeholder, &::-webkit-input-placeholder, @@ -187,11 +187,12 @@ input[type="text"].form-control, input[type="email"].form-control { height: auto; - padding: 11px 16px; + padding: 11px $sp-2; } .form-select { - height: 48px; + height: $sp-6; + padding-inline-end: $sp-5; html[dir="rtl"] & { background-position: left 0.75rem center; @@ -207,7 +208,7 @@ input[type="email"].form-control { } textarea.form-control { - padding: 12px 16px; + padding: $sp-1x $sp-2; resize: none; } @@ -224,16 +225,16 @@ textarea.form-control { pointer-events: none; position: absolute; left: 0; - top: 16px; + top: $sp-2; color: var(--grey-600); - padding-inline-start: 16px; + padding-inline-start: $sp-2; opacity: 0; transition: all .3s ease; margin-bottom: 0; } .form-control:not(:placeholder-shown) { - padding: 18px 16px 4px 16px; + padding: 18px $sp-2 $sp-x $sp-2; & ~ label { transform: translateY(-10px); @@ -268,7 +269,7 @@ select { background: var(--p4-action-yellow-600); color: white; border-radius: 4px; - padding: 6px 12px; + padding: 6px $sp-1x; width: fit-content; position: relative; pointer-events: none; @@ -284,11 +285,11 @@ select { border-bottom-color: var(--p4-action-yellow-600); border-width: 5px; right: auto; - left: 16px; + left: $sp-2; html[dir="rtl"] & { left: auto; - right: 16px; + right: $sp-2; } } } diff --git a/assets/src/scss/pages/_listing-page.scss b/assets/src/scss/pages/_listing-page.scss index 180c21e618..b2f9d3b799 100644 --- a/assets/src/scss/pages/_listing-page.scss +++ b/assets/src/scss/pages/_listing-page.scss @@ -364,3 +364,15 @@ } } } + +.listing-page-filters { + width: 100%; + + .listing-page-select { + width: 220px; + + @include mobile-only { + width: 100%; + } + } +} diff --git a/functions.php b/functions.php index 14f5084cf4..19e15663c0 100644 --- a/functions.php +++ b/functions.php @@ -407,6 +407,24 @@ function ($urls, $post_id) { 2 ); +// Add filters to the News & Stories listing page. +// Right now only "category" is available. +add_action( + 'pre_get_posts', + function ($query): void { + if (!$query->is_main_query() || is_admin() || !is_home()) { + return; + } + $category_slug = isset($_GET['category']) ? $_GET['category'] : ''; + $category = get_category_by_slug($category_slug); + if (!$category || !get_posts(['post_type' => 'post', 'category' => $category->term_id])) { + $query->set('category__in', []); + } else { + $query->set('category__in', [$category->term_id]); + } + } +); + // Calls attachment metadata update on importer job. // This triggers the wp-stateless hook (if it exists), // which sets the sm_cloud metadata for the uploaded file. diff --git a/src/ListingPage.php b/src/ListingPage.php index a4793fde8f..e6a2a379b1 100644 --- a/src/ListingPage.php +++ b/src/ListingPage.php @@ -47,6 +47,9 @@ private function update_context(): void $this->context['page_category'] = is_home() ? 'News' : 'Listing Page'; $this->context['og_type'] = isset($this->context['author']) ? 'profile' : 'website'; + // Filters (News & Stories page only) + $this->set_filters(); + $this->add_listing_page_content(); $this->set_featured_action(); $this->set_news_page_link(); @@ -104,6 +107,29 @@ private function set_news_page_link(): void $this->context['news_page_link'] = $news_page_link; } + /** + * Set the 'News & stories' page filters. + * For now only the "category" one is available. + */ + private function set_filters(): void + { + if (!is_home()) { + return; + } + + $all_categories = get_categories(); + $categories = []; + // Only categories that have at least 1 Post assigned should be displayed for filtering. + foreach ($all_categories as $cat) { + if (!get_posts(['post_type' => 'post', 'category' => $cat->term_id])) { + continue; + } + $categories[] = $cat; + } + $this->context['categories'] = $categories; + $this->context['current_category'] = $_GET['category'] ?? ''; + } + /** * View the listing page template. */ diff --git a/templates/listing-page-filters.twig b/templates/listing-page-filters.twig new file mode 100644 index 0000000000..4bbe13d58c --- /dev/null +++ b/templates/listing-page-filters.twig @@ -0,0 +1,17 @@ +
+ + +
diff --git a/templates/listing-page.twig b/templates/listing-page.twig index 31cc9b1895..16775360a6 100644 --- a/templates/listing-page.twig +++ b/templates/listing-page.twig @@ -1,7 +1,11 @@
-

{{ listing_page_title ?? __( 'All articles', 'planet4-master-theme' ) }}

+ {% if fn('is_home') %} + {% include 'listing-page-filters.twig' %} + {% else %} +

{{ listing_page_title ?? __( 'All articles', 'planet4-master-theme' ) }}

+ {% endif %} {{ 'grid-view'|svgicon }}