我已经使用 ddev 设置了一个简单的 wordrpress 环境。
我正在尝试使用
ddev share
函数,该函数应该给出
本地 WP 网站的实时预览,但是当我尝试从另一个网站访问该网站时
计算机位于不同的以太网上,然后站点加载,所有内容都与 html 和一些有关
原始 css 但不是全部。
当然,在本地一切都加载良好。
在 ngrok 网站的控制台中,我收到各种警告,如下所示:
Loading failed for the <script> with source “https://mysite.ddev.site:8443/wp-includes/js/jquery/jquery.min.js?ver=3.5.1”.
注意,“mysite.ddev...”是我本地环境的链接,所以我的猜测是这与相对/绝对网址有关,但我不确定如何解决这个问题
我参考过 5 年前的这篇文章,其中涉及到这个主题。
我安装了“绝对相对 URL”,但这并没有解决问题。
WordPress 的问题在于它将静态 URL 直接嵌入到数据库中,因此在更改主机名或执行其他任何操作的情况下使用起来要困难得多。这是 WordPress 的一个重大问题,并且有很多解决方法,但不是很令人满意。
文章DDEV分享:与其他协作者实时共享DDEV-Local项目解释了如何使用稳定的子域并进行搜索替换。
WordPress 只有一个基本 URL,但 wp 命令内置于 DDEV-Local 的 Web 容器中。
这组步骤假设 ngrok 子域为“wp23”,起始 URL 为“https://wordpress.ddev.site”。
经过一番实验,我找到了解决方案。
这篇文章有点旧,因此 DDEV 添加了一些额外的内容 升级到其 Wordpress 环境,该解决方案经过测试:
ddev -v:
ddev version v1.16.7
解决方案:
安装并激活相对网址插件
为了采取好的措施,请重新启动 DDEV 站点
ddev restart
进入终端写入:
ngrok http -host-header=rewrite .ddev.site
如果您不确定您的项目/站点名称是什么,请使用
ddev describe
在 URL 下方,第一个链接将引导您访问您的 localhost 站点应该是您插入到 ngrok 重写
中的 URL让 WP 和 ngrok 良好运行的第一步是将这一行添加到您的
.ddev/config.yaml
:
ngrok_args: "--host-header=rewrite"
这应该足以使
ddev share
ngrok URL 加载到您的手机上,但图像和样式已损坏。
Flywheel 的本地应用程序为了使其与其实时链接一起工作,所做的就是将以下(GPL 许可的)必须使用的插件添加到
wp-content/mu-plugins
。它删除了 WP 到规范 URL 的重定向,然后用大量 WP 过滤器挂钩上的公共 URL 替换本地 URL:
<?php
/*
Plugin Name: Local WP Live Link Helper
Plugin URI: https://localwp.com
Description: Makes WordPress URL functions relative to play nicely with Live Links.
Version: 2.0
Author: Flywheel
Author URI: http://getflywheel.com
License: GPLv2 or later
*/
class LocalWP_Live_Link_Helper {
/**
* host/domain parsed from 'home' option
*
* @var string|null
*/
public $home_domain;
public function __construct() {
$this->home_domain = str_replace( '/^www./', '', parse_url( get_option( 'home' ), PHP_URL_HOST ) );
$this->add_filters();
}
/**
* @return string Host from server along with port re-added if using localhost routing mode.
*/
public function get_local_host() {
$original = str_replace( '/^www./', '', $_SERVER['HTTP_HOST'] );
/**
* If using localhost and the port isn't in HTTP_HOST then it needs to be re-added.
*/
if ( $original === 'localhost' ) {
$original .= ':' . $_SERVER['SERVER_PORT'];
}
return $original;
}
/**
* Convenience method to get tunnel domain from headers.
*
* @return string
*/
public function get_tunnel_host() {
return $_SERVER['HTTP_X_ORIGINAL_HOST'];
}
/**
* @return void
*/
public function add_filters() {
/**
* Do not add any of these filters if the X-Original-Host header is missing.
*/
if ( empty( $_SERVER['HTTP_X_ORIGINAL_HOST'] ) ) {
return;
}
add_action( 'send_headers', array( $this, 'send_private_cache_control_header' ), 9999 );
add_action('send_headers', array($this, 'send_local_host_header'), 9999);
remove_action( 'template_redirect', 'redirect_canonical' );
$local_to_tunnel_filters = array(
'get_rest_url',
'wp_redirect',
'bloginfo_url',
'the_permalink',
'wp_list_pages',
'wp_list_categories',
'the_content_more_link',
'the_content',
'the_tags',
'the_author_posts_link',
'post_link',
'post_type_link',
'page_link',
'attachment_link',
'get_shortlink',
'post_type_archive_link',
'get_pagenum_link',
'get_comments_pagenum_link',
'term_link',
'search_link',
'day_link',
'month_link',
'year_link',
'option_siteurl',
'blog_option_siteurl',
'option_home',
'admin_url',
'get_admin_url',
'get_site_url',
'network_admin_url',
'home_url',
'includes_url',
'site_url',
'site_option_siteurl',
'network_home_url',
'network_site_url',
'get_the_author_url',
'get_comment_link',
'wp_get_attachment_image_src',
'wp_get_attachment_thumb_url',
'wp_get_attachment_url',
'wp_login_url',
'wp_logout_url',
'wp_lostpassword_url',
'get_stylesheet_uri',
'get_locale_stylesheet_uri',
'script_loader_src',
'style_loader_src',
'get_theme_root_uri',
'theme_root_uri',
'plugins_url',
'stylesheet_directory_uri',
'template_directory_uri'
);
foreach ( $local_to_tunnel_filters as $local_to_tunnel_filter ) {
add_filter( $local_to_tunnel_filter, array( $this, 'make_link_tunnel' ) );
}
add_filter( 'pre_update_option', array( $this, 'make_link_local' ) );
add_filter( 'wp_insert_post_data', array( $this, 'make_link_local_in_posts' ), 9999 );
}
/**
* Prevent possible cache poisoning by sending Cache-Control private header whenever the domain is replaced.
*
* @return void
*/
public function send_private_cache_control_header() {
header( 'Cache-Control: private' );
}
/**
* Send original domain so the tunnel server can perform a replacement with it.
*/
public function send_local_host_header()
{
header('X-Local-Host: ' . $this->get_local_host());
}
/**
* Convenience method for replacing old host with new host.
*
* @param string $old Host to be replaced
* @param string $new Host to use as replacement
* @param string $subject Replacement subject
*/
public function replace_host( $old, $new, $subject ) {
$subject = str_replace( 'www.' . $old, $new, $subject );
$subject = str_replace( $old, $new, $subject );
return $subject;
}
/**
* Generic replacement of the site's local hostname to the tunnel hostname
*
* @param string $str String provided by the filter
*
* @return string String with local hostname replaced with the tunnel hostname
*/
public function make_link_tunnel( $str ) {
$local_host = $this->get_local_host();
$tunnel_host = $this->get_tunnel_host();
$str = $this->replace_host( $local_host, $tunnel_host, $str );
$str = $this->replace_host( $this->home_domain, $tunnel_host, $str );
/**
* Force HTTPS, but not for local dev testing setup ($tunnel_host ends with tunnel.testing:<port> )
*/
if (!preg_match('/^.*tunnel\.testing:\d+$/i', $tunnel_host)) {
$str = str_replace( 'http://' . $tunnel_host, 'https://' . $tunnel_host, $str );
}
return $str;
}
/**
* Generic replacement of the site's tunnel hostname to the local hostname,
* used when saving options to the database via the pre_update_option filter hook
*
* @param mixed $option Option being saved, provided by the filter. Will
* usually be a serialized string, but may be an
* unserialized type in some cases. See:
* https://developer.wordpress.org/reference/functions/get_option/
*/
public function make_link_local( $option ) {
if (gettype($option) !== 'string') {
$old_str = serialize($option);
$new_str = $this->replace_host( $this->get_tunnel_host(), $this->home_domain, $old_str );
return unserialize($new_str);
}
return $this->replace_host( $this->get_tunnel_host(), $this->home_domain, $option );
}
/**
* Go through post properties and replace the tunnel host with the local host
*
* @param WP_Post $post
*/
public function make_link_local_in_posts( $post ) {
$post['post_content'] = $this->make_link_local( $post['post_content'] );
return $post;
}
}
new LocalWP_Live_Link_Helper();
我已将
the_content
过滤器添加到其中的过滤器大列表中,以便它将重写图像 URL,我发现这并不总是与原始插件一起使用;当地可能有一些涉及媒体的额外秘密,或者我可能只是做错了什么。