Thursday, September 29, 2016

WordPress Development Best Practices and Tips

WordPress is easily the most powerful open source blogging and content management system available online today, and so working knowledge of its intricacies is a boon to any developer or designer resume.
This resource contains a collection of WordPress development best practices and WordPress development tips provided by our Toptal network members. As such, this page will be updated on a regular basis to include additional information and cover emerging techniques. This is a community driven project, so you are encouraged to contribute as well, and we are counting on your feedback.
Check out the Toptal resource pages for additional information on WordPress development; there is a WordPress developer hiring guide and WordPress developer interview questions.

Use Child Themes and Plugins

A lot of newcomers to WordPress dive right in and start modifying their core theme files. This is a definite mistake. All of your changes will disappear right after an upgrade, and since plugins and themes are updated about as often as apps on your phone, this is pretty frequently.
To avoid this, create children of your plugins and themes. Not only will you preserve your changes, you can upgrade on your own time. The same steps used to create a child theme can be applied to creating a child plugin, but let’s use creating a child theme as our example.
To get started making your child theme, create a new folder in your themes folder with a unique name, then create a style.css file in your new folder.
In WordPress, all theme parameters are stored in the style.css file as the first comment block. Open the style.css from your original theme, the parent, to see an example of this.
For your child theme, go ahead and copy that comment block from your original theme’s style.css to the new file and rename it. Adding the template parameter to this header will link your new theme to the original. The Template parameter should point to the folder name of the original theme, like so:
/*
Theme Name: Twenty Fourteen Child Theme
Description: My new child theme based on Twenty Fourteen
Template: twentyfourteen
Version: 1.0
*/
Now, if you want to modify files of the original theme, copy them from the original theme’s folder and paste them into your child theme folder. WordPress will use original template files unless it sees the same file in your child theme. So if you want to make changes to header.php, copy it from your original theme into your new child theme folder, and make the changes in the copy. For adding new or modified code, you likewise create a new functions file in your child theme and make your changes there.
This same file copying strategy goes for many plugins as well: create a folder with the same name as a plugin inside your child theme, and then adhering to the file structure of the original plugin folder, copy files from the original plugin to your new folder and modify them. Most major plugins support this, but it’s always good to check with the author if you are not sure.

Speed Things Up with Caching

WordPress optimized hosting services such as Siteground, or the more expensive Wpengine, automatically support WordPress caching. If your host is one that has WordPress specific caching available, it’s the best option.
For those running on a VPS server with root access, Google PageSpeed is a turn key caching and optimization solution by Google that works with Apache and nginx. If that’s of interest to you, check out this guide on how to install PageSpeed on Plesk with CentOS.
If all of that sounds like too much work, then go with Cloudflare, a free CDN/Firewall/Caching and minification system.
Speaking of minification, minify your files yourself during development. Third party tools tend to break things more often than not, especially during upgrades. Doing it yourself gives you more control and awareness of when and where things go wrong.

Pay Attention to Security

WordPress’s popularity makes it a high priority target for hackers. If you don’t update often, you are pretty much asking to get your site hacked.
Automatic updates are a little too dangerous for users with a lot of customizations and plugins, which is why I strongly suggest installing some sort of security plugin.
I personally recommend iTheme Security, which implements security options like a password lockout and file monitoring. And Wordfence Security, a WordPress specific firewall for your site.

Three Developer Tools to Make Life Easier

WordPress has many plugins and add-ons to make your developer life a lot easier. In particular, I recommend:

WP-Cli

WP-Cli lets you work with WordPress using the command line. With this great tool you can upgrade and downgrade WordPress in seconds, as well as update plugins. Notably, when you find yourself migrating to a different server, the built in search-replace command will take care of all the url changes for you, and it’s worth installing it simply because of that.

Advanced Database Cleaner

The Advanced Database Cleaner plugin cleans out spam comments, built in revisions, and transients. You can even set up tasks to run automatically.

Query Monitor

When things are running slowly and you’re not sure what to blame, Query Monitor lets you see what queries are taking too long to execute, as well as show you PHP warnings and errors.

Don't Overdose on Plugins

Yes, WordPress has tons of plugins, but that doesn’t mean you should install them all. The more plugins you have, the bulkier your site and the slower your loading times, so don’t use plugins unless absolutely necessary. If you only need to add a few custom fields to your posts (a functionality already included in WordPress) don’t overengineer the solution by installing the advanced custom field plugin, ACF.
If you must use a lot of plugins, make sure you have Plugin Organizer installed to manage them. This great plugin lets you specify what plugins are activated on which pages (you can even use regular expressions), and this selective loading will significantly speed up your site.
You can also use tools like P3 (Plugin Performance Profiler) to see what plugins are taking up most of your precious resources.

Spring Clean Your WordPress Functions

Although great, WordPress comes out of the box with a lot of things that cannot be turned off in the settings. Here are a handful of steps to take any fresh WordPress install and make it more secure and perform better:

Remove the WordPress Version

Get rid of the WordPress version number to make your site harder to be identified by hackers. To do this, add the following to your functions.php file:
add_filter( 'the_generator', '__return_null' );

Remove Script Versions

Get rid of the version number after scripts. By default, WordPress adds versions to all your scripts. This can lead to issues with caching/minification plugins, as well as helps hackers identify your site better. To prevent this functionality, add the following code to your theme functions file:
function remove_cssjs_ver( $src ) {
  if( strpos( $src, '?ver=' ) )
   $src = remove_query_arg( 'ver', $src );
  return $src;
 }
add_filter( 'style_loader_src', 'remove_cssjs_ver', 1000 );
add_filter( 'script_loader_src', 'remove_cssjs_ver', 1000 );

Restrict WooCommerce

Did you install WooCommerce, and now the site is running slowly? Adding this function to your functions.phpwill prevent WooCommerce from loading its scripts on non-WooCommerce pages:
/**
 * Tweak WooCommerce styles and scripts.
 * Original credit goes to Greg from: https://gist.github.com/gregrickaby/2846416
 */
function grd_woocommerce_script_cleaner() {
 
 // Remove the generator tag, to reduce WooCommerce based hacking attacks
 remove_action( 'wp_head', array( $GLOBALS['woocommerce'], 'generator' ) );
 // Unless we're in the store, remove all the scripts and junk!
 if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
  wp_dequeue_style( 'woocommerce_frontend_styles' );
  wp_dequeue_style( 'woocommerce-general');
  wp_dequeue_style( 'woocommerce-layout' );
  wp_dequeue_style( 'woocommerce-smallscreen' );
  wp_dequeue_style( 'woocommerce_fancybox_styles' );
  wp_dequeue_style( 'woocommerce_chosen_styles' );
  wp_dequeue_style( 'woocommerce_prettyPhoto_css' );
  wp_dequeue_style( 'select2' );
  wp_dequeue_script( 'wc-add-payment-method' );
  wp_dequeue_script( 'wc-lost-password' );
  wp_dequeue_script( 'wc_price_slider' );
  wp_dequeue_script( 'wc-single-product' );
  wp_dequeue_script( 'wc-add-to-cart' );
  wp_dequeue_script( 'wc-cart-fragments' );
  wp_dequeue_script( 'wc-credit-card-form' );
  wp_dequeue_script( 'wc-checkout' );
  wp_dequeue_script( 'wc-add-to-cart-variation' );
  wp_dequeue_script( 'wc-single-product' );
  wp_dequeue_script( 'wc-cart' ); 
  wp_dequeue_script( 'wc-chosen' );
  wp_dequeue_script( 'woocommerce' );
  wp_dequeue_script( 'prettyPhoto' );
  wp_dequeue_script( 'prettyPhoto-init' );
  wp_dequeue_script( 'jquery-blockui' );
  wp_dequeue_script( 'jquery-placeholder' );
  wp_dequeue_script( 'jquery-payment' );
  wp_dequeue_script( 'jqueryui' );
  wp_dequeue_script( 'fancybox' );
  wp_dequeue_script( 'wcqi-js' );

 }
}
add_action( 'wp_enqueue_scripts', 'grd_woocommerce_script_cleaner', 99 );

Enable Shortcodes in a Widget Area

Trying to use shortcodes in a widget area and getting nothing? Drop this in into functions.php to use shortcodes in widget areas:
add_filter('widget_text', 'do_shortcode');

Use a Function to Load Scripts and CSS

WordPress already keeps track of all the scripts and CSS that it has loaded, so instead of adding your JS and CSS into a header or footer, let WordPress handle it with its enqueue functionality. This way WordPress will keep dependencies in check and you will avoid potential conflicts. You add enqueue methods to your theme’s function.php file: wp_enqueue_script() or wp_enqueue_style(), respectively. Here is an example with some explanatory comments:
function add_theme_scripts() {
//example script from CDN, true means our script will be in the footer.
wp_enqueue_script( 'particles', '//cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js', array(), null, true );
});

//All referred to when to load your style like: 'screen', 'print' or 'handheld.
wp_enqueue_style( 'slider', get_template_directory_uri() . '/css/slider.css',false, null,'all'); 

//this will actually execute our function above
add_action( 'wp_enqueue_scripts', 'add_theme_scripts' ); 
WordPress.org’s Theme Handbook further explains the many parameters to an enqueue method, but here’s the method signature for both enqueue methods:
wp_enqueue_style($handle, $src, $deps, $ver, $media );
wp_enqueue_script($handle, $src, $deps, $ver, $in_footer);
As you can see, the only difference between these two methods is the final parameter. For wp_enqueue_style(), the last parameter sets the media for which this stylesheet has been defined. Such as screen (computer), print (print preview mode), handheld, and so on. The last parameter for wp_enqueue_script() specifies whether or not the script should be loaded in the footer.
Here’s a breakdown for the other parameters in our example:
  • $handle is the name of the stylesheet, which can be anything you’d like.
  • $src is where the stylesheet is located (CDN, local, etc). This is the only required parameter.
  • $deps stands for dependencies. When passed a stylesheet handle, it will load it before executing the source script. When $deps is passed in wp_enqueue_script(), it’s an array.
  • $ver sets the version number.
  • $media is the wp_enqueue_style() only parameter. It specifies which type of display media the stylesheet is designed for, such as ‘all’, ‘screen’, ‘print’ or ‘handheld.’
  • $in_footer is the wp_enqueue_script()’s only parameter, a boolean that allows you to place your scripts in the footer of your HTML rather than in the header, which means it will not delay the loading of the DOM tree.

Contributors:


Wednesday, September 21, 2016

The 10 Most Common Mistakes That WordPress Developers Make

We are only human, and one of the traits of being a human is that we make mistakes. On the other hand, we are also self-correcting, meaning we tend to learn from our mistakes and hopefully are thereby able to avoid making the same ones twice. A lot of the mistakes I have made in the WordPress realm originate from trying to save time when implementing solutions. However, these would typically rear their heads down the road when issues would crop up as a result of this approach. Making mistakes is inevitable. However, learning from other people’s oversights (and your own of course!) is a road you should proactively take.
WordPressEngineers look like superheroes, but we’re still human. Learn from us.

Common Mistake #1: Keeping the Debugging Off

Why should I use debugging when my code is working fine? Debugging is a feature built into WordPress that will cause all PHP errors, warnings, and notices (about deprecated functions, etc.) to be displayed. When debugging is turned off, there may be important warnings or notices being generated that we never see, but which might cause issues later if we don’t deal with them in time. We want our code to play nicely with all the other elements of our site. So, when adding any new custom code to WordPress, you should always do your development work with debugging turned on (but make sure to turn it off before deploying the site to production!).
To enable this feature, you’ll need to edit the wp-config.php file in the root directory of your WordPress install. Here is a snippet of a typical file:
// Enable debugging
define('WP_DEBUG', true);

// Log all errors to a text file located at /wp-content/debug.log
define('WP_DEBUG_LOG', true);

// Don’t display error messages write them to the log file /wp-content/debug.log
define('WP_DEBUG_DISPLAY', false);

// Ensure all PHP errors are written to the log file and not displayed on screen
@ini_set('display_errors', 0);
This is not an exhaustive list of configuration options that can be used, but this suggested setup should be sufficient for most debugging needs.

Common Mistake #2: Adding Scripts and Styles Using wp_head Hook

What is wrong with adding the scripts into my header template? WordPress already includes a plethora of popular scripts. Still, many developers will add additional scripts using the wp_head hook. This can result in the same script, but a different version, being loaded multiple times.
Enqueuing here comes to the rescue, which is the WordPress friendly way of adding scripts and styles to our website. We use enqueuing to prevent plugin conflicts and handle any dependencies a script might have. This is achieved by using the inbuilt functions wp_enqueue_script or wp_enqueue_style to enqueue scripts and styles respectively. The main difference between the two functions is that with wp_enqueue_script we have an additional parameter that allows us to move the script into the footer of the page.
wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false )
wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false )

wp_register_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' )
wp_enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' )
If the script is not required to render content above the fold, we can safely move it to the footer to make sure the content above the fold loads quickly. It’s good practice to register the script first before enqueuing it, as this allows others to deregister your script via the handle in their own plugins, without modifying the core code of your plugin. In addition to this, if the handle of a registered script is listed in the array of dependencies of another script that has been enqueued, that script will automatically be loaded prior to loading that highlighted enqueued script.

Common Mistake #3: Avoiding Child Themes and Modifying WordPress Core Files

Always create a child theme if you plan on modifying a theme. Some developers will make changes to the parent theme files only to discover after an upgrade to the theme that their changes have been overwritten and lost forever.
To create a child theme, place a style.css file in a subdirectory of the child theme’s folder, with the following content:
/*
 Theme Name:   Twenty Sixteen Child
 Theme URI:    http://example.com/twenty-fifteen-child/
 Description:  Twenty Fifteen Child Theme
 Author:       John Doe
 Author URI:   http://example.com
 Template:     twentysixteen
 Version:      1.0.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  twenty-sixteen-child
*/
The above example creates a child theme based on the default WordPress theme, Twenty Sixteen. The most important line of this code is the one containing the word “Template” which must match the directory name of the parent theme you are cloning the child from.
The same principles apply to WordPress core files: Don’t take the easy route by modifying the core files. Put in that extra bit of effort by employing WordPress pluggable functions and filters to prevent your changes from being overwritten after a WordPress upgrade. Pluggable functions let you override some core functions, but this method is slowly being phased out and replaced with filters. Filters achieve the same end result and are inserted at the end of WordPress functions to allow their output to be modified. A trick is always to wrap your functions with if ( !function_exists() ) when using pluggable functions since multiple plugins trying to override the same pluggable function without this wrapper will produce a fatal error.

Common Mistake #4: Hardcoding Values

Often it looks quicker to just hardcode a value (such as a URL) somewhere in the code, but the time spent down the road debugging and rectifying issues that arise as a result of this is far greater. By using the corresponding function to generate the desired output dynamically, we greatly simplify subsequent maintenance and debugging of our code. For example, if you migrate your site from a test environment to production with hardcoded URLs, all of a sudden you’ll notice your site it is not working. This is why we should employ functions, like the one listed below, for generating file paths and links:
// Get child theme directory uri
stylesheet_directory_uri();
//  Get parent theme directory
get_template_directory_uri();
// Retrieves url for the current site
 site_url();
Another bad example of hardcoding is when writing custom queries. For example, as a security measure, we change the default WordPress datatable prefix from wp_ to something a little more unique, like wp743_. Our queries will fail if we ever move the WordPress install, as the table prefixes can change between environments. To prevent this from happening, we can reference the table properties of the wpdb class:
global $wpdb;
$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
Notice how I am not using the value wp_users for the table name, but instead, I’m letting WordPress work it out. Using these properties for generating the table names will help ensure that we return the correct results.

Common Mistake #5: Not Stopping Your Site From Being Indexed

Why wouldn’t I want search engines to index my site? Indexing is good, right? Well, when building a website, you don’t want search engines to index your site until you have finished building it and have established a permalink structure. Furthermore, if you have a staging server where you test site upgrades, you don’t want search engines like Google indexing these duplicate pages. When there are multiple pieces of indistinguishable content, it is difficult for search engines to decide which version is more relevant to a search query. Search engines will in such cases penalize sites with duplicate content, and your site will suffer in search rankings as a result of this.
As shown below, WordPress Reading Settings has a checkbox that reads “Discourage search engines from indexing this site”, although this does have an important-to-note underneath stating that “It is up to search engines to honor this request”.
WordPress Reading Settings
Bear in mind that search engines often do not honor this request. Therefore, if you want to reliably prevent search engines from indexing your site, edit your .htaccess file and insert the following line:
Header set X-Robots-Tag "noindex, nofollow"

Common Mistake #6: Not Checking if a Plugin is Active

Why should I check if a plugin function exists if my plugin is always switched on? For sure, 99% of the time your plugin will be active. However, what about that 1% of the time when for some reason it has been deactivated? If and when this occurs, your website will probably display some ugly PHP errors. To prevent this, we can check to see if the plugin is active before we call its functions. If the plugin function is being called via the front-end, we need to include the plugin.php library in order to call the function is_plugin_active():
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
if ( is_plugin_active( 'plugin-folder/plugin-main-file.php' ) ) {
// Run plugin code
}
This technique is usually quite reliable. However, there could be instances where the author has changed the main plugin directory name. A more robust method would be to check for the existence of a class in the plugin:
if( class_exists( ‘WooCommerce’ ) ) {
 // The plugin WooCommerce is turned on
}
Authors are less likely to change the name of a plugin’s class, so I would generally recommend using this method.

Common Mistake #7: Loading Too Many Resources

Why should we be selective in loading plugin resources for pages? There is no valid reason to load styles and scripts for a plugin if that plugin is not used on the page that the user has navigated to. By only loading plugin files when necessary, we can reduce our page loading time, which will result in an improved end user experience. Take, for example, a WooCommerce site, where we only want the plugin to be loaded on our shopping pages. In such a case, we can selectively remove any files from being loaded on all the other sites pages to reduce bloating. We can add the following code to the theme or plugin’s functions.php file:
function load_woo_scripts_styles(){
 
if( function_exists( 'is_woocommerce' ) ){
    // Only load styles/scripts on Woocommerce pages   
 if(! is_woocommerce() && ! is_cart() && ! is_checkout() ) {   
  
  // Dequeue scripts.
  wp_dequeue_script('woocommerce'); 
  wp_dequeue_script('wc-add-to-cart'); 
  wp_dequeue_script('wc-cart-fragments');
  
  // Dequeue styles. 
  wp_dequeue_style('woocommerce-general'); 
  wp_dequeue_style('woocommerce-layout'); 
  wp_dequeue_style('woocommerce-smallscreen'); 
   
  }
 } 
}

add_action( 'wp_enqueue_scripts', 'load_woo_scripts_styles');
Scripts can be removed with the function wp_dequeue_script($handle) via the handle with which they were registered. Similarly, wp_dequeue_style($handle) will prevent stylesheets from being loaded. However, if this is too challenging for you to implement, you can install the Plugin Organizer that provides the ability to load plugins selectively based on certain criteria, such as a post type or page name. It’s a good idea to disable any caching plugins, like W3Cache, that you may have switched on to stop you from having to refresh the cache constantly to reflect any changes you have made.

Common Mistake #8: Keeping the Admin Bar

Can’t I just leave the WordPress Admin Bar visible for everyone? Well, yes, you could allow your users access to the admin pages. However, these pages very often do not visually integrate with your chosen theme and don’t provide a seamless integration. If you want your site to look professional, you should disable the Admin Bar and provide a front-end account management page of your own:
add_action('after_setup_theme', 'remove_admin_bar');

function remove_admin_bar() {
if (!current_user_can('administrator') && !is_admin()) {
  show_admin_bar(false);
}
}
The above code, when copied into your theme’s functions.php file will only display the Admin Bar for administrators of the site. You can add any of the WordPress user roles or capabilities into the current_user_can($capability) function to exclude users from seeing the admin bar.

Common Mistake #9: Not Utilizing the GetText Filter

I can use CSS or JavaScript to change the label of a button, what’s wrong with that? Well, yes, you can. However, you’re adding superfluous code and extra time to render the button, when you can instead use one of the handiest filters in WordPress, called gettext. In conjunction with a plugin’s textdomain, a unique identifier that ensures WordPress can distinguish between all loaded translations, we can employ the gettextfilter to modify the text before the page is rendered. If you search the source code for the function load_plugin_textdomain($domain), it will give you the domain name we need to override the text in question. Any reputable plugin will ensure that the textdomain for a plugin is set on initialization of the plugin. If it’s some text in a theme that you want to change, search for the load_theme_textdomain($domain) line of code. Using WooCommerce once again as an example, we can change the text that appears for the “Related Products” heading. Insert the following code into your theme’s functions.php file:
function translate_string( $translated_text, $untranslated_text, $domain ) {
 if ( $translated_text == 'Related Products') {
   $translated_text = __( 'Other Great Products', 'woocommerce' );
 }
 return $translated_text;
}

add_filter( 'gettext', 'translate_string', 15, 3 );
This filter hook is applied to the translated text by the internationalization functions __() and _e(), as long as the textdomain is set via the aforementioned functions.
_e( 'Related Products', 'woocommerce' );
Search your plugins for these internationalization functions to see what other strings you can customize.
By default, WordPress uses a query string with the post’s ID to return the specified content. However, this is not user-friendly and users may remove pertinent parts of the URL when copying it. More importantly, these default permalinks do not use a search engine friendly structure. Enabling what we call “pretty” permalinks will ensure our URLs contain relevant keywords from the post title to improve performance in search engine rankings. It can be quite a daunting task having to retrospectively modify your permalinks, especially if your site has been running for a significant period of time, and you’ve got hundreds of posts already indexed by search engines. So after you’ve installed WordPress, ensure you promptly change your permalinks structure to something a little more search engine friendly than just a post ID. I generally use the post name for the majority of sites I build, but you can customize the permalink to whatever format you like using the availablepermalink structure tags.
WordPress Permalink Settings

Conclusion

This article is by no means an exhaustive list of mistakes made by WordPress developers. If there’s one thing you should take away from this article, though, it’s that you should never take shortcuts (and that’s true in any development platform, not just in WordPress!). Time saved now by poor programming practices will come back to haunt you later. Feel free to share with us some mistakes that you have made in the past – and more importantly any lessons learned – by leaving a comment below.
This article was written by Andrew Schultz, a Toptal freelance developer.