Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: coding

  • Show Featured Images on Post List

    Show Featured Images on Post List

    Let’s say you want to be sure every single post, in ever single post type, has a featured image. And you know someone might forget but you don’t want to have to open up every damn post to see.

    There are a lot of answers to this problem, and I love that there’s a plugin that will add in a Featured Image Column that shows a teeny featured image. But it wasn’t what I wanted. It was over kill.

    All I needed was a simple check mark for if there was an image and an X if there wasn’t, and that would suit me fine. And I wanted the column to be small, without a lot of fuss or folderol. I wanted something simple:

    My Featured Image Column

    That gives me a fast overview of if everything is what I wanted and where I wanted.

    The Code

    The code itself is the most basic column code, with a little bit of magic to put it as the first column on the list. Since I want to show this on all post types, I used the generic functions.

    /*
     * Show mark if featured image is set
     *
     * @since 1.1
     */
    
    add_filter('manage_posts_columns', 'helf_fi_manage_posts_columns');
    function helf_fi_manage_posts_columns( $columns ) {
    	if ( !is_array( $columns ) ) $columns = array();
    	$new_columns = array();
    
    	foreach( $columns as $key => $title ) {
    		if ( $key == 'title' ) $new_columns['featured_image'] = '<span class="dashicons dashicons-camera"></span>';
    		$new_columns[$key] = $title;
    	}
    
    	return $new_columns;
    }
    
    add_action('manage_posts_custom_column', 'helf_fi_manage_posts_custom_column', 10, 2);
    function helf_fi_manage_posts_custom_column( $column_name, $post_ID ) {
        if ($column_name == 'featured_image') {
            $post_featured_image = helf_fi_manage_column_check( $post_ID );
            $output = '<span class="dashicons dashicons-no"></span>';
            if ( $post_featured_image && $post_featured_image == true ) $output = '<span class="dashicons dashicons-yes"></span>';
            echo $output;
        }
    }
    
    function helf_fi_manage_column_check( $post_ID ) {
        $post_thumbnail_id = get_post_thumbnail_id( $post_ID );
        $post_thumbnail_img = false;
        if ( $post_thumbnail_id ) $post_thumbnail_img = true;
    	return $post_thumbnail_img;
    }
    
    add_action( 'admin_print_scripts', 'helf_fi_admin_print_styles' );
    function helf_fi_admin_print_styles(){
    	echo '
    	<style>
    		th#featured_image,
    		td.featured_image.column-featured_image {
    			max-height: 25px;
    			max-width: 25px;
    			width: 25px;
    			color: #444;
    		}
    		td.featured_image span.dashicons-no {
    			color: #dc3232;
    		}
    		td.featured_image span.dashicons-yes {
    			color: #46b450;
    		}
    		div#screen-options-wrap.hidden span.dashicons-camera {
    			padding-top: 5px;
    		}
    	</style>';
    }
    

    Fork and enjoy!

  • Custom Colors with the Twenty Seventeen Theme

    Custom Colors with the Twenty Seventeen Theme

    In building out a site, I had a cause to use Twenty Seventeen, the new theme for WordPress. I’d tested it before, helping figure out the usability of features. This time I was using it ‘for real’ and as I often say, there’s nothing quite as impressive as ‘for real.’

    Overall, I still find Twenty Seventeen as easy to work with as any other theme I’ve used. Customizing a theme to look like how you want is incredibly weird as it’s always a unique experience. This is to be expected. Themes are difficult when we’re trying to guess what people want. They’re second only to search in complex usability. In my use, I found two places where I felt other themes did things better.

    Documentation

    While there is a technical document on how to theme with Twenty Seventeen there is no walk through. For example, when I use StudioPress’ Genesis themes, every single one comes with a walkthrough of “How to make the theme look like our demo!” Twenty Seventeen has the luxury of the new default content, but even then, it’s not the same as directions. I have to do trial and error to figure out things like how to change the ‘section’ images on the front page.

    Answer? Change the featured image. Of course. That was logical to me because I’m an experienced WordPress user. I can’t say it was logical to anyone else.

    A great deal of the theme makes sense contextually. By which I mean if you look at it, it all follows and you can suss out what’s next. But it’s not perfect. No theme is. I still think if a simple walkthrough doc existed, it would help a lot of first time WordPress users.

    Colors

    About a day into my project, I’d used Twenty Seventeen, ditched it for something else, wrote a lot of custom post type/taxonomy code, and then came back to Twenty Seventeen. By the time I did, I had a very clear-cut idea in my head about what I wanted the base color to be.

    I have to explain it like that because that’s pretty abnormal, I feel. Most people don’t go “I want to use #d1548e as my base color for links and stuff!” They go “I want pink!” The problem here is that if you look at the color tool for customizing colors, it’s a slider. And worse, it’s a slider without an override.

    Twenty Seventeen Custom Color Slider

    Now compare that to the picker you get for the Header text color:

    Twenty Seventeen Custom Color Picker for Header

    Right there I can go in and put my color in hex format and it uses it. Perfect.

    I can guess why they don’t have this for the custom color, though. Twenty Seventeen does something special with colors and instead of just saying “Links are pink and headers are magenta,” it uses saturation. This lets the theme create a dynamic color scheme based on your selection. Which is fucking awesome, right up until you’re me (or you try to use the exact same color schema twice).

    I want to stress that I do not feel this was a bad choice for the theme. Since the theme is going to use math to cleverly calculate out what the related colors should be for the theme, it’s genius to set the colors on a slider. This puts the concept in your head, when you move the slider, that the colors are relative to each other. It’s a perfect example of seamlessly introducing new users to a tool. It’s actually intuitive.

    How I ‘Fixed’ My Color Woe

    First I made a lot of jokes with my buddy James about how they would ‘hue the day’ for this one. Because thats how I roll. Then I dug into where the hell this was set at all. Like all WordPress settings, its saved in the database in the wp_options table, under theme_mods_twentyseventeen which has a value like this:

    a:5:{i:0;b:0;s:18:"nav_menu_locations";a:2:{s:3:"top";i:2;s:6:"social";i:3;}s:18:"custom_css_post_id";i:-1;s:11:"colorscheme";s:6:"custom";s:15:"colorscheme_hue";i:312;}'
    

    Yours may be longer. The important bit is here: s:15:"colorscheme_hue";i:312

    That number, 312, is the color hue! If you change it, it changes the colors. Once I knew that, I had to reverse engineer a hex code into a hue. To do that, I used workwithcolor.com. That site has a color picker, and if you put in the value you want (say d15483 it spits back a whole lot of information.

    The Hue Picker with a LOOOOT of information

    That part I circled, the 337, that’s the important part. I can now go into my database and change 312 to 337 and magically it works.

    But boy that sucks. Instead I used set_theme_mod() to fix it by putting this in my theme’s function:

    add_action( 'after_setup_theme', 'helf_after_setup_theme' ); 
    function helf_after_setup_theme() {
    	$hue = '337';	
    	if ( get_theme_mod('colorscheme_hue') !== $hue ) set_theme_mod( 'colorscheme_hue', '337' );
    }
    
    

    If I wanted to get fancy, I’d put in a real control for it, but this at least gets me started.

  • Prefix or Suffix

    Prefix or Suffix

    I’ve been seeing a lot of a new trend in coding, which stems from boilerplate plugin code, and that is the use of suffixes in function names. This has become increasingly popular in WordPress code and I, for one, am not a fan.

    WordPress Function, What’s Your Function?

    Otto likes to say that well named functions don’t need code comments.

    While optimistic in this day and age of complex code, the basic concept remains quite valid. If you name your functions well, the chances are that they will trigger your contextual memory and you’ll remember what they are, what they do, and why they’re there. To this end, the difference between function activate_pluginname() and function pluginname_activate() is miniscule. Both of those are clearly functions that run on ‘activate’ and that makes perfect sense. We can see the purpose of the function by its name, and that is the majority of Otto’s point. They are well named as they indicate their job. The issue then does not like in the name of the function but in the format of the name of the function.

    Function Name Conflicts

    A majority of the time, my argument for having unique function names is that there are over fifty-thousand plugins out there, and the odds of two of them having the same function name is quite high, for cases when the function name is generic. For example, function my_plugin_init() is not unique in the slightest. Yes, people literally use my_plugin_ as a prefix. That’s not a placeholder. That particular error occurs when people use boilerplates and don’t read the directions clearly. Most state “Search and replace my_plugin with your plugin prefix.”

    Preventing conflicts means it’s incumbent of developers to select unique function names. Now this pressure is alleviated by the use of namespaces and classes, but even those have to be unique to their plugin (or theme). After all, class WordPress is not a great classname.

    Again, in this regard there is very little difference between function activate_pluginname() and function pluginname_activate() in the real world. Both are unlikely to cause conflicts.

    Internal Consistency is Good

    Another aspect of names is that good function names are logical and consistent. Few things pain me more than seeing function pluginname_init() and function pn_admin_init() (where pn is an abbreviation for the plugin name). What I see a great deal with the plugin name as suffix is this hodgepodge of names:

    • init_plugin_name()
    • plugin_name_uninstall()
    • pn_wp_class_list()

    My guess at this point is that any time a particular boilerplate doesn’t specify the name of the function needed, people fall back into old habits. Or rather, they fall back into the recommended habits. You know, a prefix. Consistently named functions make it easier for people to recognize what function belongs to what plugin or theme.

    So why Prefix?

    This takes us to an interesting point. Both function activate_pluginname() and function pluginname_activate() meet the requirement of being well named and unique (and can be consistent). So what actually is the problem here?

    The problem is the future.

    Your code does not exist in a vacuum! Code that will only ever be used on your own server still runs with the other plugins and themes you add, and they could cause a conflict. It’s somewhat trivial to change those things, but it’s not fun and usually it means that you broke something in your live environment.

    • Consistently named functions make it easier to know what function relates to what.
    • Uniquely named functions are easier to find.
    • Well named functions remind you what the function is supposed to do.

    But again, why prefix?

    Remember Who Comes Next

    I do a lot of searches on code in myriad plugins. More than most people involved in WordPress I suspect. I have a very peculiar relationship with plugins, after all. When the core developers want to figure out how ‘well used’ a function is before changing it, I help out by running a search on all the code in the plugin directory. This results in me finding a lot of weirdly named functions that require me to track back through the plugin and find out what it’s really doing. When things are prefixed, this search goes a lot faster.

    Besides just my convenience, when you remember that your code is used by thousands of people, they will have an easier time searching for your code when they have an error. If you got an error that a function named halfelf_init was doing something wrong, you could run this to find the file: grep -r "halfelf_init" ./wp-content/

    Some of the more experienced debuggers out there are probably wondering why I grep from wp-content when most errors give the full path of wp-content/plugins/plugin-name/filename.php in the first place. The answer to that is “most” but also because often functionality plugins that are related to a theme (or other plugins) will cross-reference themselves in ways that can cause PHP to give you the wrong file for the problem.

    If you ran my check and found that the function was called in nothing but files in that plugin’s folder, great. But if you found it was called in a theme, you would then want to run this: grep -r "halfelf_" ./wp-content/themes/theme-name/ — That would reveal all the calls for the functions that belonged to a specific other tool.

    And what if you got a warning that the function had already be declared? grep -r "function halfelf_" ./wp-content/plugins/other-plugin/ will list all the functions that start with halfelf_ and save you a headache of solving one warning only to have it be replaced by another. (Of course, if you use namespaces or classes, this gets thrown out the window, oh well).

    Finally there’s the human factor. This is exceptionally subjective, I know, but doesn’t a line of functions all starting with the same term feel cleaner to you? It demonstrates a repeating pattern that a human mind can follow and feel comfortable with.

    Solution: Be Consistent

    There’s only one solution to be had here. While I greatly prefer a prefix, if you chose to use a suffix, be consistent. Make every single function end with _pluginname and don’t skip a single one.

  • Mailbag: When Do I Use “If Exists”?

    Mailbag: When Do I Use “If Exists”?

    Someone pinged me on slack about this. Bear in mind, I tell people “If you got an email from plugins, please press reply and email back, don’t slack me.” because it allows me to keep track of the whole history of a conversation, but also because if I’m sick, someone else can reply to you and you’ll wait less. While, in this case, the answer should have been very short, it grew to be a lot longer than he’d expected because he didn’t quite understand what I meant.

    Unique Prefixes

    One of the requirements of the Plugin Directory is that all plugins have unique function names, defines, and classnames. This is for a pretty obvious reason: it will prevent your plugin from conflicting with other plugins or themes.

    • For plugins, use a function or classname that matches the plugin name: class ThisPluginName{} or function ThisPluginName_FUNCTION()
    • For specific specific sites, use a function class for the domain: class HalfElfOrg{} or class HELF{} or function helf_FUNCTION

    This extends to all things, including defines, namespaces, enqueue’d handles, and on and on. As I tell people, “A namespace or class of MyPlugin is not actually all that unique…” Defines are extra tricky since sometimes you want to define them and allow them to be replaced. But more on that in a minute. No matter what, this is bad: define( 'PLUGIN_PATH', plugins_url( __FILE__ ) );

    Since it’s 2016, I have to tell people that they shouldn’t use two letter slugs anymore as all the good ones are taken. I also tell them not to use wp_ or __ as a prefix.

    And then I say this:

    If those are intended to be in shared libraries, please detect IF the code is already included and not re-include it, as doing so will cause conflicts if two people call the same defines and functions.

    Yeah. It’s messy.

    If Define Exists…

    This is used a lot. Let’s say you know you need the plugin basename (the folder name) in multiple sub folders of you plugin, and it’s a pain in the ass to do plugins_urls( 'foo.css' , dirname( dirname( __FILE__ )) ); to go up two folders. That’s a case where a global define starts to make sense and it’s a case where rarely would you want to bother checking if it exists.

    The code is just this: define( 'MY_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

    But what if you want to have a default value for an API Key and allow people to override it? Then you can one of these:

    // Option 1:
    if ( ! defined( 'MY_PLUGIN_APIKEY' ) )
        define( 'MY_PLUGIN_APIKEY', 'default key value' );
    
    // Option 2:
    defined('MY_PLUGIN_APIKEY') or define('MY_PLUGIN_APIKEY', 'default key value' );
    

    What those do is check “Does the define already exist?” for you.

    Now keep in mind, I wouldn’t do that. I’d do this:

    $apikey = ( defined('MY_PLUGIN_APIKEY') ) ? MY_PLUGIN_APIKEY : 'default key value' ;

    The best example of this in core WP is how WP_DEBUG is handled. If you delete that from your wp-config.php file, it doesn’t turn on debugging. The code checks for the existence and if it’s not there, it assumes no. For the most part, if you name your defines properly, there’s no need to allow them to be overwritten because you’re not defining them in advance. But in case you do, this code is a wise idea.

    If Function (or Class) Exists …

    Lately I’ve seen a lot of people do this:

    if ( ! function_exists( 'my_awesome_function' ) ) {
    	function my_awesome_function() {
    		//function stuff
    	}
    }
    

    Okay look. This sounds like a great idea until you realize the fatal flaw. What happens when (not if, when) someone else has a function with the same name and their plugin or theme loads first?

    As Lilu Dallas would say “Big badda boom.”

    This is a terrible idea unless we’re talking about shared libraries.

    Use if-checks With Shared Libraries

    That’s my answer here folks. The only time you should be checking if-exists is WHEN you are using a shared library. If your plugin includes a common PHP library, check for it before you include it.

    It’s a little different with Javascript and CSS though. Let’s say you’ve got Bootstrap. This is a commonly used library. A lot of plugins and themes have it, and you’re a good person. You want to make sure you only load it one time no matter how many people include it in their plugins and themes. In this moment, you have to do something paradoxically brilliant.

    Don’t use a unique name for your enqueues.

    function mypluginname_resources() {
        wp_enqueue_style( 'bootstrap', plugins_url( 'css/bootstrap.min.css', __FILE__ ), array(), VERSION );
        wp_enqueue_script( 'bootstrap', plugins_url( 'css/js', __FILE__ ), array(), VERSION );
    }
    add_action('wp_enqueue_scripts', 'mypluginname_resources');
    

    The magic here is specific to how WordPress handles enqueues. It knows “There’s already something enqueued as bootstrap! I don’t need this!” and you’ve sped up sites. Of course there’s a risk here when someone might have an older version loaded first. As far as I know, the enqueue system isn’t clever enough to detect what version is included, and use the newest one (I wish it was), so you may have to do some convoluted checks. Also making this worse is that people don’t name things properly. I’ve see people using bootstrap-js and bootstrap-css for the enqueue names, which is totally unnecessary. WordPress will handle that for you.

    Remember: When in doubt, if coding for WordPress do it the WordPress way.

  • PHP Ternary Operations

    PHP Ternary Operations

    I mentioned a few days ago that I finally got to use ternary operations in my code and I was excited.

    I have a tendency to write my code out long form, which stems from how I actually sit down and think about my code. For example, when I need to check if specific parameters are set, I write it out like this:

    If variable X is equal to FOO, then do BLAH. Else do DEFAULT!

    When I translate that to PHP code, it becomes this:

    if ( $variable == 'FOO' ) {
        BLAH;
    } else {
        DEFAULT;
    }
    

    There’s nothing particularly wrong with it, but it can get a little long. And then consider code like this:

    if($_POST['variable'] == 'no' || $_POST['variable'] == 'yes'){              
        $variable = $_POST['variable'] ;
    }
    

    That has two issues. The first is that I’m trusting my data a little more than I should and not sanitizing when I save the variable. The second is I’m not validating smartly. If I want to be smarter, I do this:

    if( $_POST['variable'] == 'yes'){              
        $variable = 'yes ;
    } else {
        $variable = 'no';
    }
    

    At this point, I’m no longer allowing my code to be anything but yes or no, and if someone puts in ‘maybe’ as a value for the POST data, that’s nice but I’m forcing no.

    Another alternate way is this:

    $variable = 'no';
    if( $_POST['variable'] == 'yes'){              
        $variable = 'yes ;
    }
    

    There I default to ‘no’ and only pick ‘yes’ if it’s set to yes. This code is somewhat better because it only has one check and it’s obvious what my default is.

    But we can be even smarter! The trick is that I have to rethink how I’m checking for things. If all I care about is if a comparison is true or false, and I want to save a specific value to a variable based on that, then I can do my code all in one line:

    $variable = ( $_POST['variable'] == 'yes' )? 'yes' : 'no';
    

    This is the magic of the ternary operators. With it I get one line that checks for a specific result and defaults when that’s not it. You can make it more complicated, as long as the result is true/false. Like here:

    $schema = ( is_ssl() || get_setting( 'plugin-force-ssl' ) )? 'https' : 'http';
    

    Obviously they won’t work in all situations, and there are some cases where the two possibilities are going to make the code harder to read, but they can be downright nifty if you do them right.

  • Rebranding Featured Image

    Rebranding Featured Image

    WordPress 3.0 introduced featured images, letting everyone designate an image for a post (or page) in a way that themes have taken great advantage of in the intervening years. The concept of a ‘featured’ image was easy enough to understand. An image the content featured. Cool. But it can do so much more.

    The Defaults

    The basic box is one all WordPress users are familiar with:

    The basic featured image box

    A simple box that says “Featured Image” with a link to set the featured image.

    It’s great, but it’s a little boring.

    Changing the Title

    The actual trick to this is to remove the metabox. The three attributes you will need are the name of the meta box, the post type, and the location. The post type is the one most of you are going to change. For example, I wanted to change the title for a specific post type so it was clearer what kind of image I was looking for to use as a featured. For TV shows, I wanted it to indicate that I was looking for a Title Card type image.

    add_action('do_meta_boxes', 'featured_image_title_post_type_shows');
    function featured_image_title_post_type_shows() {
        remove_meta_box( 'postimagediv', 'post_type_shows', 'side' );
        add_meta_box('postimagediv', __('Show Image/Title Card'), 'post_thumbnail_meta_box', 'post_type_shows', 'side');
    }
    

    This little snippet removes the meta box and then adds it back with a new title:

    Customized feature image with new title

    Changing the Main Content

    Once the title is changed, the next step is to change the content. I’ve done this before, putting in the image size to the content. What I wanted to do here was change the content from “Set featured image” to “Set show image” and for that, I want to use a string replacement:

    add_filter( 'admin_post_thumbnail_html', 'set_featured_image_text_post_type_shows' );
    function set_featured_image_text_post_type_shows( $content ) {
        global $current_screen;
    
        if( !is_null($current_screen) && 'post_type_shows' == $current_screen->post_type )
            return $content = str_replace( __( 'Set featured image' ), __( 'Set show image' ), $content);
        else
            return $content;
    }
    

    But that only changed the one. Once you’ve set a featured image, the language changes to “Remove featured image”. I could add in more replacements, or I could be smart. We like being smart.

    return $content = str_replace( __( 'featured' ), __( 'show' ), $content);
    

    And yes, it works.

    Customizing by Type

    What if you have ten custom post types? Well then it’s time to get smart! By using anonymous functions, we can do this quite effectively, getting a list of all the publicly registered post types that aren’t the built-ins, and then for each one, renaming the content:

    // Customize Featyred images for CPTs
    add_action( 'admin_init', 'helf_featured_images' );
    function helf_featured_images() {
    	$post_type_args = array(
    	   'public'   => true,
    	   '_builtin' => false
    	);
    	$post_types = get_post_types( $post_type_args, 'objects' );
    	foreach ( $post_types as $post_type ) {
    
    		$type = $post_type->name;
    		$name = $post_type->labels->singular_name;
    
    		// change the default "Featured Image" metabox title
    		add_action('do_meta_boxes', function() use ( $type, $name ) {
    			remove_meta_box( 'postimagediv', $type, 'side' );
    			add_meta_box('postimagediv', $name.' Image', 'post_thumbnail_meta_box', $type, 'side');
    		});
    
    		// change the default "Set Featured Image" text
    		add_filter( 'admin_post_thumbnail_html', function( $content ) use ( $type, $name ) {
    			global $current_screen;
    			if( !is_null($current_screen) && $type == $current_screen->post_type ) {
    				return $content = str_replace( __( 'featured' ), strtolower( $name ) , $content);
    			} else {
    				return $content;
    			}
    		});
    	}
    }
    

    This trick uses the values of a custom post type which you already set when you built out your custom post types.

    Customizing the Content Further

    Now that we’ve changed ‘featured’ to match our custom post types, it’s time to take it even further. Can we smartly add in the image size? Usually the answer here is no, because it’s impossible to know what you want to have as your featured image size for each custom post type. As it happens I can because I was smart.

    Every single CPT that has a special image has an image size for it:

    add_image_size( 'character-img', 150, 200, true );
    add_image_size( 'show-img', 960, 400, true );
    

    And my post-names for those things are ‘post_type_characters’ and ‘post_type_shows’. This means I can add the following to my filter for admin_post_thumbnail_html:

    		add_filter( 'admin_post_thumbnail_html', function( $content ) use ( $type, $name ) {
    			global $current_screen;
    			if( !is_null($current_screen) && $type == $current_screen->post_type ) {
    			    // Get featured image size
    			    global $_wp_additional_image_sizes;
    			    $genesis_image_size = rtrim( str_replace( 'post_type_', '', $type ), 's' ).'-img';
    
    			    if ( isset( $_wp_additional_image_sizes[ $genesis_image_size ] ) ) {
    			        $content = '<p>Image Size: ' . $_wp_additional_image_sizes[$genesis_image_size]['width'] . 'x' . $_wp_additional_image_sizes[$genesis_image_size]['height'] . 'px</p>' . $content;
    			    }
    				$content = str_replace( __( 'featured' ), strtolower( $name ) , $content);
    			}
    			return $content;
    		});
    

    This could even be extended to only show the image size when it was not set. For now, this does what I want.

    How’s it look?

    Not bad:

    Featured Images renamed and rebranded

    And there you have it. More information for your users to know what kind of and size image to use.