Different Paragraph and Image Widths in WordPress (for Readability)

I was talking with a client recently about blog post readability and line length, and how those things are hard to balance with wider column widths and nice large images.

Here are some good articles on line length, if you’re interested:

Once you’ve decided that you do indeed want to be careful about your line length, but you still want nice big images, things get a little tricky, particularly with a content management system like WordPress in the mix.

In theory, you’d just make your paragraphs narrower than your images by a small amount. This would keep the line lengths reasonable without having to adjust the font size too large or the image/ column size too narrow.

The problem is, WordPress wraps images in paragraph tags, so anything you do to the paragraph width will also impact your images.

If you don’t mind a little jQuery or javascript, you can fix this! Here’s what to do if you want your WP blog paragraphs narrower than your images:

I’ve done it recently in this site, as illustrated in this screenshot:

paragraph that is narrower than an image

You can even see it with this very paragraph compared to that screenshot (so meta)!

This took a little bit of jQuery and some CSS. Rather than take away the paragraph around the images (which seemed less reliable once you start to consider how the markup might change for captions, for example), I decided to add a class to those paragraphs.

This snippet went into my general theme.js file in my theme:

function imgParagraphs() {
    jQuery(document).ready(function($) {
        $('.post-body img.aligncenter, .post-body img.alignnone').each(function(){
            $(this).parents('p').addClass('img-parent');
        });
    });
}

It finds every image that is center aligned or has alignment set to “none” and gives their parent paragraphs the class img-parent.

I did not do this with right- and left-aligned images. The left-aligned images don’t need any modification, and I’m still messing with right-aligned images in this model, especially across various devices. (My general plan is that they are adjusted to the right via positioning for larger screens, then they become full width at smaller screens.)

Anyway, with that script in the main theme scripts file (which is loaded on each page, more on this centralized file method here), I added this to the blog template files:

<script>
    <!--
        imgParagraphs();
    //-->
</script>

This causes the relevant script to actually run on those pages (otherwise it just hangs out in the theme.js file not doing anything).

From there, I used CSS to alter the styling to add padding to the right of the paragraphs, and to take it away again on the image parent paragraphs:

// this is SCSS-formatted
.post .entry-content p {
    padding-right: 40px;
    &.img-parent {
        padding-right: 0;
    }
}

Maybe it’d be better to have that be a relative value (ems or percent) than a pixel value, that’s something I’d encourage you to explore if you try something similar!

Is line length something you consider on your site? How do you handle it?

Three Quick Links: Responsive Images

three quick links for responsive images graphic

I’ve been generally following along with the conversations out there on responsive images but haven’t really felt it necessary to deep dive and actually do things with code yet.

Ok, that’s not entirely true – I’ve made big shifts in how I work with layout graphics such that I use almost all CSS and SVG/ scalable graphics. But for content graphics, I’ve mostly just been keepin’ on and waiting for some of the early back and forth to resolve itself.

I think we’re there, just about, so I’ve finally committed to some reading on responsive content images – here are three great resources. While there are tons of great articles out there, these stand out as particularly useful on this topic:

1

Responsive Images in Practice, from A List Apart, is extremely long and in-depth. It’s everything you need to know to implement responsive content images using all the major, forward-looking techniques. Start here.

2

It’s basically impossible to learn about newer techniques without referencing CSS Tricks, so I won’t try. There’s a great article there that talks about how srcset is the thing to use if you’re just changing resolutions. It also links to a bunch of other interesting resources.

3

Finally, one of the big barriers to responsive content images is that most of us aren’t actually coding all our content images. Never fear, there’s a WordPress plugin that seems to be the standard for handling responsive content images. You can also use it for themes, although I’m not sure I’m convinced you should (instead probably work on not using bitmap graphics in themes, I think).


I think I’ll probably start tackling some of this code in my Shopify starter theme – that seems like a place where optimizing graphics like this could go a long way, and since Shopify generates a ton of image sizes it seems like it should work pretty well.

What are you thinking and reading about responsive images these days?

Inline Click to Tweet Functionality

Warning! While I try to write a lot of my tutorials for people with varying degrees of coding experience, this particular tutorial is more for intermediate/ advanced readers. I wanted to explain the functionality but my implementation is pretty rough.

If you’re comfortable modifying your theme but work in WYSIWYG mode, you might want to try the WP Tweetable Text code this is based on.

Awhile back I noticed a really nice, unobtrusive “click to tweet” functionality on the InVision blog. While I’ve played around with click to tweet functionality before, this implementation felt much more smooth than having super huge callouts so I put it on my list to experiment with and forgot about it until recently.

I finally had time to mess around with getting this working on this site, and I’ve used it on a few recent posts to good feedback (if not much more in the way of shares so far). Here’s a screenshot of what this looks like in action:

My code was heavily based on this WP Tweetable Text plugin, which is not a WordPress plugin the way you usually would think of one (you add it to your theme, not via the Plugins area). I did try that code, but it only works with WYSIWYG editing mode, which I don’t use. If you’re working in WYSIWYG mode, I’d probably go with the original.

How It Works

I’m going to go a little backwards here and show you how this works once you’ve got the code in place first, then show you the code I used.

As a result of the code in this post, you end up with a “tweet” button in your post and page editor while in text mode:

tweet button in text mode

You can select text in your post, then click the button to be presented with a little modal asking you for the URL to share in the tweet:

tweet-url-modal

I’ve been using Bit.ly for my URLs to shorten them and leave more room for the text, so I installed a WP Bit.ly plugin to let me generate those URLs using the built in shortlink button on the page. I copy that URL, and then paste it into the modal.

If you wanted to get really fancy, you could try modifying to code to tie into the Bit.ly API or the built in shortlinks automatically, but so far I’m good with copying and pasting.

After you accept your URL (which you can leave blank if you want), you get markup like this on the page:

<span class="twitterHighlight" data-tweet="Here's my tweetable text" data-shorturl="http://bit.ly.com/">Here's my tweetable text</span>

Your selected text is wrapped in span tags and a few data attributes are in place with the tweet text (same as whatever you had selected) and the URL. From there you can edit the markup if you want to change the URL or modify the tweet text at all.

You’ll want to keep an eye on the text length as you choose what to make tweetable, especially if you are including your handle in the Tweet plus the post or page URL. I generally just test it in preview view to make sure it’s right, adjusting as necessary.

You’ll also have to keep an eye on the characters you’re using, as using quotes will break your markup. You’ll catch this if you give the links a quick test in preview as well.

The beauty of this method is that you can totally customize the way it looks, it fails cleanly if there are javascript issues, and you can use it within your regular paragraphs and lists without breaking them up visually.

The Code

On to the implementation! There are two main parts to this, plus whatever CSS styling you want to use.

Part 1: Creating the Quicktag Button in the Admin

First up, you’ve got to create the button in the admin that generates the markup for you.

My code for this is heavily based on this StackOverflow thread, and looks like this:

This goes into your theme’s functions.php file. Hopefully the comments throughout that code block make it pretty clear what’s going on. This block generates the required markup in your post for the link. So far, this markup won’t do anything visible on the front end, which is where the next block comes in.

Part 2: Creating the Front-End Functionality

At this point, you’ve got the new span in your markup but that’s it. Based on that original WP Tweetable Text plugin, I’ve used javascript to find those spans and create the links, and then I used jQuery to trigger the link click to open in a nice little Tweet pop up window.

Here’s that code:

I like that this creates the link markup and adds the icon using javascript because that way it just doesn’t show up at all if there’s a problem with javascript (no broken link with an icon that doesn’t do what it should).

Part 3: Styling the Links

Finally, you’ll probably want to style your links to make them noticeable (and for fun). As mentioned, I used Font Awesome (which I already had integrated into my site) for the Twitter icon. Here are the styles I have active (in SCSS format):

.twitterHighlight a {
    text-decoration: none;
    background: #f2f0f0;
    color: #333;
    padding: 1px 4px;
    i {
        color: #777;
    }
    &:hover,
    &:focus {
        color: #000;
        background: #fff;
        i {
            color: #55acee;
        }
    }
}

I’ve got light highlighting on the text by way of the background color, and that gets brighter on hover. I’ve also got the Twitter icon going from gray to the Twitter brand blue.


So to recap, you add the PHP code to your theme’s functions.php and the scripts wherever you put those things in your theme (I have a theme.js file in mine). Then, you can add your inline tweets right in the post text editor as you write via the quicktag button!

Two “Where Have You Been All My Life” WordPress Plugins

There’s a type of WordPress plugin that provides functionality that is simple and targeted but so useful that once you’ve got it you wonder how on earth you functioned previously.

Here are two such plugins that I’ve started using recently and now install on almost all of the sites I work on:

1. Schedule Posts Calendar

schedule post calendar screenshotIf you ever need to schedule blog posts to publish in the future (which I think is probably everybody who blogs), you’re familiar with selecting a post date and time.

The problem with the “normal” way of doing this is that you’re just looking at numbers. For me, that means I have to reference a calendar to figure out the day of the week for each date.

Yes, it’s a total first world problem but it’s annoying and it’s unnecessary given that there’s a handy little plugin called Schedule Posts Calendar that adds a calendar picker to that area, letting you click to select a date (and time).

A calendar picker for scheduling WordPress posts? Yes please! It also has a “Today” button in case you want to jump to present.

2. Admin Collapse Subpages

Some sites end up with a lot of pages and subpages, which the admin “All Pages” screen is really not well set up to handle. At a certain point a humongous list of page titles with hyphens indicating hierarchy is basically unusable.

Don’t worry! The Admin Collapse Subpages plugin does exactly what the name implies:

pages with subpage collapse screenshot

It gives you that nice little +/- next to each parent page so that you can collapse all the subpages. So easy, so functional.


What are your must-use utility plugins for WordPress?

Custom Instagram Feed and Stats Integration for High Traffic

One of the modules on the semi-recently redesigned/ updated Love Taza site (designed by Bre from Rowan Made) was an Instagram sidebar area that shows images and stats from both Naomi and Josh’s accounts:

love-taza-instagram-module

The left side is all Naomi, with two of her most recent images and her stats for followers, posts and the number of other accounts she’s following, and the right side shows the same for Josh.

The Problem with Plugins

I tend to use existing plugins when I can for features like this, but none of the plugins I found handled the stats (the best I could get was a plugin that would let me show one user’s follower count). I implemented a modification of an existing plugin but we quickly realized that the plugin’s lack of caching system was going to be a big problem given their high levels of traffic – we kept hitting Instagram’s API rate limit and losing the data displays.

Finally, I sat down with the Instagram API docs and wrote them a custom module that uses WordPress transients to store the data and limit the number of API calls we’re making.

The Custom Setup

Let’s dig through the code needed to get a feed similar to the one on Love Taza (and/or stats) up and running on WordPress (or any PHP site).

Authentication & API Access

The first thing to deal with in an API integration is authentication. In this case, we only need to get data from Instagram (we aren’t modifying their accounts in any way) so the integration is easier and has a lower barrier of authentication than if we wanted two-way control.

In order to get the necessary access, we need an access token for each account.

If you don’t already have an access token, you can head to this page to get one. You’ll need to authenticate by logging into your account and giving permission, but none of your data is stored on this site. The page uses client side authentication so your data never even hits my server. Once you’ve authenticated, the token will be displayed on the page and you can copy it and paste it to your working file.

Setting Up the Data

I used a lot of what I learned about accessing API data from the Shopify integration I wrote for another site to build this integration. You can check out this GitHub Gist for the full code, but let’s break it all down in more detail.

NOTE: In this example, I’m only showing a single account but for Love Taza there are two accounts in play. I essentially just duplicated this code for the second account, replacing all instances of `user` with a different string for the second user, and changed out the access token.

So first up, I created a couple of variables for the base data:

// Set variables
$image_number = 2;
$image_size = 'low_resolution'; //options: low_resolution (306), thumbnail (150), standard_resolution (612)

// Create the API URL for the user data
$user_access_token = '123456.xxxxxxxx.zzzzzzzzzzzzzzzzzzzzzzz';
$user_data_url = 'https://api.instagram.com/v1/users/self/?access_token=' . $user_access_token;

I’ve set the image number and size to variables to make it super easy to change them if I want to in the future, and I’ve also set that access token to a variable and then used it to create the API access URL. I did all of this in variables because it made it a lot easier to manage multiple accounts, but also because it makes the code easier to use for other applications in the future without having to do a lot of find and replace action within the markup.

Accessing the Account Stats (with Transient)

Now we’re ready to actually use that $user_data_url to access the API and get the account data, but as I mentioned Instagram has rate limits and we kept hitting them on Love Taza, killing our feeds.

The solution is to wrap the feed access in a WordPress transient, which stores the data for the specified amount of time and reuses it instead of repeatedly calling the API. Here’s the code:

// Use a transient for the feed URL (performance boost)
if ( false === ( $user_data = get_transient( 'instagram_user_data' ) ) ) {
    $user_data = @file_get_contents( $user_data_url );

    // Put the results in a transient. Expire after 4 hours.
    set_transient( 'instagram_user_data', $user_data, 4 * HOUR_IN_SECONDS );
}

This code checks for the “instagram_user_data” transient (similar to a cookie) and if it doesn’t find it then it gets that file data and creates that transient, set to expire after 4 hours. Two notes about this method:

  1. The @ symbol in @file_get_contents suppresses errors, which I wanted in this case but which will suppress errors that may be useful as well. If you are running into problems with your feed you may find it helpful to temporarily remove that for troubleshooting.

  2. Since the feed only gets updated about every 4 hours, it isn’t quite real-time. Sometimes it’s a couple hours behind the actual Instagram account, which is usually fine but is something to know if you’re implementing this.

As a result of this snippet, we have all the feed data stored in $user_data and ready to use.

Next, I set the stats from Instagram to a series of variables. Again, this is something I did for organizational purposes to make it easier to use multiple accounts and to see exactly what is going on in my code.

$user_stats = json_decode( $user_data, true );
$user_image_count = $user_stats['data']['counts']['media'];
$user_followers_count = $user_stats['data']['counts']['followed_by'];
$user_follows_count = $user_stats['data']['counts']['follows'];

The first line decodes the JSON file that the API returns, and the next three set the data points we’re going to be displaying to a series of variables for use in our markup later on. The first is the media count, which is the number of posts (images or videos), the second is the number of followers, and the third is the number of users this account follows.

Accessing the Image Feed (with Transient)

So far we’ve tackled the stats, but we also need to feed in a few of the recent images. To do this, we’ll set up another API call with another transient:

// Create the API URL for the user feed
$user_feed_url = 'https://api.instagram.com/v1/users/self/media/recent/?access_token=' . $user_access_token . '&COUNT=' . $image_number;

// Use a transient for the feed URL (performance boost)
if ( false === ( $user_feed = get_transient( 'instagram_user_feed' ) ) ) {
    $user_feed = @file_get_contents( $user_feed_url );

    // Put the results in a transient. Expire after 4 hours.
    set_transient( 'instagram_user_feed', $user_feed, 4 * HOUR_IN_SECONDS );
}

// Decode the JSON in the file
$user_images = json_decode( $user_feed, true );

Here, we’ve again set up a feed URL (this one uses that $image_number variable we set back in the beginning to tell Instagram how many images to send back), and then we’ve created another transient for the feed data with the same expiration time frame. Finally, we’ve set the decoded data to $user_images.

Setting Up the Display

Now that we’ve got the data and images we need, we can set up the display in a combination of HTML markup and PHP to spit out all that account information.

The Image Feed

Here’s the rough markup for the image feed:

<div id="instagram-feed">
    <?php $image = 0;
    // Loop through images in the feed
    for ( $user_image = 0; $user_image < $image_number; $user_image++ ) {
            $user_image_data = $user_images['data'][$image];

            // Display the images:
            $user_link = $user_image_data['link'];
            $user_caption = $user_image_data['caption']['text'];
            $user_image_url = $user_image_data['images'][$image_size]['url'];
            ?>
            <div class="instagram-image">
                <a href="<?php echo $user_link; ?>" target="_blank"><img src="<?php echo $user_image_url; ?>" alt="<?php echo $user_caption; ?>" /></a>
            </div>
        <?php 
        $image++;
    } ?>
</div>

We’re using PHP to loop through each image and grab its link, caption, and the image file URL. Instagram helpfully uses the same format for image previews for videos, so the $user_image_url will work even for video posts.

Then we use the variables we’ve created to display the image inside a link, inside a div (for layout and styling purposes).

The Account Data

The markup for the account data is also fairly simple, pulling in those variables we set earlier in the code:

<div class="instagram-info">
    <a href="http://instagram.com/username" target="_blank">@username</a><br>
    <?php echo $user_followers_count; ?> followers<br>
    <?php echo $user_image_count; ?> posts<br>
    <?php echo $user_follows_count; ?> following
</div>

The first linked line is just a regular HTML link to the account (you’d want to replace “username” with the actual account username, though). The next three lines show how to echo out and display the account stats using our variables.

The actual Love Taza display has more markup than this example in order to allow for the formatting and font styles, but this gives you the actual data display to work with.

Customization

That’s all there is to this custom implementation! Don’t forget, you can check out the full code in the gist.

The nice thing about going custom like this is that you have total control over the output, and how the data is handled and stored. You could get much more about each image, for example (comment count, likes, filter used, location data), or you could pull in the user’s profile photo and bio. It’s just down to the design at this point!