Php Wordpress add_rewrite_tag()、add_rewrite_rule()和post_link()

Php Wordpress add_rewrite_tag()、add_rewrite_rule()和post_link(),php,wordpress,Php,Wordpress,我正在努力做到以下几点: 重写我的WordPress安装的URL结构,使其中有一个语言字段。例如 然后我想从/lang/获取输入,并使用它来显示适当的内容。例如,如果lang是“en”,我将使用英语自定义字段,并用英语显示主题 以下是我到目前为止的情况: <?php function add_directory_rewrite() { global $wp_rewrite; add_rewrite_tag('%lang%', '(.+)'); add_rewrit

我正在努力做到以下几点:

重写我的WordPress安装的URL结构,使其中有一个语言字段。例如

然后我想从/lang/获取输入,并使用它来显示适当的内容。例如,如果lang是“en”,我将使用英语自定义字段,并用英语显示主题

以下是我到目前为止的情况:

<?php
 function add_directory_rewrite() {
    global $wp_rewrite;
    add_rewrite_tag('%lang%', '(.+)');
    add_rewrite_rule('^/(.+)/', 'index.php?p=$matches[1]&lang=$matches[2]', 'top');
    add_permastruct('lang', '%lang%');

   }
    add_action( 'init', 'add_directory_rewrite' );
?>

这在获取语言方面是有效的,但我现在面临的问题是,_permalink()有“/%lang%/”其中/en/应该是或/fr/或/de/或任何语言。要添加更多细节,我的permalink结构是/%lang%/%category%/%postname%/,假设我有一个名为food的类别和一个标题为chicken的帖子,permalink将生成


知道我做错了什么吗?干杯。

您还需要添加一个函数,该函数将获取包含错误“/%lang%/”段的永久链接,并将其替换为帖子的相应默认语言。通常,您可以通过
'pre\u post\u link'
过滤器或
'post\u link'
过滤器来执行此操作。如果您使用前者,您将从头开始创建永久链接(完全自定义URL,不使用core WP提供的任何内容)。如果使用了后者,那么您可以在WP发挥神奇作用之后,但在网站上使用之前过滤permalink。以下是一个例子:

function lou_rewrite_lang_in_permalink($permalink, $post, $leavename) {
  // find the default post language via a function you have created to 
  // determine the default language url. this could be based on the current
  // language the user has selected on the frontend, or based on the current
  // url, or based on the post itself. it is up to you
  $default_post_language = get_default_post_lang($post);

  // once you have the default language, it is a simple search and replace
  return str_replace('%lang%', $lang, $permalink);
}
add_filter('post_link', 'lou_rewrite_lang_in_permalink', 11, 3);
你别提,我会的。有了你原来的独奏功能,如果它是独立的,你会很难过。原因是,尽管您已经告诉重写器存在一个新的url段,但您没有告诉WordPress将其作为url参数。因此,即使您有一些花哨的代码来重写url并告诉WordPress花哨的lang param,WordPress也不知道应该查找它,因此忽略了它。您需要添加类似的内容来纠正:

function lou_add_lang_query_var($vars) {
  // tell WP to expect the lang query_var, which you can then later use
  $vars[] = 'lang';

  // return the new list of query vars, which includes our lang param
  return array_unique($vars);
}
add_filter('query_vars', 'lou_add_lang_query_var', 10, 1);
这将告诉
WP()
类它需要接受
'lang'
,而不是跳过它。然后,您可以执行类似的操作,以确定当前页面以其语言发送:

function lou_somefunction() {
  // do stuff
  ...

  // access the $wp object
  global $wp;

  // determine the language from the query_vars of the current page
  $lang = $wp->query_var['lang'];

  // do other stuff with $lang
  ...
}
希望这有帮助

编辑

首先我想说,WordPress不支持语言URL,这绝对是一种讽刺。老实说,我从来没有必要这样做,但我的大多数客户都不是国际公司,有国际需求。我将以代码的形式向WordPress提交一些东西,以便在以后的版本中解决这个问题,但现在,您需要一个类似于我在下面创建的插件

所以我做了很多调查来实现这一点。在与提问者进行简短对话后,if发现我的答案不完整。自然地,我开始挖掘。看起来应该是一项平庸的任务,结果却不是一项平庸的任务。简短的版本是,WordPress根本不希望你在URL的中间或开始,在每个URL上插入URL的额外部分。您可以通过上面的代码轻松地使用post URL来实现这一点,但除此之外(页面、附件、作者页面等),您必须做一些特殊的事情。您还可以将部分添加到url的末尾(端点),但即使这样也很复杂

在过去和现在,我与WordPress重写器进行了广泛的合作,我拥有关于这个主题的专家知识。尽管如此,我还是花了4-5个小时编写了一些东西,允许您为所有URL预先添加一个语言指示符,以后可以使用该指示符确定页面应以何种语言显示,而不管页面类型如何。有一个陷阱,我认为是可以接受的。您必须确切地知道并指定要支持的语言前缀。我不认为这对任何使用它的人都是一个问题,但尽管如此,这是一个限制,仅仅是因为重写引擎的工作方式

最后,这里有一个插件,您可以使用它来完成这项工作。我在barebone WP安装上工作,主题是。如果您安装了其他第三方插件,这可能不会适用于它们的所有URL,这取决于它们添加重写规则的方式。在短期内,我可能会将其转换为WP的插件,并将其安装起来,但这至少需要几天的时间。这是一个插件形式的代码原型。在plugins文件夹中创建一个新目录(类似于/wp-content/plugins/lou-lang),然后将此代码粘贴到该文件夹中的php文件中(类似于/wp-content/plugins/lou-lang/lou-lang.php)。然后通过你的管理仪表板激活插件,它将被标记为“Loushou语言URL”

代码:

一旦你安装了插件并定义了你的自定义语言,你就有了最后一步。您必须保存永久链接。要从管理员处执行此操作,请转到:设置->永久链接->保存更改(按钮)。在这一切之后,你应该可以走了


希望这对某人有所帮助,希望我能抽出一些时间在wp.org上发布这篇文章。

我在寻找在url路径前面放置语言标记的解决方案时偶然发现了这篇文章。虽然wp_rewrite-solution非常可靠,但它对我来说并不起作用(例如,默认语言前面没有语言标签等等)

因此,我仔细研究了qTranslate插件,之后我发现它使用了一个非常简单而优雅的解决方案:

基本上它做两件事:

  • (显然)它会更改Wordpress生成的所有链接(例如post_链接、post_类型链接、page_链接等),以便在url中包含正确的语言标记

  • 它没有操纵复杂的重写规则让wordpress接受并正确处理语言标记,而是挂接到“plugins_loaded”(这是正确的)
    <?php (__FILE__ == $_SERVER['SCRIPT_FILENAME']) ? die(header('Location: /')) : null;
    /**
     * Plugin Name: Loushou Language URLs
     * Plugin URI:  http://quadshot.com/
     * Description: Adding the ability to have language support in your frontend urls.
     * Version:     0.1-beta
     * Author:      Loushou
     * Author URI:  http://quadshot.com/
     */
    
    class lou_rewrite_takeover {
      protected static $add_rules = array();
    
      public static function pre_init() {
        // debug
        add_action('admin_footer-options-permalink.php', array(__CLASS__, 'qsart_rewrite_debug'));
    
        // add rw tag
        add_action('init', array(__CLASS__, 'add_directory_rewrite'));
    
        // rw rule adds
        add_filter(is_admin() ? 'setup_theme' : 'do_parse_request', array(__CLASS__, 'do_parse_request'), 0);
        add_filter('post_rewrite_rules', array(__CLASS__, 'post_rewrite_rules'));
        add_filter('date_rewrite_rules', array(__CLASS__, 'date_rewrite_rules'));
        add_filter('root_rewrite_rules', array(__CLASS__, 'root_rewrite_rules'));
        add_filter('comments_rewrite_rules', array(__CLASS__, 'comments_rewrite_rules'));
        add_filter('search_rewrite_rules', array(__CLASS__, 'search_rewrite_rules'));
        add_filter('author_rewrite_rules', array(__CLASS__, 'author_rewrite_rules'));
        add_filter('page_rewrite_rules', array(__CLASS__, 'page_rewrite_rules'));
        add_filter('rewrite_rules_array', array(__CLASS__, 'final_rules_correction'), PHP_INT_MAX, 1);
    
        // query vars
        add_filter('query_vars', array(__CLASS__, 'add_lang_query_var'), 10, 1);
        add_filter('request', array(__CLASS__, 'default_language'), 9);
    
        // fix permalinks
        $link_filters_needing_rewrite = array(
          'post_link',
          'post_type_link',
          'page_link',
          'attachment_link',
          'search_link',
          'post_type_archive_link',
          'year_link',
          'month_link',
          'day_link',
          'feed_link',
          'author_link',
          'term_link',
          'category_feed_link',
          'term_feed_link',
          'taxonomy_feed_link',
          'author_feed_link',
          'search_feed_link',
          'post_type_archive_feed_link',
        );
        add_filter('pre_post_link', array(__CLASS__, 'change_permalink_structure'), 10, 3);
        foreach ($link_filters_needing_rewrite as $link_filter)
          add_filter($link_filter, array(__CLASS__, 'rewrite_lang_in_permalink'), 11, 3);
      }
    
      public static function do_parse_request($cur) {
        self::get_page_permastruct();
        self::get_author_permastruct();
        self::correct_extras();
        return $cur;
      }
    
      public static function get_supported_langs() {
        return apply_filters('lou-get-supported-languages', array(
          'en',
        ));
      }
    
      public static function add_directory_rewrite() {
        global $wp_rewrite;
        $supported_languages = self::get_supported_langs();
        add_rewrite_tag('%lang%', '('.implode('|', $supported_languages).')');
      }
    
      public static function unleadingslashit($str) {
        return ltrim($str, '/');
      }
    
      public static function final_rules_correction($rules) {
        global $wp_rewrite;
    
        $new_rules = array();
        $supported_languages = self::get_supported_langs();
        $find = implode('|', $supported_languages);
        $find_find = '#(?<!\()('.preg_quote($find, '#').')#';
        $preg_node = str_replace('%%%', '(\d+)', preg_quote($wp_rewrite->preg_index('%%%'), '#'));
    
        foreach ($rules as $k => $v) {
          if (preg_match($find_find, $k)) {
            $nk = preg_replace($find_find, '('.$find.')', $k);
            $parts = explode('?', $v);
            $index = array_shift($parts);
            $pv = implode('?', $parts);
            $pv = preg_replace_callback('#'.$preg_node.'#', function ($matches) use ($wp_rewrite) {
              return $wp_rewrite->preg_index($matches[1]+1);
            }, $pv);
            $nv = $index.'?lang='.$wp_rewrite->preg_index(1).(!empty($pv) ? '&'.$pv : '');
            $new_rules[$nk] = $nv;
          } else {
            $new_rules[$k] = $v;
          }
        }
    
        return $new_rules;
      }
    
      public static function change_permalink_structure($struct) {
        $struct = self::unleadingslashit($struct);
        $struct = preg_replace('#^%lang%/?#', '', $struct);
        return '/%lang%/'.$struct;
      }
    
      public static function extras_rewrite_rules($rules, $struct) {
        global $wp_rewrite;
    
        if ( is_array( $struct ) ) {
          if ( count( $struct ) == 2 )
            $new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct[0]), $struct[1] );
          else
            $new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct['struct']), $struct['ep_mask'], $struct['paged'], $struct['feed'], $struct['forcomments'], $struct['walk_dirs'], $struct['endpoints'] );
        } else {
          $new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct) );
        }
    
        return $new_rules + $rules;
      }
    
      public static function post_rewrite_rules($rules) {
        global $wp_rewrite;
    
        // hack to add code for extras type urls (usually created by other plugins)
        $func = array(__CLASS__, 'extras_rewrite_rules');
        foreach ($wp_rewrite->extra_permastructs as $type => $struct) {
          $filter = ($type == 'post_tag' ? 'tag' : $type).'_rewrite_rules';
          add_filter($filter, function ($rules) use ($struct, $func) { return call_user_func_array($func, array($rules, $struct)); });
        }
    
        return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->permalink_structure), EP_PERMALINK ) + $rules;
      }
    
      public static function date_rewrite_rules($rules) {
        global $wp_rewrite;
        return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_date_permastruct()), EP_DATE) + $rules;
      }
    
      public static function root_rewrite_rules($rules) {
        global $wp_rewrite;
        return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_date_permastruct()), EP_DATE) + $rules;
      }
    
      public static function comments_rewrite_rules($rules) {
        global $wp_rewrite;
        return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->root . $wp_rewrite->comments_base), EP_COMMENTS, false, true, true, false) + $rules;
      }
    
      public static function search_rewrite_rules($rules) {
        global $wp_rewrite;
        return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_search_permastruct()), EP_SEARCH) + $rules;
      }
    
      public static function author_rewrite_rules($rules) {
        global $wp_rewrite;
        return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_author_permastruct()), EP_AUTHORS) + $rules;
      }
    
      public static function page_rewrite_rules($rules) {
        global $wp_rewrite;
        $page_structure = self::get_page_permastruct();
        return $wp_rewrite->generate_rewrite_rules( $page_structure, EP_PAGES, true, true, false, false ) + $rules;
      }
    
      protected static function get_page_permastruct() {
        global $wp_rewrite;
    
        if (empty($wp_rewrite->permalink_structure)) {
          $wp_rewrite->page_structure = '';
          return false;
        }
    
        $wp_rewrite->page_structure = self::change_permalink_structure($wp_rewrite->root . '%pagename%');
    
        return $wp_rewrite->page_structure;
      }
    
      protected static function get_author_permastruct() {
        global $wp_rewrite;
    
        if ( empty($wp_rewrite->permalink_structure) ) {
          $wp_rewrite->author_structure = '';
          return false;
        }
    
        $wp_rewrite->author_structure = self::change_permalink_structure($wp_rewrite->front . $wp_rewrite->author_base . '/%author%');
    
        return $wp_rewrite->author_structure;
      }
    
      protected static function correct_extras() {
        global $wp_rewrite;
    
        foreach ($wp_rewrite->extra_permastructs as $k => $v)
          $wp_rewrite->extra_permastructs[$k]['struct'] = self::change_permalink_structure($v['struct']);
      }
    
      public static function get_default_post_lang($post) {
        return ( $lang = get_query_var('lang') ) ? $lang : 'en';
      }
    
      public static function rewrite_lang_in_permalink($permalink, $post=0, $leavename=false) {
        // find the default post language via a function you have created to 
        // determine the default language url. this could be based on the current
        // language the user has selected on the frontend, or based on the current
        // url, or based on the post itself. it is up to you
        $lang = self::get_default_post_lang($post);
    
        // once you have the default language, it is a simple search and replace
        return str_replace('%lang%', $lang, $permalink);
      }
    
      public static function add_lang_query_var($vars) {
        // tell WP to expect the lang query_var, which you can then later use
        $vars[] = 'lang';
    
        // return the new list of query vars, which includes our lang param
        return array_unique($vars);
      }
    
      public static function default_language($vars) {
        if (array_diff( array_keys($vars), array('preview', 'page', 'paged', 'cpage') ))
          $vars['lang'] = !empty($vars['lang']) ? $vars['lang'] : 'en';
        return $vars;
      }
    
      public static function qsart_rewrite_debug() {
        if (isset($_COOKIE['rwdebug']) && $_COOKIE['rwdebug'] == 1) {
          global $wp_rewrite;
          echo '<pre style="background-color:#ffffff; font-size:10px;">';
          print_r($wp_rewrite->rules);
          echo '</pre>';
        }
      }
    }
    
    if (defined('ABSPATH') && function_exists('add_action')) {
      lou_rewrite_takeover::pre_init();
    }
    
    function more_languages($list) {
      $my_languages = array(
        'de', 'zh', 'bg', 'fr'
      );
      return array_unique($list + $my_languages);
    }
    add_filter('lou-get-supported-languages', 'more_languages', 10, 1);
    
    function localization_uri_process() {
    
      global $lang; // then you can access $lang value in your theme's files
    
      if( preg_match("%\A/([a-z]{2})/%", $_SERVER['REQUEST_URI'], $matches) ){
        $lang = $matches[1];
        $_SERVER['REQUEST_URI'] = preg_replace("%\A/[a-z]{2}/%", '/', $_SERVER['REQUEST_URI'] );
      }
      else
        $lang = 'en'; // your default language
    }
    add_action( 'plugins_loaded', 'localization_uri_process' );