【问题标题】:Wordpress: Automatically change specific URLs in postsWordpress:自动更改帖子中的特定 URL
【发布时间】:2020-07-04 21:09:19
【问题描述】:

我找到了一个解决方案来更改我的 wordpress 主题中的链接,但不是内容中的链接。怎么可能获取内容中的 URL,所以我也可以更改它们?

我需要使用the content 过滤器。但是如何更改诸如 apple.com/test/apple.com/test-123/、apple.com、microsoft.com、microsoft.com/test/ 之类的 URL。该函数还应该正确更改内容中每个匹配的 URL。

add_filter('the_content ', 'function_name');

很遗憾,answer of a similiar question 不起作用。

这是我更改链接的工作解决方案,但不是内容中的链接。

add_filter('rh_post_offer_url_filter', 'link_change_custom');
function link_change_custom($offer_post_url){

$shops= array(
        array('shop'=>'apple.com','id'=>'1234'),
        array('shop'=>'microsoft.com','id'=>'5678'),
        array('shop'=>'dell.com','id'=>'9876'), 
    );
    foreach( $shops as $rule ) {
        if (!empty($offer_post_url) && strpos($offer_post_url, $rule['shop']) !== false) {      
            $offer_post_url = 'https://www.network.com/promotion/click/id='.$rule['id'].'-yxz?param0='.rawurlencode($offer_post_url);
}    
    }
$shops2= array(
        array('shop'=>'example.com','id'=>'1234'),
        array('shop'=>'domain2.com','id'=>'5678'),
        array('shop'=>'domain3','id'=>'9876'),  
    );
    foreach( $shops2 as $rule ) {
        if (!empty($offer_post_url) && strpos($offer_post_url, $rule['shop']) !== false) {      
            $offer_post_url = 'https://www.second-network.com/promotion/click/id='.$rule['id'].'-yxz?param0='.rawurlencode($offer_post_url);
}    
    }

        return $offer_post_url; 
}

【问题讨论】:

  • 内容是指帖子编辑器内容中的链接吗?
  • @mikerojas 是的,完全正确。
  • 我下面提供的方案是用来过滤内容的。
  • 等等,帖子编辑器中实际出现的内容或输出中出现的内容或两者兼而有之,还是什么?
  • @CKMacLeod 我认为帖子编辑器中出现的内容。在输出中它应该已经被改变了。

标签: php wordpress redirect


【解决方案1】:

如果我理解正确,那就是你需要的

add_filter( 'the_content', 'replace_links_by_promotions' );
function replace_links_by_promotions( $content ) {
    $shop_ids = array(
        'apple.com'     => '1234',
        'microsoft.com' => '5678',
        'dell.com'      => '9876',
    );

    preg_match_all( '/https?:\/\/(www\.)?([-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6})\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)/', $content, $matches, PREG_OFFSET_CAPTURE );

    foreach ( $matches[2] as $index => $match ) {
        if ( ! isset( $shop_ids[ $match[0] ] ) ) {
            continue;
        }

        $offer_post_url = 'https://www.network.com/promotion/click/id=' . $shop_ids[ $match[0] ] . '-yxz?param0=' . rawurlencode( $matches[0][ $index ][0] );
        $content        = substr_replace( $content, $offer_post_url, $matches[0][ $index ][1], strlen( $matches[0][ $index ][0] ) );
    }

    return $content;
}

【讨论】:

  • 非常感谢。我已经在内容中使用 2 个或更多 apple.com URL 对其进行了测试,但只更改了第一个。有些链接完全消失了。是否可以将我的函数和你的函数结合起来,所以我不需要添加我所有的数组和 foreachs(336 行)。
  • 我不仅有一个带有商店的阵列,这就是为什么我为每个阵列为每个附属网络都设置一个 foreach。
  • 请给我你的数据(网址和内容)
  • 这里是所有网址。您的函数不仅应更改第一个匹配的 URL。 paiza.io/projects/zHPQv4D2XjhXJdE-_fDUYg
  • 也许您有类似 CK_MacLeod 的解决方案。我更改的版本与其他链接有一些错误。 paiza.io/projects/8V8BJmt4pZOy4ihLjsyjRg
【解决方案2】:

我认为这行得通。请注意,正如所写,它将匹配每个“apple.”、“dell.”和“microsoft”。在使用内容过滤器的每种类型的内容中链接 - 帖子、页面、摘录、许多自定义帖子类型等 - 所以,如果你真的不想要,而且你很可能不想要,那么主要的替换功能将必须条件化,并且正则表达式函数更精确地定位......,这可能会变得复杂。

(另外,想想看,我不确定 Regex 找到的锚标记中的引号是否需要特殊处理。如果这不起作用,我们也可以看看。或者也许切换到 DOM 解析器,就像我应该开始做...)

/** INITIATE FILTER FUNCTION **/
add_filter( 'the_content', 'wpso_change_urls' ) ;

/**
 * PREG CALLBACK FUNCTION
 * Match Matches to id #s
 * and return replacement urls enclosed in quotes (as found)
 */ 
function wpso_found_urls( $matches ) { 

  //someone else probably has a v clever parsimonious way to do this next part
  //but at least this makes what's happening easy to read
  if ( strpos( $matches[0], 'apple' ) ) {

      $id = '1234' ;

  } 

  if ( strpos( $matches[0], 'microsoft' ) ) {

      $id = '5678' ;

  } 

  if ( strpos( $matches[0], 'dell' ) ) {

      $id = '9876' ;

  } 

  $raw_url = trim( $matches[0], '"' ) ;

  return '"https://www.network.com/promotion/click/id='. $id .'-yxz?param0='.rawurlencode( $raw_url) . '"' ; 

}

/** ENDURING A DREADFUL FATE USING REGEX TO PARSE HTML **/
function wpso_change_urls( $content ) { 

    $find_urls = array( 
        '/"+(http|https)(\:\/\/\S*apple.\S*")/',
        '/"+(http|https)(\:\/\/\S*microsoft.\S*")/',
        '/"+(http|https)(\:\/\/\S*dell.\S*")/',
    );

    return preg_replace_callback( $find_urls, 'wpso_found_urls', $content ) ; 

}

返回(注意:在编码之前从“原始 URL”中修剪引号之前的示例):

...来自像这样的原始(帖子编辑器)内容:

【讨论】:

  • 感谢您的回答。如果它可以更短并与我的功能 replace_links_by_promotions 相结合,那就太好了,因为我有超过 300 家商店和 7 家 foreach 的每个附属网络。报价真的错了,因为他们把 URL 改错了:@987654327 @
  • 我不明白最后一部分关于错误的引用。如果问题只是返回的 URL 需要用引号括起来,那可以很容易地完成。如果需要以其他方式对其进行修改,则可以,但您需要更清楚地指定它。扩大规模和进一步合理化例程也是如此,但在某些时候,您可能会超出 StackOverflow 问题的参数并查看自定义开发工作。
  • (我已经编辑了脚本以包含引号。)
  • 如何删除返回的 URL 中的引号?结果应该是例如https://www.network.com/promotion/click/id=1234-yxz?param0=https%3A%2F%2Fwww.apple.com
  • 哦,我知道问题出在哪里了...等一下 - 现在应该可以了
【解决方案3】:

可能会尝试使用类似the_content 过滤器来执行此操作:

add_filter('the_content', function($content){

  // filter $content and replace urls
  $content = str_replace('http://old-url', 'http://new-url', $content);

  return $content;
});

更多:https://developer.wordpress.org/reference/hooks/the_content/

【讨论】:

  • 感谢您的回答,但我已经找到了这个解决方案。我需要像我的函数 link_change_custom 这样的解决方案,其中来自 apple.com 等域的所有链接都会自动更改,如 apple.com/test-123/、apple.com/test-123/example.html 等。跨度>
  • 这正是它的作用。您需要为您的案例交换旧 url 和新 url,但如果您希望以编程方式交换内容中的这些 url,则此过滤器正是您所需要的。
  • 我不知道如何交换旧网址。您能否编写一个函数或更好地使用我的函数 link_change_custom 并扩展它以更改内容中的 URL 而不仅仅是 $offer_post_url
  • 你有什么想法吗?
  • 我确实有一个想法...给我一些努力。
猜你喜欢
  • 2017-03-30
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多