浏览次数 :  159


<link rel=’stylesheet’ id=’joshuatzwp-style-css’ href=’http://joshuatz-wp.test/wp-content/themes/joshuatzwp/style.css‘ type=’text/css’ media=’all’ />


<link rel=’stylesheet’ id=’joshuatzwp-style-css’ href=’/wp-content/themes/joshuatzwp/style.css‘ type=’text/css’ media=’all’ />

第一个技巧: WP 强迫绝对链接



你指望 wp_make_link_relative 会生成一个相对的链接,但是仍然是绝对链接:

<link rel=’stylesheet’ id=’joshuatzwp-style-css’ href=’http://joshuatz-wp.test/wp-content/themes/joshuatzwp/style.css’ type=’text/css’ media=’all’ />


WordPress do_item 难题

为了搞清楚发生了什么, 我从<script>和<link>标记实际回显到页面的位置开始向后追踪,看看HTML是如何生成的。大概是这样:

None of this knowledge was strictly necessary to force relative paths, but it gives some insight into how the whole process works. I wouldn’t actually want to change any of these files, since they are part of the core of WP, and would be overwitten on a system update anyways.

The solution for relative paths:

The solution here is to hook into a WordPress filter. I’ve written about this before, when trying to add async/defer attributes to scripts and style tags, in this post. In fact, our solution is going to look pretty similar.

Basically, we will hook into the filter for ‘script_loader_tag’, which is the filter for <script> tags, and ‘style_loader_tag’, which is the filter for stylesheet <link> tags. In our hook, we will take the source that WordPress has prefixed and forced into an absolute URL, and remove the domain part that they added.

Here is the code:

function makeInternalLinkRelative($src){
    return str_replace(get_option('siteurl'),'',$src);

add_filter('style_loader_src',function($src, $handle){
    return makeInternalLinkRelative($src);
add_filter('script_loader_src',function($src, $handle){
    return makeInternalLinkRelative($src);

Pretty simple, huh! Just add this code to your theme’s (or child theme’s) function.php file, and you should be good to go!

The Solution for Dynamic Domains

If you don’t want to use relative paths, but just want WordPress to know when you are serving it through a different domain (such as when using Ngrok or swapping domains) and automatically adjust all the links, there is another solution we can employ. We can modify the wp-config.php file in the root of our WordPress install to dynamically set the “siteurl”, which as my earlier research pointed out, is used internally by WP to auto-prefix relative links.

Here is what I have added to my wp-config.php file:



$host = $_SERVER['HTTP_HOST'];
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT']===443)) ? 'https://' : 'http://';
define('WP_SITEURL', $protocol . $host);
define('WP_HOME', $protocol . $host);

Now, here is the really important thing. Make sure this code comes before this line of code that should already be in the file:

require_once(ABSPATH . 'wp-settings.php');

This matters because wp-settings.php is responsible for the chain of events that fills in the $base_url variable we were looking at earlier, and is ultimately responsible for prefixing URLs. If that runs before you set the “siteurl” global, it will have the domain from your admin settings, not from our dynamic override. I found this out the hard way!