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】:

autoembedthe_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的主要内容,如果未能解决你的问题,请参考以下文章

GeoIP 根据用户位置 WordPress 自动更改货币

Wordpress:自动更改 the_content 部分中的 URL

WordPress管理员ID自动更改。我能做什么?

Wordpress 自动缩放更新

更改默认的 wordpress youtube 嵌入视频尺寸

Wordpress:仅针对所有通知电子邮件更改###ADMIN_EMAIL###