A client recently asked me to code for functionality that would allow links from within the same page to have different social media images displayed when those links were shared.
Since the client had the Yoast SEO plug-in installed, I investigated the Yoast SEO documentation to see what could be done whether through the settings or through custom coding.
At least with the free version, it appears that the ability to selectively choose the image that would appear when the link was shared is not available unless you do custom coding.
I eventually found this documentation link on the Yoast SEO website , and it was helpful in explaining what could be done via PHP:
The gist of that article is that you’re able to manipulate the meta tags that Yoast outputs.
In my case, I needed to modify the images that were output, so I needed to deal with the Open_Graph\Image_Presenter
and Twitter\Image_Presenter
presenters which would display different images then what would have been by default used.
It should be noted you shouldn’t blindly copy and paste the code from that documentation page I listed earlier, as if you do, and you deactivate Yoast for whatever reason, you’re going to have an error on your site and that’s because the ‘use’ statement is referencing a class that is not available as the plugin did not generate the class and so you should just use the fully qualified name, like so:
Yoast\WP\SEO\Presenters\Open_Graph\Image_Presenter
We need to add a conditional around our code to detect whether or not the plug-in is active:
if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ))
As that page states you’re better off extending the Abstract_Indexable_Tag_Presenter
since it reduces the room for error because the results of the get
function are returned to the placeholder in the formatted string instead of having to call the get
function.
The documentation page provides a good explanation of the $tag_format
and get()
function so I won’t discuss that here.
Here is some example Custom Presenter code for demonstration purposes:
class Custom_Image_Presenter extends Yoast\WP\SEO\Presenters\Abstract_Indexable_Tag_Presenter {
/**
* The tag format including placeholders.
*
* @var string
*/
protected $tag_format = '<meta property="og:image" content="%s" />';
/**
* Returns the value of our new tag.
*
* @return string The value of our meta tag.
*/
public function get() {
return “https://via.placeholder.com/150C”;
}
}
Now we must not forget to add the presenters to the array of presenters with the following code:
/**
* Adds our custom presenter to the array of presenters.
*
* @param array $presenters The current array of presenters.
*
* @return array Presenters with our custom presenter added.
*/
function add_my_custom_presenter( $presenters ) {
$presenters[] = new Custom_Image_Presenter();
return $presenters;
}
add_filter( 'wpseo_frontend_presenters', 'add_my_custom_presenter' );
When the HTML is generated, you should see an additional meta tag added to the HTML: <meta property="og:image" content="%s" />
.
Although we added the presenter to the array, the existing image presenter with the undesired image is still within the array so we need to remove that presenter.
foreach($presenters as $index=>$presenter)
{
if ($presenter instanceof Yoast\WP\SEO\Presenters\Open_Graph\Image_Presenter || $presenter instanceof Yoast\WP\SEO\Presenters\Twitter\Image_Presenter)
{
$presenters[$index] = new Custom_Image_Presenter();
}
}
Since we only want the code to be active on a certain page we have to use a is_page
conditional to control where the image presenters are added.
if (is_page(42))
//42: some of you will get the joke
{
….
}
Earlier we set the image to be an example image, but what if we wanted the image to be set based on some info from within the URL?
For instance, we could set the image URL to be based on a GET
query parameter:
public function get() {
return wp_get_attachment_url($_GET['seo_image']);
}
Here’s the full code from all the examples provided:
if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ))
{
/**
* Adds our custom presenter to the array of presenters.
*
* @param array $presenters The current array of presenters.
*
* @return array Presenters with our custom presenter added.
*/
function ian_sackofwits_add_my_custom_presenter( $presenters ) {
if (is_page(2413))
{
foreach($presenters as $index=>$presenter)
{
if ($presenter instanceof Yoast\WP\SEO\Presenters\Open_Graph\Image_Presenter)
{
$presenters[$index] = new Custom_Image_Presenter();
}
}
}
return $presenters;
}
add_filter( 'wpseo_frontend_presenters', 'ian_sackofwits_add_my_custom_presenter' );
/**
* Adds a custom my:property.
*/
class Custom_Image_Presenter extends Yoast\WP\SEO\Presenters\Abstract_Indexable_Tag_Presenter {
/**
* The tag format including placeholders.
*
* @var string
*/
protected $tag_format = '<meta property="og:image" content="%s" />';
/**
* Returns the value of our new tag.
*
* @return string The value of our meta tag.
*/
public function get() {
return "https://via.placeholder.com/150C";
}
}
}
Essentially, we now have the ability to selectively to choose what image appears when the page is shared on social media.
Add this code to your theme’s functions.php file or use a plugin such as Code Snippets.
In the next post in this series, I will show you a more complex example with the Presenters.