How to Link to Your WordPress Theme and Plugin Resources

Links | Linking to WordPress plugin and theme resources

In WordPress theme and plugin development, you’ll often need to link to resources inside the theme or plugin you’re working on.

For example, maybe your plugin comes bundled with a necessary image file saved as a PNG. Or maybe your theme loads a particular web font inside a fonts subdirectory. Most commonly, you may want to enqueue CSS and JavaScript files in your theme or plugin. How do you link to these things?

The answer’s simple once you get it, but there are a lot of ways to do it wrong as well. So this article is a very quick “Two things to do,” plus a brief discussion of a few other ways to link to resources and why they often fall short.

First Things First: Don’t Hardcode Links

Don’t assume anything about file paths in WordPress—don’t hardcode URLs.

The first thing to know is: Don’t assume anything about file paths in WordPress. In other words, don’t hardcode URLs.

Never manually write out directories like the following:

  1. http://mysite.com/wp-content/themes/my-theme/new.css
  2. http://mysite.com/wp-content/plugins/my-plugin/img/image.png

Why? Because almost everything could change. Your site might someday no longer be at mysite.com—or someone else might someday use your theme on her site with a different domain name. Similarly, the wp-content, themes, my-theme, my-plugin directory names are all subject to change—and if anything does, your hard-coded links will break.

Toto, We’re Not in the Database Anymore

WordPress comes with decent ways to rewrite links that are stored in the database. This is why you can hardcode links that you write in post content: those links are saved in the database, so if your site’s domain changes from mysite.com to mysecondsite.com, it’s easy to track down references to the old domain and change them.

Theme and plugin development is a different story: the links you’ll be writing are saved directly within PHP files, and changing them becomes a chore that you shouldn’t put yourself or others through.

The Goal: Get to the Theme or Plugin Root with WordPress Functions

To link to a theme or plugin’s resources, the crucial thing is to get to its root directory.

The only stable, hardcodable links are those inside the theme or plugin itself, because you determine those. In the example above, that would be:

  1. new.css
  2. img/image.png

In other words, to link to a theme or plugin’s resources, the crucial thing is to get to its root folder, or root directory. Here’s what a theme root looks like:

Use get_stylesheet_directory_uri to access your theme's directory

From there, you can hardcode the rest of your links to get where you need to inside your theme or plugin. Below, we’ll cover the WordPress functions to get you to your theme or plugin root.

If you need a primer on function writing, check out our quick tutorials on PHP functions, and on understanding WordPress functions specifically.

Getting to the Theme Root with get_stylesheet_directory_uri()

To get to your active theme’s root, you’ll use a WordPress function called get_stylesheet_directory_uri(). This function will work flawlessly, whether you’re working in a parent theme or a child theme.

<!-- Environment: functions.php or a theme template file -->

<!-- Points to the current theme's root directory, then photo.jpg -->
<img src="<?php echo get_stylesheet_directory_uri(); ?>/photo.jpg">

<!-- Points to the current theme's root directory, then images/photo.jpg -->
<img src="<?php echo get_stylesheet_directory_uri(); ?>/images/photo.jpg">

The two resulting image links from the code above will look like:

  1. <img src="https://mysite.com/wp-content/themes/mytheme/photo.jpg">
  2. <img src="https://mysite.com/wp-content/themes/mytheme/images/photo.jpg">

Not-Quite-There Alternatives

get_template_directory_uri()

This function behaves almost exactly like get_stylesheet_directory_uri()—but not if you’re using a child theme. get_template_directory_uri() always links to the root of the parent theme, which is sometimes—but not very often—what you want if you’re working in a child theme.

get_theme_root_uri()

get_theme_root_uri() gets you to the root of the folder usually called /themes/. Great, right? You can just do that plus your theme’s name and the rest of it.

The problem is that if you—or someone else—renames your theme, all these calls will break. Renaming themes is perfectly legitimate, so don’t use get_theme_root_uri() to link to theme resources.

Getting to the Plugin Root with plugin_dir_url()

If you’re writing a plugin and want to link to something inside it, you’ll use a WordPress function called plugin_dir_url(). This function returns the root directory of the plugin from which it’s called. The syntax is a little unusual, but you’ll get used to it:

<!-- Environment: a PHP file inside a plugin -->

<!-- Points to the current plugin's root directory, then photo.jpg -->
<img src="<?php echo plugin_dir_url( __FILE__ ) . 'photo.jpg'; ?>">

<!-- Points to the current plugin's root directory, then images/photo.jpg -->
<img src="<?php echo plugin_dir_url( __FILE__ ) . 'images/photo.jpg'; ?>">

The two resulting image links from the code above will look like:

  1. <img src="https://mysite.com/wp-content/plugins/myplugin/photo.jpg">
  2. <img src="https://mysite.com/wp-content/plugins/myplugin/images/photo.jpg">

You can use this syntax as written out above anytime you want to link to another resource inside the same plugin you’re writing.

How Does This Work?

__FILE__

Well, the scary piece of this function is the huge __FILE__ argument, right? __FILE__ is a type of PHP variable called a magic constant. For our purposes, just think of it as meaning “The file I’m writing right now”—and the full function as meaning, “Get me to the root directory of the plugin that contains the file I’m writing right now.”

The Trailing Slash

Unlike get_stylesheet_directory_uri(), plugin_dir_url() does include a “trailing slash”—a slash after the name of the plugin folder. This is why we write:

plugin_dir_url( __FILE__ ) . 'photo.png'

rather than:

plugin_dir_url( __FILE__ ) . '/photo.png'

This is just an inconsistency in WordPress that you’ll need to keep in mind.

PHP String Concatenation

Finally, please note that:

<?php echo plugin_dir_url( __FILE__ ); ?>images/photo.jpg

ought to work just as well as:

<?php echo plugin_dir_url( __FILE__ ) . 'images/photo.jpg'; ?>

in the example we gave above. To us, though, the former looks weird. Furthermore, in plugin writing you’ll often need to be concatenating strings in PHP rather than pulling PHP into a raw HTML environment, so the second way of using the function is more broadly useful.

Not-Quite-There Alternatives

plugins_url()

Used without any arguments, plugins_url() will get you to the folder usually called /plugins/. Again, we don’t want this, because then we have to hardcode your plugin’s name, which may change.

Used with arguments, plugins_url() is a viable alternative to plugin_dir_url(). It’s used as follows:

<!-- Points to the current plugin's root directory, then /photo.jpg -->
<img src="<?php echo <plugins_url( '/photo.jpg', __FILE__ ); ?>">

Syntax-wise, though, we think it’s a bit confusing: everything’s a function argument, and it’s just too different from get_stylesheet_directory_uri(). If you can get closer to consistency, why not do it?

Now You Know!

Linking to theme and plugin resources comes up constantly in a WordPress developer’s work. It’s simple once you know how to do it, and avoiding the “not-quite-right” options can save you significant headaches when things change. Hopefully you’re better equipped to write links the right way in WordPress.

By the way, we pulled a lot of this content from our recently published book and video series on WordPress development, Up and Running. If you thought we did a great job, there’s a good chance you’ll love Up and Running, so have a look!

Image credit: Yandle


2 Responses

Comments

  • Dave Dean says:

    A nice round-up. Another not-quite-there alternative for getting your child theme directory is bloginfo('stylesheet_directory');

    It still works but has been deprecated. Cheers!