Simple Custom CSS Turns Three!

Standard

This month, 0ur Simple Custom CSS WordPress Plugin turns 3 years old, and it has made the GoDaddy Top 100 Plugins of the week!

As you can imagine, I’m quite proud.  This plugin began a quick four-hour project to solve a development problem I was having.  Now, it’s used in over 300,000 active WP installs.  Wow!

Thanks to everyone who has commented in the support forums, both asking and answering questions.  Also, a huge thanks to those who have contributed by issuing pull requests in our GitHub repo with code improvements and translations.

It’s crazy to think that something I cooked up in my home office is now used by so many people in so many diverse places.

I love being part of the open source WordPress community, where our work benefits people all over the world, and with all of us working together to make the internet a better place to communicate and share ideas.

Featured Image via GoDaddy.

Practical Tips for your WordPress Job Application

Standard

I’ve been increasingly involved in hiring at my company, and I’ve learned a lot about the job hunt from being in the seat across the table, so to speak. I’d like to pass my experience and perspective on to you to help you get an interview.

I’ve come up with some tips to help you land a job, specifically in the development field, and even more specifically if your application comes my way. Most of these tips would apply to any job search, and I’ve also included some more information on what development employers are looking for.

These are all things I wish I would have known earlier in my career. I truly hope this helps you put your best foot forward with your prospective employer!

Perception is Everything

Perception is everything. It’s not fair, but it’s a psychological fact: employers get a “feel” about who you are based on your communication. And, for as hard as I try to overcome that bias, it’s just naturally going to happen. “You never get a second chance to make a first impression.”

Rock your Initial Email

Your initial contact email to an employer is critical. You must make a statement as quickly as possible, and this means attaching examples of your best work in that email; don’t just send a written message.

It’s easy for an employer to make assumptions about you based on that initial contact, and you want to give me access to as much information about you as you can provide to help with that first perception.

It goes without saying that you must ensure you’re using good grammar and spelling in your email. This speaks a lot to your professionalism and attention to detail.

Attach a resume, functional code sample, and links to your best work. Having quick access to these items will help me have an objective view of what type of developer you are.

Bonus points for links to WP community contributions, including core patches and your own plugins and themes.

ProTip: don’t use your KurtCocaine@SofaKingCool.com email address to send this.

Your Resume

Make this look sharp!

It’s impressive to have a great design. You can find some great help with this on GraphicRiver.

Include a cover letter with a bit about yourself and your personal philosophy about development and what you are doing to grow.

Avoid overly general and/or convoluted wording about your former responsibilities. It just looks like filler or complete BS to me.

Outline relevant work experience. It’s irrelevant to me if you were a cashier at Wal-Mart, so in my opinion, you can ethically leave that off. These minor facts don’t take points off with me (unless you used to work for Comcast), they just add more data to scan through. I only use relevant development work experience in my own personal resume.

In our field, a solid portfolio of work is much, much more important than degrees or awards. List those, to be sure, but be aware that your actual work experience and quality is much more important.

Code Sample

Attach a code sample in your initial email. Make sure this is functional code that I can install and test, not just a few code snippets. I know how easy it is to pull some fancy looking stuff off of StackOverflow, and you don’t want me to even have that thought in my mind when I’m looking at your work.

Do some advanced stuff in your code sample. For Front End folks, use CSS3 transitions and keyframes. I also like to see Object Oriented Javascript. On the Backend, I like to see WordPress-flavored Ajax, API interaction, and Object Oriented Programming.

Whether Front End or Back End, all of your work should adhere to WP Coding Standards, including details like proper spacing on all code, as well as docblocks.


Online Presence

It’s been my personal mission to find out everything I can about a prospect before writing a response email to either set up an initial interview with the developer or writing the dreaded (but kindly worded) rejection email.

Even more than what you say about yourself, I want to find out who you really are. Having a positive, teachable team player is even more important to me than dealing with a snobby but talented code-jockey.

I’ll be all over the internet to find out everything I can about you. I think I’m reasonable enough to know that all of your online interaction isn’t going to be “professional” or development-related, but I will be looking for insight into your personality.

Google Yourself

30 Rock Google YourselfWhen researching a prospect, the first place I go is Google — sometimes before even digging deeply into their code. Your online activity says a lot about your personality, and to me, who you are is more important than your skillset.

Take some time and check out what Google has to say about you. I’m not saying you should try to have Google wipe undesirable facts about you, but if you have an old personal site that would look bad to a potential employer, you might want to take it down, edit your SEO settings in your robots.txt, require authentication to view the site, or even use Google Webmasters to block certain pages of the site from being crawled.

ProTip: I usually start with a search on “John Smith Developer,” or “John Smith Kansas City.”

Focus on beefing up the sites that are the top results for your name. This means things like your personal site, WP profile, LinkedIn account, etc.

By the way, I understand if I find an ancient Blogger site that was barely used at all. Don’t sweat it; I have those myself.

Social Media

The next thing I do is stalk you on social media to gauge your personality and interests. You don’t have to post a lot about development, I just want to get a feel for you.

Start by maintaining a social media presence. If you don’t have one, it looks like you live under a rock, and that’s not going to work in a media-driven field.

Remember that prospective employers will read everything you post. You don’t always have to be dressed in a suit in your pictures, but be mindful that your overall personality will be revealed by your tweets and posts.

Facebook is a common place I search. I like being able to read about your daily life. If you have questionable activities you don’t want me to see, change your privacy settings; if there’s a bong on the table in the background of a pic, I’m going see that. 😉

ProTip: Don’t let me find your Reddit username. We both know you don’t want me to see that.

Your Personal Site

Keep your site up to date. It doesn’t matter if it’s about your passion for N-scale model railroading. I just want to get to know you.

Remember that perception is everything to get that first interview. The design of your blog is a reflection of your work and attention to quality, even if you didn’t build it yourself. You get major bonus points if you did build it yourself. It doesn’t have to be fancy, but the code needs to be tight.

You don’t have to update your blog regularly; we all understand how hard it is to maintain a personal blog. However, if your posts are focused on your development, include some stuff about your passion for the work. Post helpful code snippets and your opinion about development tools and issues.

Also, it looks really good to host examples of your work, even if they’re not linked from the main blog. Full demo sites are great. They give you the power to make your own decisions about sweet design and technical features that you may not have on sites built for clients and picky designers.

If you’re not a designer, go and download a PSD or HTML template then build it out yourself. There’s no shame in that at all. Ultimately, I care more about your code than visual appeal, but once again, keep in mind that initial perceptions are important.

Github/Bitbucket

I love to see activity on your GitHub and/or Bitbucket accounts. This shows me that you’re developing your own personal projects, and that’s a big plus. These serve as code samples that you haven’t polished up before submission to an employer, so they reveal how you typically work.

Smarterer Score

There is debate about the reliability of a Smarterer score in relation to actual development skills, but it helps people like me get a feel for your knowledge of WordPress. Take the quiz on CodePoet and work to get your score over 700. I’ve known some incredible PHP/JS developers who I’ve been unable to hire simply because they don’t know the WP system. This score will give us both a quick glance at your proficiency.

Final Thoughts

Your work and online persona are an opportunity for you to shine before a prospective employer. I’ve included this “insider” information to help you make a great impression when you first reach out for a new position.

These are all things I wish I’d known several years ago, and I hope they will help you make a powerful first impression to those considering you as a new member of their team.

By the way, if you’re interested in working with me and my teammates on big projects with lots of fun challenges and opportunities to grow, hit us up at xwp.co. I’d love the chance for us to get to know each other!

OOP with WordPress – For the Total Newbie

Standard

Object-Oriented Programming (OOP) is a common method used to encapsulate code. Although it can be used for techniques much more advanced than we’ll discuss here, it can be used for basic plugins quite easily so you can learn its basics.

In this tutorial, we’ll create a short plugin that creates a Custom Post Type called “Books,” and an associated taxonomy called “Genres.” This is a fairly common operation in WordPress, and can certainly be created without using OOP, but since you’re probably already familiar with that process, it will serve as a good base for this tutorial.

Skip to the full code »

The primary “element” of OOP is the Class. For our purposes, it’s a wrapper that holds all of the internal functions, which in the context of OOP are called methods.

Creating a Simple Class

We start by creating our Class.

class JR3_Books {
     static function setup() {}
}
add_action( 'plugins_loaded', array( 'JR3_Books', 'setup' ) );

Our Class is “JR3_Books.” Each word in a Class’s name is capitalized, and underscores represent spaces.

Inside of it, we place a method that we’ll call setup(). You’ll note that you usually want to prefix your functions in WordPress to avoid conflicts, but since this is within our Class, it isn’t necessary.

You’ll note the word static before the method setup(). This is important for the way that we will be calling our methods in this tutorial, but the reason why isn’t important right now.

Firing the Class

Finally, we called the plugins_loaded action after the class. This is an important thing to note, as we’ll use a similar format within the Class.

Note that usually, an action looks like this:

add_action( 'plugins_loaded', 'setup' );

However, we have to let the add_action() know that setup() is located within our Class.

This is done by turning the second argument from a simple string into an array that includes the name of our Class, which gives us this:

add_action( 'plugins_loaded', array( 'JR3_Books', 'setup' ) );

Note: There are a lot of ways to instantiate a Class, and some are more appropriate than others. For the sake of simplicity and consistency in this tutorial, I’m taking the simple add_action() route

Adding A Method

Now, we add our method to register the post type. This will be done very similarly to how we commonly use register_post_type(), and we’ll use an action to fire this off in just a minute.

For now, this method goes within the Class, just like our setup() method.

static function register_books_cpt() {
     register_post_type( 'jr3_books', array(...) );
}

Note that I haven’t filled in the register_post_type() function completely here for the sake of clarity.

So, right now, our plugin doesn’t do anything. As I said above, we need to use an action to make this new method fire off. We do this by adding the appropriate action within our setup() method.

static function setup() {
     add_action( 'init', array( __CLASS__, 'register_books_cpt' ) );
}

Once again, you’ll note that we’re using an array as the second argument in the action. This time, however, we aren’t using the Class name, “JR3_Books.” Within a class, you use the Magic Constant __CLASS__. Also, the second value in the array is the name of our new method.

To translate this action into words, it tells the code to, on init, look inside of this Class for the method register_books_cpt.

In the code snippet below, you’ll see that I’ve also added a method for adding a custom Taxonomy (called, “Generes”), using the same technique.

Conclusion

What we’ve done here is we created a Class to hold our code. Inside of it, we added a setup() method to maintain the actions we’ll fire during our plugin. Then, to kick things off, we added the add_action( 'plugins_loaded' ... ) to tell WP to load our Class.

Naturally, this is a very high-level view of OOP. These can do extremely intricate and complex functions for you on your projects, and I hope that this will get you on your way to understanding how they work!

BONUS: The code below is a partial example of what we’ve covered. Here’s a fully-functional example this code that you can place in your wp-content/plugins directory to play around with.

Further Reading

 

Basic Example of this Tutorial

/*
* Plugin Header…
*
* Note: This particular block of code won't actually run because it doesn't have
* the details of the register_post_type and register_taxonomy functions filled in.
*/
class JR3_Books {
/**
* Fires all hooks for this plugin
*/
static function setup() {
add_action( 'init', array( __CLASS__, 'register_books_cpt' ) );
add_action( 'init', array( __CLASS__, 'register_genres_taxonomy' ) );
}
/**
* Basic setup of a Custom Post Type
* @see http://codex.wordpress.org/Function_Reference/register_post_type
*/
static function register_books_cpt() {
register_post_type( 'jr3_books', array() );
}
/**
* Register Custom Taxonomy for this Custom Post Type
* @see http://codex.wordpress.org/Function_Reference/register_taxonomy
*/
static function register_genres_taxonomy() {
register_taxonomy( 'jr3_genres', 'jr3_books', array() );
}
}
//Load the plugin by firing the setup() method.
add_action( 'plugins_loaded', array( 'JR3_Books', 'setup' ) );

view raw
oop-plugin-basic.php
hosted with ❤ by GitHub

Adding Support for Vertical Featured Images in WordPress Themes

Standard

Here’s a quick and easy way to add support for Vertical Featured images in your WordPress themes.

How it Works

Using a filter hook, we’re going to add a class to the Featured Image markup if the image’s height is greater than its width. Then, using CSS we’ll float it to the right. Pretty simple, huh?

The Script

In your functions.php file add:

The CSS

This code floats the image to the right and adds some margin to separate the image from the post’s content. Be sure to include it in your CSS file.

.vertical-image {
	float:right;
	margin-bottom: 1em;
	margin-left: 2%;
	max-width: 33%;
}

Caveats

Your Post title will need to be clear: none; if this happens:

Screen Shot 2014-01-02 at 2.13.46 PM

You may need to add overflow:hidden to your post’s CSS to prevent this from happening in case the post excerpt is too short:

Screen Shot 2014-01-02 at 1.59.06 PM

The Result

This is what it should look like if the Feature Image has a vertical (portrait) orientation:

Screen Shot 2014-01-02 at 1.53.14 PM

Conclusion

When researching this, I had a hard time finding resources on this topic, so I hope this helps! If you find this post helpful, be sure to pass it on, including a link to this post!

Scheduling Events with WordPress Tutorial

Standard

There are many reasons to schedule events; maybe you need to check an external API, or prehaps periodically empty a cache. This process can even be used for something as simple as making a post un-sticky after a certain length of time.

Scheduling Events in WordPress is basically running a Cron, just simplified by WP. There are several functions available as tools for this process, and here we’re going to take a look at three of them:

In the code at the bottom of this post is a plugin that you can insert into your wp_content/plugins folder. It will produce an admin menu item entitled “Schedule Event Tutorial.” This plugin is very simple: You check a checkbox and set a time for it to become unchecked. After that time has passed, the checkbox will become unchecked.

Screen Shot 2013-11-11 at 10.23.07 PM

The Process

The way the plugin works is that when the checkbox is checked and a time is selected, a function is run that does two things:

1. Checks to see if another “unchecking” event is already scheduled. If so, it removes that event.

2. Schedules the new “unchecking” event.

How it Works

First of all, The actual unchecking is done by the function uncheck_checkbox(). You will see around line 44 that we have hooked that function into the action we’re calling ‘uncheck_event_hook’.

This is just like any other add_action(). The array(__CLASS__….) part is a part of the Object-Oriented Programming we’re using. It tells the add_action function that we’re referencing a method (funciton) inside this class.

add_action( 'uncheck_event_hook', array( __CLASS__, 'uncheck_checkbox' ) );

The interesting part is teling ‘uncheck_event_hook’ when to fire.

Now, follow along in the schedule_event() function…

First, check to make sure process only runs if the “Save Changes” button has been pressed.

if ( ! isset( $_GET['settings-updated'] ) )
    return;

Then a check is run to see if an event exists on this hook. It gets the next time this hook is scheduled to fire by using wp_next_scheduled. Then, if any value is returned, wp_unschedule_event is used to unschedule that event from the ‘uncheck_event_hook’.

// Remove any scheduled event on this hook
    $scheduled_event = wp_next_scheduled( 'uncheck_event_hook' );
    if ( $scheduled_event !== false ) {
        wp_unschedule_event( $scheduled_event, 'uncheck_event_hook' );
    }

Next, we do the actual scheduling. We grab the value of our expiration time setting, and if it’s a number, we set the time the ‘uncheck_event_hook’ will run.

// Schedule the event to uncheck the checkbox
    $exp_time = self::expiration_time();
    if ( is_numeric( $exp_time ) ) {
        wp_schedule_single_event( $exp_time, 'uncheck_event_hook' );
    }

At this point, we wait until the time passes our expiration time, then on the next time any page is viewed on your site, the ‘uncheck_event_hook’ will fire off uncheck_checkbox(), as we set in the add_action() at the beginning of the process.

The Full Plugin Code

I decided to write this as a fully-featured plugin for a few reasons:

  1. An installable plugin would help make this process a bit more practical
  2. I learn best by viewing others’ code. Maybe you can learn something new by looking at how another developer does it

By presenting the full code, less-experienced developers have the chance to learn more about Object-Oriented code, as well as what it takes to set up a Plugin. Of course, if you have any questions about what’s going on, be sure to hit me up. I’d love to help you on your way to learning something new!

<?php
/**
* Plugin Name: Schedule Event Tutorial
* Description: Schedules single event to uncheck a checkbox on a custom Menu page
* Version: 0.1
* Author: John Regan
* Author URI: http://johnregan3.me
* Text Domain: setjr3
* License: GPLv2+
*/
/**
* Copyright (c) 2013 X-Team (http://x-team.com/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2 or, at
* your discretion, any later version, as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* This class is where you can see Scheduled Events in action.
*
* Here, the old scheduled event is unscheduled and the new event is set.
*/
class Schedule_Event_Tutorial {
/**
* Registers our 'uncheck_event_hook" action hook that fires our un-checking action.
*/
static function setup() {
// Scheduled Event Hook
add_action( 'uncheck_event_hook', array( __CLASS__, 'uncheck_checkbox' ) );
}
/**
* On settings save, Update scheduled event time.
*
* Begin by removing any scheduled event on our 'uncheck_event_hook' hook.
* Then, we format the saved time to Unix.
* Finally, we schedule the event.
*
* Typically, this could be fired when a post is saved ('save_post' hook, for instance),
* but it's not really that easy on an options page like this one.
*
* @action 'load-{page}'
* See Schedule_Event_Tutorial_Setup::menu_page()
*/
static function schedule_event() {
if ( ! isset( $_GET['settings-updated'] ) )
return;
// Remove any scheduled event on this hook
$scheduled_event = wp_next_scheduled( 'uncheck_event_hook' );
if ( $scheduled_event !== false ) {
wp_unschedule_event( $scheduled_event, 'uncheck_event_hook' );
}
// Schedule the event to uncheck the checkbox
$exp_time = self::expiration_time();
if ( is_numeric( $exp_time ) ) {
wp_schedule_single_event( $exp_time, 'uncheck_event_hook' );
}
}
/**
* Fetches and formats the saved expiration time
*
* Get expiration time from options, set it according to the local timezone
* then format it as Unix time.
*
* @return int $time Unix-formatted time string
*/
static function expiration_time() {
$exp_time = get_option( 'setjr3_time' );
$time = ( ! empty( $exp_time ) ) ? $exp_time : null ;
// If no time is set, exit.
if ( is_null( $time ) )
return false;
$tz_local = new DateTimeZone( get_option( 'timezone_string' ) );
$time = new DateTime( $time, $tz_local );
$time = (int)$time->format('U');
return $time;
}
/**
* The actual un-checking of the checkbox
*
* Fires on 'uncheck_event_hook' action, set in setup() above.
*
* @action 'uncheck_event_hook'
*/
static function uncheck_checkbox() {
update_option( 'setjr3_checkbox', null );
}
} // End class Schedule_Event_Tutorial
/**
* Set up the Tutorial
*
* The content of this class simply sets up the tutorial form.
* If you find it confusing, just ignore it.
*/
class Schedule_Event_Tutorial_Setup {
/**
* Add our actions/filter
*/
static function setup() {
$plugin = plugin_basename(__FILE__);
add_filter( "plugin_action_links_$plugin", array( __CLASS__, 'tutorial_link' ) );
// add action for Menu page
add_action( 'admin_menu', array( __CLASS__, 'menu_page' ) );
// add action for Settings
add_action( 'admin_init', array( __CLASS__, 'settings' ) );
// Run our Schedule_Event_Tutorial class above
Schedule_Event_Tutorial::setup();
// Clean up when this plugin is uninstalled
register_uninstall_hook( __FILE__, array( __CLASS__, 'uninstall' ) );
}
/**
* Print direct link to Tutorial Admin Page
*
* Fetches array of links generated by WP Plugin admin page ( Deactivate | Edit )
* and inserts a link to the Custom CSS admin page
*
* @param array $links Array of links generated by WP in Plugin Admin page.
* @return array $links Array of links to be output on Plugin Admin page.
*/
static function tutorial_link( $links ) {
$settings_page = '<a href="' . admin_url( 'admin.php?page=schedule-event-tutorial.php' ) .'">Tutorial</a>';
array_unshift( $links, $settings_page );
return $links;
}
/**
* Create Admin Menu Page
*
* Also fires action to Schedule the Event when page reloads.
* see Schedule_Event_Tutorial::schedule_event()
*/
static function menu_page() {
$slug = add_menu_page( __( 'Schedule Event Tutorial', 'setjr3' ), __( 'Schedule Event Tutorial', 'setjr3' ), 'manage_options', basename(__FILE__), array( __CLASS__, 'render_tutorial_page' ) );
add_action( 'load-' . $slug, array( 'Schedule_Event_Tutorial', 'schedule_event' ) );
}
/**
* Settings Page setup
*
* For more info: http://codex.wordpress.org/Settings_API
*/
static function settings() {
register_setting( 'setjr3_settings_group', 'setjr3_checkbox' );
register_setting( 'setjr3_settings_group', 'setjr3_time' );
add_settings_section( 'setjr3_section', '', '', __FILE__ );
add_settings_field( 'checkbox', __( 'Checkbox', 'setjr3' ), array( __CLASS__, 'checkbox' ), __FILE__, 'setjr3_section' );
add_settings_field( 'expiration_time', __( 'Expiration Time', 'setjr3' ), array( __CLASS__, 'expiration_time' ), __FILE__, 'setjr3_section' );
}
/**
* Render Checkbox
*/
static function checkbox() {
$checkbox_value = get_option( 'setjr3_checkbox' );
echo '<input type="checkbox" name="setjr3_checkbox" value="1" ' . checked( 1, $checkbox_value, false ) . '/>&nbsp;&nbsp;<span class="description">This checkbox will uncheck after the expiration time set below.</span>';
}
/**
* Render Date Input
*/
static function expiration_time() {
$exp_time = get_option( 'setjr3_time' );
$exp_time_value = ( ! empty( $exp_time ) ) ? $exp_time : substr_replace( current_time( 'mysql' ), 'T', 10, 1 ) ;
echo '<input name="setjr3_time" type="datetime-local" value="' . $exp_time_value .'" step="1" />';
}
/**
* Render Menu Page
*/
static function render_tutorial_page() {
$curr_time = substr_replace( current_time( 'mysql' ), 'T', 10, 1 );
$exp_time = get_option( 'setjr3_time' );
$exp_time_value = ( ! empty( $exp_time ) ) ? $exp_time : 'Not set' ;
?>
<div class="wrap">
<h2><?php echo __( 'Schedule Event Tuorial', 'setjr3') ?></h2>
<?php if ( isset( $_GET['settings-updated'] ) ) { ?>
<div id="message" class="updated">
<p><strong><?php _e( 'Settings saved.', 'setjr3' ) ?></strong></p>
</div>
<?php } ?>
<p>
<?php _e( 'This is a tutorial demonstrating how to Schedule Events.<br />Begin by checking the checkbox below, then set a time for the checkbox to become unchecked.<br />Then, on the next page refresh after that time, the checkbox will be unchecked.', 'setjr3' ) ?>
</p>
<p>
<code><?php _e( 'Current Time', 'setjr3' ) ?>: <?php echo $curr_time ?></code><br />
<code><?php _e( 'Uncheck Time', 'setjr3' ) ?>: <?php echo $exp_time_value ?></code>
</p>
<form method="post" action="options.php" enctype="multipart/form-data">
<?php settings_fields( 'setjr3_settings_group' ) ?>
<?php do_settings_sections( __FILE__ ) ?>
<?php submit_button() ?>
</form>
</div>
<?php
}
/**
* Cleanup on unistnall
*/
static function uninstall() {
unregister_setting( 'setjr3_settings_group', 'setjr3_checkbox' );
unregister_setting( 'setjr3_settings_group', 'setjr3_time' );
}
}
add_action( 'plugins_loaded', array( 'Schedule_Event_Tutorial_Setup', 'setup' ) );