0

I would like to add an html element right before the title of the blog posts. The code I'm using is as follows:

function add_html_above_title($title, $post_id) {
    if (is_single() && $post_id === get_the_ID()) {
        $html = '<div class="custom-html">Custom HTML content above the title</div>';
        // Return the HTML element followed by the original title
        return $html . $title;
    }
    return $title;
}

add_filter('the_title', 'add_html_above_title', 10, 2);

However, the problem with this code is that it also alters the titles used in other parts of the blog post template, like the title of the post used in the breadcrumb. How can I target only the main post title and not the other ones? Can't I for example first check if the title I'm going to modify is inside a specific css class and only then modify it?

Update: The output of debug_backtrace() ran on functions.php in the child theme:

enter image description here

4
  • Where are you inputting this code? If you're doing it in a child theme or a custom theme, then you should have the ability to just edit the actual output template and not have to worry about fiddling with a filter. Commented May 13 at 17:49
  • @TonyDjukic I'm doing this inside the functions.php file of the child theme. How can I edit the output template? I can't figure out which template is powering the single post page as the main theme is too big and files are scattered all over the place.
    – s.sufi
    Commented May 14 at 5:13
  • 1
    @TonyDjukic I found the template and successfully edited it. Thanks.
    – s.sufi
    Commented May 14 at 8:08
  • Fantastic. :-) Glad I was able to help. Commented May 14 at 22:48

1 Answer 1

1

There are several ways to achieve this, none of them elegant. That's because there is no general way to know exactly where get_the_title was called.

(1) Not completely foolproof, but possibly enough in your scenario would be to add is_main_query to your conditions. That would rule out titles generated in secondary loops. However, if the breadcrumb is generated inside the loop, this would obviously not work.

(2) You could use debug_backtrace to find which template file called get_the_title and add this being single.php as a condition. Assuming the theme uses such a template. Also assuming there is no secondary loop in this template.

(3) You could skip the filter on the server side and convert your code to a piece of javascript that detects the presence of a certain class and insert the html on the user end.

3
  • The first option didn't work out. Apparently, the title displayed in the breadcrumb is also using the main loop. The content I want to put above the title is dynamic and it should be read from a custom field (created with ACF) so I think the 3rd option is not applicable either. Now I'm in search of the template that generates this main title but there are many template parts in the parent theme and I can't figure out which one is responsible for outputing the title. I used debug_backtrace (inside functions.php file of the child theme) but the output wasn't helpful. I'll add it to question.
    – s.sufi
    Commented May 14 at 6:00
  • If you have a child theme anyway, the best way is to find that template and duplicate it in your child theme, adding the dynamic html. The third option is still applicable if you generate the javascript dynamically and add it inline in the header
    – cjbj
    Commented May 14 at 7:56
  • Yeah I finally found the template and added the code. There were multiple content-style#.php files that one of them was getting selected supposedly based on a configuration setting. I copied all these files into my child theme as you said and added the code to all of them. Problem solved. Thanks.
    – s.sufi
    Commented May 14 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.