programing

워드프레스 add_rewrite_tag(), add_rewrite_rule() 및 post_link()

mbctv 2023. 3. 22. 22:00
반응형

워드프레스 add_rewrite_tag(), add_rewrite_rule() 및 post_link()

다음을 수행하려고 합니다.

언어 필드가 들어가도록 WordPress 설치 URL 구조를 다시 작성합니다.예: http://www.mydomain.com/lang/

그런 다음 /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()에 /en/ 또는 /fr/ 또는 /de/ 또는 그 어느 언어에 대해서도 "/%lang%/"가 있다는 것입니다.자세한 내용을 추가하기 위해 나의 permalink structure는 /%pargate%/%category%/%postname%/ 입니다.예를 들어 food라는 카테고리와 ticken이라는 타이틀의 post가 있다고 가정하면 _permalink는 http://www.mydomain.com/%lang%/food/chicken/를 생성합니다.

내가 뭘 잘못하고 있는지 알기나 해?건배.

또한 잘못된 '/%lang%/' 세그먼트를 포함하는 permalink를 가져오는 함수를 추가하여 게시물에 적합한 기본 언어로 대체해야 합니다. 할 수.'pre_post_link' 「」의'post_link'필터링을 실시합니다.전자를 사용하는 경우 permalink는 처음부터 작성됩니다(코어 WP가 제공할 필요가 없는 완전 커스텀 URL).후자를 사용하는 경우 WP가 실행한 후 사이트에서 사용하기 전에 퍼멀링크를 필터링할 수 있습니다.다음은 예를 제시하겠습니다.

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 세그먼트가 존재한다고 rewriter에게 말했지만 WordPress에게 그것을 URL 파라미터로 기대하라고 말하지 않았기 때문입니다.따라서 url을 다시 쓰고 WordPress에게 fancy 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
  ...
}

이게 도움이 됐으면 좋겠다.

편집

먼저, 언어 URL이 WordPress에서 기본적으로 지원되지 않는다는 것은 완전히 잘못된 표현입니다.는 솔직히 이런 일을 할 필요가 없었습니다만, 제 고객 대부분은 국제적인 요구를 가진 국제적인 회사가 아닙니다.나중에 WordPress에 코드 형태로 제출하여 해결할 예정입니다만, 지금으로서는 아래와 같은 플러그인이 필요합니다.

그래서 나는 이것을 실현하기 위해 많은 조사를 했다.질문자와 짧은 대화를 나눈 후, 내 솔루션이 불완전하다는 것을 알게 되었다.자연스럽게 땅을 파기 시작했어요.그렇지 않으면 평범한 일이어야 할 것처럼 보였던 것이 아주 평범한 일이었음이 드러났다.간단히 말하면, WordPress는 URL의 중간이나 시작 부분에 URL의 추가 부분을 모든 URL에 삽입하는 것을 원하지 않습니다.이 작업은 위의 코드를 가진 게시 URL에서만 쉽게 수행할 수 있지만, 그 이상의 것(페이지, 첨부 파일, 작성자 페이지 등)은 특별한 작업을 수행해야 합니다.URL 끝(엔드포인트)에 부품을 추가할 수도 있지만 그마저도 복잡합니다.

저는 과거와 현재 WordPress rewriter와 폭넓게 일해 왔으며, 이 주제에 대한 Expert 지식을 가지고 있습니다.그럼에도 불구하고, 모든 URL에 언어 표시기를 추가할 수 있는 것을 쓰는데 4-5시간이 걸렸습니다.이것들은 나중에 페이지 유형에 관계없이 어떤 언어로 표시되어야 하는지 결정하는 데 사용될 수 있습니다.내가 받아들일 수 있는 단점이 하나 있다.지원하는 언어 프레픽스를 정확하게 파악하고 지정해야 합니다.이것을 이용하는 사람의 문제라고는 생각하지 않지만, 역시 리라이트 엔진의 동작에 의한 한계입니다.

마지막으로 이 작업을 수행하기 위해 사용할 수 있는 플러그인이 있습니다.저는 WooTheme를 테마로 베어본 WP 설치 작업을 하고 있습니다.다른 서드파티제의 플러그인이 인스톨 되어 있는 경우는, 개서 룰의 추가 방법에 따라서는, 일부의 URL 에 대해서 동작하지 않을 가능성이 있습니다.단기적으로는 WP용 플러그인으로 변환하여 Wordpress.org에 올릴 예정입니다만, 적어도 며칠은 걸립니다.다음은 플러그인 형식의 코드 작업 프로토타입입니다.플러그인 폴더에 새 디렉토리(/wp-content/plugins/lou-lang 등)를 만들고 이 코드를 해당 폴더 내의 php 파일(/wp-content/plugins/lou-lang/lou-lang.php 등)에 붙여넣습니다.그런 다음 관리 대시보드를 통해 플러그인을 활성화하십시오. 이 대시보드는 'Loushou Language URLs'로 라벨이 지정됩니다.

코드:

<?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();
}

기본적으로 이 플러그인이 지원하는 유일한 언어 코드는 다음과 같습니다.'en'그 이상의 것이 필요한 게 분명합니다.따라서 플러그인이 설치되면 코드를 추가할 수 있습니다.<theme>/functions.php이렇게 생긴 줄에 남은 것을 더하는 거죠.

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);

플러그인을 설치하고 사용자 지정 언어를 정의하면 마지막 단계가 하나 있습니다.당신은 당신의 과민반응을 아껴야 합니다.관리자에게 문의하려면 [설정(Settings)]-> [퍼멀링크(Permalinks)]-> [변경사항 저장(Save Changes)]버튼으로 이동합니다.이 모든 것이 끝나면, 당신은 갈 준비가 되어 있을 거야!

이것이 누군가에게 도움이 되기를 바라며, wp.org에 게시할 시간을 차단할 수 있기를 바랍니다.

오래된 질문이지만..다국어 사이트용 경량 솔루션을 개발하던 중 같은 문제가 발생했습니다.내장 WordPress 기능으로는 쉽게 할 수 있는 방법이 없습니다.그러나 (사용자1254824에서 언급한 것처럼) 이를 실현하기 위한 정말 쉬운 방법이 있습니다.

인터셉트 할 수 있습니다.$_SERVER['REQUEST_URI']global var, WordPress 구문 분석 전에 /lang/ 부분을 추출하여 제거합니다.WordPress는 일반 페이지를 제공하지만 lang 파라미터가 var에 포함되어 있습니다.

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' );

그런 다음 필터를 사용하여 모든 링크를 자동으로 다시 작성할 수도 있습니다.

PS : 코드는 플러그인에 있어야 합니다.템플릿 php 파일에서는 동작하지 않습니다.

URL 경로 앞에 언어 태그를 붙이는 솔루션을 찾다가 우연히 이 게시물을 발견했습니다.wp_rewrite-solution은 거의 견고하지만, 제 목적에 맞지 않는 것 같습니다(예를 들어 디폴트 언어에는 언어 태그가 붙어 있지 않은 것 등).

그래서 qTranslate 플러그인에 대해 자세히 살펴본 결과 매우 심플하고 우아한 솔루션을 사용하고 있다는 것을 알게 되었습니다.

기본적으로 다음 두 가지 작업을 수행합니다.

  1. (분명히)Wordpress에서 생성된 모든 링크(예: post_link, post_type_link, page_link 등)를 변경하여 URL에 올바른 언어 태그를 포함합니다.

  2. 복잡한 개서 규칙을 조작하여 워드프레스가 언어태그를 받아들이고 올바르게 처리하도록 하는 대신, "plugins_loaded"(워드프레스가 요청을 해석하기 직전)에 접속하여 조작합니다.$_SERVER['REQUEST_URI']언어 태그를 지웁니다.예를 들어 www.example.com/en/myurlpath Wordpress only www.example.com/myurlpath으로 전화하는 경우. $_SERVER['REQUEST_URI'] = "/en/myurlpath"조작하기 전에 말이야 $_SERVER['REQUEST_URI'] = "/myurlpath"조작이 끝난 후에요

이렇게 하면 Wordpress가 URL을 구문 분석하기 전에 URL을 정리하는 것이 유일한 "작업"입니다.

언급URL : https://stackoverflow.com/questions/20754505/wordpress-add-rewrite-tag-add-rewrite-rule-and-post-link

반응형