From 8ec07925571e3d7f651bad3f4a6b6975aec0833d Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Fri, 23 Jan 2015 15:40:31 +0000 Subject: [PATCH] Add classes for custom taxonomy terms in `get_post_class()`. Props sillybean. Fixes #16223. git-svn-id: https://develop.svn.wordpress.org/trunk@31271 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/post-template.php | 42 +++++++------- tests/phpunit/tests/post/getPostClass.php | 67 +++++++++++++++++++++++ 2 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 tests/phpunit/tests/post/getPostClass.php diff --git a/src/wp-includes/post-template.php b/src/wp-includes/post-template.php index d6dfa322a3..d5a4009770 100644 --- a/src/wp-includes/post-template.php +++ b/src/wp-includes/post-template.php @@ -389,14 +389,15 @@ function post_class( $class = '', $post_id = null ) { * * The class names are many. If the post is a sticky, then the 'sticky' * class name. The class 'hentry' is always added to each post. If the post has a - * post thumbnail, 'has-post-thumbnail' is added as a class. For each - * category, the class will be added with 'category-' with category slug is - * added. The tags are the same way as the categories with 'tag-' before the tag - * slug. All classes are passed through the filter, 'post_class' with the list - * of classes, followed by $class parameter value, with the post ID as the last - * parameter. + * post thumbnail, 'has-post-thumbnail' is added as a class. For each taxonomy that + * the post belongs to, a class will be added of the format '{$taxonomy}-{$slug}' - + * eg 'category-foo' or 'my_custom_taxonomy-bar'. The 'post_tag' taxonomy is a special + * case; the class has the 'tag-' prefix instead of 'post_tag-'. All classes are + * passed through the filter, 'post_class' with the list of classes, followed by + * $class parameter value, with the post ID as the last parameter. * * @since 2.7.0 + * @since 4.2.0 Custom taxonomy classes were added. * * @param string|array $class One or more classes to add to the class list. * @param int|WP_Post $post_id Optional. Post ID or post object. @@ -446,21 +447,22 @@ function get_post_class( $class = '', $post_id = null ) { // hentry for hAtom compliance $classes[] = 'hentry'; - // Categories - if ( is_object_in_taxonomy( $post->post_type, 'category' ) ) { - foreach ( (array) get_the_category($post->ID) as $cat ) { - if ( empty($cat->slug ) ) - continue; - $classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->term_id); - } - } + // All public taxonomies + $taxonomies = get_taxonomies( array( 'public' => true ) ); + foreach ( (array) $taxonomies as $taxonomy ) { + if ( is_object_in_taxonomy( $post->post_type, $taxonomy ) ) { + foreach ( (array) get_the_terms( $post->ID, $taxonomy ) as $term ) { + if ( empty( $term->slug ) ) { + continue; + } - // Tags - if ( is_object_in_taxonomy( $post->post_type, 'post_tag' ) ) { - foreach ( (array) get_the_tags($post->ID) as $tag ) { - if ( empty($tag->slug ) ) - continue; - $classes[] = 'tag-' . sanitize_html_class($tag->slug, $tag->term_id); + // 'post_tag' uses the 'tag' prefix for backward compatibility. + if ( 'post_tag' == $taxonomy ) { + $classes[] = 'tag-' . sanitize_html_class( $term->slug, $term->term_id ); + } else { + $classes[] = sanitize_html_class( $taxonomy . '-' . $term->slug, $taxonomy . '-' . $term->term_id ); + } + } } } diff --git a/tests/phpunit/tests/post/getPostClass.php b/tests/phpunit/tests/post/getPostClass.php new file mode 100644 index 0000000000..b7392fd3c2 --- /dev/null +++ b/tests/phpunit/tests/post/getPostClass.php @@ -0,0 +1,67 @@ +post_id = $this->factory->post->create(); + } + + public function test_with_tags() { + wp_set_post_terms( $this->post_id, array( 'foo', 'bar' ), 'post_tag' ); + + $found = get_post_class( '', $this->post_id ); + + $this->assertContains( 'tag-foo', $found ); + $this->assertContains( 'tag-bar', $found ); + } + + public function test_with_categories() { + $cats = $this->factory->category->create_many( 2 ); + wp_set_post_terms( $this->post_id, $cats, 'category' ); + + $cat0 = get_term( $cats[0], 'category' ); + $cat1 = get_term( $cats[1], 'category' ); + + $found = get_post_class( '', $this->post_id ); + + $this->assertContains( 'category-' . $cat0->slug, $found ); + $this->assertContains( 'category-' . $cat1->slug, $found ); + } + + public function test_with_custom_taxonomy() { + register_taxonomy( 'wptests_tax', 'post' ); + wp_set_post_terms( $this->post_id, array( 'foo', 'bar' ), 'wptests_tax' ); + + $found = get_post_class( '', $this->post_id ); + + $this->assertContains( 'wptests_tax-foo', $found ); + $this->assertContains( 'wptests_tax-bar', $found ); + } + + /** + * @group cache + */ + public function test_taxonomy_classes_hit_cache() { + global $wpdb; + + register_taxonomy( 'wptests_tax', 'post' ); + wp_set_post_terms( $this->post_id, array( 'foo', 'bar' ), 'wptests_tax' ); + wp_set_post_terms( $this->post_id, array( 'footag', 'bartag' ), 'post_tag' ); + + // Prime cache, including meta cache, which is used by get_post_class(). + update_object_term_cache( $this->post_id, 'post' ); + update_meta_cache( 'post', $this->post_id ); + + $num_queries = $wpdb->num_queries; + + $found = get_post_class( '', $this->post_id ); + + $this->assertSame( $num_queries, $wpdb->num_queries ); + } +}