WordPress.org

Ready to get started?Download WordPress

Forums

output of post classes using apply_filters (10 posts)

  1. bibbli
    Member
    Posted 4 months ago #

    I added this to my functions.php to show custom taxonomies as post classes:

    add_filter( 'post_class', 'custom_taxonomy_post_class', 10, 3 );
    
        if ( ! function_exists('custom_taxonomy_post_class') ) {
        function custom_taxonomy_post_class($classes, $class, $ID) {
    
            $taxonomies_args = array(
                'public' => true,
                '_builtin' => false,
            );
    
            $taxonomies = get_taxonomies( $taxonomies_args, 'names', 'and' );
    
            $terms = get_the_terms( (int) $ID, (array) $taxonomies );
    
            if ( ! empty( $terms ) ) {
                foreach ( (array) $terms as $order => $term ) {
                    if ( ! in_array( $term->slug, $classes ) ) {
                        $classes[] = $term->slug;
                    }
                }
            }
    
            $classes[] = 'clearfix';
    
            return $classes;
        }
        }

    I'm trying to output the resulting post classes using 'post_class' but I only get array=" " in the output. Any help would be appreciated.

    function start_el(&$output, $page, $depth = 0, $args = array(), $id = 0) {
                if ( $depth )
                    $indent = str_repeat("\t", $depth);
                else
                    $indent = '';
    
                extract($args, EXTR_SKIP);
    
                $output .= $indent . '<li id="item_'.$page->ID.'" '.apply_filters( 'post_class', $page->post_class ).'><span>'.apply_filters( 'the_title', $page->post_title, $page->ID ).'</span>';
            }
  2. bcworkz
    Member
    Posted 4 months ago #

    I tried your script on my site and it works as expected. I have to believe your theme or one of your plugins is creating a conflict that prevents your script from working.

    FWIW, though the script works as expected, get_the_terms() throws a bunch of warnings (array to string conversion) when taxonomies are supplied as an array. To run completely clean, you'd have to call it for one taxonomy at a time, supplying a simple string argument for each taxonomy in turn.

  3. bibbli
    Member
    Posted 4 months ago #

    Hi, thanks so much for your generous response. I think I wasn't perfectly clear...the first script works fine, only showing that to add context (sorry).

    The 2nd script is a portion of a plugin that I'm hoping to resolve to separately output the post classes that the first script is already making.

    I should mention that I'm fairly new to this level so appreciate anything I can learn as I go.

    Thanks a ton. :)

  4. bibbli
    Member
    Posted 4 months ago #

    Do I need a function to hook into the classes the above script makes?

  5. bcworkz
    Member
    Posted 4 months ago #

    Sorry for the late reply, I've been away.

    The 2nd function you posted appears to be from a walker class method, which applies the 'post_class' filter, so it is inappropriate to use to output new post classes without modification. You cannot apply the same filter you hook, it causes infinite regression.

    You can add any class attributes you like by using the 'post_class' filter, hooking in your own function just as is done in your first example. (you don't need the function_exists part unless you expect other users to override your function)

    Your callback function is passed an array of class attributes that will be output. You can add (or remove) whatever class attributes you desire before returning the modified array.

    $classes[] = 'clearfix'; is the basic way to add elements to an array. You can assign a specific string like 'clearfix' or the value of any variable or the returned value of any function, or any combination of those.

    If you're still having trouble, post the code you are actually using and someone should be able to set your straight.

  6. bibbli
    Member
    Posted 4 months ago #

    Thanks...below is the unaltered script excerpt. I would definitely like to return the value of that function because the post classes will vary.

    function start_el(&$output, $page, $depth = 0, $args = array(), $id = 0) {
          if ( $depth )
            $indent = str_repeat("\t", $depth);
          else
            $indent = '';
          extract($args, EXTR_SKIP);
          $output .= $indent . '<li id="item_'.$page->ID.'"><span>'.apply_filters( 'the_title', $page->post_title, $page->ID ).'</span>';
        }
  7. bibbli
    Member
    Posted 4 months ago #

    I'm hell bent to solve this...I'm terrible at this (b/c I'm a noob) but I'm enjoying it too much.

    Really looking fw to learning how I can use the returned value of the first function by placing properly in the plugin script below, plus the proper syntax to output the classes. The first script successfully assigns various classes to posts, so the mission is to output those right after .$page->ID. at the bottom of this one:

    class Post_Types_Walker extends Walker
          {
            var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
            function start_lvl(&$output, $depth = 0, $args = array()) {
              $indent = str_repeat("\t", $depth);
              $output .= "\n$indent<ul class='children'>\n";
            }
            function end_lvl(&$output, $depth = 0, $args = array()) {
              $indent = str_repeat("\t", $depth);
              $output .= "$indent</ul>\n";
            }
            function start_el(&$output, $page, $depth = 0, $args = array(), $id = 0) {
              if ( $depth )
                $indent = str_repeat("\t", $depth);
              else
                $indent = '';
              extract($args, EXTR_SKIP);
              $output .= $indent . '<li id="item_'.$page->ID.'"><span>'.apply_filters( 'the_title', $page->post_title, $page->ID ).'</span>';
            }
            function end_el(&$output, $page, $depth = 0, $args = array()) {
              $output .= "</li>\n";
            }
          }
  8. bcworkz
    Member
    Posted 4 months ago #

    Ah, I think I finally understand where you're going with this, sorry for my confusion.

    Actually, the return value of the 'post_class' callback custom_taxonomy_post_class() is not appropriate for direct concatenation to $output because it returns an array of class strings while start_el() of the walker class requires a single string, not an array. Fortunately, converting an array to a single string is simple with join().

    If you want all of the post classes listed, not just the taxonomies, you could do this (the title part is omitted, add it back if need be):
    $output .= $indent . '<li id="item_'.$page->ID.'"><span>'.join( " ", get_post_class( "", $page->ID )).'</span>';

    If you just want the taxonomy classes as returned by the filter callback, without the other classes added by other portions of the code, replace the call to get_post_class() with custom_taxonomy_post_class(array(), "", $page->ID) (still as a parameter for the join() function )

    That will cover basic functionality, but there are improvements that would be a good idea to implement, depending on if this plugin is authored by you or is authored by others and will occasionally be updated, among other variables.

    If you call custom_taxonomy_post_class() directly from a plugin, there is a potential issue because the function might not be available since it is part of a theme. If the plugin is yours, it's best to move the declaration to the plugin. If not, you need to do the if ( ! function_exists()) logic to avoid errors if the theme is switched. In your case using ternary operators would be slightly tidier than the if ( ! function_exists()) syntax. The entire join() function could be replaced with this:
    !function_exists('custom_taxonomy_post_class')?join(" ", custom_taxonomy_post_class(array(), "", $page->ID)):''

    If this plugin is subject to updates, you shouldn't really be altering it at all. Instead create your own site specific plugin that extends the Post_Types_Walker class and overrides the start_el() function with your variation.

    Your site will work without these improvements, but the improvements make your installation more robust, you will not lose modifications when plugins are updated and your site will not crash if the theme is switched.

    I'm glad you are enjoying this. It gets even better once you develop an adequate knowledge base. Then you have the ability to have your site do practically anything you desire, which is very empowering!

  9. bibbli
    Member
    Posted 4 months ago #

    The join() method worked beautifully! Thanks so much! What a thrill to get that to work. I had it showing classes very quickly...sorry my request wasn't immediately clear.

    $output .= $indent . '<li id="item_'.$page->ID.'" class="'.join( " ", get_post_class( "", $page->ID )).'"><span>'.apply_filters( 'the_title', $page->post_title, $page->ID ).'</span>';

    Thanks also for the caution re: usage/themes, etc...very relevant, I'll save for reference. It may indeed become an issue.

    Thank you again for your thorough, thoughtful help.

  10. bcworkz
    Member
    Posted 4 months ago #

    You're most welcome, I'm glad it ended up being an easy fix.

Reply

You must log in to post.

About this Topic