Those that are supposed to know such things say that internal links are really important on your websites. But just plain links are kind of ugly. So, I wrote the following little snippet that adds a [block_link]
shortcode to WordPress
All of the code for this is available in a GitHub repository. Everything that follows here is loaded directly from that repo.
Block Link Shortcode
I was looking for a nice, easy way to embed internal links on a site without going to just plain text links. Lifehacker does a really good job of internal links, and I modeled this plugin a bit from their style.
What's it do?
With the code from block_link.php
added to your theme functions.php
you'll get a new shortcode [block_link]
. You can use it in 3 different ways.
[block_link id=#]
will embed the post or page by database ID[block_link slug="permalink"]
will embed the post or page by permalink[block_link url="url_to_page"]
will embed the post or page by trying to determine by URL. It does need to be a URL on your site.
Assuming that it can figure out what post you're trying to embed it'll kick out the HTML to build the block link.
What's it look like?
I originally wrote this shortcode snippet for my site CompSci.rocks. You can see a block link in action on the page for a square root curve calculator.
Be sure to look at the SASS file in this repo to see how the link is styled. The actual link is wrapped in quite a few styles, and the included SASS makes it look like the screen shot with some help from flexboxes.
Installation
It didn't seem worthwhile to split this off into a separate plugin, so I just dumped the code from block_link.php
in this repo into the functions.php
file for my theme. Such a small little snippet just didn't seem to warrant a separate plugin.
To use with your theme just paste the code from block_links.php
into your theme functions.php
file. If that doesn't make sense to you, there's a pretty good explanation on WordPress.org.
Images, Title and Excerpts
The title comes from the post title that you're linking to.
The subtext is pulled from one of several different places, in this order. It will first look for an excerpt that you've entered for the post. If the execrpt is empty it will look to meta data from the Yoast SEO plugin. First meta description, then the Facebook description and then the Twitter description.
The same thing happens for the image. First choice is the featured image. Then it will look to Yoast Facebook and Twitter images.
Customization
Do whatever you want with the SASS in block_links.scss
. What's there is what I'm using on my sites, but you can tweak it however you want.
Why not a plugin?
This was originally going to be a plugin, but since it's pretty likely you're going to want to add the CSS to your theme instead of loading a separate external file just for this little block it made more sense to just toss the code into functions.php
instead.
Here’s the PHP that adds the shortcode. It goes into the functions.php
file for your theme, or you could paste it into a separate plugin if you’d rather.
<?php add_shortcode('block_link', 'block_link'); function block_link( $atts ) { global $post; $atts = shortcode_atts( [ 'id' => '', 'slug' => '', 'url' => '' ], $atts ); /* If the ID wasn't passed we have to do a little more work * to figure it out */ if ( empty( $atts[ 'id' ] ) ) { if ( ! empty( $atts[ 'slug' ] ) ) { $test_post = get_posts( [ 'name' => $atts[ 'slug' ], 'post_status' => 'publish', 'numberposts' => 1, 'post_type' => ['post', 'page'] ] ); $atts[ 'id' ] = ! empty( $test_post ) ? $test_post[ 0 ]->ID : 0; } else if ( ! empty( $atts[ 'url' ] ) ) { $atts[ 'id' ] = url_to_postid( $atts[ 'url' ] ); } } /* If we can't find the post, just don't show anything except maybe some * comments if we're in debug mode. */ if ( empty( $atts[ 'id' ] ) ) { return 'id is empty'; return defined( 'WP_DEBUG' ) && true === WP_DEBUG ? '<-- Post not found for block link -->' : ''; } /* Time to load the post and build the layout */ $link_post = get_post( $atts[ 'id' ] ); if ( empty( $link_post ) ) { die('no post by id'); return defined( 'WP_DEBUG' ) && true === WP_DEBUG ? '<-- Could not find post by ID for block link -->' : ''; } /* Start with the image if it exists */ $image_url = get_the_post_thumbnail( $link_post, 'thumbnail' ); if ( empty( $image_url ) ) { // Fallback to Yoast meta fields $yoast_url = get_metadata( $link_post->post_type, $link_post->ID, '_yoast_wpseo_opengraph-image', true ); if ( empty( $yoast_url ) ) { // Try Twitter $yoast_url = get_metadata( $link_post->post_type, $link_post->ID, '_yoast_wpseo_twitter-image', true ); } if ( ! empty( $yoast_url ) ) { $attachment_id = attachment_url_to_postid( $yoast_url ); if ( $attachment_id ) { $yoast_url = wp_get_attachment_image( $attachment_id, 'thumbnail' ); $image_url = $yoast_url; } } } /* Excerpt is next */ $excerpt = has_excerpt( $link_post->ID ) ? get_the_excerpt( $link_post ) : ''; if ( empty( $excerpt ) ) { $excerpt = get_metadata( $link_post->post_type, $link_post->ID, '_yoast_wpseo_metadesc', true ); } if ( empty( $excerpt ) ) { $excerpt = get_metadata( $link_post->post_type, $link_post->ID, '_yoast_wpseo_opengraph-description', true ); } if ( empty( $excerpt ) ) { $excerpt = get_metadata( $link_post->post_type, $link_post->ID, '_yoast_wpseo_twitter-description', true ); } if ( empty( $excerpt ) ) { /* Just make sure it's a string */ $excerpt = ''; } /* And now, it's time to build the HTML */ $permalink = get_permalink( $link_post ); $html = '<div class="block-link">'; if ( ! empty( $image_url ) ) { $html .= '<a href="' . $permalink . '">'; $html .= '<div class="link-image">' . $image_url . '</div>'; $html .= '</a>'; } $html .= '<div class="link-text">'; $html .= '<a href="' . $permalink . '">'; $html .= '<div class="link-hdr">' . get_the_title( $link_post ) . '</div>'; $html .= '<div class="link-excerpt">' . $excerpt . '</div>'; $html .= '</a>'; $html .= '</div>'; // .link-text $html .= '</div>'; // .block-link $html .= '</a>'; return $html; }
This is the SASS that I use on the site I originally wrote this for. Feel free to copy and paste it, and customize it however you like.
.block-link { border-top: 1px solid gainsboro; border-bottom: 1px solid gainsboro; overflow: auto; margin: { top: 16px; bottom: 16px; right: 0px; left: 0px; } padding: { top: 8px; bottom: 8px; } display: flex; flex-direction: row; flex-wrap: nowrap; .link-image { flex-grow: 0; width: 100px; img { max-height: 100px !important; width: auto !important; } } .link-text { flex-grow: 1; padding-left: 8px; max-height: 100px; overflow: hidden; text-overflow: ellipsis; .link-hdr { font-size: 1.5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .link-excerpt { overflow: hidden; } } a { color: black; text-decoration: none; &:hover{ color: black; } } }
Be First to Comment