Bestway To Define Theme and Plugin path and url

Do not use constants for that. Do not use global constants at all.

There are two types of constants: class/interface constants and global constants.

Constants in classes or interfaces are fine and sometimes useful. An overly simplistic example:

interface Requirements
{
    const MIN_PHP_VERSION = 5.4;

    public function php_is_good();
}

class Theme_Requirements implements Requirements
{
    public function php_is_good()
    {
        return version_compare( PHP_VERSION, self::MIN_PHP_VERSION, '>=' );
    }
}

But keep in mind, these constants are always public. If you change them later, you might break code that depends on them.

This is worse with global constants. Imagine the following:

define( 'THEME_URI', get_template_directory_uri() );

And then a function for a default header image:

function get_default_header_image()
{
    return THEME_URI . '/img/default-header.jpg';
}

This function makes an assumption about something that is out of its control, it knows too much. How do you test that function with different values for the constant? You can’t.

Let’s say you want to test what happens when the constant is set to a non-existing directory or to another, slower server. But once you have defined the constant, you cannot change its value. You cannot run all tests in one rush, this makes testing harder than necessary.

And in a child theme that tries to use its own default image – how do you implement that? The constant is set by the parent theme. You could add a check with defined(), but that makes it harder to see where its value was actually written.

It would be much better to rewrite the function to:

function get_default_header_image( $base )
{
    return esc_url( $base ) '/img/default-header.jpg';
}

I said earlier, constants are an API. APIs should be easy to change, but it is really hard to deprecate a constant, because PHP doesn’t log the access. So your deprecation message will never reach other developers, except when they read your source code or your docs very carefully. Trust me, they don’t.

Use get_stylesheet_directory_uri() in child themes and get_template_directory_uri() in parent themes. Both can be filtered at runtime, so you can run all your test at once.

Leave a Comment