Open Graph and Twitter Card Meta Tags for WordPress

Rich link previews for links posted on social media or messaging apps help make content more engaging. There are a ton of WordPress plugins that will add Open Graph and Twitter Card meta tags, but plugins can be bloated and possibly break other parts of a WordPress site. The function below adds the required Open Graph and Twitter Card meta tags without needing a plugin. This will conditionally display meta tags specific to Post pages, to Front pages, and to Single/Archives pages.

<?php
function evo_og_meta_tags() {
	global $post;
	if ( has_post_thumbnail( $post->ID ) ) {
		$img_src = get_the_post_thumbnail_url( $post->ID, 'large' );
	} else {
		$img_src = get_stylesheet_directory_uri() . '/assets/images/default-post-image.png';
	}
	$current_url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
	$current_uri = $_SERVER['REQUEST_URI'];
	if ( is_single() ) { ?>
		<meta name="twitter:card" content="summary_large_image" />
		<meta property="og:url" content="<?php the_permalink() ?>" />
		<meta property="og:title" content="<?php the_title(); ?>" />
		<meta property="og:description" content="<?php echo wp_strip_all_tags( get_the_excerpt() ); ?>" />
		<meta property="og:image" content="<?php echo $img_src; ?>" />
	<?php } elseif ( is_front_page() ) { ?>
		<meta name="twitter:card" content="summary" />
		<meta property="og:url" content="<?php echo get_home_url(); ?>" />
		<meta property="og:title" content="<?php bloginfo( 'name' ); ?>" />
		<meta property="og:description" content="<?php bloginfo( 'description' ); ?>" />
		<meta property="og:image" content="<?php site_icon_url() ?>" />
	<?php } else { ?>
		<meta name="twitter:card" content="summary" />
		<meta property="og:url" content="<?php echo $current_url; ?>" />
		<meta property="og:title" content="<?php bloginfo( 'name' ); ?>" />
		<meta property="og:description" content="<?php echo $current_uri; ?>" />
		<meta property="og:image" content="<?php site_icon_url() ?>" />
	<?php }
}
add_action( 'wp_head', 'evo_og_meta_tags', 99 );
View Post

Get all Post Content without Images in WordPress

When all post content except the images is needed for a section of a post/page layout, like a post summary or a custom post type, the method below strips all images from the post content. This works well when combined with either code from the previous two posts micro.e33.io/112 and micro.e33.io/123 to make unique layouts as needed.

<?php
function evo_post_without_images() {
	global $post;
	$content = get_the_content();
	$content = preg_replace( '/<img[^>]+\>/i', ' ', $content );
	$content = apply_filters( 'the_content', $content );
	$content = str_replace( ']]>', ']]>', $content );
	echo $content;
}

Use the function in the loop like this.

<?php evo_post_without_images(); ?>

If only the post excerpt is needed instead of the full content, the method below displays the WordPress standard 55 words of the post with HTML tags stripped out.

<?php echo wp_strip_all_tags( get_the_excerpt() ); ?>
View Post

Get all Post Images in WordPress

Single post pages with multiple images like a photoset, etc. can be very resource heavy when browsers download images that are larger than needed. The method below allows you to designate the initial size (thumbnail, medium, large or full), while using the native WordPress responsive image support by including srcset and sizes attributes to the image. Browsers will download the most appropriate size and ignore the others. This method also ignores the Featured Image of a post.

<?php
function evo_all_post_images() {
	global $post;
	$args = array(
		'post_type'   => 'attachment',
		'numberposts' => -1,
		'post_status' => 'any',
		'post_parent' => $post->ID,
		'exclude'     => get_post_thumbnail_id(),
	);
	$attachments = get_posts( $args );
	if ( $attachments ) {
		foreach ( $attachments as $attachment ) {
			echo wp_get_attachment_image( $attachment->ID, 'large', false, array( 'class'=>'img-responsive-post' ) );
		}
	}
}

Use the function in the loop like this.

<?php evo_all_post_images(); ?>
View Post

Get the First or Featured Image in WordPress

There are several ways to get the first or Featured Image in WordPress for use on a Home page blog feed, an Archives page feed, etc. The method below first checks for a Featured Image, then for the first attached image, and finally a default image if needed. This also allows you to designate the initial size (thumbnail, medium, large or full), while using the native WordPress responsive image support by including srcset and sizes attributes to the image. Browsers will download the most appropriate size and ignore the others.

<?php
function evo_thumbnail_image() {
	if ( has_post_thumbnail() ) {
		the_post_thumbnail( 'medium' );
	} else {
		global $post;
		$args = array(
			'post_type'   => 'attachment',
			'numberposts' => -1,
			'post_status' => null,
			'post_parent' => $post->ID
		);
		$attachments = get_posts( $args );
		if ( $attachments ) {
			echo wp_get_attachment_image( $attachments[0]->ID, 'medium', false, array( 'class'=>'img-responsive' ) );
		} else {
			echo '<img src="' . get_stylesheet_directory_uri() . '/assets/images/default-post-image.png' . '" />';
		}
	}
}

Use the function in the loop like this.

<?php evo_thumbnail_image() ?>

If only the Featured Image is needed, the method below will work.

<?php the_post_thumbnail( 'medium' ); ?>
View Post

CSS Reset for WordPress

Even though the User Agent Stylesheet CSS across modern browsers is fairly consistent, I sometimes like to start from scratch when writing CSS. The CSS Reset below makes for a clean slate to start CSS from, while sprinkling in a few WordPress-specific tags and making media items responsive. Some of it might be a bit overkill or heavy-handed, but it’s a solid start that works for me and it’s only 775 bytes.

This is my current CSS Reset for WordPress.

* {
	vertical-align: baseline;
	font: inherit;
	font-size: 100%;
	border: 0;
	outline: 0;
	padding: 0;
	margin: 0;
}
html {
	box-sizing: border-box;
	line-height: 1;
	-webkit-text-size-adjust: 100%;
	-webkit-tap-highlight-color: transparent;
}
*,
*:before,
*:after {
	box-sizing: inherit;
}
hr {
	box-sizing: content-box;
	height: 0;
}
pre,
code {
	font-family: monospace, monospace;
}
strong,
b {
	font-weight: 700;
}
blockquote,
q,
em,
i {
	font-style: italic;
}
ins {
	text-decoration: underline;
}
del,
s {
	text-decoration: line-through;
}
ol,
ul {
	list-style: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
input,
textarea {
	border: 1px solid;
	border-radius: 0;
	max-width: 100%;
	-webkit-appearance: none;
	-moz-appearance: none;
}
::-webkit-search-decoration {
	-webkit-appearance: none;
}
img,
video,
audio {
	display: block;
}
img,
video {
	height: auto;
	max-width: 100%;
}
embed,
iframe,
object {
	max-width: 100%;
}

This is a minified version of the code above.

*{vertical-align:baseline;font:inherit;font-size:100%;border:0;outline:0;padding:0;margin:0}html{box-sizing:border-box;line-height:1;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}*,*:before,*:after{box-sizing:inherit}hr{box-sizing:content-box;height:0}pre,code{font-family:monospace,monospace}strong,b{font-weight:700}blockquote,q,em,i{font-style:italic}ins{text-decoration:underline}del,s{text-decoration:line-through}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}input,textarea{border:1px solid;border-radius:0;max-width:100%;-webkit-appearance:none;-moz-appearance:none}::-webkit-search-decoration{-webkit-appearance:none}img,video,audio{display:block}img,video{height:auto;max-width:100%}embed,iframe,object{max-width:100%}
View Post