How to Build a WordPress Starter Theme: Part 4 – The functions.php File


Welcome back to the “How to Build a WordPress Starter Theme” series! In the previous part, we created our index.php file and made a good start on our theme. In this part, we’ll be creating our functions.php file and using it to attach our CSS and scripts the correct way. We’ll also, look at localisation and fixing our wp_title the correct way.

Before We Continue

We’re quite close to the end of this series now, so I think it’s safe to release all the code to you for this theme which we’re building. You can find the finished theme on GitHub. In particular, I’d like you to take a look at the functions.php file in the repository as there are detailed descriptions taken from the Codex in the DocBlocks above each function. I find it quite useful to do this while learning a WordPress feature, function, API etc. It saves jumping back and forth between the browser and code editor too often.

What’s the File All About?

So, what is the purpose of the fabled functions.php file? Well, the functions.php file is where WordPress really gets it’s flexibility from. If you need to insert a script, stylesheet or alter some output generated by a plugin (or indeed WordPress itself), the file allows you to do it. Need to add a sidebar, a brand new widget or a shortcode? The functions.php file is where you do it. Need to create a custom post type or even an entire admin panel like those fancy premium themes? You guessed it, the function.php file allows you to do it all and much, much more. Alright, enough talk… lets write some code!

Adding the Functions

First, create a file called functions.php in your theme root. Once that’s done, open it your text editor, and the first function we’ll include is called load_theme_textdomain(). This function handles translating certain strings in WordPress into other languages using translation files, which have the .mo and .po extensions. This function takes two arguments: $textdomain and $path. The textdomain is what you used in your style.css file. This ensures that if you have translated a string for your theme and a plugin has translated the same string differently WordPress will know which one to use. The $path argument is the location of the .mo (.po) files. Usually, this is the languages directory in the theme root.

So, here’s our code so far:

 * See the github functions.php file for more detailed comments. I'm serious!
 * @link
load_theme_textdomain( 'noesis', get_template_directory() . '/languages' );

A Bit More on “i18n”

“i18n” is shorthand for “internationalisation”, because there are 18 characters between the “i” and “n” (smart, eh?). You’ll also see it called localisation. Any theme that wants to be “translation ready” starts by doing this. The next step is to pick the strings in your functions which require translation, and then what kind of translation. The only things you’ll need to make translation ready are menu text, admin messages, and pretty much anything output by your function which a user will see. That means admins and front-end users.

So, to do this you simply wrap the text in either __( 'Text to simply be translated', 'noesis' ) or _e( 'Text to be translated and then echoed out', 'noesis' ).

To begin with, that’s all you’ll really need to know, but if and when you want to know more you can find more in the Codex

Adding the CSS

The next logical step is to get our style.css file loaded through the wp_head() hook in our index.php file. The action for this is called wp_enqueue_scripts().

We first need to wrap it in our own function to be used in the action. This is a common method of writing and using WordPress function. The name of this function should be unique, seeing as plugins are also likely to be using this action also. The easiest way to make your names unique is to prefix them with your theme (or plugin) name.

function noesis_enqueue_scripts() {
   * Load our main stylesheet.
  wp_enqueue_style( 'noesis-style', get_stylesheet_uri(), array(), '1.0', 'screen' );
add_action( 'wp_enqueue_scripts', 'noesis_enqueue_scripts' );

Inside of our function, noesis_enqueue_scripts(), we have the WordPress function wp_enqueue_style() which accepts 5 arguments:

  • handle: Unique name given to the stylesheet. This will be its ID (id="noesis-style")
  • src: The URL to the stylesheet. You should never “hardcode” URLs in WordPress. Depending on what you are trying to achieve, WordPress has helper functions for URLs. In this case, our stylesheet URL can be inserted with get_stylesheet_uri()
  • deps: Dependencies. This is an array of files which this file requires to be loaded before it. For example you may need Bootstrap or some other grid framework to come before it.
  • ver: This is the version which will be appended on at the end of the files URL (example: What this does is it forces the browser to load the CSS file from the server, and not cache it in the browser.
  • media: Finally, we define the media type this stylesheet is to be used for. In this case it is “screen”, though it could be “print”, “all”, or even a media query rule such as max-width: 900px.

Once we have our function, we can insert it dynamically using the add_action() function. The first argument is the tag, which tells WordPress what we want this function to be hooked into. In this case, we’re using the wp_enqueue_scripts tag which automatically inserts scripts in the wp_head and wp_footer hooks. The second argument is the callback function, which is the function we just wrote noesis_enqueu_scripts. add_action actually takes four parameters in total, but these two are the ones you’re required to use. You can read more about this in the Codex. In fact, the Codex has just got a facelift and a new subdomain, so you can now read about add_action in the new WordPress Code Reference.

Once you’ve attached your style.css file using the wp_enqueue_style function you should see it when you view source. If you want to start styling your theme now you can. You can also add more stylesheets and even JavaScript by simply placing the appropriate functions within noesis_enqueue_scripts. You can find more on adding scripts here.

Fix wp_title for Feed and Home/Front Page

Remember our temporary fix for the title not displaying on the homepage? Well, we should move that into our functions.php file and beef it up so it also handles our RSS feed titles properly. This is taken from the twentyfourteen theme’s functions.php file:

function noesis_wp_title( $title, $sep ) {
  global $paged, $page;

  if ( is_feed() ) {
    return $title;

  // Add the site name.
  $title .= get_bloginfo( 'name', 'display' );

  // Add the site description for the home/front page.
  $site_description = get_bloginfo( 'description', 'display' );
  if ( $site_description && ( is_home() || is_front_page() ) ) {
    $title = "$title $sep $site_description";

  // Add a page number if necessary.
  if ( $paged >= 2 || $page >= 2 ) {
    $title = "$title $sep " . sprintf( __( 'Page %s', 'noesis' ), max( $paged, $page ) );

  return $title;
add_filter( 'wp_title', 'noesis_wp_title', 10, 2 );

This time, we’re using the add_filter() function which also accepts the same four arguments as add_action(). In fact, they’re similar in how they work, but add_filter is used to modify content which has been output by either a plugin or WordPress itself, while add_action is used to insert/output said content.

This function will now handle our homepage, feeds, and paginated pages for us. Now, you need to remove our temporary fix for the title in the index.php file. Modify the <title> as follows:

<title><?php wp_title(); ?></title>

In Summary

We’ve looked at some simple concepts about the functions functionality in WordPress. These include filters, actions and hooks. In the next part, we’ll continue working in the functions.php file, where we’ll activate our navigation and also register our sidebar. Happy coding!


About Author

Founder and Lead Developer at, a web development agency in Galway, Ireland. Develops mosty with WordPress, Laravel, PHP, MySQL, Git, Github, Sass and Compass.

Leave A Reply