Wordpress:自动更改 the_content 部分中的 URL
Posted
技术标签:
【中文标题】Wordpress:自动更改 the_content 部分中的 URL【英文标题】:Wordpress: Automatically change URLs in the_content section 【发布时间】:2020-07-27 16:32:48 【问题描述】:here 的解决方案并没有解决我们的问题。
我已经有了一个解决方案来更改我们主题中字段表单中的所有链接。我为每个网络使用不同的数组,例如 $example_network_1
$example_network_2
,每个附属网络都有一个 php foreach。
现在我需要一个解决方案来将相同的数组用于 WordPress 帖子的内容。
此解决方案适用于一个网络,但它导致 YouTube 视频出现 404e 错误。我们将来自 YouTube 视频的 URL 和 WordPress 自动生成嵌入视频。使用以下代码,我们会得到 404 错误 iframe 或类似的东西。
我们需要针对多个网络的解决方案。
我非常感谢每一个帮助!
$example_network_1 = array(
array('shop'=>'shop1.com','id'=>'11111'),
array('shop'=>'shop2.co.uk','id'=>'11112'),
);
$example_network_2 = array(
array('shop'=>'shop-x1.com','id'=>'11413'),
array('shop'=>'shop-x2.net','id'=>'11212'),
);
add_filter( 'the_content', 'wpso_change_urls' ) ;
function wpso_found_urls( $matches )
global $example_network_1,$example_network_2;
foreach( $example_network_1 as $rule )
if (strpos($matches[0], $rule['shop']) !== false)
$raw_url = trim( $matches[0], '"' ) ;
return '"https://www.network-x.com/click/'. $rule['id'].'lorem_lorem='.rawurlencode($raw_url ) . '"';
/*
foreach( $example_network_2 as $rule )
if (strpos($matches[0], $rule['shop']) !== false)
$raw_url = trim( $matches[0], '"' ) ;
return '"https://www.network-y.com/click/'. $rule['id'].'lorem='.rawurlencode($raw_url ) . '"';
*/
function wpso_change_urls( $content )
global $example_network_1,example_network_2;
return preg_replace_callback( '/"+(http|https)(\:\/\/\S*'. $example_network_1 ['shop'] .'\S*")/', 'wpso_found_urls', $content ) ;
// return preg_replace_callback( '/"+(http|https)(\:\/\/\S*'. $example_network_2 ['shop'] .'\S*")/', 'wpso_found_urls', $content ) ;
【问题讨论】:
在没有看到内容的情况下,尚不清楚此过滤器如何在 YouTube 嵌入中导致 404 错误。您能否以三种形式提供内容:1)您在后端放入 WordPress 的内容,2)正确的输出和 3)您得到的错误而不是正确的输出? 【参考方案1】:如果阻止 wp 自动嵌入工作,那么只需将此行添加到您的主题 functions.php
remove_filter( 'the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
【讨论】:
我们希望对 YouTube 视频使用自动嵌入功能,但在 the_content 部分更改特定 URL 的代码不应导致此问题。【参考方案2】:我在没有测试的情况下编写了解决方案。如果没有您的网站,您的代码很难测试,但我认为问题出在正则表达式上。回调很难调试。下面是我的版本。
第一步,改变你的结构。我怀疑域是独一无二的。一维数组更有用。
$domains = array(
'shop1.com'=>'11111',
'shop2.co.uk'=>'11112',
'shop-x1.com'=>'11413',
'shop-x2.net'=>'11212',
);
下一步:
$dangerouschars = array(
'.'=>'\.',
);
function wpso_change_urls( $content )
global $domains,$dangerouschars;
foreach($domains as $domain=>$id)
$escapedDomain = str_replace(array_keys($dangerouschars),array_values($dangerouschars), $domain);
if (preg_match_all('/=\s*"(\s*https?:\/\/(www\.)?'.$escapedDomain.'[^"]+)\s*"\s+/mi', $content, $matches))
// $matches[0] - ="https://example.com"
// $matches[1] - https://example.com
for($i = 0; $i<count($matches[0]); $i++)
$matchedUrl = $matches[1][$i];
$url = rawurlencode($matchedUrl);
//is very important to replace with ="..."
$content = str_replace($matches[0][$i], "=\"https://www.network-x.com/click/$idlorem_lorem=$url\" ", $content);
return $content;
Example script
【讨论】:
感谢您的解决方案,但它不起作用。我不明白你为什么要添加数组$dangerouschars
。在我的测试中,我添加了缺少的add_filter( 'the_content', 'wpso_change_urls' ) ;
,我可以使用一维数组,但我需要一个解决方案,其中每个合作伙伴网络使用不同的数组,甚至广告商只有一个域。对于某些网络,我需要对 URL 进行原始编码,而对于其他网络,我不需要。对于两个网络,我没有为域使用 ID。我的脚本仅更改我的 Wordpress 主题字段中的 URL。
请查看我为每个合作伙伴提供的完整代码:paiza.io/projects/9a0m-brPc6B4vBVLcqzgMA【参考方案3】:
autoembed
与the_content
挂钩,wp-includes/class-wp-embed.php:39
上的优先级为 8
尝试降低 the_content
过滤器的优先级,以便 URL 替换发生在嵌入之前,如下所示:
add_filter( 'the_content', function ( $content )
/*
* Here, we define the replacements for each site in the network.
* '1' = main blog
* '2' = site 2 in the network, and so on
*
* To add more sites, just add the key number '3', etc
*/
$network_replacements = [
'1' => [
[ 'shop' => 'shop1.com', 'id' => '11111' ],
[ 'shop' => 'shop2.co.uk', 'id' => '11112' ],
],
'2' => [
[ 'shop' => 'shop-x1.com', 'id' => '11413' ],
[ 'shop' => 'shop-x2.net', 'id' => '11212' ],
]
];
// Early bail: Current blog ID does not have replacements defined
if ( ! array_key_exists( get_current_blog_id(), $network_replacements ) )
return $content;
$replacements = $network_replacements[ get_current_blog_id() ];
return preg_replace_callback( '/"+(http|https)(\:\/\/\S*' . $replacements['shop'] . '\S*")/', function( $matches ) use ( $replacements )
foreach ( $replacements as $rule )
if ( strpos( $matches[0], $rule['shop'] ) !== false )
$raw_url = trim( $matches[0], '"' );
return '"https://www.network-x.com/click/' . $rule['id'] . 'lorem_lorem=' . rawurlencode( $raw_url ) . '"';
, $content );
, 1, 1 );
这不是复制和粘贴解决方案,但应该可以帮助您。你可能需要调整你的“preg_replace_callback”代码,但你说它可以工作,所以我就让它保持原样。
【讨论】:
感谢您的解决方案。有用。但我需要一个解决方案,其中每个合作伙伴网络使用不同的阵列,甚至广告商只有一个域。对于某些网络,我需要对 URL 进行原始编码,而对于其他网络,我不需要。对于两个网络,我没有为域使用 ID。在我的示例中,我在 cmets 中添加了第二个网络,因为它不起作用。一个函数只能返回一个结果。 '1' 和 '2' 在网络中,我想用字符串而不是数字来调用它们以进行概述。 对于您的版本,the_content
中的所有图像都不会显示。图片不是来自阵列中的域,而是在我们的服务器上。
它不仅仅是一个网络。它们有 400 多个域,而且我的列表还会增加。这是整个代码,其中 URL 在主题字段中进行了更改。所有 URL 也应该更改为 int the_content
: link
你有什么想法吗?
您需要在 400 个不同的网站中更改the_content
?以上是关于Wordpress:自动更改 the_content 部分中的 URL的主要内容,如果未能解决你的问题,请参考以下文章
Wordpress:自动更改 the_content 部分中的 URL