Pi on Chalkboard

6-minute read

Path and URL Constants for ClassicPress Plugins

A consistent set of constants for paths and URLs can improve speed and efficiency in creating ClassicPress plugins. Learn how to leverage this technique to save time and get more work done faster.

When you’re developing plugins for ClassicPress, you will often be referring to various paths and URLs, both within your plugin and within the greater ecosystem. You might need the site’s admin url, maybe you need your plugin’s scripts or styles directory… there are a lot of paths and URLs that you may need.

ClassicPress Paths and URLs

To be clear, ClassicPress does have functions that will get most paths and URLs that you typically would use in a plugin. However, if you’re like me, you may have trouble remembering all the function names or the arguments they take… or whether they have a trailing slash. What’s more, my code auto-completer can handle some of them quickly, while others leave me tabbing around to get in the right spot. I wanted a better solution.

Custom Paths and URLs

I’ve created a consist set of constants for paths and URLs that I can easily use in any ClassicPress plugin. They are easy to remember, work great with auto-completers, and there’s no more wondering about trailing slashes. Moreover, I’m able to write code much more efficiently – and that’s a win in my book!

The way I implement these constants in my plugins is to put them all into /my-plugin/includes/constants.php and include that file immediately within my initialization function in my plugin. So, let’s check’em out!

<?php

// Declare the namespace - change or remove this for your own use!
namespace MyCompanyName\MyPluginName;

// Prevent direct access.
if (!defined('ABSPATH')) {
	die();
}

// Gain access to the get_home_path() function.
require_once(ABSPATH.'wp-admin/includes/file.php');

// Ex: /home/user/mysite
define(__NAMESPACE__.'\PATH_HOME', untrailingslashit(get_home_path()));

// Ex: https://mysite.com
define(__NAMESPACE__.'\URL_HOME', untrailingslashit(home_url()));

// Ex: /home/user/mysite/wp-admin
const PATH_ADMIN = PATH_HOME.'/wp-admin';

// Ex: /home/user/mysite/wp-content/plugins
const PATH_PLUGINS = WP_PLUGIN_DIR;

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name
const PATH_SELF = PATH_PLUGINS.'/'.PLUGIN_SLUG;

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/extensions
const PATH_EXTENSIONS = PATH_SELF.'/extensions';

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/scripts
const PATH_SCRIPTS = PATH_SELF.'/scripts';

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/styles
const PATH_STYLES = PATH_SELF.'/styles';

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/images
const PATH_IMAGES = PATH_SELF.'/images';

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/languages
const PATH_LANGUAGES = PATH_SELF.'/languages';

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/includes
const PATH_INCLUDES = PATH_SELF.'/includes';

// Ex: /home/user/mysite/wp-content/plugins/my-plugin-name/classes
const PATH_CLASSES = PATH_SELF.'/classes';

// Ex: https://mysite.com/wp-admin
const URL_ADMIN = URL_HOME.'/wp-admin';

// Ex: https://mysite.com/wp-content/plugins
const URL_PLUGINS = WP_PLUGIN_URL;

// Ex: https://mysite.com/wp-content/plugins/my-plugin-name
const URL_SELF = URL_PLUGINS.'/'.PLUGIN_SLUG;

// Ex: https://mysite.com/wp-content/plugins/my-plugin-name/extensions
const URL_EXTENSIONS = URL_SELF.'/extensions';

// Ex: https://mysite.com/wp-content/plugins/my-plugin-name/scripts
const URL_SCRIPTS = URL_SELF.'/scripts';

// Ex: https://mysite.com/wp-content/plugins/my-plugin-name/styles
const URL_STYLES = URL_SELF.'/styles';

// Ex: https://mysite.com/wp-content/plugins/my-plugin-name/images
const URL_IMAGES = URL_SELF.'/images';

Namespacing the Constants

You’ll see that these constants have been namespaced. This isn’t a requirement, but it is recommended to avoid your code from polluting the global space and causing collisions. Now, let’s cover a few gotchas before they, well, getchya.

Gotcha #1

If you need to check whether a namespaced constant is defined, you must prepend the namespace.

<?php 

// If you have a namespaced constant MyCompanyName\MyPluginName\MY_PLUGIN_NAME

// ...and you're in the same namespace, you can check it like this:
if (defined(__NAMESPACE__.'\\PLUGIN_NAME')) {
    // Constant is defined.
}

// ...if you're in a different namespace, you can do it like this:
if (defined('MyCompanyName\MyPluginName\MY_PLUGIN_NAME')) {
    // Constant is defined.
}

Gotcha #2

If you use the `define()` function to define a constant, it must be prepended with the namespace. However, if you use the `const` keyword to define your constant, then the namespace is prepended automatically. The following code block demonstrates both methods of defining a constant.

<?php 

    // Declare the namespace.
    namespace MyCompanyName\MyPluginName;

    // The namespace magic constant can be used to prepend the namespace...
    define(__NAMESPACE__.'\\MY_CONSTANT', 'My Value');

    // ...or, the const keyword can be used to prepend the namespace automatically.
    const MY_CONSTANT = 'My Value';

Be sure to note that the code block above would produce an error – you can’t define the same constant twice, after all. You must choose one method or the other. These lines were included together above simply so you could see the differences in close proximity. No matter which method was chosen, the result would be the following namespaced constant:

MyCompanyName\MyPluginName\MY_CONSTANT

To define() or to const? That is the question.

If you can use the const keyword, go for it. It’s the more modern way to define constants and gives you access to some additional cool tricks. In most cases, the `const` keyword will work. But, not always.

If you need to use a function (or any PHP) to generate the value of the constant defined by the `const` keyword, you’ll get an error. This is because you can’t have “code” on the right-hand side of the equation when you’re using `const`. In those cases, you can simply fall back to the older `define()` method of defining constants. The following code block demonstrates both succeeding and failing code.

<?php

    // Declare the namespace.
    namespace MyCompanyName\MyPluginName;

    // Define the plugin name.
    const PLUGIN_NAME = 'My Sweet Plugin';
    const PLUGIN_VERSION = '1.0.0';    

    // FAIL: No "code" allowed in value.
    const PLUGIN_TITLE = PLUGIN_NAME . ' - ' . PLUGIN_VERSION;
    // SUCCESS
    define(__NAMESPACE__.'\\PLUGIN_TITLE', PLUGIN_NAME . ' - ' . PLUGIN_VERSION); 

    // FAIL: No "code" allowed in value.
    const PLUGIN_RELEASE = get_release_date(); 
    // SUCCESS
    define(__NAMESPACE__.'\\PLUGIN_RELEASE', get_release_date());

Wrapping Up

The idea of using constants for frequently used paths and URLs isn’t new, but, it is often overlooked. It’s actually quite easy to implement these constants and it can dramatically improve your efficiency in writing new ClassicPress plugins. Time saved is money saved – start saving today!

What do you think?

Do you like the idea of having a set of defined constants, or do you think it’s overkill? And how about namespaces… were they easy to understand in this context? Or are you scraping your brain up off the keyboard right now? I’d love to know your thoughts – let me know in the comments.

2 comments on “Path and URL Constants for ClassicPress Plugins”

  1. A commenter said:

    This is interesting. When I write plugins, I use composer for the namespace and autoloading. Then I create a class for my constants which I extend to classes that require them. OOP perks.

    • AUTHOR
      Code Potent replied:

      Hey Laurence,

      It’s great to hear how you’re doing it! By placing all the constants into a class, it can make a handy “config object” for dependency injection elsewhere in a plugin. This can also help with testing. I like it. I’ve always tended to keep my constants outside of a class (though under a namespace,) but, I think it’s been more out of habit than anything. Thanks for sharing your thoughts.

Comments are closed.

Click to access the login or register cheese