Say a theme “foo” is used on across a network of sites. In each site, all the theme resources (.css
, .js
, etc.) will have distinct URLs:
- http://network/siteA/wp-content/themes/foo/style.css
- http://network/siteB/wp-content/themes/foo/style.css
- http://network/siteC/wp-content/themes/foo/style.css
I want these to all be:
What’s the best way to do this? I can fix URLs directly output in the theme, but how do I normalize the URLs in enqueued scripts/stylesheets?
Aside: What’s the benefit of having expressions like
get_bloginfo('template_url')
create URLs that differ across sites?
Hi @mrclay:
Good questions.
WordPress Multisite is Many Independant Sites, not Many Dependant Sites
To answer your aside, WordPress multisite was designed to be a collections of independent WordPress installs collected into one where each site is likely to be very different, unlike your use-case. So each site has it’s own theme and WordPress wants those themes to work on both single site installs and for sites in a multisite install.
WordPress Out-of-the-Box: Decisions, not Options, but Change with Plugins
While WordPress could have had an option for doing what you want built in the philosophy at WordPress is to make decisions for you instead of giving you a thousand options you’ll feel you need to understand, and then letting plugin developers changes those decisions if needed.
Yes: Central Resources = Better Load Times
Still, it would be nice to be able to do what you are asking as it would improve average load times by leveraging HTTP GET caching for multisites with common themes.
No Need to “Rewrite” URLs
To start, there’s no need to “rewrite” the URLs, just make sure the stylesheet and other resources you want are part of the theme assigned to the main site and then they will be located at the URLs you want.
Creating the “Hook” for
style.css
In WordPress you change the out-of-the-box decisions by adding “hooks”; i.e. references to functions that will let you modify values. One such hook is
'stylesheet_uri'
which modifies the URL for the'style.css'
file that you explicitly referenced. You can copy this code to your theme’sfunctions.php
file or you can put into the .PHP file of a WordPress plugin you might be writing. Note that I coded this to support either subdomain installs or subdirectory installs:Other Resource URLs May Need Their Own Hooks
The code above only modifies the main stylesheet URL; if you need other URLs modified you may not to use other hooks. For example, you may end up needing to use
'style_loader_src'
and/or'plugins_url'
too but I didn’t have my test system set up with enough use-cases to verify if it’s needed or not:Enqueued Scripts and Styles use a
base_url
PropertyAnd it turns out that the enqueued scripts and styles use a property named
base_url
of the global variables$wp_scripts
and$wp_styles
, respectively to determine their location if a full URL is not passed explicitly by the developer. The property ofbase_url
is only set once for scripts and left blank for styles; the former is set upon instantiation of aWP_Scripts
object that is then assigned to the global variable$wp_scripts
.Set the
base_url
Property in an Early'init'
HookIf you instantiate and assign those early before any calls to
wp_enqueue_script()
orwp_enqueue_style()
you can then set thebase_url
property immediately after which you can do with aninit
hook with a priority of1
(1
priorities run very early, before most hooks). Here’s the'init'
hook to accomplish this:Or Set the
base_url
Property in a Late'init'
HookIt’s also possible to use a very high number for the priority for the
'init'
hook (such as 100) after allwp_enqueue_script()
orwp_enqueue_style()
have been called by (higher numbered priority hooks run after those with lower numbers). If so you don’t need to instantiate the globals, just assign thebase_url
property:Might Need to Adjust
'init'
Hook Priorities if Conflicting PluginsWhichever your preference, I believe either of those two (2)
'init'
hooks will work for you, but if you have plugins that use conflicting priorities you might need to lower the priority number to 0 or less with the first approach, or raise the priority above 100 for the second approach. Again I didn’t have enough use-case test scenarios to 100% verify so let me know if some use cases are not working for you.