Hire the top 3% of freelance WordPress developers.

Toptal is a marketplace for top WordPress developers, engineers, programmers, coders, architects, and consultants. Top companies and start-ups choose Toptal WordPress freelancers for their mission-critical software projects.
  • Trusted by:

Hire WordPress developers and engineers

How to Hire a Great WordPress Developer

The Challenge

Currently, WordPress is one of the most popular Content Management Systems (CMS). It may be used to create a personal blog, internet shop, landing page, corporate website and more. Clients love it because it’s easy to set up, there are a variety of plugins and, overall, it has a user-friendly approach. Developers like it because of its understandable functionality, which means it’s easy enough to set up yet still gives you decent quality.

The number of sites using WordPress is growing, which is creating a demand for a significant number of WordPress developers. So, how do we distinguish a novice from an experienced WordPress developer? In this guide, we suggest questions and answers that will help you determine the level of skills your candidate has.

Why spend money and time building a website from scratch, when you can hire top WordPress developer and save?

Questions and Answers

Q: Discuss how to setup a custom theme, name the minimum required files, and explain how WordPress recognizes a new theme.

Every WordPress site requires a theme; it is how it is structured and is, therefore, an integral part of the site.

The new theme is created as follows: In the wp-content/themes/ directory, create and name a new folder. Best practice is to use the name of the company for which you are making the website. Use lower case (Roman alphabet) without spaces. Note that you need to put in the theme folder these five files: style.css, functions.php, index.php, header.php and footer.php. Later, you can extend the theme with other custom files.

The formation of the style.css file header is a part of the base theme settings. With the help of file style.css and headers in it, WordPress’s core will recognize your folder as the new theme.

The beginning of the style.css should be as follows:

Theme Name: [theme name]
Author: [author name]
Author URI: [author URL]
Version: [theme version]
Description: [theme description]
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

If you create a child theme, you need to add another line where the base theme is indicated.

Template: twentyfifteen

Where twentyfifteen is the name of the main (parent) folder theme.

Q: Explain how WordPress generates a page.

WordPress recognizes and analyzes the request entered in the URL bar, picks the best PHP file, and generates the webpage. It makes a global object $wp_query based on the request in the URL. Then, with the help of its functions, WordPress loads other files, such as header.php, footer.php, and sidebar.php.

Check the template hierarchy scheme, which defines the process and file that will output the content of the current query.

For example, if the address is /? Cat = 1, WordPress will first look for category-slug.php file. If the file is not found, it will search the category-id.php file. If this can’t be found, either, it looks for the file category.php, and so on, until it finds the appropriate file. If it can’t find one, it simply selects the index.php file.

Q: Explain the semantics of a theme’s development and the basic principles of a good theme. What should be kept in the theme files?

Here are some of WordPress’s best practices and recommended principles for creating a new theme:

  • The function wp_head() must be in the header.php file.
  • The function that operates classes, must be in the header.php file, inside the body tag: <body <php body_class ();? ? >>
  • The function wp_footer() must be in the footer.php file.
  • If you have a repeating functionality, this code must be put into separate function, and this function must be added to the functions.php file.
  • In all files, except header.php and the footer.php, the number of opening HTML tags must be equal to the number of closing tags.
  • If the file contains duplicate pieces of HTML code, it is better to unite them in a single file, put it in a theme subfolder, which can be named blocks or whatever you need, connect this piece of code, and call the function get_template_part( 'blocks/[name-of-the-file.php]' );.
  • File index.php is the final file to process the request, so it needs to have the main loop minus any queries. That means it will be impossible to alter the main loop in index.php.
  • All the theme settings must be in the functions.php file: actions, filters, custom functions, and custom classes. Although classes and functions may be located in different files, and be connected to the main functions.php, or be placed in a separate plugin.
  • The code should not contain commented code. Commenting as a description is allowed, but code chunks that have been used in the design, should be removed.
  • Code in the files should be structured with the aid of indents.
  • Themes must be validated by the w3c standards.
  • The theme should work without exterior plug-ins. For example, if we use the WP-PageNavi plugin, you must write:
if (function_exists ( 'wp_pagenavi')):
    wp_pagenavi ();
    get_template_part ( 'blocks / pager');
  • If the code uses functions or plugins classes, make sure the function or class exists:
if (function_exists ('name_of_the_function'))
  • For direct requests to the database, you must use the class $wpdb and its methods.
  • If you use the form and need to create an options page admin panel, you must use wp_nonce_field(), and on the server side check this field and action:

if ( ! isset( $_POST['name_of_nonce_field'] ) || ! wp_verify_nonce( $_POST['name_of_nonce_field'], 'name_of_my_action' ) 
) {
   print 'Sorry, your nonce did not verify.';
} else {

   // process form data

/* some code is here*/

<form method="post">
   <!-- some inputs here ... -->
   <?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?>
  • If some files are not used, remove them from theme folder. If a client doesn’t need to use “search” on his site, remove searchform.php from the theme folder.
  • Functions that begin with the _ must only be written in the loop. And in the loop, if possible, use the functions started with the _ for presenting display fields.

Q: Explain how to create a custom page template.

For custom page templates, it is better to create a separate folder; do not mix custom templates with existing WordPress templates. Place the custom template file into this folder. At the beginning of the file you need to add the following code:

<? Php
/ *
Template Name: [Template_Name]
* /
get_header (); ?>

Q: Explain how to include your CSS and JavaScript files into the theme or plugin correctly.

You can use <link> or <script>, but the correct way is to connect them in the functions.php file. You need to add action to wp_enqueue_scripts, and our action is to connect JavaScript and CSS files:

function theme_scripts_styles () {
    // Connection of a custom JS file after jquery library that will be  connected independently by WordPress
    wp_enqueue_script ( 'theme-script', get_template_directory_uri () '/js/jquery.main.js', array ( 'jquery').);
    // Loads default theme style.css.
    wp_enqueue_style ( 'theme-style', get_stylesheet_uri (), array ());
    // Connection of a custom css file
    wp_enqueue_style (. 'theme-theme', get_template_directory_uri () '/theme.css', array ());
add_action( 'wp_enqueue_scripts', 'theme_scripts_styles' );

Q: Explain how you make a custom menu and how you display that menu on the page.

To display the menu, you must:

  • Select the location for ther menu in the functions.php:
register_nav_menus (array (
 	'Primary' => __ ( 'Primary Navigation'),
  • Use this location to display a menu:
if (has_nav_menu ( 'primary'))
 	wp_nav_menu (array (
	'Theme_location' => 'primary',

Menus are placed on a page via the admin panel, which also allows other pages to have menus (with the same look) placed in the same location.

Custom settings can be made through parameters wp_nav_menu() function, but should you need to create a custom menu, do this:

  1. Create inheritance class from Walker_Nav_Menu, where you can write your custom functionality: class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {...}.
  2. When displaying the menu, add another parameter walker:
if( has_nav_menu( 'primary' ) )
	wp_nav_menu( array(
        	 'theme_location' => 'primary',
        	 'walker'       	=> new Custom_Walker_Nav_Menu

Q: Explain what a loop is and how it works.

Loop means “cycle” from which WordPress generates the page content. If there is a single page, for example, page.php or single.php, the cycle remains with the template, but it will be realized only once. If you have search.php, archive.php or the index.php, the cycle will take place as many times as necessary to satisfy the request, which depends on the query URL, and consequently, on how the object is formed wp_query. Loop runs for posts in the global $wp_query object.

Q: Explain the difference between functions that begin with the_ and other functions.

Functions starting with the_ are intended to be used in the loop. Note they can’t be used out of the cycle.

Q: Explain custom post types; why do we use them, and how can we create them?

Custom post types are needed to break content logically. For example, we want to list all the sales managers in a company, so that customers may contact them directly from our website. Say, we have about 20 people in the sales department, and at any time, one of them might quit or someone new might join. So, for this task, the most logical action is to create the post type Team and in the template list everybody who is in the post type Team.

A simple example of the creation of a custom post type:

add_action( 'init', 'theme_create_post_type' );
function theme_create_post_type()
        	register_post_type( 'team',
        	        	'labels' => array(
                            		'name' => __( 'Team' ),
                            		'singular_name' => __( 'team' ),
        	        	'publicly_queryable' => true,
        	        	'public' => true,
'show_ui' => true,
        	        	'hierarchical' => false,
        	        	'menu_position' => null,
        	        	'query_var' => true,
        	        	'supports' => array('title','editor','thumbnail','custom-fields','comments')

Custom post types are created at the action init. Therefore, you need to create action and name it register_post_type() in function with the desired set of parameters.

Q: Explain how to get posts from custom post type and custom taxonomy.

For example, we have a post type Team and taxonomy Department, and in a custom taxonomy, we have the term Managers. Our task is to display all the managers.

Provided the “slug” of the term Managers in custom taxonomy Department is equal to Managers, we can utilize WP_Query class, like this:

$args = array(
        	'post_type' => 'team',
        	'tax_query' => array(
                                	'taxonomy' => 'department',
                                	'field'	=> 'slug',
                                	'terms'	=> 'managers',
$query = new WP_Query( $args );

Q: Explain shortcodes and provide few examples.

Shortcodes are keywords used to create macros that can be used later in a post’s content. In WordPress, they are enclosed in square brackets []. Shortcodes can be used either in the content editor’s post or in a pattern, if you apply do_shortcode() function. The simplest example is when a client does not know HTML, but it is necessary to insert something in the content of the posts.

In WordPress, we can create three types of shortcodes. However, because they can be configured in different ways, shortcodes have unlimited possibilities. It is important to note that the shortcode processing function must return the value, not display it. For example, if we need to display the phrase “Hello World”, we would write in functions.php something like the following:

function hworld_func( $atts ){
        	return ‘<div class=”block-wrapper”><div class=”block”>Hello world</div></div>’;
add_shortcode( 'hworld', 'hworld_func' );

To get the shortcode to work, we need to insert [hworld] into the post content.

If we have to adjust the shortcode from the admin panel, we can add parameters to it, like this: [hworld cssclass = "red"].

A code in the functions.php will be as follows:

function hworld_func( $atts ){
        	return ‘<div class=”block-wrapper ’ . $atts[‘cssclass’] . ’”><div class=”block”>Hello world</div></div>’;
add_shortcode( 'hworld', 'hworld_func' );

Also, as well as the parameters, we can handle the text itself. To do that, the shortcode should look like this: [hworld cssclass = "red"] Hello world [/ hworld].

The functions.php will then look like this:

function hworld_func( $atts, $content ){
        	return ‘<div class=”block-wrapper ’ . $atts[‘cssclass’] . ’”><div class=”block”>’ . $content . ’</div></div>’;
add_shortcode( 'hworld', 'hworld_func' );

Q: Describe how to make a widget. Explain primary widget functions.

In WordPress, you can create custom widgets by creating a class that inherits basic functions from WP_Widget class.

The primary functions of the widget class:

  • __construct(): Constructor of the widget, it will add a widget to the admin panel.
  • widget($ args, $ instance): Displays the content on the front-end based on the function arguments. $ args are widget arguments which are set in the sidebar to wrap a widget. $ instance are parameters of the widget, which can be configured in the admin area.
  • update($ new_instance, $ old_instance): A feature that saves the new widget options, if they have been changed by the administrator in the admin panel.
  • form($ instance): Creates a widget settings form in the admin panel on the page widgets.php.

The final thing to make the widget work is on the action widgets_init attach function that will record (register) it:

add_action ( 'widgets_init', create_function ( '', 'return register_widget ( "CustomWidget");'));

Widget example:

class CustomWidget extends WP_Widget {
	function __construct() { ... }
	function widget( $args, $instance ) { ... }
	function update( $new_instance, $old_instance ) { ... }
	function form( $instance ) { ... }
add_action( 'widgets_init', create_function( '', 'return register_widget( "CustomWidget" );' ) );

Q: Explain what actions and filters are. Discuss their differences, and how and when to use them.

You can not change WordPress core files and plugins. However, sometimes we need to change default core behavior, which is when actions and filters come to the rescue.

They work almost identically, the only difference is that functions that are imposed on the filters return a value, while actions do not. So, filters change some content or meaning, which would later be used by the core or plugin.

Here’s an example of a filter that must be written in the functions.php:

add_filter(‘the_content’, ‘theme_the_content’);
function theme_the_content($content){
        	return ‘<div class=”contentwrap”>’ . $content . ‘</div>’;

This means that somewhere in the core code or plugin there is a line similar to this:

$content = apply_filters(‘the_content’, $content);

So, the variable $content is the second parameter that’s sent to theme_the_content() function. It may also look like the following code:

$var = apply_filters(‘some_filter_name’, $var1, $var2, $var2);

In this case, you need to write in functions.php:

add_filter(‘some_filter_name’, ‘theme_some_filter_name’, 10, 3);
function theme_the_content($var1, $var2, $var2){
        	return [SOME_CODE];

In the filter function, number 10 can be any integer that indicates the priority of this filter, if such filters will be several, and number 3 is a number of variables that come into function.

add_action( 'init', 'theme_create_post_type' );
function theme_create_post_type()
        	register_post_type( 'team',
        	        	'labels' => array(
                            		'name' => __( 'Team' ),
                            		'singular_name' => __( 'team' ),
        	        	'publicly_queryable' => true,
        	        	'public' => true,
        	        	'show_ui' => true,
        	        	'hierarchical' => false,
        	        	'menu_position' => null,
        	        	'query_var' => true,
        	        	'supports' => array('title','editor','thumbnail','custom-fields','comments')

Parameters may be passed to both actions and filters. If we do not need the filter or action, we can remove it. For example:

remove_filter ( 'some_filter_name', 'theme_some_filter_name', 10);
remove_action ( 'init', 'theme_create_post_type');

Q: Discuss different ways of integrating plugins into a theme. Explain correct ways of doing it.

Plugins can be integrated in many ways:

  • Through actions and filters.
  • Through shortcodes.
  • Through widgets.
  • Through a PHP function.

If the plugin is integrated with the aid of PHP code, you should check for the existence of a function:

<?php if(function_exists('bcn_display')) bcn_display(); ?>

It is important to check the theme’s ability to work without plugins, so that when the plugin is deactivated the theme will keep working. For example, if we use the plugin WP_PageNavi, we should write code like this:

	    	get_template_part( 'blocks/pager' );

That means when you turn off the plugin, the theme will continue to operate while maintaining a functional page. However, it will be a standard page, not one that would show with the use of the plugin.

Q: Describe the steps to create a simple plugin.

The plugin is an addition; it is an expansion of WordPress’s functionality. To create a plugin, you first need to create a folder in the wp-content/plugins directory, using lower case, Roman alphabet, and no spaces. Inside this folder, you need to create a file with the same name as the folder using the extension .php. This will be the main file. Additionally, create an empty index.php file to hide the list of files and catalogs.

At the beginning of the main file, add predefined metadata lines through which WordPress understands that it is a plugin:

Plugin Name: [PLUGIN NAME]
License: GPL2
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Designing (creating) plugins with classes is recommended. So, an example of a plugin’s code structure might be like this:

Plugin Name: TestPlugin_Name
Description: TestPlugin_Name description.
Version: 1.0.0
Author: [email protected]
Author URI: https://www.linkedin.com/in/evgengavrilov
License: GPL2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
class TestPlugin {
        	function TestPlugin(){
        	 [CODE IS HERE]
        	[CODE IS HERE]
$testplugin = new TestPlugin();

Remember the rules of creating a theme: Media may only connect through action wp_enqueue_scripts, and the plugin must not contain any errors.

Q: Explain the role of child themes. How do you make a basic child theme?

Child themes are necessary when you need to change styles and functions of the main, or parent, theme but without changing its code. It’s like Object Oriented Programming: a class and its derived class. The inheritance does not break the parent, but it can change existing methods and add new ones.

A child theme may be created quickly and easily in a few steps:

  1. Create a folder inside the wp-content/themes with the name [name-of-parents-folders-theme]-child.
  2. Inside the folder, create styles.css file and to the main header file, add another line: Template: [name-of-parents-folders-theme].
  3. Create a functions.php file.

Thus, we can alter the styles of the parent theme by adding to our child folder template files. WordPress will use these files, and, if necessary, other files will be used from the parent theme folder.

Q: Explain a WordPress network, and how to create one.

WordPress network is a way of managing multiple sites through a single admin panel. The main difference in roles of Administrator and Super Administrator is that the Super Administrator can manage the network (Multisite).

The network can be made on any WordPress website. Although this functionality is integrated, by default, it is not activated.

To create a network:

  1. At the end of the wp-config.php file, write a line: define ( 'WP_ALLOW_MULTISITE', true);
  2. Refresh the Admin panel, and Subparagraph “Network Setup” should appear in the Tools menu. Click on it and go to the installation page. Fill in the fields created by WordPress.
  3. Next, you will be transferred to the page settings that should be copied to wp-config.php and .htaccess files. Simply copy the suggested code, and paste it into the appropriate file.
  4. When the files are changed, remember to logout of the Admin panel to allow a user to create and manage the network’s websites.


We hope you find the questions and answers in this post to be a useful foundation as you search for great candidates among the few elite WordPress developers. Finding such candidates is well worth the effort, as they will undoubtedly have a significant, positive impact on your team’s productivity.

Hire WordPress developers now
See also: Toptal’s growing, community-driven list of essential WordPress interview questions.