Yoast / wordpress-seo

Yoast SEO for WordPress
https://yoast.com/wordpress/plugins/seo/
Other
1.73k stars 881 forks source link

Changing the og:image for Custom Post Type archive pages #2416

Open GermanKiwi opened 9 years ago

GermanKiwi commented 9 years ago

Hi, I'd like to request the ability to change the og:image for an archive page, and in particular for a Custom Post Type archive page.

I'm using Genesis, and I have a CPT (generated by a plugin), and I enabled the Archive Settings sub-menu for it using this code (as described here):

add_action( 'init', 'my_archive_settings' );
function my_archive_settings() {
    add_post_type_support( 'my_cpt', 'genesis-cpt-archives-settings' );
}

WP-SEO automatically replaces the Genesis "SEO Settings" panel on this Archive Settings page, with its own SEO Settings panel, as shown here:

screenshot

I would like to request an extra field in this "SEO Settings" panel for specifying a different og:image (ie. "Facebook Image") URL.

It would also be nice to be able to do the same for regular (non-CPT) archive pages too - unless that is already possible?

An alternative place for adding this new Facebook Image field could be at SEO > Titles & Metas > Post Types > "Custom Post Type Archives" (eg. under the respective Title and Meta Description fields there for each CPT Archive).

GermanKiwi commented 9 years ago

In the meantime, I tried to create a filter using wpseo_opengraph_image to change the og:image value for my CPT archive pages, using the following. But it doesn't seem to work. Any tips here would be much appreciated!

add_filter('wpseo_opengraph_image', 'cpt-archive-image', 10, 1);
function cpt-archive-image($og_image) {
    if( is_post_type_archive('my_cpt') )
        $og_image = 'http://www.example.com/my-image.jpg';

   return $og_image;
};
Rarst commented 8 years ago

I would expect that filter to work, would be my first thing to recommend.

Try to dump your condition and see if it fires?

What is resulting output in that case? Is it different image or no image at all?

kevinwhoffman commented 7 years ago

I've not found it possible to set an og:image for CPT archive pages. I confirmed via Xdebug that the following function does not fire on an archive page because the filter itself is not applied on archive pages.

add_filter( 'wpseo_opengraph_image', 'prefix_filter_og_image', 10, 1 );
function prefix_filter_og_image( $img ) {
    if( is_post_type_archive( 'my_cpt' ) )
        $img = 'http://www.example.com/my-image.jpg';
    return $img;
}

The function does fire on other pages where the Social meta box is available in the Yoast UI.

Ideally there would be way to do this in the admin UI, but at least applying the filter on archive pages would be a step forward. Thanks.

kevinwhoffman commented 7 years ago

This is the workaround I came up with using wp_head.

add_action( 'wp_head', 'prefix_add_og_image', 10, 1 );
function prefix_add_og_image( $img ) {
    if( is_post_type_archive( 'my_cpt' ) ) {
        echo '<meta property="og:image" content="http://example.com/my-image.jpg" />';
    }
}
thulshof commented 7 years ago

Thanks for debugging. Great to hear that you have solved the problem.

Unfortunately we're not able to implement this at short notice. Currently we're focusing on issues that affect many users. We've concluded that this issue is not experienced by many users, therefore we are not able to fix this short-term. However, if more users are affected by this bug, we'll of course revisit this issue.

As you already have a solution for this issue, we would like to invite you to submit a patch.

jerturowetz commented 6 years ago

I believe the filter doesn't fire is because without an og:image set there is nothing to filter. You'll also find that the filter won't fire on any post/page without a set featured image (which is where yoast grabs default og info from).

This is the workaround I used which takes advantage of wpseo_opengraph and the image_output method.

function example_cpt_archive_add_opengraph_image() {

    if ( is_post_type_archive( 'example_cpt' ) ) {
        $image_id = $some_id;
        if ( $image_id ) {
            $og_image = wp_get_attachment_image_src( $image_id, 'featured', false );
            $GLOBALS['wpseo_og']->image_output( $og_image[0] );
        }
    }

}
add_filter( 'wpseo_opengraph', 'example_cpt_archive_add_opengraph_image', 29 );

Personally, i think it would make a bit more sense to have a method similar to update_post_thumbnail which would either set the og:image if it doesn't exist or change if if it does. This would have it's own issues as multiple images would need to be supported in a user defined order (the OpenGraph spec supports more than one og:image per page and sometimes requires image info in between).

Still, it would be nice to have a method we could use to access this more directly. Maybe we could store multiple og:images and any attributes as an array of arrays accessible via a global method? It would be especially valuable on pages where it's hard to determine whether an og:image has been defined (For example: on a cpt archive page we know none exists so we can use the wpseo_opengraph action; however, on a post or a page there's no easy way to check if one exists other than has_post_thumbnail() and just assuming. In such cases we need to use either an action or a filter which can get cumbersome and confusing (and still doesn't really offer a way to manage multiple images).

yumyo commented 3 years ago

I believe the reason the filter doesn't fire is because without an og:image set there is nothing to filter. I believe you'll also find that the filter won't fire on any post/page without a set featured image (which is where yoast grabs default og info from I imagine).

This is the workaround I used which takes advantage of wpseo_opengraph and the image_output method.

function example_cpt_archive_add_opengraph_image() {

  if ( is_post_type_archive( 'example_cpt' ) ) {
      $image_id = $some_id;
      if ( $image_id ) {
          $og_image = wp_get_attachment_image_src( $image_id, 'featured', false );
          $GLOBALS['wpseo_og']->image_output( $og_image[0] );
      }
  }

}
add_action( 'wpseo_opengraph', 'sp_success_archive_add_opengraph_image', 29 );

Personally, i think it would make a bit more sense to have a method similar to update_post_thumbnail which would either set the og:image if it doesn't exist or change if if it does. This would have it's own issues as multiple images would need to be supported in a user defined order (the OpenGraph spec supports more than one og:image per page and sometimes requires image info in between).

Still, it would be nice to have a method we could use to access this more directly. Maybe we could store multiple og:images and any attributes as an array of arrays accessible via a global method? It would be especially valuable on pages where it's hard to determine whether an og:image has been defined (For example: on a cpt archive page we know none exists so we can use the wpseo_opengraph action; however, on a post or a page there's no easy way to check if one exists other than has_post_thumbnail() and just assuming. In such cases we need to use either an action or a filter which can get cumbersome and confusing (and still doesn't really offer a way to manage multiple images).

This is now causing a Fatal error. It would be amazing to understand how to achieve the same with the new 'wpseo_frontend_presenters' but docs seem lacking any examples on existing meta.

andizer commented 3 years ago

You can hook into wpseo_add_opengraph_images. See for reference: open-graph-image-generator.php

The filter is receiving an instance of an image container. You can use the method add_image_by_id to add an image by its id. See images.php for more reference

I've converted the example above to the new way:

function example_cpt_archive_add_opengraph_image( $container ) {
    if ( is_post_type_archive( 'example_cpt' ) ) {
        $image_id = $some_id;
        if ( $image_id ) {
                    $container->add_image_by_id( $some_id );
        }
    }
}
add_action( 'wpseo_add_opengraph_images', 'example_cpt_archive_add_opengraph_image', 29 );

Let me know if the given information is helpful.

andizer commented 3 years ago

I see. Just copied the example, but forgot to check which method the filter is calling. It's fixed and should work:

add_action( 'wpseo_add_opengraph_images', 'example_cpt_archive_add_opengraph_image', 29 );
yumyo commented 3 years ago

It seems to be a filter now #15342

yumyo commented 3 years ago

it blows my mind releasing such an upgrade without proper docs ... Also related to #1060

jerturowetz commented 3 years ago

Sorry @andizer & thanks for bringing to my attention. I updated my example above with the right function name & with the filter switch.

atlanteh commented 3 years ago

This has been changed again. in 14.0 the solution is:

function change_og_image_for_archives($img_url) {
    if (is_post_type_archive('my-archive')) {
        $image_id = $some_id;
        if ( $image_id ) {
            $og_image = wp_get_attachment_image_src( $image_id , 'featured', false );
            return $og_image[0];
        }
    }
    return $img_url;
}
add_filter( 'wpseo_opengraph_image', 'change_og_image_for_archives', 29 );
mistergraphx commented 3 years ago

Hi i was strugling with this filter, wondering why my function was never fired : in fact this function is executed ONLY if you 've set a default image in the Yoast > social > facebook settings.

Hope this help others

pocketcolin commented 3 years ago

@mistergraphx There's a workaround for this issue with wpseo_opengraph_image only triggering when a default image is added through the UI that I just added to this old ticket, https://github.com/Yoast/wordpress-seo/issues/1060. Workaround also includes how to add a default Twitter image at the same time.

conkonig commented 3 years ago

As of v15.9 none of these solutions work unfortunately, at least not in the responses coming back from /wp-json/yoast/v1/get_head

omarreiss commented 3 years ago

Hmm, I must admit we haven't documented this part very well. I'll ask our docs team to take a look at this usecase.

From going through the code, I cannot see a reason why the filter wpseo_add_opengraph_images or the filter wpseo_add_opengraph_additional_images wouldn't do the trick. Did you try one of thos @conkonig? These should allow you to filter in any opengraph image you like. @pocketcolin is right that the wpseo_opengraph image only runs on images we have detected for the url ourselves. So if no images have been detected, it will not run.

FYI: We are working to add settings for this stuff in our Premium plugin. We've almost got that feature done and plan to ship it somewhere in the upcoming two to three months.

conkonig commented 3 years ago

Thanks for the reply.

I am trying to use it on a taxonomy archive page so site.com/posttype/taxonomy I get the Facebook image from wp-admin general yoast settings if it is set. Otherwise there is no og:image tag at all appearing in the yoast get_head rest response.

I can post examples of with and without Facebook image set. My understanding was that the filter wpseo_add_opengraph_images https://github.com/Yoast/wordpress-seo/blob/2117a8d186d92785b9656c02a412bb2e7523feb6/src/generators/open-graph-image-generator.php#L89 Would change the Facebook image to something else for og:image but behaviour is as I described.

On Fri, 7 May 2021 at 13:27, Omar Reiss @.***> wrote:

Hmm, I must admit we haven't documented this part very well. I'll ask our docs team to take a look at this usecase.

From going through the code, I cannot see a reason why the filter wpseo_add_opengraph_images https://github.com/Yoast/wordpress-seo/blob/2117a8d186d92785b9656c02a412bb2e7523feb6/src/generators/open-graph-image-generator.php#L89 or the filter wpseo_add_opengraph_additional_images https://github.com/Yoast/wordpress-seo/blob/2117a8d186d92785b9656c02a412bb2e7523feb6/src/generators/open-graph-image-generator.php#L103 wouldn't do the trick. Did you try one of thos @conkonig https://github.com/conkonig? These should allow you to filter in any opengraph image you like. @pocketcolin https://github.com/pocketcolin is right that the wpseo_opengraph image only runs on images we have detected for the url ourselves. So if no images have been detected, it will not run.

FYI: We are working to add settings for this stuff in our Premium plugin. We've almost got that feature done and plan to ship it somewhere in the upcoming two to three months.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Yoast/wordpress-seo/issues/2416#issuecomment-834330643, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC5GOU7KLKIPU3AC6BN2VGLTMPMCRANCNFSM4BDX2XIQ .

andresgomez-pulpo commented 1 year ago

Hi,

I think the best way to replace the og:image for a Custom post type is:

`function fb_YOUR_CUSTOM_POST_TYPE_image( $tags ) { if( is_post_type_archive( 'your_cpt' ) ) { // Remove the default blank image added by Jetpack unset( $tags['og:image'] );

    $fb_cpt_img = 'YOUR IMG';
    $tags['og:image'] = esc_url( $fb_cpt_img );
}

return $tags;

} add_filter( 'jetpack_open_graph_tags', 'fb_YOUR_CUSTOM_POST_TYPE_image' ); `

Best.

GermanKiwi commented 1 year ago

@andresgomez-pulpo I'm afraid your answer isn't valid for this issue. Your function uses jetpack_open_graph_tags but this issue doesn't involve or require the JetPack plugin. Rather, this issue is simply about setting a specific image URL for the og:image tag on a CPT Archive page on any site using Yoast, not just those with JetPack.

The function provided by @atlanteh on 4 Nov 2020 is the correct one. It still works correctly today, with Yoast SEO 20.4: https://github.com/Yoast/wordpress-seo/issues/2416#issuecomment-721728996