Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yoast wpseo_opengraph_image filter doesn't run if no default image #1060

Closed
toddlevy opened this issue Apr 29, 2014 · 22 comments
Closed

Yoast wpseo_opengraph_image filter doesn't run if no default image #1060

toddlevy opened this issue Apr 29, 2014 · 22 comments

Comments

@toddlevy
Copy link

WordPress SEO Version 1.5.2.7
Wordpress 3.8.x

Attempting to add an og:image tag via the wpseo_opengraph_image using the following code...

add_filter('wpseo_opengraph_image', function() use($myimage){       
    return $myimage;
});

This is on a page template for a page that has no featured image.

If there is no default image URL on the Facebook tab of the social settings, the filter does NOT run.

If there IS a default image URL, the filter DOES run.

Would like to be able to hook into this filter without having to specify a default image URL.

@jrfnl
Copy link
Contributor

jrfnl commented Apr 29, 2014

Silly question maybe, but sounds like you are using this template for one specific page: why don't you set the image for that page via the SEO metabox on the page itself ? no need for using the filter.

screenshot

@toddlevy
Copy link
Author

Thanks for the reply jrfnl.

The page is really just a "hook" for a plugin that then delivers the appropriate page content based on rewrite rules.

So it's one page, but it's really hundreds of pages and a handful of different templates.

Based on different conditions (mostly templates) I need to show different og:images based on rule-driven paths.

@jrfnl
Copy link
Contributor

jrfnl commented Apr 30, 2014

Well, the filter is meant to filter (=change) a variable, not to add one. It might be an idea to add an action where you can add images yourself, but as this is the only request for something like that that I've come across, I'm hesitant to do so, especially as this can be solved easily in another way.

You can solve your particular issue by calling the WPSEO image output function directly from your own function using code along the lines of the below.

Hope this helps.

function my_own_og_function() {
    /*
     Put the logic to determine which image to display here (set the $my_image_url variable)
    */

    $GLOBALS['wpseo_og']->image_output( $my_image_url ); // This will echo out the og tag in line with other WPSEO og tags
}
add_action( 'wpseo_opengraph', 'my_own_og_function', 29 );

@jrfnl
Copy link
Contributor

jrfnl commented May 8, 2014

Just checking: did my suggestion solve your issue ? If so, let's close it.

@toddlevy
Copy link
Author

toddlevy commented May 8, 2014

Hi, sorry for slow reply. Just tested. Works like a champ. Thank you.

For future reference in case it comes up for anyone else, I did a variation of the code you provided using an anonymous function. In this way $my_image_url can be set outside of the function.

var $my_image_url = 'http:https://www.mydomain.com/image.png';

add_action('wpseo_opengraph', function() use($my_image_url ){       
    $GLOBALS['wpseo_og']->image_output( $my_image_url ); ;
});

@toddlevy toddlevy closed this as completed May 8, 2014
@jrfnl
Copy link
Contributor

jrfnl commented May 8, 2014

Looks good, glad to hear it works. Just as a little sitenote: this does make your theme incompatible with the WP minimum requirements as PHP5.2.x does not support anonymous functions, but I presume you knew that already.

@Twansparant
Copy link

This doesn't seem to work anymore in version 2.1.1.
This code:

function my_own_og_function() {
    $GLOBALS['wpseo_og']->image_output( $my_image_url );
}
add_action( 'wpseo_opengraph', 'my_own_og_function', 29 );

Now outputs the meta property og:image three times like this:

<meta property="og:image" content="http:https://domain.com/media/default.jpg" />
<meta property="og:image" content="http:https://domain.com/media/my-custom-ogimage.jpg" />
<meta property="og:image" content="http:https://domain.com/media/default.jpg" />

Resulting in Facebook displaying the default image instead of the custom one (where default.jpg is the default image set in the social facebook settings of the plugin).

I try to see what changed in the plugin function, but can't seem to find it.
$GLOBALS['wpseo_og'] is still correct and in the plugin's file: frontend/class-opengraph.php on line 43, the og:image is added with priority 30, so 29 should also still be correct:

add_action( 'wpseo_opengraph', array( $this, 'image' ), 30 );

Any ideas anyone?

@Rarst
Copy link
Contributor

Rarst commented May 27, 2015

As far as I follow this thread it's inherently about producing custom output, not changing existing one.

If you want to prevent native output from showing you could probably achieve that by unhooking respective method: remove_action( 'wpseo_opengraph', array( $GLOBALS['wpseo_og'], 'image' ), 30 ); (not tested, just writing out from quick look at the code).

@Twansparant
Copy link

As far as I follow this thread it's inherently about producing custom output, not changing existing one.

Correct, it should change the existing og:image, not add one.
But this worked perfectly before, the action swapped the default image with the custom one and didn't add one...
I tried the remove action, but it doesn't work unfortunately. Same triple output

@Rarst
Copy link
Contributor

Rarst commented May 27, 2015

It might have been due to order of output, not preventing output. It's somewhat puzzling why do you have default twice there, the single native one at priority 30 should be after your custom output at priority 29.

@Twansparant
Copy link

the single native one at priority 30 should be after your custom output at priority 29

But then Facebook will still display the single native one, it should replace the default image entirely when custom output is present?
If I remove the add_action('wpseo_opengraph', 'custom_og_image', 29) it only outputs 1 default og:image.

@Rarst
Copy link
Contributor

Rarst commented May 28, 2015

I am not following what exactly is your desired output. I think between being able to remove plugin's own output and to add your own — from technical point of view you can have sufficient control over it.

If you think code has issues or could be improved in some way please elaborate, beyond that I am afraid is getting into support territory and not in scope of this channel.

@Twansparant
Copy link

Ok thanks.

I used to be able to 'swap' out the og:image with the add_action('wpseo_opengraph', 'custom_og_image', 29) hook, but that doesn't work anymore somehow.

I just switched back to the add_filter('wpseo_opengraph_image', function() use($ogimage){}): hook and that works. Here's my entire code for this:

/*
 *  Replace facebook og:image based upon page type
 *  Only works if default image is set in Social Media > Facebook settings
 */
add_filter('wpseo_opengraph_image', function() use($ogimage){

  global $wp_query;
  $post_id = get_the_ID();

  // Homepage    
  if(is_front_page()) {
    $wp_query = new WP_Query( array(
        'post_type'           => 'project',
        'meta_key'            => 'project_date',
        'meta_query'      => array(
        'key'             => 'project_date',
        'type'            => 'date'
      ),
        'orderby'             => 'meta_value_num',
        'order'                   => 'DESC'
    ));
    $first_project  = $wp_query->posts[0];
    $featured       = get_field('project_feature', $first_project->ID);
    if ($featured == 'image') $projectimage = get_field('project_image', $first_project->ID);
    $ogimage        = $projectimage['sizes']['large'];
    wp_reset_query();

  // Project archive    
  } elseif(is_post_type_archive('project')) {
    // Get client projects
    $clientslug = get_query_var('klant');
    if ($clientslug) {
        $args = array(
          'name'          => $clientslug,
          'post_type' => 'client'
        );
        $clients = get_posts($args);
        if ($clients) {
            $clientid = $clients[0]->ID;
            $wp_query = new WP_Query( array(
                'connected_type'    => 'project-client',
                'connected_items' => $clientid,
                'meta_key'            => 'project_date',
                'meta_query'      => array(
            'key'             => 'project_date',
            'type'            => 'date'
          ),
                'orderby'             => 'meta_value_num',
                'order'                   => 'DESC'
            ));
        }
    } else {
        // Get all projects
        $wp_query = new WP_Query( array(    
            'post_type'         => 'project',
            'meta_key'          => 'project_date',
            'meta_query'    => array(
          'key'           => 'project_date',
          'type'          => 'date'
        ),
            'orderby'           => 'meta_value_num',
            'order'                 => 'DESC'
        ));
    }
    $first_project  = $wp_query->posts[0];
    $featured       = get_field('project_feature', $first_project->ID);
    if ($featured == 'image') $projectimage = get_field('project_image', $first_project->ID);
    $ogimage        = $projectimage['sizes']['large'];
    wp_reset_query();

  // Discipline archive    
  } elseif(is_tax('discipline')) {
    $term       = $wp_query->get_queried_object();
    if (ICL_LANGUAGE_CODE != 'nl') {
        remove_all_filters('get_term');
        $termid_org = icl_object_id($term->term_id, 'discipline', true, 'nl');
        $term               = get_term($termid_org, 'discipline');
    }
    $clientslug = get_query_var('klant');
    // Get client term projects
    if ($clientslug) {
        $args = array(
          'name'          => $clientslug,
          'post_type' => 'client'
        );
        $clients = get_posts($args);
        if ($clients) {
            $clientid = $clients[0]->ID;
            $wp_query = new WP_Query( array(
                'connected_type'    => 'project-client',
                'connected_items' => $clientid,
          'discipline'        => $term->slug,
                'meta_key'            => 'project_date',
                'meta_query'      => array(
            'key'             => 'project_date',
            'type'            => 'date'
          ),
                'orderby'             => 'meta_value_num',
                'order'                   => 'DESC'
            ));
        }
    } else {
        // Get all term projects
        $wp_query = new WP_Query( array(    
            'post_type'         => 'project',
            'discipline'        => $term->slug,
            'meta_key'          => 'project_date',
            'meta_query'    => array(
          'key'           => 'project_date',
          'type'          => 'date'
        ),
            'orderby'           => 'meta_value_num',
            'order'                 => 'DESC'
        ));
    }
    $first_project  = $wp_query->posts[0];
    $featured       = get_field('project_feature', $first_project->ID);
    if ($featured == 'image') $projectimage = get_field('project_image', $first_project->ID);
    $ogimage        = $projectimage['sizes']['large'];
    wp_reset_query();

  // Client archive  
  } elseif(is_post_type_archive('client')) {
    $wp_query = new WP_Query( array(
        'post_type' => 'client',
        'orderby'     => 'name',
        'order'       => 'ASC',
        'nopaging'  => true
    ));
    $first_client = $wp_query->posts[0];
    $clientimage  = get_field('client_image', $first_client->ID);
    $ogimage        = $clientimage['sizes']['large'];
    wp_reset_query();

  // Publication archive  
  } elseif(is_post_type_archive('publication')) {
    $wp_query = new WP_Query( array(
        'post_type'     => 'publication',
        'meta_key'      => 'publication_date',
        'orderby'       => 'meta_value_num',
        'order'             => 'DESC'
    ));
    $first_pub  = $wp_query->posts[0];
    $featured   = get_field('publication_feature', $first_pub->ID);
    if ($featured == 'image') $pubimage = get_field('publication_image', $first_pub->ID);
    $ogimage      = $pubimage['sizes']['large'];
    wp_reset_query();

  // Single project  
  } elseif (is_singular('project')) {
    $featured = get_field('project_feature', $post_id);
    if ($featured == 'image') $projectimage = get_field('project_image');
    $ogimage  = $projectimage['sizes']['large'];

  // Single client  
  } elseif(is_singular('client')) {
    $clientimage = get_field('client_image', $post_id);
    $ogimage       = $clientimage['sizes']['large'];

  // Single publication  
  } elseif(is_singular('publication')) {
    $featured = get_field('publication_feature', $post_id);
    if ($featured == 'image') $pubimage = get_field('publication_image');
    $ogimage    = $pubimage['sizes']['large'];
  }

  // Use default if custom image is not set
  if ($ogimage) {
    //$GLOBALS['wpseo_og']->image_output($ogimage);
  } else {
    $ogimage    = $GLOBALS['wpseo_og']->options['og_default_image'];
  }
  return $ogimage;
});

@rcosgrave
Copy link

rcosgrave commented Apr 10, 2019

So this is still an issue in 2019 but there is a workaround.

You must have a Facebook image set in your Yoast Settings (Yoast->Social->Facebook->Image URL), if you don't then the image hooks will not fire (unless you do indeed have a featured image on the post). Once that default image is set you can use the hook to serve whatever image you would like. Here is my version for example:


function hotswap_og_img($str) {
	if ( is_singular('post') ) {
		$category = get_the_category()[0];
		// @TODO this needs to switch so featured image takes priority after testing
		$cat_img = get_field("category_thumbnail", $category)['url'];

		if (is_null($cat_img)) {
			$image = get_the_post_thumbnail_url($post->ID, 'full');
		}
		else {
			$image = $cat_img;
		}

		if (!empty($image)) {
			return $image;
		}

		return wp_upload_dir("2019/02") . "/Logo_Web_450x300.png";
    }
	elseif (is_page() || is_single()) {
		$image = get_the_post_thumbnail_url($post->ID, 'full');

		if (empty($image)) {
			return wp_upload_dir("2019/02")['url'] . "/Logo_Web_450x300.png";
		}
		else {
			return $image;
		}
	}
}
add_filter('wpseo_opengraph_image', 'hotswap_og_img');
add_filter('wpseo_twitter_image', 'hotswap_og_img');

@santerref
Copy link

You can do it with the action wpseo_add_opengraph_additional_images:

/**
 * @param \WPSEO_OpenGraph_Image $opengraph_image
 */
public function default_facebook_image( $opengraph_image ) {
    if ( ! $opengraph_image->has_images() ) {
        $image_id = get_theme_mod( 'facebook_share_image', FALSE );
        if ( ! empty( $image_id ) ) {
            $image_url = wp_get_attachment_url( $image_id );
            $opengraph_image->add_image( $image_url );
        }
    }
}
add_action( 'wpseo_add_opengraph_additional_images', 'default_facebook_image' );

The action is located here: class-opengraph-image.php line 581

/**
 * Filter: wpseo_add_opengraph_additional_images - Allows to add additional images to the OpenGraph tags.
 *
 * @api WPSEO_OpenGraph_Image The current object.
 */
do_action( 'wpseo_add_opengraph_additional_images', $this );

$this->maybe_set_default_image();

@gavin310
Copy link

gavin310 commented Feb 8, 2020

@santerref Any reason why you don't use the action wpseo_add_opengraph_images instead? Is it preferable to use wpseo_add_opengraph_additional_images?

@FriendlyDotCH
Copy link

This bug still persists for me. wpseo_opengraph_image only worked after adding a FB default image.

@pocketcolin
Copy link

pocketcolin commented Feb 19, 2021

It's 2021 and this is still an issue 7 years later. The docs talk about the wpseo_opengraph_image hook as if it will always fire with no indication that it actually only fires when there is a default image in place. Interestingly, the Twitter version of this hook, wpseo_twitter_image, does fire without a default image indicating to me that there's a bug here that just hasn't been addressed.

In case anyone else lands here looking for a solution to this issue, here's my workaround that utilizes a combination of the answer @santerref provided with the original wpseo_opengraph_image. If you're like me and wanted to programmatically set defaults for both the Twitter image AND the OG image, you may have noticed that the issue with @santerref 's answer is that there is no Twitter action equivalent to wpseo_add_opengraph_additional_images.

// set a default og image value so wpseo_opengraph_image is triggered
function default_og_image ($image) {
    global $post;

    if (!$image->has_images()) {
        $image->add_image('default'); // this can be whatever you want it to be as long as it isn't falsey
    }
}
add_action( 'wpseo_add_opengraph_additional_images', 'default_og_image' );

// set the default share image
function default_share_image ($image) {
    if (!$image || $image === 'default') { // twitter will pass an empty string for $image 
        $image = "http:https://yourimagedomain.com/image.jpg";
    }

    return $image;
}
// now we can call the same function for both actions without having to set a default facebook image in the UI
add_action( 'wpseo_twitter_image', 'default_share_image' );
add_action( 'wpseo_opengraph_image', 'default_share_image' );

iolandasequino pushed a commit that referenced this issue May 12, 2021
Removes the prepare hook in the package.json.
@J-Brk
Copy link

J-Brk commented Nov 29, 2021

Confirmed; it's now almost 12/2021 and the issue still exist.... @toddlevy
had to use @pocketcolin 's workaround because the hook otherwise doesn't trigger...

@Jorgu5
Copy link

Jorgu5 commented Dec 8, 2021

+1 bug still exists, @pocketcolin workaround works!

@McMdesigns
Copy link

2023 and this bug still exists... @pocketcolin's workaround is still working as of version 20.8

@ryanfoote
Copy link

We blew past the 🎂🎉 10 year anniversary 🎂🎉 of this issue without any fanfare or celebration! Confirming that @pocketcolin's workaround still works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests