I have a plugin that will automatically load articles from a news publisher by checking query vars in the URL.

If an article was requested, it does an AJAX call to this publisher, creates a new WP_Post and loads it in a template.

I need to add open graph meta tags to this page, and I'm at a loss.

My first failed attempt was a generic:

add_action( 'wp_head', 'insert_fb_in_head', 5 );

from the functions.php of the theme, that I would have expected to take the info from my built post, but it turns out that global $post returned NULL in this particular case.

So I'm guessing that my $post gets built later.

Adding the og meta within the body will not get them picked up by Facebook, I checked.

Grasping at straws, I tried calling that hook from within the function that builds the post, but that wasn't even triggered.

Where does one modify the head in this case? I'm sure you will need more code, but I'm not quite sure what code to provide. I'll update this post to accomodate to comments.

Update: some code background

  1. I have several public hooks in the plugin.

    private function define_public_hooks() {
        $plugin_public = new MyPlugin_Public( $this->get_plugin_name(), $this->get_version(), $this->get_public_name(), $this->get_endpoint_domain() );
        $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
        $this->loader->add_filter( 'query_vars', $plugin_public, 'mp_virtualpage_query_vars' );  
        $this->loader->add_action('loop_start', $plugin_public, 'mp_display_post');
        //and then some more
  2. The display_post function:

    public function mp_display_post($query) {
        global $wp_query;
        if (isset($query->query['virtualpage'])) {
            $mp_post = $this->mp_query_post($query->query['nda_id'],  false, true);
            // replace the query with it
            $query->posts = array();
            $query->posts[0] = $nd_post;
            $query->post_count  = 1;
  3. Outline of the post query:

    public function mp_query_post($nda_id, $redirect = false, $adapt_url = false) 
            global $post; 
        $chars = array("/", "-", ":", ".");
        $endpoint = $this->endpoint_domain . 'articles/'. $nda_id;
        $response =  wp_remote_get($endpoint, $args);               
        $response_body = json_decode(wp_remote_retrieve_body($response));
        $response_code = wp_remote_retrieve_response_code( $response );
        if ($response_code == 200) {
            $article = $response_body->article;
            // create the post and fill up the fields
            $new_post = new WP_Post((object)array(
                //'ID' => $article->id,
                'post_title'   => $article->title,
                'post_content' => $article->body,
                //so on and so forth with all properties
        } else {
            $new_post = new WP_Post((object) array(
                'post_title' => "Oops! We could not find this article",
        return $new_post;
  • So your page is being loaded into the browser in JS? But opengraph tags are only relevant to social media sites which will ping the page directly, as long as they appear correctly on first load it shouldn't matter? Additionally can you not modify the opengraph tags directly in JS? – Tom J Nowell Jul 13 '18 at 16:04
  • The page is loaded into the plugin using the AJAX api, and then rendered as a normal post, using PHP. Modifying them via JS would not happen before first load, so it's not an option. – Victoria Ruiz Jul 13 '18 at 16:11
  • HOLY MOLY you're scraping another website then presenting the entire HTML page as if you'd generated it yourself?! Why would you want to do such a thing?! Surely there's a better way of solving the original problem. No wonder your approaches so far haven't worked, to use WP filters to modify that output you'd need them to run on the remote server, not the current server. – Tom J Nowell Jul 13 '18 at 16:37
  • I'm not scraping another website, I'm using someone's API and building a plugin for it. I don't see a difference between pulling info from an API and pulling fields from a database... – Victoria Ruiz Jul 13 '18 at 16:44
  • So is that part relevant to the question? AKA Can we ignore that entire part and focus on just how to include a static opengraph tag in the header? Then a follow up question can customise it? Or have I misunderstood? From what I see, you can't show opengraph data based on what the API request returns because that request doesn't happen until the start of the loop, and you need the OG data in the header – Tom J Nowell Jul 13 '18 at 17:26

It took me a while of tinkering with the hooks, but in the end, I fixed it by loading the post earlier. Instead of loop_start:

$this->loader->add_action('loop_start', $plugin_public, 'mp_display_post');

I used get_header:

$this->loader->add_action('get_header', $plugin_public, 'mp_display_post');

This worked properly because now the post information is loaded before wp_head gets called, and therefore I can use the loaded post's data for the open graph tags, the regular way:

add_action( 'wp_head', 'insert_og_in_head', 5 );
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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