• Resolved Guido

    (@guido07111975)


    Hi,

    How do I use do_action() inside a posts loop (query)?

    
    function my_custom_text() {
        echo 'Some custom text';
    }
    add_action( 'custom_posts_content', 'my_custom_text' );
    

    Currently my posts query is build with so called concatenation assignment:

    
    $output .= '<div class="my-class">';
    $output .= esc_attr__( 'Some text.', 'my-text-domain' );
    $output .= '</div>';
    return $output;
    

    When adding the do_action(), “Some custom text” is echoed multiple times before the other content, instead of inside every post.

    
    $output .= do_action( 'custom_posts_content' );
    

    When changing the echo to return in the function, nothing happens.

    What am I missing here?

    Guido

Viewing 8 replies - 1 through 8 (of 8 total)
  • Hello,
    do_action has no return. It calls the callback functions. You are echoing when building $output.

    Use add_filter and then apply_filters.

    Thread Starter Guido

    (@guido07111975)

    Hi,

    Great, that’s it. Thanks!

    
    function my_custom_text() {
    	return 'Some custom text';
    }
    add_filter( 'custom_posts_content', 'my_custom_text' );
    
    

    And output it:

    
    if ( has_filter( 'custom_posts_content' ) ) {
    	$output .= apply_filters( 'custom_posts_content', 'my_custom_text' );
    }
    

    Guido

    Thread Starter Guido

    (@guido07111975)

    Still have a question:

    How do I output ALL attached functions, when I don’t know the names of these functions?

    Simply doing this doesn’t work, because I need to add at least 1 value (function name):

    
    $output .= apply_filters( 'custom_posts_content' );
    

    Guido

    Thread Starter Guido

    (@guido07111975)

    Hi again,

    I’m wondering whether using the filter hook is the right way to just adding some custom content, or not.

    I can also use output buffering:

    Functions file of plugin:

    
    function my_custom_hook() {
    	ob_start();
    	do_action( 'custom_posts_content' );
    	$content = ob_get_clean();
    	return $content;
    }
    

    A custom function:

    
    function my_custom_text() {
        echo 'Some custom text';
    }
    add_action( 'custom_posts_content', 'my_custom_text' );
    

    And adding it to my template file:

    
    $output .= my_custom_hook();
    

    How about this?

    Guido

    Moderator bcworkz

    (@bcworkz)

    Hey Guido!

    How do I output ALL attached functions, when I don’t know the names of these functions?

    Functions attached/added to ‘custom_posts_content’? Output what? The output or return from the functions? The function names themselves?

    For output or return, you don’t need the names, they’re all called. But FWIW the names are stored in the global $wp_filter array. Action callbacks are saved there as well.

    The main reason to do actions or apply filters is to allow other devs to piggy back on to whatever your code is doing. IMO, using hooks solely to call your own function is a little silly, why not just call the function directly? OTOH, I always appreciate plentiful hooks in plugins by others.

    Whether to use an action or filter is up to you. Action hooks denote a point in code execution. Callbacks can do whatever at that point, but are unable to alter any data that you are using. Filters let callbacks alter passed data. If you see the need to use output buffering, it’s a sign that filter hooks would be more applicable than action hooks. If someone adds a callback that echoes out within a filter callback, it’d be their responsibility to capture the buffered output for return. Or rewrite the callback to assign output to a return value instead of echoing out.

    It would normally be assumed any output within an action callback would occur immediately when the action fires. If you need to buffer that to defer output, and a filter is inappropriate for some reason, it’s an indication you are calling do_action() from the wrong place.

    Thread Starter Guido

    (@guido07111975)

    Hi BC,

    Thanks for replying!

    I want to add this to a plugin, so users can add custom content if they want, without changing plugin file itself. Many themes and plugins use them, but I did not fully understand how they work, and having problems with the output of the content. That’s why I started this thread.

    Guess my latest reply is the best way? Please note that I return and not echo my plugin content.

    Guido

    Moderator bcworkz

    (@bcworkz)

    Adding content via hook requires the user to have some basic PHP coding skills. Depending on who your target end users are, it may or may not be “best”. If you’re providing a hook for others, what their callback may look like is irrelevant. They’ll need to conform to how you applied or did the hook. If you choose to use an action hook, assume others will echo out content when the action fires. If you need to capture their added content for further manipulation, then a filter hook is in order.

    You do need to pass at least two values to an apply_filters() call. The second can be an empty string or null if that’s appropriate. You may also wish to pass additional args that may provide context or additional data that the callback may find useful. Where post content is involved, you could pass the current content so others can add where they like or alter existing. Similar to “the_content” WP filter. If you require additional content to occur in a specific spot, pass an empty string, then do with the returned filter value as you wish. For example:
    $output .= apply_filters( 'custom_posts_content', '' );

    FYI, there is a third way to allow users to alter data via hook, by using the ref_array variants. Here you can pass data by reference so users can directly manipulate the data in memory instead of needing to return it for assignment. The “pre_get_posts” WP action is probably the best example of this. The entire $wp_query object is passed by reference (by using the & modifier on $this) so users can directly modify query vars and other object properties as they wish. Probably not applicable in your case here, but maybe something to keep in mind for the future.

    Thread Starter Guido

    (@guido07111975)

    Hi BC,

    Adding content via hook requires the user to have some basic PHP coding skills. Depending on who your target end users are, it may or may not be “best”.

    You’re probably right. Most users aren’t developers. I was thinking about users adding their custom content via the Code Snippets plugin, but most users don’t have the knowledge to use this.

    Where post content is involved, you could pass the current content so others can add where they like or alter existing

    Yes, and I already use this to add custom content to the post content section.

    Food for thought.. Thanks!

    Guido

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Using do_action() in loop’ is closed to new replies.