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:
get_template_directory_uri()
get_template_directory()
get_stylesheet_directory_uri()
get_stylesheet_directory()
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' );
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.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:
I almost always define my own constants for things involving URLs (pattern 3).
The reasons:
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.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.
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
andWP_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
andget_stylesheet_directory_uri
, however. Both rely on database options (if you trace things back to the beginning), which are fetched withget_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.