Support » Developing with WordPress » How do I add my class the earliest possible?

  • Hi there,

    I am using the following code to add my class “noTypo”:

    function prefix_register_block( $blocks ) {
        
        // 'my_block' corresponds to the block slug.
        $blocks['wpgb_custom_title'] = [
            'name' => __( 'WPGB Custom Title', 'text-domain' ),
            'render_callback' => 'prefix_my_block_render',
        ];
    
        return $blocks;
        
    }
    
    add_filter( 'wp_grid_builder/blocks', 'prefix_register_block', 10, 1 );
    
    // The render callback function allows to output content in cards.
    function prefix_my_block_render() {
    
        // Get current post, term, or user object.
        $post = wpgb_get_post();
    
        // Output the post title.
        echo '<span class="noTypo">' . esc_html( $post->post_title ) . '</span>';
    
    }

    But it seems that this code above is adding the class later than this code:

    function add_notypo_to_title( $title ) {
     
        return "<span class='noTypo'>$title</span>";
    }
    
    if (! is_admin() ) {
        add_filter( 'the_title', 'add_notypo_to_title', 10, 1 );
    }

    Both codes add the class successfully, yet the plugin that should use the class for dewidowing – wpTypography -, does not see the class if it’s added with the first code, but it does see the class when it’s added with the second code.

    The conclusion is that the class is not available for the plugin at the time it’s processing my content:

    add_filter('wp_grid_builder/the_content', [ 'WP_Typography', 'process' ] );

    My question is how do I modify the first code so that the class will be added at the earliest possible time, so that at the time wpTypography is processing the content, it would already be available?

    The wpTypography plugin does not inspect the final HTML, but it looks for the class at a much earlier stage.

    It seems that when I am hooking into the_title in a global function, the class is added earlier.

    Is there a way to make my first function global?
    Would that make it add the class earlier?

    It makes sense that native WP code like the_title runs earlier than plugin code.

    I tried to add “global $post;” into my function, but it will not make the class to be added earlier.

    Can I troubleshoot this with Query Monitor to see when are these functions running? And how do I do that?

    Does anyone have any other ideas?

    According to the wpTypography developer:

    what matters is whether the string ultimately passed to WP_Typography::process as its first parameter contains the element with the class

    How do I verify if the string passed is the first parameter of the process?

    Thanks in advance.

    • This topic was modified 3 months, 1 week ago by berry metal.
    • This topic was modified 3 months, 1 week ago by berry metal.
    • This topic was modified 3 months, 1 week ago by berry metal.
Viewing 9 replies - 1 through 9 (of 9 total)
  • Moderator bcworkz

    (@bcworkz)

    Registering a block needs to be done at a specific time using a specific hook. You can manage which callback for a particular hook runs earlier than others with the $priority argument. 10 is commonly used and is the default value. Use a smaller number to execute earlier. Use a larger number to override something done earlier.

    However, you may declare a class much earlier. It could be declared directly in the plugin’s primary code without using any hook. That’s about as early as it can get. You may declare, but instantiating an object from it might be more particular about when it can happen. It depends on what the class constructor does and what resources are needed.

    Thread Starter berry metal

    (@erikalleman)

    add_filter( 'wp_grid_builder/blocks', 'prefix_register_block', 1, 1 );
    
    // The render callback function allows to output content in cards.
    function prefix_my_block_render() {
    
        // Get current post, term, or user object.
        $post = wpgb_get_post();
    
        // Output the post title.
        echo '<h3><span class="noTypo">' . esc_html( $post->post_title ) . '</span></h3>';
    
    }

    Hi, after reading your reply I increased the priority to 1 to execute it earliest possibe, but even though the class is still added, wpTypography still doesn’t see the class, because the title is not dewidowed.

    So it’s still not added early enough.
    How do I troubleshoot this further?
    Thanks!

    • This reply was modified 3 months, 1 week ago by berry metal.
    Moderator bcworkz

    (@bcworkz)

    Thinking about this some more, I don’t think any dynamic block rendered content will be picked up by wpTypography, even when declared as early as possible in ‘wp_grid_builder/blocks’ filter. I suspect wpTypogaphy has no idea what grid_builder is doing. For wpTypography to “see” a class, it’d need to exist in a more conventional WP filter like “the_title” or “the_content”. It cannot be expected to be aware of custom filters introduced by other plugins.

    By the time grid_builder renders content, it’s too late for wpTypography no matter when a class is added within grid_builder. I don’t know wpTypography at all, but I assume it hooks into conventional filters like “the_content” to do its thing. You may need to hook whatever wpTypography callback is added to “the_content” into a wp_grid_builder hook in a similar manner to have any hope of this working.

    For example:
    add_filter( 'wp_grid_builder/blocks', ['WP_Typography', 'process'], 9999 );
    This is unlikely to work as-is, it’s just to illustrate how wpTypography might be looped into a grid_builder process.

    Thread Starter berry metal

    (@erikalleman)

    Thanks for the suggestion.
    It does not work, it breaks the layout and removes content no matter what priority I use for it.

    So instead of adding the dewidowing class only to my grid block, I could use my previous code and add it to all titles again, and then try to remove the class from my breadcrumbs or from my template that contains my breadcrumbs, after it was added, and then I would achieve the same: it would only be added to my grid blocks in the end.

    But if it’s not possible to add the class before wp-Typography is looking for it, then I guess it’s not possible to remove it either before it’s looking for it, is that right?

    And because plugin code runs before theme code runs, theme code cannot remove it either early enough, or?

    So I thought I would add a conditional instead to exclude my sticky top bar template (that is a template within my post template) since I am not sure how to target only my breadcrumbs – the title in the breadcrumbs should not be dewidowed:

    add_filter( 'the_title', 'add_notypo_to_title', 10, 1, function add_notypo_to_title( $title ) {
            if (!is_singular()) {
                    $template = 8127;
                    return "<span class='noTypo'>$title</span>";
            }
    } );

    I have seen this structure in some of my theme code – function within a filter hook (it was actually an action hook), but I hope it works with filter hooks too.

    The problem is I am not sure that the priority and the args syntax is correct in my code above – could you advise?

    I want this code to add the dewidowing class to all titles except the title in my breadcrumbs, which is in my top bar template, hence I defined the ID of my template – but is this the correct way to exclude my template?

    This is my working theme code that I got inspired from for my code structure:

    add_action( 'mythemeprefix_hook_header_inner', function() {
            if (is_singular()) {
                    $template = 7027; // Change this to the templatera post ID you want to grab content from
                    echo do_shortcode( '[templatera id="' . $template . '"]' );
            }
    } );

    And the result is critical error, but it’s probably because of a syntax error.

    I tried to move the parameters to the end:

    add_filter( 'the_title', 'add_notypo_to_title', function add_notypo_to_title( $title ) {
            if (!is_singular()) {
                    $template = 8127;
                    return "<span class='noTypo'>$title</span>";
            }
    } 10, 1 );

    But this also results in a criticall error.
    What am I doing wrong?

    • This reply was modified 3 months, 1 week ago by berry metal.
    Thread Starter berry metal

    (@erikalleman)

    This is how my theme code looks that would target the title within my breadcrumbs, not sure if early enough:

    // Remove page title from breadcrumbs
    function my_remove_title_from_breadcrumbs( $trail ) {
    
        // Remove title (trail_end) for single posts
        if ( is_singular() ) {
            unset( $trail['trail_end'] );
        }
    
        // Return trail
        return $trail;
    
    }
    add_filter( 'mythemeprefix_breadcrumbs_trail', 'my_remove_title_from_breadcrumbs', 20 );
    Thread Starter berry metal

    (@erikalleman)

    The goal is to only apply devidowing to my specific grid titles, but that turned out impossible since the grid is adding the class too late.
    So the goal is instead to add the dewidowing class globally with a conditional that excludes the title in my breadcrumbs title, because that would result the same:
    – only my grid titles need to be dewidowed
    – not the title in my breadcrumbs

    These titles are both present on the same “page” in every post.

    Thread Starter berry metal

    (@erikalleman)

    These 2 titles are also the same post type.
    My grid is my related posts grid.

    Meanwhile, I will ask the theme developer to see if he knows a way to target only my related posts titles, early enough – but the problem is that they also have the same “related” meta field as my breadcrumbs title, because my breadcrumbs title is my current post title, and my current post is also a related post for other posts – so probably there is no way to differentiate between the 2 using the “related” meta value.

    Thread Starter berry metal

    (@erikalleman)

    There’s no point to target the grid it seems, because it adds the class too late.

    • This reply was modified 3 months, 1 week ago by berry metal.
    Moderator bcworkz

    (@bcworkz)

    It can be very difficult to get two different plugins or a theme to play well together, even for many full stack developers. Especially given the need to accommodate periodic updates. For us mere mortals, I agree there’s no point due to when these events take place. You’d need to implement your own functionality to do one or the other in time for the other instead of relying on existing solutions.

    To answer a few of your questions, just for future reference: To determine proper priority, try to determine the one used by the process you’re trying to modify. Then your priority should be either larger or smaller. Try both 🙂

    You can use filter hooks like action hooks, but if you want to alter something passed to an action hook like you would a filter, you probably cannot. The exception being if the action is passed an object by reference. Then you can use its methods to alter object properties. The most common example being the “pre_get_posts” action where you can alter the query object this way.

Viewing 9 replies - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.