From d309213742ba65f0a35c968356615d6176955861 Mon Sep 17 00:00:00 2001 From: Tetrakern <26898880+Tetrakern@users.noreply.github.com> Date: Wed, 8 Mar 2023 11:36:26 +0100 Subject: [PATCH] Improve latest_posts shortcode --- DOCUMENTATION.md | 5 ++- FILTERS.md | 12 ++--- includes/functions/_shortcodes.php | 70 ++++++++++++++++-------------- partials/_latest-posts.php | 53 +++++++++++----------- 4 files changed, 73 insertions(+), 67 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 3d393a47..a966c077 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -485,13 +485,14 @@ Renders a two-column grid of small cards, showing the latest four chapters order ### Latest Posts -Renders the last blog post or a list of blog posts, ignoring sticky posts, ordered by publishing date, descending. Optional parameters are **count**, **author**, **posts**, **categories**, **tags**, and **class**. +Renders the last blog post or a list of blog posts, ignoring sticky posts, ordered by publishing date, descending. Optional parameters are **count**, **author**, **posts**, **categories**, **tags**, **rel**, and **class**. * **count:** Limit posts to any positive number, although you should keep it reasonable. Default `1`. * **author:** Only show posts of a specific author. Make sure to write the name right. * **posts:** Comma-separated list of post IDs, if you want to pick from a curated pool. * **categories:** Comma-separated list of category names (case-insensitive), if you want to pick from a curated pool. * **tags:** Comma-separated list of tag names (case-insensitive), if you want to pick from a curated pool. +* **rel:** Relationship between different taxonomies, either `AND` or `OR`. Default `AND`. * **class:** Additional CSS classes, separated by whitespace. ``` @@ -499,7 +500,7 @@ Renders the last blog post or a list of blog posts, ignoring sticky posts, order ``` ``` -[fictioneer_latest_posts count="16" tags="world building, characters"] +[fictioneer_latest_posts count="16" tags="world building, characters" categories="blog, tutorials" rel="or"] ``` ``` diff --git a/FILTERS.md b/FILTERS.md index 3aa1450e..0f8b1ee7 100644 --- a/FILTERS.md +++ b/FILTERS.md @@ -370,7 +370,7 @@ Filters the boolean return value of the `fictioneer_is_editor( $user_id )` funct --- ### `apply_filters( 'fictioneer_filter_latest_posts_query_args', $query_args, $args )` -Filters the arguments to query the posts in the `fictioneer_latest_posts` shortcode. +Filters the query arguments in the `fictioneer_latest_posts` shortcode. The optional taxonomy arrays can include categories and tags. **$query_args:** * $post_type (string) – `'post'` @@ -383,14 +383,16 @@ Filters the arguments to query the posts in the `fictioneer_latest_posts` shortc * $posts_per_page (int) – `$args['count']` * $ignore_sticky_posts (boolean) – `true` * $no_found_rows (boolean) – `true` +* $author_name (string|null) – `$args['author']` **$args:** * $author (boolean|string) – The author provided by the shortcode. Default `false`. * $count (int) – The number of posts provided by the shortcode. Default `1`. -* $post_ids (\[string]) – Optional. Array of post IDs. -* $tags (\[string]) – Optional. Array of tag names. -* $categories (\[string]) – Optional. Array of category names. -* $class (string) – Optional. Additional CSS classes. +* $post_ids (\[string]) – Array of post IDs. Default empty. +* $taxonomies (array) – Array of taxonomy arrays (names). Default empty. +* $rel (string) – Relationship between taxonomies. Default `'AND'`. +* $classes (\[string]) – Array of additional CSS classes. Default empty. +* $classes (\[string]) – Array of additional CSS classes. Default empty. --- diff --git a/includes/functions/_shortcodes.php b/includes/functions/_shortcodes.php index ce80cd75..fa716dfe 100644 --- a/includes/functions/_shortcodes.php +++ b/includes/functions/_shortcodes.php @@ -269,49 +269,48 @@ function fictioneer_shortcode_latest_stories( $attr ) { $order = $attr['order'] ?? 'desc'; $orderby = $attr['orderby'] ?? 'date'; $post_ids = []; + $taxonomies = []; $classes = []; + // Post IDs if ( ! empty( $attr['stories'] ) ) { - $post_ids = str_replace( ' ', '', $attr['stories'] ); - $post_ids = explode( ',', $post_ids ); - $post_ids = is_array( $post_ids ) ? $post_ids : []; + $post_ids = fictioneer_explode_list( $attr['stories'] ); $count = count( $post_ids ); } + // Tags + if ( ! empty( $attr['tags'] ) ) { + $taxonomies['tags'] = fictioneer_explode_list( $attr['tags'] ); + } + + // Categories + if ( ! empty( $attr['categories'] ) ) { + $taxonomies['categories'] = fictioneer_explode_list( $attr['categories'] ); + } + // Extra classes if ( ! empty( $attr['class'] ) ) $classes[] = esc_attr( wp_strip_all_tags( $attr['class'] ) ); + // Args + $args = array( + 'count' => $count, + 'author' => $author, + 'order' => $order, + 'orderby' => $orderby, + 'post_ids' => $post_ids, + 'taxonomies' => $taxonomies, + 'classes' => $classes + ); + // Buffer ob_start(); switch ( $type ) { case 'compact': - get_template_part( - 'partials/_latest-stories-compact', - null, - array( - 'count' => $count, - 'author' => $author, - 'order' => $order, - 'orderby' => $orderby, - 'post_ids' => $post_ids, - 'classes' => $classes - ) - ); + get_template_part( 'partials/_latest-stories-compact', null, $args ); break; default: - get_template_part( - 'partials/_latest-stories', - null, - array( - 'count' => $count, - 'author' => $author, - 'order' => $order, - 'orderby' => $orderby, - 'post_ids' => $post_ids, - 'classes' => $classes - ) - ); + get_template_part( 'partials/_latest-stories', null, $args ); } // Return buffer @@ -497,8 +496,8 @@ function fictioneer_shortcode_latest_posts( $attr ) { $author = $attr['author'] ?? false; $count = max( 1, intval( $attr['count'] ?? 1 ) ); $post_ids = []; - $tags = []; - $categories = []; + $taxonomies = []; + $rel = 'AND'; $classes = []; // Post IDs @@ -511,12 +510,17 @@ function fictioneer_shortcode_latest_posts( $attr ) { // Tags if ( ! empty( $attr['tags'] ) ) { - $tags = fictioneer_explode_list( $attr['tags'] ); + $taxonomies['tags'] = fictioneer_explode_list( $attr['tags'] ); } // Categories if ( ! empty( $attr['categories'] ) ) { - $categories = fictioneer_explode_list( $attr['categories'] ); + $taxonomies['categories'] = fictioneer_explode_list( $attr['categories'] ); + } + + // Relation + if ( ! empty( $attr['rel'] ) ) { + $rel = strtolower( $attr['rel'] ) == 'or' ? 'OR' : $rel; } // Extra classes @@ -532,8 +536,8 @@ function fictioneer_shortcode_latest_posts( $attr ) { 'count' => $count, 'author' => $author, 'post_ids' => $post_ids, - 'tags' => $tags, - 'categories' => $categories, + 'taxonomies' => $taxonomies, + 'relation' => $rel, 'classes' => $classes ) ); diff --git a/partials/_latest-posts.php b/partials/_latest-posts.php index bf3ca97a..fd14319d 100644 --- a/partials/_latest-posts.php +++ b/partials/_latest-posts.php @@ -11,9 +11,8 @@ * @internal $args['author'] The author provided by the shortcode. Default false. * @internal $args['count'] The number of posts provided by the shortcode. Default 1. * @internal $args['post_ids'] Array of post IDs. Default empty. - * @internal $args['tags'] Array tag names. Default empty. - * @internal $args['categories'] Array of category names. Default empty. - * @internal $args['class'] Additional classes. Default empty. + * @internal $args['taxonomies'] Array of taxonomy arrays. Default empty. + * @internal $args['classes'] Array of additional CSS classes. Default empty. */ ?> @@ -33,37 +32,37 @@ $query_args = array( 'no_found_rows' => true ); +// Parameter for author? +if ( isset( $args['author'] ) && $args['author'] ) $query_args['author_name'] = $args['author']; + // Taxonomies? -if ( ! empty( $args['tags'] ) || ! empty( $args['categories'] ) ) { +if ( ! empty( $args['taxonomies'] ) ) { $query_args['tax_query'] = []; // Relationship? - if ( ! empty( $args['tags'] ) && ! empty( $args['categories'] ) ) { - $query_args['tax_query']['relation'] = 'OR'; + if ( count( $args['taxonomies'] ) > 1 ) { + $query_args['tax_query']['relation'] = $args['relation']; + } + + // Tags? + if ( ! empty( $args['taxonomies']['tags'] ) ) { + $query_args['tax_query'][] = array( + 'taxonomy' => 'post_tag', + 'field' => 'name', + 'terms' => $args['taxonomies']['tags'] + ); + } + + // Categories? + if ( ! empty( $args['taxonomies']['categories'] ) ) { + $query_args['tax_query'][] = array( + 'taxonomy' => 'category', + 'field' => 'name', + 'terms' => $args['taxonomies']['categories'] + ); } } -// Tags? -if ( ! empty( $args['tags'] ) ) { - $query_args['tax_query'][] = array( - 'taxonomy' => 'post_tag', - 'field' => 'name', - 'terms' => $args['tags'], - ); -} - -// Categories? -if ( ! empty( $args['categories'] ) ) { - $query_args['tax_query'][] = array( - 'taxonomy' => 'category', - 'field' => 'name', - 'terms' => $args['categories'], - ); -} - -// Parameter for author? -if ( isset( $args['author'] ) && $args['author'] ) $query_args['author_name'] = $args['author']; - // Apply filters $query_args = apply_filters( 'fictioneer_filter_latest_posts_query_args', $query_args, $args );