Generate WordPress theme templates with Underscores Components

You might already know about Underscores, often abbreviated as _s, which is a popular starter theme for WordPress. This is a big project maintained by Automattic which is the company operating WordPress.

Recently they created another tool called Components. This is a free online theme generator built on WordPress with custom blueprints made for portfolios, business sites, and different blog themes from standard blogs to magazines.

Components is completely free to use and it’s one of the most powerful generators on the web. Why start a new theme from scratch when you can work with the proven Underscores framework?

Each theme comes with a responsive layout, pre-built menus, and Sass code along with raw CSS.

You just need to select which template you want and give it a name (for example “My Theme”). Other optional info can include the theme’s slug, the author’s name/URI, and a brief description of the theme.

But with just a theme name you can download a complete package with a basic Underscores WP theme ready to go.

Naturally you can customize all of these themes to your liking and they’re pretty simple to work with.

Some developers may prefer to work with their own codebase rather than relying on someone else’s. But if you need to get a project online fast there’s no better way to get moving than with a pre-built blueprint.

You can also find all the Components source code on GitHub along with the individual themes located by themselves. If you want a WordPress-approved theme blueprint then the Components generator is an excellent place to start.

How to Build A Fully Customized WordPress Login Page

Many of you, I believe, are familiar with the WordPress login page at wp-login.php. It looks nice, and works fine. But when it comes to creating a website for clients, you might want a more customized login page, so that it integrates nicely with the website design as a whole. In addition, having a customized login page could also give your clients a good impression of your skills.

If this is something that you want to achieve on your site, here’s how you can build a fully customized WordPress login page.

Custom Login Page

First, we need to create a custom page template for the login page. To do so, you can create a new page template and name it – for example – page-login.php. Then, create a new Page from the WordPress backend and set the permalink to login so that WordPress will automatically take the page-login.php template for the page.

The Login Form

Put the wp_login_form tag in the page-login.php page template to display the login form.

<?php wp_login_form(); ?>

The following is optional, but could be useful in certain cases. You can configure a few things for the login form, like specifying the redirecting of URL after the user has successfully logged in, changing the ID of the username, and the password input field.

$args = array(
'redirect' => home_url(), 
'id_username' => 'user',
'id_password' => 'pass',
<?php wp_login_form( $args ); ?>

Furthermore, you can also add something aside. It could be your logo and a little description of your site, for example.

<div class="login-branding">
<a href="#" class="login-logo"></a>
<p class="login-desc"> is a design weblog dedicated to designers and bloggers. We constantly publish useful tricks, tools, tutorials and inspirational artworks.
<div class="login-form">
$args = array(
'redirect' => home_url(), 
'id_username' => 'user',
'id_password' => 'pass',
<?php wp_login_form( $args ); ?>

Now, let’s make the form nicer with CSS. You can make the CSS up on your own as per your site requirements. In this example, here is how my login form looks like. It has black background, with a blue button, which fits quite well with the site theme.


At this point, the login page is already functional. We can try logging in, and if suceeded we will be redirected to the URL that we have specified in the redirect parameter above. But, there is something that we need to address.

First, the wp-login.php page is still accessible. It would be better to redirect the wp-login.php to our new login page to deliver a unified experience to our clients.

To do so, you can add the following codes in the functions.php of your theme.

function redirect_login_page() {
$login_page  = home_url( '/login/' );
$page_viewed = basename($_SERVER['REQUEST_URI']);
if( $page_viewed == "wp-login.php" && $_SERVER['REQUEST_METHOD'] == 'GET') {

Remember to change the $login_page variable to your own login page (thanks to Montana Flynn for the tip).

Second, the login page can work as expected when we are successfully logged in. But if an error occurs like when submiting invalid user and password combinations, or submitting an empty field, we will also be thrown away to wp-login.php. To solve this issue, add the following functions in the functions.php.

function login_failed() {
$login_page  = home_url( '/login/' );
wp_redirect( $login_page . '?login=failed' );
add_action( 'wp_login_failed', 'login_failed' );
function verify_username_password( $user, $username, $password ) {
$login_page  = home_url( '/login/' );
if( $username == "" || $password == "" ) {
wp_redirect( $login_page . "?login=empty" );
add_filter( 'authenticate', 'verify_username_password', 1, 3);

These two functions perform two tasks. They will redirect the user upon failing, and append a login query string to the URL with the value of either failed or empty.

The last problem is we will also be redirected to wp-login.php when we have logged out from the site. So, we also need to specify the redirecting URL upon logging out, like so.

function logout_page() {
$login_page  = home_url( '/login/' );
wp_redirect( $login_page . "?login=false" );

Error Message

We will display an error message, showing the user when the error occurred, and when they have logged out by using the query string that we have put in the URL. To get the value from the login query string above, we can use $_GET.

Put this code below in the login page template.

$login  = (isset($_GET['login']) ) ? $_GET['login'] : 0;

The above code will check whether the login variable contains value, otherwise it will set to 0. Then we will display different notification messages based on the value of $error, like so.

if ( $login === "failed" ) {
echo '<p class="login-msg"><strong>ERROR:</strong> Invalid username and/or password.</p>';
} elseif ( $login === "empty" ) {
echo '<p class="login-msg"><strong>ERROR:</strong> Username and/or Password is empty.</p>';
} elseif ( $login === "false" ) {
echo '<p class="login-msg"><strong>ERROR:</strong> You are logged out.</p>';

And below is what the error message looks like.


There are several things that we could do to improve our login page such as adding Lost Password link, Register Link, and a personalized error message. But, at this point it is now functioning well enough for our users to login and logout, and it could also be a good start to create a more advanced login page.

We hope that you find this tutorial useful.

How To Put WordPress Site Into Maintenance Mode

Sometimes, you may have the need to put your website into maintenance mode for upgrades. This would make your website temporarily unavailable to public access. You wouldn’t want errors to pop up when you are running important updates in the background, right?

There are several ways of putting a website into maintenance mode, and the technical details may differ accordingly. If you are on WordPress, here are 3 ways to put your website into maintenance mode.

Using .Htaccess

If you are using the Apache server, you can use.htaccess to control access of the directories within the server, and send a response code of the server status.

To put the website into maintenance mode, you can use the 503 status code, which indicates that the server is temporarily unavailable.

Before we specify anything in .htaccess, however, we need to create a new file in.html or .php format, and add a message in the file, e.g.

Sorry we are down for maintenance, but we’ll be back up shortly.

Style your page. Next, open the .htaccess file in your server, and add the following:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^123\.456\.789\.000
RewriteCond %{REQUEST_URI} !/maintenance.html$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteRule .* /maintenance.html [R=503,L]

This will set the server status code to 503, while also redirects visitors to the maintenance page. You can set your IP address with the following line RewriteCond %{REMOTE_ADDR} !^123\.456\.789\.000 so that you will still be able to access your website.

WordPress Built-in Maintenance Page

When updating WordPress, plugins, or themes, you can create a file called .maintenance that says

Briefly unavailable for scheduled maintenance. Check back in a minute.

This file will be automatically removed when the process is completed – if the process fails, the file could get stuck in your server, so you have to remove it manually.

The problem is that .maintenance is not customizable, as it is generated dynamically.

So, if your emphasis is on the overall appearance of your website, you can create a file named maintenance.php, which you can customize with CSS, then put inside thewp-content folder. That way, the next time you update WordPress or plugins, WordPress will use the content inside this file.

The function is specfied in wp-includes/load.php, like so.

if ( file_exists( WP_CONTENT_DIR . '/maintenance.php' ) ) {
require_once( WP_CONTENT_DIR . '/maintenance.php' );

Using a Plugin

There are several WordPress plugins available to help put your website into maintenance mode, but my personal favorite is the Maintenance Mode plugin by Michael Wohrer. Although this plugin hasn’t been updated for about 2 years now, it still works perfectly.

Using the Maintenance Mode plugin, you can simply activate or deactivate the maintenance mode with a few clicks. You can also specify how long the website will be in maintenance mode.

In addition, this plugin comes with a default theme template to be displayed when the maintenance mode is activated. You can also use your own theme by creating a 503.php file and uploading it to your theme directory. Just go to the Maintenance Mode Setting page and select the 503.php file you have created.

Here is a sample page where I used this plugin along with a 503.php page template.


We hope you found this tutorial useful in helping you run your WordPress site more efficiently. For further reading on the subject, you can head over to the following sites.

Adding Custom Meta Descriptions to WordPress Posts Without Using a Plugin

It is true that meta descriptions no longer play a role as a ranking factor, but they still hold a lot of value. This is considering the fact that Google and other search engines use meta descriptions in their SERPs (search engine result pages) which makes meta descriptions a great way to attract user attention and make them click on your listing.

Adding Meta Descriptions to WordPress Posts

By default wordpress does not have a field that allows a user to add a meta description, but this can be easily achieved using custom fields and then calling this field from within the head section when a page loads. The following are the steps required to achieve this:

  1. Create a custom field using the wordpress dashboard
  2. Edit your theme’s functions.php page and add a function to call this custom field.

Let’s see how this can be done in details:

1.) Creating the Custom field

The first step is the create a custom field. This can be done as follows:

Step 1: Login to your wordpress dashboard.

Step 2: Create a new post or open an existing post to which you need to add a meta description.

Step 3: Make sure that custom fields are being displayed. If not, click Screen Options located in the top right corner of your dashboard and make sure the check-box next to custom fields is checked as shown in the image below.

Step 4: Scroll down to the bottom of the post editor and you should now be able to see a Add New Custom Field area.

Step 5: Click Enter new and in the Name section write down the text description and in the Value section write down the custom meta description of the respective article as shown in the image below.

Step 6: Click on ‘Add Custom field’.

Now the next step is to create a function that calls this custom field and outputs it in the head section of the site. Remember that the name of the custom field we need to call is description (all lower caps).

2.) Adding the Function to Functions.php

Open your theme’s functions.php page and add the following code to it:

/*Display custom meta description or the post excerpt */
function add_custom_meta_des(){

#Homepage Meta Description
if( is_home() || is_front_page() ){
	$meta_des = "Enter your homepage meta description here"; #Edit here
	echo '';

#Single Page Meta Description
if( is_single() ){
	$des = get_post_meta( get_the_id(), 'description', true);
	if( ! empty( $des )  ){
		$meta_des = esc_html($des);
		echo '';
add_action( 'wp_head', 'add_custom_meta_des', 4 );

This is how the above code works:

  • The first line of the code checks if the current page is the homepage and if yes, displays the meta description entered in the code.
  • If it is not the homepage the code checks if the page is a single post page and if yes, it checks if the page has a custom field named description and outputs the custom field if present. If not present, it outputs nothing.

So this is how easily you can displays custom meta tags in your posts. You can also use the same code to display meta keywords and other related meta tags. If you have any questions, feel free to leave it in the comments below.

How to Easily Hide Your WordPress Login Page From Hackers

Hackers are getting smarter and smarter with the methods they use to try and hack through your WordPress admin page’s.

The most common way is to use a script and try and login from the wp-login page.

It’s no secret that all login pages for WordPress users look like this:,  so hackers know exactly which URL to use to run the script.

Consider this: What would happen if someone hacked your site and deleted all your content or injected a malicious program to ruin your databases?

The solution to this security issue is to change the default login address to a custom login link so only you know what it is.

Another method is to limit login attempts.

Caution. Always create a full backup of your WordPress files & Databases before making changes.

Create a Custom Login URL Using Code

One way to change your login address is to add some code to your .htaccess file

If you wanted to change your login link from


Add this code to your .htaccess file just above the WordPress rewrite rule

RewriteRule ^login$ [NC, L]

Login URL Example: Your login url will now be

You can customize your url to anything you want by changing login in code above in your .htaccess file.

Place the code on line 1 of your .htaccess file before the rewrite rules start.

This solution doesn’t hide the default login url. It only adds an easier to remember url which redirects to the default being wp-admin. The next section of this posts deals with creating the secret url and disabling the default.

How to Easily Hide Your WordPress Login Page From Hackers

Hide WordPress Login Page Without A Plugin

If you want to hide your login page without using a plugin, all you need is a text editor, access to your WordPress installation files (FTP, cPanel File Manager, etc), and then do the following:

1 – Make a backup of your wp-login.php file.

While you are at it, go ahead and make a backup of everything else too, as you’re about to mess with code and enter the danger zone!

Note: If you’re looking for a great plugin to backup and restore your files and WordPress site, we recommend using our very own Snapshot.

Next, open your wp-login.php file. Select and copy all the code to your clipboard.

2 – Create a new PHP login file. 

Create a new file using your text editor. Call this file anything you like (e.g. ‘canny-login.php’, ‘danger-zone.php’ etc.).

Paste the code from your existing wp-login.php file into your new file and save. Alternatively, open your wp-login.php file and ‘save as’ your new filename.

3 – Search and replace the ‘wp-login.php’ string in your new file code.

Search and replace every instance of ‘wp-login.php’ in the code with your new login filename.

Resave the file with the modified code.

4 – Upload your new login file to your server.

Log into your server and upload the new login file to the root folder or directory where you have installed WordPress. Delete the original wp-login.php file from your server.

5 – Update the default login and logout URLs.

The last step is to hook into the login_url and logout_url filters to update our file.

Add the following code to your theme’s functions.php (preferably in your child theme):

12345678910add_filter( 'logout_url', 'custom_logout_url' );function custom_logout_url( $default ){return str_replace( 'wp-login', 'danger-zone', $default );}add_filter( 'login_url', 'custom_login_url' );function custom_login_url( $default ){return str_replace( 'wp-login', 'danger-zone', $default );}

6 – Test your new login URL

Test your new login page URL. Anyone visiting the default wp-login.php page will experience an error.

To revert to the original login page, simply restore the wp-login.php file from your backup and delete the new file from your server.

WordPress Login URL .htaccess File Hacks

There are ways to ‘obscure’ your WordPress login details using the .htaccess file. Obscuring your WordPress login URL, however, doesn’t necessarily mean hiding it from others.

For example, let’s take a look at what happens when you add URL forwarding to your .htaccess. Remember to make a complete backup of your site before making any changes to your .htaccess file.

WordPress Login Page Obscurity With URL Redirection

You can change the location of your login page by changing the name of your WordPress login file using the mod_rewrite module in an Apache server.

To do this, add the line below to your .htaccess file (note: replace ‘newloginpage’ with any alias and change the URL to your domain):

RewriteRule ^newloginpage$ [NC,L]

In this example, we’ll add an alias called ‘dancekevindance’ and reupload the .htaccess file to our server:

Now, go back to the site and enter the new URL.

As you can see, the above method doesn’t hide the default WordPress login URL, it merely creates an alias that lets users log into their WordPress dashboard using a web address that is easier for them to remember than

Hide Your WordPress Login Page With Code

Ideally, we recommend just sticking to using a plugin if you want to change your WordPress login URL, hide the wp-admin wp-login.php pages, or redirect users away from the default login page. Messing with code can cause compatibility issues, slow down your site, and create other problems.

If you want to look at other options that involve code, however, then check out this post we’ve written about hiding your WordPress login page from hackers with code.

Don’t Let Them Gonna Take You Right Into The Danger Zone

WordPress is a magnet for hackers and malicious bots, so it’s important to understand WordPress security best practices and implement multiple WordPress security strategies to protect your site from hackers and brute-force attacks. This includes security through obscurity.

When used as part of a more comprehensive security strategy, obscurity can be helpful. As we’ve just seen, however, simply hiding the WordPress login page is not enough to guarantee that you will see zero malicious login attempts.

Unless you actually change the WordPress login URL of your site and redirect unwanted visitors away from pages like wp-login.php and wp-admin, hackers and bots will still be able to find your login page and attempt to guess your login details.

Messing with code can cause compatibility issues, slow down your site, and create other problems. Using a plugin like Defender is the easiest way to hide your WordPress login page from hackers and make it all but invisible to the vast majority of low-flying malicious login attempts.

To protect your site against the worst of the worst, you need help from the best of the best. If you’re not a member of WPMU DEV yet, join our elite group of top gun WordPress developers and website owners with our no-risk free 7-day trial and get access to all the security tools, protection features, and support your site needs to fly high and free out of the danger zone.

How To Make WordPress Hard For Clients To Mess Up

WordPress is a wonderfully powerful CMS that ships with many versatile features giving it the flexibility to work out of the box for a wide range of users. However, if you are a professional building custom themes and plugins, sometimes these features can be problematic. The same features and options that allow off-the-shelf themes to adapt to many different use cases can sometimes also be used to undermine a carefully designed custom theme built for a specific use case.

The following article comprises a collection of code snippets that I use again and again on almost every WordPress project. What they all have in common is that they limit functionality that is either unnecessary, confusing, or unsafe. Everything that follows can be used on any site, but these tips are especially applicable for professionals making custom themes and plugins for clients.

The notable distinction is that custom themes can be built to serve a specific purpose. So the blanks for the authors’ content can and should also be much narrower. A well-designed WordPress theme should make as many design decisions as possible so the author doesn’t have to.

Disable The Plugins And Theme Editor

There is no good reason why anyone should be live-editing your custom theme or plugin files via the WordPress dashboard. Professionals don’t work that way, and muggles typically don’t realize just how easy it is to break a site by skipping a single semicolon. It is also a security vulnerability hackers can exploit. Fortunately, our friends at made it really easy to disable this feature. Simply add the following snippet to the wp-config.php file.

define( 'DISALLOW_FILE_EDIT', true );

In addition to the theme editor, this will also disable the plugin editor. I consider this a feature not a bug.

Limit The Visual And Text Editor

By default, the WordPress WYSIWYG editor supports far too many formatting options for a well-designed custom theme. Letting clients override text colors or font sizes is a fast way to make even the most chic site look cheap and ugly. If blog post text is designed to always be left-aligned, why give the author a button to right-align it? Do you think it will look good if the text on the About page is purple, bold, and italicized? Then don’t arm your client with the means to do it. In most situations I recommend disabling the visual editor entirely.


Add the following snippet to your theme’s functions.php file and the tab to toggle the WYSIWYG editor will disappear.

function emersonthis_disable_visual_editor(){
    # add logic here if you want to permit it selectively
    return false;
add_filter('user_can_richedit' , 'emersonthis_disable_visual_editor', 50);

This is a good start, but you’ll notice that the bold and italic buttons are still present on the plain text editor. In my experience, clients abuse these buttons much less often when the instant gratification of the WYSIWYG editor is gone. But I still prefer to remove them if they are not necessary.


The text editor has quicktag buttons that will wrap selected text with <strong> and <em> tags. Add the following code in your theme’s functions.php file and authors will no longer have bold or italics buttons.

# Removes bold and italic quicktags from text editor
function emersothis_quicktags_settings( $qtInit  ) {
    //To disable ALL butons it must be set to "," (not "")
    $qtInit['buttons'] = 'more,';
    return $qtInit;
add_filter('quicktags_settings', 'emersonthis_quicktags_settings');

This removes the possibility that your client will decide to, say, italicize an entire article. But this does not remove the ability to write markup into the text editor by hand. Every now and then that can come in handy when you’re in a pinch.

If you are in a rare situation where the user should be formatting text themselves, you can leave the visual editor enabled but disable specific buttons individually.


One of the few times I leave the visual editor enabled is when authors are writing long posts or pages that have internal structure of their own. For example, an author of a 10-page article might need the ability to add subheadings. In these situations I set up custom classes for the subsections and then disable all the other formatting buttons that are not needed.

The WordPress API for modifying the TinyMCE editor is a bit tricky because you need to look up the code names used to refer to each button you want to remove. You get the most bang for your buck by removing the “kitchen sink” button which toggles the entire second row that contains the most problematic formatting buttons. Adding the following code to your theme’s functions.php file will do this.

# Remove visual editor buttons
function emersonthis_tinymce_buttons($buttons)
    # Remove the text color selector
    $remove = array('wp_adv'); //Add other button names to this array
    # Find the array key and then unset
    return array_diff($buttons,$remove);

One trick to figuring out the code name of the button you want to remove is by inspecting the markup of the form. At the time of writing, each button has a class name that begins with mce-i- followed by the code name you would put in the array above.

Remove The “Add Media” Button

The “Add media” button appears by default whenever a custom post type supports the editor feature. But custom post types can be used for a wide range of things, and often it is inappropriate for that field to include images.

Most of the time, when I expect the author to publish an image to accompany text, I use post thumbnails (aka featured images). This makes it easy to integrate the images into theme templates, and it also gives the developer more control over the size and specifications for the images.

Ad hoc photos embedded using the “Add media” button in the editor are hard to control and they have a tendency to look awkward depending on where the author inserts the image in relation to the surrounding text. They also cause confusion for many authors, because at a glance the “Add media” button is easily confused with the “Featured image” upload button that appears further down the page (by default), and may be used very differently by the theme. I almost always remove it, by adding the following code to the theme’s functions.php file.

# Remove media buttons
function emersonthis_remove_add_media(){
    # do this conditionally if you want to be more selective
    remove_action( 'media_buttons', 'media_buttons' );
add_action('admin_head', 'emersonthis_remove_add_media');

You can add logic before the remove_action() to remove only the media button conditionally for certain post types. For example, you might want to let authors add images to pages, but not blog posts which instead use thumbnails.

Disable Theme Customizer Options

If you are working on a child theme, the parent theme may offer customization options that are inappropriate for the child. The customization options may be unused in your child theme, or have the potential to break things. Either way, the WordPress theme customizer API makes it easy to get rid of them by adding the following snippet to your theme’s functions.php file.

# Remove customizer options.
function emersonthis_remove_customizer_options( $wp_customize ) {
    // $wp_customize->remove_section( 'static_front_page' );
    // $wp_customize->remove_section( 'title_tagline' );
    $wp_customize->remove_section( 'colors' );
    $wp_customize->remove_section( 'header_image' );
    $wp_customize->remove_section( 'background_image' );
    // $wp_customize->remove_section( 'nav' );
    // $wp_customize->remove_section( 'themes' );
    // $wp_customize->remove_section( 'featured_content' );
    // $wp_customize->remove_panel( 'widgets' );
add_action( 'customize_register',

Each line in the snippet above corresponds to an individual theme customization option that you can disable by uncommenting it.

Hide Unused Dashboard Menu Items

Not every site has the same types of content; some sites have no blog, for example. If we apply the same logic to the WordPress dashboard that we apply to any other user interface, it is confusing and unnecessary to show buttons that do not do anything. In this example, the Posts menu item would be unnecessary, so let’s remove it by adding the following snippet to functions.php:

function emersonthis_custom_menu_page_removing() {
  // remove_menu_page( 'index.php' );                  //Dashboard
  // remove_menu_page( 'jetpack' );                    //Jetpack* 
  remove_menu_page( 'edit.php' );                   //Posts
  remove_menu_page( 'upload.php' );                 //Media
  // remove_menu_page( 'edit.php?post_type=page' );    //Pages
  remove_menu_page( 'edit-comments.php' );          //Comments
  // remove_menu_page( 'themes.php' );                 //Appearance
  // remove_menu_page( 'plugins.php' );                //Plugins
  // remove_menu_page( 'users.php' );                  //Users
  // remove_menu_page( 'tools.php' );                  //Tools
  // remove_menu_page( 'options-general.php' );        //Settings
add_action( 'admin_menu', 'emersonthis_custom_menu_page_removing' );

Each line corresponds to a specific menu in the dashboard. The file names do not always match the name that appears in the dashboard menu, so the commented lines are left in as a quick reference.

It is important to understand that removing these menu items does not actually revoke the user’s permissions. A user could still access the hidden menu item directly using the URL. If the goal is to make the dashboard less cluttered by hiding superfluous controls, then this is probably fine. If the goal is to actually prevent a user from accessing those controls, then you will need to modify the capabilities of the user’s role. To accomplish this, add a snippet like the following to the activation hook of a plugin (it only needs to run once):

global $wp_roles; // global class
$role = 'author';
$cap = 'delete_published_posts';
$wp_roles->remove_cap( $role, $cap );

Use this comprehensive table of all capabilities to find the specific capabilities you can add or remove for each of the default roles.

Add A Hint About How Line Breaks Work In The Editor

By default the visual editor (TinyMCE) will create a new paragraph when the author presses Return. If you just want an old fashioned line break (aka carriage return) you need to press Shift+Return. This is nifty and powerful but not intuitive for many authors. I’ve started adding a quick reminder to avoid the inevitable complaint about “a bunch of weird white space” showing up in a post or page.

Add the following snippet to your functions.php file. Change the value of $tip to say whatever you want to remind your authors of.

# Adds instruction text after the post title input
function emersonthis_edit_form_after_title() {
    $tip = '<strong>TIP:</strong> To create a single line break use SHIFT+RETURN. By default, RETURN creates a new paragraph.';
    echo '<p style="margin-bottom:0;">'.$tip.'</p>';

This technique could be used to inject a reminder about anything you want authors to remember when adding or editing content.

Do Not Dole Out Administrator Accounts

The WordPress administrator role is very powerful and with great power comes great responsibility. Some clients are experienced WordPress power users who administer their site competently. Many of them are not. The latter should not be poking around as administrators. Instead, make them an editor and create a separate admin account with a super strong password. If you have an ongoing affiliation with the client you can hang on to those credentials until the client is ready to administer the site themselves.

Alternatively, give the client both sets of credentials and have them store the admin credentials somewhere safe and only use it to perform admin tasks. Many clients will promptly lose the admin credentials but that is fine: the password can always be reset, and these are often the types of clients who will rehire you to do the routine site maintenance for them anyway.

The most important reason for being stingy with admin accounts is that they are a security vulnerability. A pleasant side effect is that beginner WordPress users often find the dashboard UI less overwhelming when they log in as authors or editors because there are fewer menus to sort through while learning basic skills such as adding or editing posts.

Use Mu-Plugins

The mu-plugins/ directory has existed for a long time, but most WordPress hackers I meet have never heard of it. The “mu” stands for must use. The directory is an alternative location where plugins can be installed.

The difference is that “must use” plugins are automatically active and cannot be disabled by accident throughout the dashboard. They are also loaded before the other plugins. This is ideal for plugins that must be present for the site to run properly. It’s also a great alternative for non-presentational hacks that might normally get jammed into your custom theme’s functions.php file. For example, I like to define custom post types in a mu-plugin, because that content should persist whether or not a particular theme is active.

The mu-plugins/ directory does not exist out of the box. You create it manually inside wp-content/.


The biggest limitation is that WordPress only looks for files in the top level of mu-plugins/ and will ignore code inside a subdirectory. However, you can work around this by creating a single PHP file at the top of mu-plugins/ that loads code from a sibling subdirectory. Also keep in mind that update notifications do not apply to mu-plugins. I think of mu-plugins/ as the place to put important code that the client should never have to think about.

Read more about must use plugins in the Codex. If you want to require other plugins by preventing the ability to deactivate them, you might find the WDS-Required-Plugins library useful.

Final Note

You may find it counterintuitive to disable functionality that WordPress gives you for free. But remember that your client is not paying you to give them a lot of buttons. Your job is to make an effective, robust website that is tailored to match the client’s goals. By disabling problematic or extraneous functionality you are actually delivering more value.

If you want more snippets, I have created a public GitHub repository of useful WordPress snippets which contains up-to-date versions of the hacks above, as well as others I add periodically. If you have your own handy snippets you want to share, pull requests are more than welcome!

Prefix all the things

When building WordPress themes, there’s a rule that sits at the top of the list of rules. It’s something all developers should do out of habit, not as an afterthought.

Prefix everything.

What does it mean to prefix something? Basically, when you create custom functions, classes, and other items in the global namespace, it needs to be unique so that it doesn’t conflict with WordPress, plugins, or other scripts. Therefore, you add a prefix that’s unique to your theme name. If everyone follows this simple rule, it’s rare to see any conflicts. Like rare on the level of seeing a real-life unicorn.

Is it really a simple rule? Yes, and no. There are times to follow the rules and times to break the rules. There’s also a few extra things to cover, so follow along. While I’ll be focusing on themes, this applies directly to plugins as well.

What’s my prefix?

Fortunately, you have a prefix already made available to you, so all the guesswork about what prefix to use is already taken care of. This prefix is your theme slug. Take a look at the folder name you’ve packaged your theme in. That’s your prefix.

Let’s assume you have a theme named “Firefly” with a folder name of firefly. Your theme prefix is firefly_ or firefly-, depending on the circumstance. We’ll get to when to use an underscore or hyphen later.

Wait? What if my theme name has more than one word like “Firefly Browncoats”? That’s simple. You follow the same convention. Your slug becomes firefly_browncoats_ or firefly-browncoats-.

What should be prefixed?

Believe it or not, there are loads of things that need to be prefixed. Function names are the most obvious, but we’re not limited to those. Here’s a list of the most common things that should be prefixed:

  • PHP function names.
  • PHP class names.
  • PHP global variables.
  • Action/Filter hooks.
  • Script handles.
  • Style handles.
  • Image size names.

Don’t assume this list is exhaustive. I’m sure there are things that I’m missing and new things will come in the future. These are just the common items in WordPress themes.

Also, while not technically prefixes, theme textdomains should also match the slug.

How to use prefixes

The simplest way to use a prefix is to add firefly_ (prefix we used above) to the beginning of whatever it is that you’re prefixing. So, if you had a function named do_something_cool(), you’d want to change that to firefly_do_someting_cool(). Sure, it makes the function name longer, but it also makes sure that the function doesn’t conflict with core WordPress, a plugin, or another PHP script running on a user’s site, which would create a nasty fatal error.

Depending on what you’re prefixing, you’ll need to know how to use that prefix. While there aren’t always hard-and-fast rules, if you follow core WordPress coding standards, things get pretty clear. The following is are examples of the various items that you should prefix.

Function names

function firefly_engine_failed()

Class names

class Firefly_Transport_Boat {}

Global variables

global $firefly_passengers;

Action hooks

do_action( ‘firefly_start_engine’ );

Filter hooks

$shutdown = apply_filters( ‘firefly_shutdown’, true );

Script handles

wp_enqueue_script( ‘firefly-vertical’, trailingslashit( get_theme_directory_uri() ) . ‘js/firefly-vertical.js’ );

Style handles

wp_enqueue_style( ‘firefly-paint-job’, trailingslashit( get_theme_directory_uri() ) . ‘css/firefly-paint-job.css’ );

Image size names (Note: Hyphens or underscores acceptable. Just be consistent.)

add_image_size( ‘firefly-large’, 1000, 500 );
add_image_size( ‘firefly_small’, 200, 200 );

When to break the rules

For every rule there’s an exception, right? Pretty much. There are times when it’s actually better to break the rules.

Pluggable functions immediately come to mind. I almost always advocate for not using pluggable functions for various reasons (we’ll save that discussion for another day). They exist, so we’ll talk about them. When building a child theme, it’s possible that the parent theme developer created some functions that can be overwritten in child themes. In that particular case, you must use the same function name to actually overwrite it.

Third-party script/style handles also offer a unique situation. See, if your theme loads the Genericons font stylesheet and another plugin does the same, you’d only want that file to load once. If both have unique handles, it’ll load twice. The best thing to do in this situation is to not prefix and simply use genericons in this case. Follow the core naming convention of lowercase letters and hyphenating between words in the handle.

Third-party PHP scripts/libraries are something I’d avoid prefixing as well. While it’s possible you could run a string replace in a text editor to add your prefix in, it’d be silly to do this every time you updated the library. Not to mention, if you’re using a version control system, you’re probably just pulling in those changes. In this particular scenario, your theme should do a function_exists() or class_exists() (whichever the case may be) before loading the third-party file.

I’m sure there are other exceptions as well, but these are the big three. Once you’ve learned the rules, it becomes a lot easier to recognize situations where you can or should break them.

A good rule of thumb to code by: When in doubt, prefix.

How to load files within WordPress themes

For this second edition of the “how to better code WordPress themes” series, I want to cover properly including files and templates in WordPress themes. This is one of those areas that many themes seem to get wrong.

You might not think loading a file would be such a difficult task, but there are some things you have to be considerate of in WordPress. Things can get confusing for a newcomer to WordPress theme development because there are specific functions a developer should use in certain cases. Sometimes these functions have hooks that WordPress fires that plugins can take advantage of. And, child themes should always be considered when loading files.

This tutorial will walk you through everything you need to know about loading files in WordPress.

Getting the appropriate path

No discussion on loading files would be complete without covering the correct way of getting paths. There are two important terms you need to understand when referring to paths in WordPress themes.

  • Template: This refers to the directory the theme templates are located in. When using a parent/child theme setup, it refers to the parent theme.
  • Stylesheet: This refers to the directory the theme stylesheet is located in. This will always be the currently activated theme, so when using a parent/child theme setup, it refers to the child theme.

If you didn’t figure it out on your own, “template” and “stylesheet” refer to the same directory when you’re not using a child theme. It’s important to know that there’s a difference because you wouldn’t want to use a stylesheet constant or function when trying to include a file from the parent theme directory.

WordPress gives you two constants to the template and stylesheet directories that you may use:

  • TEMPLATEPATH: Returns the absolute template directory path. Deprecated in WordPress.
  • STYLESHEETPATH: Returns the absolute stylesheet directory path. Deprecated in WordPress.

You also have several functions available for getting the path:

  • get_template_directory(): Returns the absolute template directory path.
  • get_template_directory_uri(): Returns the template directory URI.
  • get_stylesheet_directory(): Returns the absolute stylesheet directory path.
  • get_stylesheet_directory_uri(): Returns the stylesheet directory URI.

The biggest thing to note about the above functions is that the get_*_uri() functions are for getting the directory URI. This should be used when including JavaScript, CSS, and image files. You wouldn’t load something like a PHP file or check if a file exists with the get_*_uri() functions.

Using require() and include()

Most WordPress themes will never need to use functions such as require(), require_once(), include, or include_once(). These are standard PHP functions for loading files. However, there are some uses cases where they’re needed.

Theme developers should never use these functions to load a theme template file. WordPress has functions that should always be used for loading templates, even functions for custom templates (covered later).

Most uses of the include/require functions are going to be within a theme’s functions.php file. For example, you might have organized your theme functions into separate files or you may be using a framework to build your theme. For now, suppose you have a separate file called widgets.php within your theme folder that defines some custom widgets. You could load this widgets functions file as shown below.

require_once( trailingslashit( get_template_directory() ). 'widgets.php' );

Remember, the term “template” refers to the template (parent theme) directory. So, if you were loading this file from within a child theme, you’d code it a little differently.

require_once( trailingslashit( get_stylesheet_directory() ) . 'widgets.php' );

One thing I’ve seen in some themes is the use of the get_template_part() function (described below) to load a functions file like this. Using the widgets.php example, the code would look like:

get_template_part( 'widgets' );

This is absolutely the wrong way to load function files. Please do not do this. That’s a template-loading function, which will allow child themes to overwrite the file. That’s not what you want to happen in this scenario. You should always use an include/require function for loading files such as this.

Loading theme templates

Templates are files that WordPress themes use to display content. This is very much different than loading a functions-type file. Templates house a mixture of PHP and HTML to set the site structure and output content.

In this section, I’ll walk you through each of the template-loading functions WordPress has available. These functions cover all scenarios for loading templates. When loading a template, you should always use one of these functions.

There are several reasons the use of these functions is important.

  • You never have to check if a file exists before trying to include it.
  • Works with child themes, allowing the child theme to overwrite templates within the parent theme.
  • No need to worry about the correct path since WordPress figures it out for you.
  • Some functions execute hooks that plugins might use to perform specific functionality.

Header templates

The get_header() function is for getting the theme header. By default, it loads a template called header.php as shown in the code below.

<?php get_header(); ?>

You can also load a more specific template file by specifying the $name parameter. The code below will check if the header-blog.php file exists. If not, it will fall back to the basic header.php template.

<?php get_header( 'blog' ); ?>

Footer templates

Loading a footer template works the same way as loading a header template. You’ll just use a different function and file(s). The basic function call loads the footer.php template.

<?php get_footer(); ?>

You can also pass the $name parameter to load a more specific footer template. The code below looks for the footer-home.php template and falls back to footer.php if it doesn’t exist.

<?php get_footer( 'home' ); ?>

Sidebar templates

If you read my blog, you should already know how to load a sidebar template. I covered this in the Sidebars in WordPress tutorial. I recommend reading that tutorial since it goes into some more specifics about sidebar usage.

Like the header and footer template functions, a basic sidebar template function call will load the sidebar.php.

<?php get_sidebar(); ?>

Inputting the $name variable will allow you to check for a specific template. The example below will load sidebar-special.php and fall back to the standard sidebar.php if it doesn’t exist.

<?php get_sidebar( 'special' ); ?>

Search form template

The search form is a bit different from the previous functions covered. When using the get_search_form() function, WordPress will look for the searchform.php file. If this file isn’t found, WordPress will output its own search form.

<?php get_search_form();

If your theme doesn’t include a searchform.php file, the output of the WordPress-generated search form can be filtered by plugins using the get_search_form hook.

Comments template

Most theme developers know that the comments_template() function loads the comments.php template by default. However, you can actually load a different file by specifying the first parameter.

Basic usage would load the comments.php template.

<?php comments_template(); ?>

Suppose you wanted to display something different for comments on pages, you could load a comments-page.php template by using this code within your theme’s page.php file:

<?php comments_template( '/comments-page.php' ); ?>

Template parts

get_template_part() was the fun new function WordPress 3.0 added for theme developers, but some theme authors have went overboard with its usage. I’ve seen this used in all kinds of ways, so I want to make sure theme developers are using this properly.

The function was created so that theme developers could create reusable sections (“parts”) of code within their templates. For example, a developer could create one loop.php file to handle The Loop rather than recoding it in several templates. As with the other template functions, this allows child themes to overwrite these template parts.

This function should not be used to just load any file in a WordPress theme. It’s for template parts.

<?php get_template_part( $slug, $name = null ); ?>

The function takes in two parameters and works in much the same was as get_header(), get_footer(), and get_sidebar(). The big difference here is that this function is for custom templates rather than standard WordPress templates.

  • $slug: This is the file slug for the default version of the template. This parameter is required.
  • $name: A more specific version of the template to load. If it doesn’t exist, fall back to the default template. This parameter is optional.

Suppose you wanted to create a loop.php file to house the code for The Loop in your theme, which would allow you to cut back on your coding requirements (this is done in the Twenty Ten theme). The code below would allow you to load this template part into other templates.

<?php get_template_part( 'loop' ); ?>

Really simple, right? Suppose you wanted to separate files for specific types of loops or just allow child theme users to overwrite specific types of loops. The code example below will attempt to load the loop-home.php file and fall back to the loop.php template if it doesn’t exist.

<?php get_template_part( 'loop', 'home' ); ?>

The grandaddy of template-loading functions

The functions shown above have one thing in common: they use the locate_template() function to load the template. This function does all the hard work of loading templates:

  • Uses the correct theme directory path.
  • Checks if a file exists before trying to load it.
  • Allows child themes to overwrite parent theme templates.

WordPress uses this function internally for loading all sorts of templates. Theme developers should be using it when needed too. Although the functions covered earlier are great, there are some things you simply can’t do with them. You should instead use the locate_template() function under certain conditions:

  • If no other template function handles the functionality needed. Always use a more specific template function if it does what you need and is within the function’s scope.
  • When you need to load files from sub-folders within your theme.
  • When you have more than two possible templates that could be loaded.

The locate_template() function takes in three parameters.

locate_template( $template_names, $load = false, $require_once = true );
  • $template_names: An array of templates to search for. The first template found from the array within the child or parent theme is the “located” template. The templates should be added to the array in the order they should be searched for. This parameter is required.
  • $load: Whether WordPress should automatically load the template. By default, this is set to false and will return the template file name and path if found. If you set it to true, the template will be loaded.
  • $require_once: Whether to only load the template once. By default, this parameter is set to true. If the template might need to be loaded more than once, set this to false.

Let’s revisit the loop.php idea discussed in the previous section. Suppose you wanted a more hierarchical template load order than what the get_template_part() function provides. For example, in your theme’s category.php file, you might want to allow for a search for these loop templates (in this order):

  • loop-category.php
  • loop-archive.php
  • loop.php

The locate_template() function is perfect for this.

<?php locate_template( array( 'loop-category.php', 'loop-archive.php', 'loop.php' ), true, false ); ?>

One big difference here from other functions is that you directly input the entire file name. It also allows you to search for templates within sub-folders. For example, you could search for loop/category.php if you wanted.

Getting theme templates right

The biggest thing to keep in mind is the difference between loading a template and a functions file. Always make sure to load templates with one of the template functions so that child themes can overwrite them. Never use template functions for loading a functions-type file because you don’t want child themes to overwrite them (use a require/include function).

Some of you may have noticed that I didn’t cover the major templates like index.php, single.php, and so on. This is because WordPress loads these templates. The purpose of this tutorial was to cover code that’s used within themes. I’ll save the WordPress template hierarchy for another day.

I hope this tutorial has been helpful to theme developers. Keeping up with the appropriate functions can sometimes be a tough task. Even I’ve made mistakes in this area. If you just use the available functions, you’ll be safe and your theme will be forward compatible with future versions of WordPress.

Styling Wide and Full-Width Gutenberg Blocks in WordPress

The Gutenberg block editor for WordPress has changed how we create content within the CMS. But it’s also opened up some new possibilities on the front end as well.

One of the more interesting developments in this area is the ability to add “full” or “wide” blocks to a page or post. This feature adds the potential for a Gutenberg block to break out from the default width of a theme’s content – something that was nearly impossible in the old Classic Editor.

There are a number of possible uses for a full or wide-aligned block. You could, for instance, introduce new page sections with a full-width cover block that overlays text on an image background. Or you might leverage the feature to build a can’t-miss call-to-action area. Just about any type of content could be added here, which is part of the appeal.

However, there is one small caveat: Your theme must support full and wide-aligned blocks. Thankfully, it’s rather easy to do. The following is a quick tutorial for adding wide alignment support to your WordPress theme and styling the blocks via CSS.

Adding Theme Support

The first step involves adding a single line of code to your active theme’s functions.php file. Download this file from your website if you haven’t already done so (it can be found in the /wp-content/themes/yourtheme/ folder – substituting “yourtheme” for the actual name of the folder). Then, copy and paste the following PHP snippet:

add_theme_support( 'align-wide' );

Once you’ve added the code, upload the changed functions.php file back into your theme’s folder.

This code will signify that you want to turn on full and wide-aligned blocks. Now, when you log into WordPress and go to the page/post editor, you should notice that some blocks (not all) have the new “Full” and “Wide” alignment options.

Using a Commercial or Default Theme?
If you’re using a commercial or default WordPress theme, you’ll want to make sure you’re utilizing a child theme. This will let you make changes to the theme without potentially losing them after an update.

Basic Block Styling

Styling a wide or full-aligned block can be a little tricky. And there are a number of different techniques floating around. The one we’ll use here came from this example on CodePen.

@media screen and (min-width: 960px) {
     .alignwide, .alignfull {
          width:  100vw;
          max-width:  100vw;
          margin-left:  calc(50% - 50vw);

Notice that we’re using a CSS media query to only integrate this style when the screen size is 960 pixels or wider. That’s because we won’t necessarily want this effect on smaller screens.

In this case, we have used the same styles for both block alignments. Of course, it’s entirely possible to style them separately so that they each offer a unique look on the front end.

It’s also worth noting a potential drawback: A horizontal scrollbar may appear on some layouts when using this technique. That can be taken care of via CSS with the following added to the body element:

body {
     overflow-x:  hidden;

The Results

Now that we’ve turned on the ability for full and wide-aligned blocks, it’s time to test things out. Here, we’ve created a page with a cover block, set to a wide alignment.

When looking at the front end of the website, the cover block works as intended. The element spans the entire width of the page, while the content below stays within the theme’s predefined 960-pixel width.

Using just the default styles, this element really stands out. Still, there are plenty of opportunities to do more with the design.

By adding extra CSS classes or targeting specific blocks, we have a full arsenal of design possibilities at our disposal. Things like backgrounds, borders or clipping paths can add a unique touch.

Going Wide with WordPress Themes

In a default installation, Gutenberg doesn’t provide all the bells and whistles of a page builder plugin. But block alignments do allow us to dabble in that territory.

That’s a good thing, because web design has evolved from the days when the Classic Editor first appeared. Back then, websites tended to use a uniform content width throughout.

These days, full-width sections are among the more popular and useful layout choices. The ability to take advantage of this without the need for plugins or theme hacks makes WordPress all the better for designers.