WordPress snippet that will turn links (either internal or external) wrapped in specific markers into a preview card showing:
Works for:
-
Both internal and external URLs
-
Only triggers when wrapped in
[linkpreview]...[/linkpreview]
Final PHP Shortcode Snippet:
add_shortcode('linkpreview', function($atts, $content = null) {
if (empty($content) || !filter_var($content, FILTER_VALIDATE_URL)) {
return '';
}
$url = esc_url($content);
$parsed = wp_parse_url($url);
$host = $_SERVER['HTTP_HOST'];
ob_start();
// Internal post?
if (isset($parsed['host']) && $parsed['host'] === $host) {
$post_id = url_to_postid($url);
if ($post_id) {
$title = get_the_title($post_id);
$excerpt = get_the_excerpt($post_id);
$thumbnail = get_the_post_thumbnail($post_id, 'medium');
?>
<div class="custom-link-preview internal-link">
<a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener noreferrer">
<?php if ($thumbnail): ?>
<div class="link-thumb"><?php echo $thumbnail; ?></div>
<?php endif; ?>
<div class="link-content">
<strong><?php echo esc_html($title); ?></strong>
<p><?php echo esc_html($excerpt); ?></p>
</div>
</a>
</div>
<?php
}
} else {
// External URL
$response = wp_remote_get($url);
if (!is_wp_error($response)) {
$html = wp_remote_retrieve_body($response);
// Grab <title> content
preg_match('/<title>(.*?)<\/title>/is', $html, $matches);
$title = $matches[1] ?? $url;
// Grab og:image
preg_match('/<meta property=["\']og:image["\'] content=["\']([^"\']+)["\']/', $html, $img_match);
$image = $img_match[1] ?? '';
// Grab og:description
preg_match('/<meta property=["\']og:description["\'] content=["\']([^"\']+)["\']/', $html, $desc_match);
$desc = $desc_match[1] ?? '';
?>
<div class="custom-link-preview external-link">
<a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener noreferrer">
<?php if ($image): ?>
<div class="link-thumb"><img src="<?php echo esc_url($image); ?>" alt=""></div>
<?php endif; ?>
<div class="link-content">
<strong><?php echo esc_html($title); ?></strong>
<p><?php echo esc_html($desc); ?></p>
</div>
</a>
</div>
<?php
}
}
return ob_get_clean();
});
Usage:
Works in Gutenberg, Classic Editor, and anywhere shortcodes are parsed.