WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Edit: Thanks for your replies, guys. This is exactly what I was after. You each brought up some good points. I think I'll stick with using constants.

This is really a best practices/performance question.

I'm mainly concerned with the following functions:


I've been under the impression that it is bad practice to repeatedly call a function over and over in certain situations. So, this would be considered bad practice:

// Pattern 1
wp_enqueue_script( 'test-1', get_template_directory_uri() . '/js/test-1.js', 'jquery', '20120206', true );
wp_enqueue_script( 'test-2', get_template_directory_uri() . '/js/test-2.js', 'jquery', '20120206', true );
wp_enqueue_script( 'test-3', get_template_directory_uri() . '/js/test-3.js', 'jquery', '20120206', true );

And this would be better:

// Pattern 2
$template_directory_uri = get_template_directory_uri();
wp_enqueue_script( 'test-1', $template_directory_uri . '/js/test-1.js', 'jquery', '20120206', true );
wp_enqueue_script( 'test-2', $template_directory_uri . '/js/test-2.js', 'jquery', '20120206', true );
wp_enqueue_script( 'test-3', $template_directory_uri . '/js/test-3.js', 'jquery', '20120206', true );

I've seen some themes initialize constants:

// Pattern 3
define( 'THEME_URI', get_template_directory_uri() );
define( 'THEME_JS', trailingslashit( BASETHEME_THEME_URI ) . 'js/' );
// Then, later on...
wp_enqueue_script( 'test-1', THEME_JS . 'test-1.js', 'jquery', '20120206', true );
wp_enqueue_script( 'test-2', THEME_JS . 'test-2.js', 'jquery', '20120206', true );
wp_enqueue_script( 'test-3', THEME_JS . 'test-3.js', 'jquery', '20120206', true );

I'm getting the impression that using constants is not such a good idea, even if they are initialized using get_template_directory_uri() et al., because they can be inflexible. Here's a ticket in WP trac where the constant approach got the boot. Taking a look at _s, (sample below), they are (potentially) calling get_template_directory_uri() multiple times.

I know this isn't a huge deal, but I run into this question all the time, and see it done differently in themes and plugins. Can you guys help me to set the record straight?

// ...sample code from _s using the multiple calls to get_template_directory_uri()
 * Enqueue scripts and styles
function _s_scripts() {
    global $post;

    wp_enqueue_style( 'style', get_stylesheet_uri() );

    wp_enqueue_script( 'jquery' );

    wp_enqueue_script( 'small-menu', get_template_directory_uri() . '/js/small-menu.js', 'jquery', '20120206', true );

    if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
        wp_enqueue_script( 'comment-reply' );

    if ( is_singular() && wp_attachment_is_image( $post->ID ) ) {
        wp_enqueue_script( 'keyboard-image-navigation', get_template_directory_uri() . '/js/keyboard-image-navigation.js', array( 'jquery' ), '20120202' );
add_action( 'wp_enqueue_scripts', '_s_scripts' );
share|improve this question

I think there is zero performance issue regarding multiple uses of get_template_directory() (or any of its siblings). The return values of these functions are part of the cache. Multiple calls to these functions do not incur multiple database hits.

share|improve this answer

I don't think there is a right or best way to do that (there are wrong ways), if you use constants you save function execution calls at run time but loose the flexibility of filtering which can be handled with direct function calls.

In my theme's i define my own constants and where no filtering is needed and if there is an option or need of filtering i use in functions variables, meaning if its all in the same function then calling the same function over and over is just dumb ex:

function _s_scripts() {
    global $post;
    wp_enqueue_style( 'style', get_stylesheet_uri() );
    wp_enqueue_script( 'jquery' );
    $get_template_directory_uri = get_template_directory_uri();
    wp_enqueue_script( 'small-menu',  $get_template_directory_uri. '/js/small-menu.js', 'jquery', '20120206', true );
    if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
        wp_enqueue_script( 'comment-reply' );
    if ( is_singular() && wp_attachment_is_image( $post->ID ) ) {
        wp_enqueue_script( 'keyboard-image-navigation', $get_template_directory_uri . '/js/keyboard-image-navigation.js', array( 'jquery' ), '20120202' );
add_action( 'wp_enqueue_scripts', '_s_scripts' );
share|improve this answer

I almost always define my own constants for things involving URLs (pattern 3).

The reasons:

  1. Enqueueing does not account for child theme files. Using get_style_sheet_directory_uri will obviously fetch the child theme's template URI, but what if the child theme didn't copy over the JS or CSS file(s)? Those enqueued resources 404. I'd rather my enqueues work.

  2. Scripts and styles can easily be dequeued. If a child theme or user wants to change something they can easily dequeue the script. That more than makes up for how "un-dynamic" using constants is.

  3. Dynamic filtering only seems useful if it's conditional. get_stylesheet_directory_uri does have a filter inside it, but how do you know which of its calls your filtering? Did you want to filter all of them?

There are filters inside the WP_Scripts and WP_Styles, which handle enqueues, where one can hook in and alter enqueue's href's and src's conditionally based on the script handle and change the URI as necessary.

I'm not sure this is the right approach, but I've looked a lot of theme's and plugin's code and a lot of them do use self-defined constants at the top of their plugin or functions.php files.

I agree with Bainternet: multiple calls to the same function seems a bit silly. There is some catching going on with get_template_directory_uri and get_stylesheet_directory_uri, however. Both rely on database options (if you trace things back to the beginning), which are fetched with get_option, which is cached. But there's still some overhead to calling a function and doing a bunch of string concatenation to product a full URI.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.