사용자 지정 계층 분류 체계에서 분류 체계 슬러그 제거


21

다음 규칙을 사용하여 '포럼'분류법을 작성했습니다.

register_taxonomy(
  'forum',
  array('topic'),
  array(
    'public' => true,
    'name' => _a('Forums'),
    'singular_name' => _a('Forum'),
    'show_ui' => true,
    'show_in_nav_menus' => true,
    'hierarchical' => true,

    'labels' => array(
      'name' => _a('Forums'),
      'singular_name' => _a('Forum'),
      'search_items' => _a('Search Forums'),
      'popular_items' => _a('Popular Forums'),
      'all_items' => _a('All Forums'),
      'parent_item' => _a('Parent Forum'),
      'parent_item_colon' => _a('Parent Forum:'),
      'edit_item' => _a('Edit Forum'),
      'update_item' => _a('Update Forum'),
      'add_new_item' => _a('Add New Forum'),
      'new_item_name' => _a('New Forum Name'),
    ),
    'query_var' => true,
    'rewrite' => array('slug' => 'forums', 'with_front' => false, 'hierarchical' => true),  
  )
);

프론트 엔드에서 URL은 다음과 같습니다.

forums/general-discussion/sub-forum

프론트 슬러그 ( "포럼")를 어떻게 제거합니까? 즉, URL을 다음과 같이 변경하십시오.

general-discussion/sub-forum

빈 슬러그 인수를 register_taxonomy ()에 전달하면 작동하지만이 분류와 관련된 게시물 유형의 영구 링크에 문제가 발생합니다


@One Trick Pony- 'slug' => 'forums'공란 으로 남겨 두는 대신 완전히 제거하고 그냥 사용해 보셨습니까 'rewrite' => array('with_front' => false, 'hierarchical' => true)? 나는 그것이 과거에 나를 위해 일했다고 생각합니다. 또한 영구 링크를 플러시해야합니다.
eileencodes

그것을 시도하고, permalinks는 동일하게 보입니다. 추가 'slug' => ''이 분류를 사용하여 포스트 404은 생성 작동 차종을하지만
onetrickpony

@One Trick Pony- '일반 토론'외에도 다른 최상위 경로 세그먼트가 필요하십니까?
MikeSchinkel 5

모두 %forum%최상위 세그먼트 여야합니다
onetrickpony

@One Trick Pony-방금 컨텍스트에 대한 다른 최상위 경로 세그먼트를 제공하기를 바랐습니다.
MikeSchinkel

답변:


11

최신 정보

이 WordPress 코어를 작성했기 때문에 클래스 'do_parse_request'를 확장하지 않고도 URL 라우팅을 우아하게 처리 할 수 있는 후크를 추가했습니다 WP. 나는 2014 년 애틀랜타 워드 캠프 강연에서 " 하드 코어 URL 라우팅 " 이라는 제목의 주제를 자세히 다루었 다 . 슬라이드는 링크에서 사용할 수 있습니다.

원래 답변

URL 디자인 은 10 년이 넘도록 중요했습니다. 나는 몇 년 전에 블로그를 썼습니다 . 그리고 워드 프레스는 총체적으로 유감스럽게도 소프트웨어의 화려한 비트 이지만 URL 재 작성 시스템은 두뇌가 부족합니다 (물론 IMHO) .

내가 제공 할 대답은 내가 호출하는 플러그인 입니다. Trac에WP_Extended 대한 이 제안에 대한 개념 증명입니다 (제안은 한 가지로 시작하여 다른 것으로 진화 했으므로 전체 내용을 읽어야합니다. 향했다.)

기본적으로 아이디어는 클래스를 서브 WP클래스 화하고 parse_request()메소드를 대체 한 다음 $wp서브 클래스의 인스턴스에 글로벌 변수 를 지정하는 것 입니다. 그런 다음 parse_request()실제로 URL 전체와 일치 해야하는 정규식 목록을 사용하는 대신 경로 세그먼트별로 경로를 검사하십시오 .

그래서 앞에 명시 적으로이 기술을 삽입 논리를 상태로 parse_request()URL - 투 - 정규식 일치 및 분류 기간 경기에 대한 대신 첫 외모에 대한 어떤 검사하지만 ONLY 을 대체 parse_request()하고 잎 워드 프레스 URL 라우팅 시스템의 전체 나머지를 그대로 포함하고 특히 $query_vars변수 사용.

사용 사례의 경우이 구현 단지 그것이 당신이 필요로하는 모든이기 때문에 분류 조항을 URL 경로 세그먼트를 비교합니다. 이 구현은 부모 - 자식 용어 관계를 존중 분류 조건을 검사하고 일치하는 항목을 발견하면 그것은 URL 경로를 지정합니다 (앞과 끝에 슬래시 마이너스)$wp->query_vars['category_name'],$wp->query_vars['tag']또는$wp->query_vars['taxonomy']&$wp->query_vars['term']와는 우회parse_request()의 방법WP클래스를.

반면에 URL 경로 분류 체계의 용어 와 일치하지 않으면 URL 경로 지정 논리를 클래스 의 parse_request()메소드를 호출하여 WordPress 재 작성 시스템에 위임 합니다 WP.

유스 WP_Extended케이스에 사용 하려면 register_url_route()테마 functions.php파일 내에서 다음 과 같이 함수 를 호출해야합니다 .

add_action('init','init_forum_url_route');
function init_forum_url_route() {
  register_url_route(array('taxonomy'=>'forum'));
}

플러그인의 소스 코드는 다음과 같습니다.

<?php
/*
Filename: wp-extended.php
Plugin Name: WP Extended for Taxonomy URL Routes
Author: Mike Schinkel
*/
function register_url_route($args=array()) {
  if (isset($args['taxonomy']))
    WP_Extended::register_taxonomy_url($args['taxonomy']);
}
class WP_Extended extends WP {
  static $taxonomies = array();
  static function on_load() {
    add_action('setup_theme',array(__CLASS__,'setup_theme'));
  }
  static function register_taxonomy_url($taxonomy) {
    self::$taxonomies[$taxonomy] = get_taxonomy($taxonomy);
  }
  static function setup_theme() { // Setup theme is 1st code run after WP is created.
    global $wp;
    $wp = new WP_Extended();  // Replace the global $wp
  }
  function parse_request($extra_query_vars = '') {
    $path = $_SERVER['REQUEST_URI'];
    $domain = str_replace('.','\.',$_SERVER['SERVER_NAME']);
    //$root_path = preg_replace("#^https?://{$domain}(/.*)$#",'$1',WP_SITEURL);
$root_path = $_SERVER['HTTP_HOST'];

    if (substr($path,0,strlen($root_path))==$root_path)
      $path = substr($path,strlen($root_path));
    list($path) = explode('?',$path);
    $path_segments = explode('/',trim($path,'/'));
    $taxonomy_term = array();
    $parent_id = 0;
    foreach(self::$taxonomies as $taxonomy_slug => $taxonomy) {
      $terms = get_terms($taxonomy_slug);
      foreach($path_segments as $segment_index => $path_segment) {
        foreach($terms as $term_index => $term) {
          if ($term->slug==$path_segments[$segment_index]) {
            if ($term->parent!=$parent_id) { // Make sure we test parents
              $taxonomy_term = array();
            } else {
              $parent_id = $term->term_id; // Capture parent ID for verification
              $taxonomy_term[] = $term->slug; // Collect slug as path segment
              unset($terms[$term_index]); // No need to scan it again
            }
            break;
          }
        }
      }
      if (count($taxonomy_term))
        break;
    }
    if (count($taxonomy_term)) {
      $path = implode('/',$taxonomy_term);
      switch ($taxonomy_slug) {
        case 'category':
          $this->query_vars['category_name'] = $path;
          break;
        case 'post_tag':
          $this->query_vars['tag'] = $path;
          break;
        default:
          $this->query_vars['taxonomy'] = $taxonomy_slug;
          $this->query_vars['term'] = $path;
          break;
      }
    } else {
      parent::parse_request($extra_query_vars); // Delegate to WP class
    }
  }
}
WP_Extended::on_load();

PS주의 사항 # 1

특정 사이트에서이 기술은 훌륭하게 작동한다고 생각하지만 이 기술을 다른 사람들이 사용할 수 있도록 WordPress.org에 플러그인을 배포하는 데 사용해서는 안됩니다 . WordPress 기반의 소프트웨어 패키지의 핵심이라면 괜찮을 것입니다. 그렇지 않으면이 기술은 특정 사이트에 대한 URL 라우팅을 향상시키는 것으로 제한되어야합니다 .

왜? 하나의 플러그인 만이 기술을 사용할 수 있기 때문 입니다. 두 개의 플러그인이 사용하려고하면 서로 충돌합니다.

이 전략을 제쳐두고 필요할 수있는 거의 모든 사용 사례 패턴을 일반적으로 처리하도록 확장 할 수 있으며, 여가 시간을 찾거나 고객이 원하는 시간을 후원 할 수있는 고객을 찾 자마자 구현하려고합니다 완전히 일반적인 구현을 빌드하십시오.

경고 # 2

나는 이것을 parse_request()매우 큰 함수 인 재정의하기 위해 썼고 , 전 세계의 속성이나 두 가지를 놓쳤을 가능성이 있습니다.$wp 내가 설정해야 객체 . 그래서 뭔가 이상한 행동이 있으면 알려 드리겠습니다. 그것을 조사하고 필요하다면 답을 수정하십시오.

어쨌든...


이 글을 쓰고 난 후에 나는 일반적으로 분류학 용어 대신 카테고리를 테스트 했으므로 위의 'forum'분류법에서는 작동하지 않지만 나중에 나중에 작동하도록 수정하겠습니다 ...
MikeSchinkel

그래서 이전 의견에서 언급 한 문제를 해결하기 위해 코드를 업데이트했습니다.
MikeSchinkel

이 작업을 수행 할 수 없습니다 ... 다시 쓰기 규칙을 변경해야합니까?
onetrickpony

@One Trick Pony-좀 더 진단 정보가 도움이 될 것입니다. :) 무엇을 시도 했습니까? 브라우저에 URL을 입력하면 어떻게됩니까? 분류 체계 전화 당신이 기회를 당 했는가 'forums'보다는 'forum'? 이 페이지들에 링크 된 URL들이 변경 될 것으로 기대하고 있습니까? (그렇다면 내 코드가 URL 인쇄를 다루지 않고 URL 만 라우팅합니다.)
MikeSchinkel

아니요, URL을 변경할 수 있습니다 (연결 해야하는 term_link 함수라고 생각합니다). site/rootforum/작동하지만 작동 site/rootforum/subforum/하지 않습니다 (404 오류) ...
onetrickpony

7

정말 간단합니다.

1 단계 : 다시 쓰기 매개 변수 사용을 중지하십시오. 우리는 당신의 자신의 재 작성을 굴릴 것입니다.

'rewrite'=>false;

2 단계 : 자세한 페이지 규칙을 설정합니다. 이렇게하면 일반 페이지가 페이지 하단에 포괄적이지 않고 자체 규칙을 갖습니다.

3 단계 : 사용 사례를 처리하기 위해 다시 쓰기 규칙을 만듭니다.

4 단계 : 수동으로 플러시 규칙이 발생하도록합니다. 가장 쉬운 방법 : 설정-> 영구 링크로 이동하여 저장 버튼을 클릭하십시오. 나는 주변 환경을 바꿀 때마다 규칙을 강제로 플러시 할 수 있기 때문에 플러그인 사용 방법을 선호합니다.

따라서 코드 시간 :

function test_init() {
    // create a new taxonomy
    register_taxonomy(
        'forum',
        'post',
        array(
            'query_var' => true,
            'public'=>true,
            'label'=>'Forum',
            'rewrite' => false,
        )
    );

    // force verbose rules.. this makes every Page have its own rule instead of being a 
    // catch-all, which we're going to use for the forum taxo instead
    global $wp_rewrite;
    $wp_rewrite->use_verbose_page_rules = true;

    // two rules to handle feeds
    add_rewrite_rule('(.+)/feed/(feed|rdf|rss|rss2|atom)/?$','index.php?forum=$matches[1]&feed=$matches[2]');
    add_rewrite_rule('(.+)/(feed|rdf|rss|rss2|atom)/?$','index.php?forum=$matches[1]&feed=$matches[2]');

    // one rule to handle paging of posts in the taxo
    add_rewrite_rule('(.+)/page/?([0-9]{1,})/?$','index.php?forum=$matches[1]&paged=$matches[2]');

    // one rule to show the forum taxo normally
    add_rewrite_rule('(.+)/?$', 'index.php?forum=$matches[1]');
}

add_action( 'init', 'test_init' );

이 코드를 추가 한 후에는 설정-> 퍼머 링크에 페이지를 저장하여 퍼머 링크 규칙을 플러시 할 때 활성화해야합니다!

규칙을 플러시하고 데이터베이스에 저장 한 후 / whatever는 forum = whatever 분류 페이지로 이동해야합니다.

정규식을 이해하면 다시 쓰기 규칙은 그리 어렵지 않습니다. 디버깅 할 때이 코드를 사용하여 나를 도울 수 있습니다.

function test_foot() {
    global $wp_rewrite;
    echo '<pre>';
    var_dump($wp_rewrite->rules);
    echo '</pre>';
}
add_action('wp_footer','test_foot');

이렇게하면 내 페이지에서 현재 규칙을 한눈에 볼 수 있습니다. URL이 주어지면 시스템은 규칙의 맨 위에서 시작하여 일치하는 URL을 찾을 때까지 내려갑니다. 그런 다음 일치 항목을 사용하여 쿼리를보다 일반적인 모양의? key = value 세트로 다시 작성합니다. 이 키들은 WP_Query 객체로 들어가는 것에 파싱됩니다. 단순한.

편집 : 참고로,이 방법은 일반적인 사용자 정의 게시물 구조가 % category %와 같은 포괄적이지 않은 것으로 시작하거나 그와 같은 것으로 시작하는 경우에만 작동합니다. 정적 문자열이나 % year %와 같은 숫자로 시작해야합니다. 이는 규칙에 도달하기 전에 URL이 걸리지 않도록하기위한 것입니다.


다시 쓰기 규칙을 더 쉽게 디버깅하려면 다시 쓰기 분석기 플러그인을 권장합니다.이 플러그인 을 사용하면 규칙을 시험해보고 쿼리 변수를 즉시 확인할 수 있습니다.
Jan Fabry

불행히도 현재 URL 재 작성 시스템은 URL 경로의 고유 트리 구조를 따르는 것과 비교하여 모든 잠재적 URL 패턴을 큰 목록으로 병합합니다. 현재 설정은 범주 또는 포럼 이름과 같은 리터럴 배열과 편리하게 일치 할 수 없습니다 . 아시다시피 모든 "페이지" URL을 먼저 평가해야합니다. 경로 세그먼트를 기준으로 일치시키고 여러 가지 방법 (리터럴, 범주, 태그, 세금 용어, 사용자 이름, 게시물 유형, 게시물 이름, 콜백, 필터 후크 및 마지막으로 RegEx 배열)로 확장하면 복잡성이 향상되고 더 쉬워집니다. 이해하다.
MikeSchinkel

Mike : 사실, 당신이 이야기하고있는 첫 번째 단서가 없기 때문에 이해하기 쉽지 않습니다. URL 라우팅에 대한 귀하의 아이디어는 혼란스럽고 어렵습니다. 아시다시피 동의하지 않습니다. 플랫 검색은 크레딧을 제공하는 경향이있는 것보다 더 의미가 있고 더 유연합니다. 대부분의 사람들은 URL에 불필요하게 복잡한 것을 원치 않으며 거의 ​​아무도 그것을 필요로하지 않습니다.
Otto

감사합니다,하지만 난 이미 (전에이 시도 생각 wordpress.stackexchange.com/questions/9455/... )
onetrickpony

다행히 워드 프레스는 지금 답변 할 수 있습니다 사람들이 어떻게 자신의 URL을 찾는 제어 에 마침내 목소리를 가지고, 그들은 많은 수 (100 개)을 보인다. 그러나 완전한 구현 전에는 내 예를 따르지 못할 수도 있습니다. 나는 내가 주장하는 접근 방식이 플러그인으로 완전히 구현되고 약 6-12 개월 후에 WordPress 기반 CMS 사이트가 URL을 라우팅하는 선호되는 방법이 될 것으로 예상합니다. 약 9 개월 후에이 토론을 재개하겠습니다.
MikeSchinkel

4

용어 슬러그와 포스트 슬러그를 구분할 수 없으므로 WP_Rewrite 만 사용하여이 작업을 수행 할 수 없습니다.

또한 분류 체계 대신 사후 쿼리 var를 설정하여 '요청'에 연결하고 404를 방지해야합니다.

이 같은:

function fix_post_request( $request ) {
    $tax_qv = 'forum';
    $cpt_name = 'post';

    if ( !empty( $request[ $tax_qv ] ) ) {
        $slug = basename( $request[ $tax_qv ] );

        // if this would generate a 404
        if ( !get_term_by( 'slug', $slug, $tax_qv ) ) {
            // set the correct query vars
            $request[ 'name' ] = $slug;
            $request[ 'post_type' ] = $cpt_name;
            unset( $request[$tax_qv] );
        }
    }

    return $request;
}
add_filter( 'request', 'fix_post_request' );

분류 체계는 게시물 유형 보다 먼저 정의 되어야 합니다.

이것은 분류법과 동일한 쿼리 var를 가진 게시물 유형을 갖는 것이 나쁜 생각임을 지적하기에 좋은시기입니다.

또한 용어 중 하나와 동일한 슬러그가있는 게시물에는 도달 할 수 없습니다.


분류 체계와 같은 쿼리 VAR과 게시물 유형을 가진 것은 나쁜 생각이지만, 그 것을 합의 할 수 경우가 아니라 나쁜 생각은, 분류 체계와 같은 이름을 가진 후 유형을 가진 사람들에게 의미입니다. 동일한 이름을 사용하는 경우 둘 중 하나에 만 쿼리 var가 있어야합니다.
MikeSchinkel

2

최상위 고양이 플러그인의 코드를 살펴 보겠습니다.

http://fortes.com/projects/wordpress/top-level-cats/

당신은 쉽게 그것을 조정할 수 있도록 변경하여 사용자 정의 분류 슬러그를 찾고 있습니다.

$category_base = get_option('category_base');

74 번째 줄에 다음과 같은 내용이 있습니다.

$category_base = 'forums';

카테고리에 대해서는 효과가 있지만 사용자 정의 분류법에는 적합하지 않습니다 (적어도 wp 3.1에서는). URL을 변경할 수는 있지만 404 오류가 발생합니다
onetrickpony

2

Custom Post Permalinks 플러그인을 살펴 보는 것이 좋습니다 . 지금 테스트 할 시간이 없지만 상황에 도움이 될 수 있습니다.


그것은, 그것은 단지 글이 아니라 분류 체계, 심지어는 것인지, 내가 전에 접두사의 어떤 종류를 추가해야 할 것 처리하지 않습니다 %forum%내가 ... 피하기 위해 노력하고있어 정확히 무엇 인
onetrickpony

2

나는 당신의 다른 질문에 익숙하기 때문에 염두에두고 대답 할 것입니다.

나는 이것을 전혀 테스트하지는 않았지만 원하는 모든 permastruct를 등록한 직후에 이것을 한 번 실행하면 작동 할 수 있습니다.

class RRSwitcher {
  var $rules;
  function RRSwitcher(){
    add_filter( 'topic_rewrite_rules', array( $this, 'topics' ) );
    add_filter( 'rewrite_rules_array', array( $this, 'rules' ) );
  }
  function topics( $array ){
    $this->rules = $array;
    return array();
  }
  function rules( $array ){
    return array_merge( (array)$array, (array)$this->rules );
  }
}
$RRSwitcher = new RRSwitcher();
global $wp_rewrite;
$wp_rewrite->use_verbose_rules = true;
$wp_rewrite->flush_rules();

이것이하는 일 : 규칙 배열의 정상적인 흐름에서 주제 퍼머 링크에서 생성 된 다시 쓰기 규칙을 제거하고 배열 끝에 다시 병합합니다. 이렇게하면 해당 규칙이 다른 다시 쓰기 규칙을 방해하지 않습니다. 다음으로, 자세한 재 작성 규칙을 강제 실행합니다 (각 페이지는 특정 정규식을 갖는 개별 규칙을 가져옵니다). 이렇게하면 페이지가 주제 규칙을 방해하지 않습니다. 마지막으로 하드 플러시를 실행하고 (.htaccess 파일을 쓸 수 있는지 확인하십시오. 그렇지 않으면 작동하지 않습니다) 매우 복잡한 매우 큰 다시 쓰기 규칙을 저장합니다.


시도해
보아도


2

이것이 분류법에서 작동하는지 확실하지 않지만 사용자 정의 게시물 유형에서는 효과가 있습니다.

2 년 동안 업데이트되지 않았지만 아래 플러그인이 저에게 효과적이었습니다. http://wordpress.org/plugins/remove-slug-from-custom-post-type/

참고 3.9.1로 WP 유형으로 WP를 실행 하고 있습니다.1.5.7


2

슬러그의 값 으로 슬래시 사용 ... 100 % 작동

'rewrite' => array(
    'slug'       => '/', 
    'with_front' => FALSE
 ),

2
확실히, 이것은 모든 page 게시물 유형을 404로
Milo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.