Created
December 6, 2024 21:46
-
-
Save seanlanglands/0f7e0395f94f7e53a265445d62baf2a5 to your computer and use it in GitHub Desktop.
Fix failed X/Twitter embeds by rendering them client-side when oembed has failed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
add_filter( 'the_content', 'fix_failed_twitter_embeds', 11 ); | |
/** | |
* Fix failed X/Twitter embeds by rendering them client-side when oEmbed has failed. | |
* | |
* Does not prevent WordPress core's oEmbed from being attempted, which can result in | |
* a server-side 404 request to Twitter's API. | |
* | |
* @param string $content The post content. | |
* | |
* @return string The modified post content. | |
*/ | |
function fix_failed_twitter_embeds( $content ) { | |
// Determine the width (for classic themes). | |
global $content_width; | |
if ( ! wp_is_block_theme() ) { | |
$data_width = isset( $content_width ) && ! empty( $content_width ) ? intval( $content_width ) : 500; | |
} else { | |
$data_width = 500; | |
} | |
// Ensure the width stays within Twitter's constraints (220px to 550px). | |
$data_width = max( 220, min( 550, $data_width ) ); | |
// Store the original content, in case there are no matches. | |
$original_content = $content; | |
// Use regex to find raw Twitter URLs NOT inside an <a> tag. | |
$content = preg_replace_callback( | |
'/<a.*?<\/a>(*SKIP)(*F)|https?:\/\/(?:twitter\.com|x\.com)\/[a-zA-Z0-9_]+\/status\/\d+(?:\?[^\s"<]*)?(?=\s|$|<)/', | |
function ( $matches ) use ( $data_width ) { | |
$tweet_url = $matches[0]; | |
// Wrap the raw URL in the fallback blockquote structure. | |
$fallback_html = sprintf( | |
'<blockquote class="twitter-tweet" data-width="%d"><a href="%s"></a></blockquote>', | |
intval( $data_width ), | |
esc_url( $tweet_url ) | |
); | |
return $fallback_html; | |
}, | |
$content | |
); | |
// If no match, return the original content and return early, so no need to enqueue enqueue_twitter_widgets_script. | |
if ( null === $content ) { | |
return $original_content; | |
} | |
// (Maybe) add the required widgets.js script. | |
add_action( 'wp_footer', 'enqueue_twitter_widgets_script' ); | |
return $content; | |
} | |
/** | |
* Enqueue the Twitter widgets.js script (once). Omit for themes that include it already. | |
*/ | |
function enqueue_twitter_widgets_script() { | |
static $twitter_script_enqueued = false; | |
if ( ! $twitter_script_enqueued ) { | |
echo '<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>'; | |
$twitter_script_enqueued = true; | |
} | |
} | |
add_filter('add_post_metadata', 'prevent_bad_oembed_cache', 10, 5); | |
add_filter('update_post_metadata', 'prevent_bad_oembed_cache', 10, 5); | |
/** | |
* Prevents the addition or update of oEmbed metadata with the value '{{unknown}}'. | |
*/ | |
function prevent_bad_oembed_cache($check, $object_id, $meta_key, $meta_value, $prev_value) { | |
if (strpos($meta_key, '_oembed_') === 0 && $meta_value === '{{unknown}}') { | |
return true; // Short-circuit the meta update/addition. | |
} | |
return null; // Proceed with the normal meta update/addition. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment