WordPress 분류 내에서 게시물을 정렬하는 방법

게시 됨: 2020-12-18

지금까지 Nelio는 WordPress.org 저장소에 여러 플러그인을 게시했습니다. 그 중 일부는 완전 무료이며 예를 들어 Gutenberg로 만든 페이지나 게시물에 Google 지도를 삽입할 수 있는 Nelio Maps와 같은 일반적인 문제에 대한 우아한 솔루션을 제공합니다. 블록은 이름에서 알 수 있듯이 두 이미지를 나란히 비교합니다. 청구서 지불에 도움이 되는 몇 가지 프리미엄 플러그인인 Nelio Content 및 Nelio A/B Testing도 게시했습니다.

당사 웹 사이트를 살펴보면 두 가지 프리미엄 플러그인이 모두 몇 개의 랜딩 및 가격 페이지가 있고 사용자가 질문에 대한 답변을 찾을 수 있는 관련 지식 기반이 있기 때문에 두 가지 프리미엄 플러그인이 눈에 띄는 위치를 차지하고 있음을 알 수 있습니다. 오늘 우리는 Nelio A/B Testing과 Nelio Content에 대한 문서 페이지를 만든 방법과 우리가 원하는 대로 질문을 정렬하기 위해 무엇을 해야 했는지에 대해 이야기할 것입니다.

WordPress에서 사용자 정의 게시물 유형을 만드는 방법

먼저 지식 기반에 포함될 모든 질문을 추적하기 위해 사용자 정의 게시물 유형을 생성해 보겠습니다. Nelio A/B Testing의 지식 기반에 대한 이 새로운 게시물 유형의 인스턴스가 있는 다음 스크린샷에서 결과를 볼 수 있습니다.

Nelio A/B Testing의 지식 기반
Nelio A/B Testing의 기술 자료에 있는 질문의 예.

사용자 정의 게시물 유형을 만들려면 다음과 같이 WordPress register_post_type 함수를 사용하기만 하면 됩니다.

 function nelio_add_help_type() { $labels = array( 'name' => __( 'Questions', 'nelio-help' ), 'singular_name' => __( 'Question', 'nelio-help' ), 'menu_name' => __( 'Testing's Help', 'nelio-help' ), 'all_items' => __( 'All Questions', 'nelio_help' ), 'add_new_item' => __( 'Add New Question', 'nelio_help' ), 'edit_item' => __( 'Edit Question', 'nelio_help' ), 'view_item' => __( 'View Question', 'nelio_help' ), ); register_post_type( 'nab_help', array( 'capability_type' => 'post', 'labels' => $labels, 'map_meta_cap' => true, 'menu_icon' => 'dashicons-welcome-learn-more', 'public' => true, 'show_in_rest' => true, 'supports' => [ 'title', 'editor', 'author' ], ) ); } add_action( 'init', 'nelio_add_help_type' );

그리고 짜잔! 사용자 지정 게시물 유형의 인터페이스를 만들고 사용자 지정하는 데 도움이 되는 고급 사용자 지정 필드와 같은 플러그인이 있다는 것을 이미 알고 있을 수 있지만, 그렇게 간단한 예제를 구현하기 위해 반드시 권장하지는 않습니다.

그건 그렇고, 이 스니펫을 어디에 배치해야 하는지 궁금하다면 사용자 정의 플러그인으로 WordPress를 사용자 정의하는 방법에 대한 튜토리얼을 놓치지 마세요.

콘텐츠를 구성하기 위해 새 분류를 만드는 방법

우리의 지식 기반은 다음 스크린샷에서 볼 수 있듯이 "주제" 및 "키워드"로 구성되어 있습니다.

주제와 키워드라는 두 가지 분류와 함께 새로운 게시물 유형을 보여주는 WordPress 대시보드의 스크린샷.
두 가지 분류인 주제키워드 와 함께 새로운 게시물 유형 Testing의 도움말 을 보여주는 WordPress 대시보드의 스크린샷.

주제 및 키워드는 기본적으로 WordPress 게시물에 있는 카테고리 및 태그와 동일합니다. 후자는 정확히 같기 때문에 전자에 집중합시다.

이미 상상할 수 있듯이 주제는 사용자 지정 콘텐츠 유형에 대해 만든 사용자 지정 분류법입니다. WordPress 게시물 유형에 새 분류를 추가하려면 다음과 같이 register_taxonomy 함수를 사용하기만 하면 됩니다.

 function nelio_add_help_taxonomy() { $labels = array( 'name' => __( 'Topics', 'nelio-help' ), 'singular_name' => __( 'Topic', 'nelio-help' ), 'menu_name' => __( 'Topics', 'nelio-help' ), 'all_items' => __( 'All Topics', 'nelio_help' ), /* ... */ ); register_taxonomy( 'nab_topic', [ 'nab_help' ], array( 'hierarchical' => true, 'label' => __( 'Topic', 'nelio-help' ), 'query_var' => true, 'show_admin_column' => false, 'show_ui' => true, 'show_in_rest' => true, ) ); } add_action( 'init', 'nelio_add_help_taxonomy' );

이 기능은 사용하기 매우 간단합니다. 먼저 분류의 이름을 지정합니다(이 예에서는 nab_topic ). 그런 다음 관련된 게시물 유형을 지정합니다(단 하나: nab_help ). 마지막으로 몇 가지 인수를 추가하여 분류 체계를 사용자 지정합니다. 그 결과 지식 기반의 질문을 분류하는 데 필요한 구체적인 주제 를 생성하는 새로운 분류법이 생성되었습니다.

WordPress 대시보드의 사용자 정의 분류 스크린샷.
사용자 정의 분류의 스크린샷( 주제 ).

분류법에서 게시물을 정렬하는 방법

이제 사용자 정의 분류가 있고 생성한 각 주제 에 질문을 추가할 수 있으므로 특정 주제 내에서 이러한 질문을 어떻게 정렬합니까? 글쎄요, 우리가 코딩을 조금 해야 할 것 같습니다...

데이터베이스 살펴보기

WordPress 및 게시물과의 관계는 4개의 서로 다른 데이터베이스 테이블에 저장됩니다.

  • wp_terms 에는 특정 분류 내에서 생성한 모든 용어가 포함됩니다. 예를 들어 주제 분류에는 일반 질문 , 호환성지불 및 청구 와 같은 용어가 있습니다.
  • wp_termmeta 는 각 용어와 관련된 추가 데이터를 저장하는 데 도움이 됩니다. wp_postmeta 와 매우 유사합니다.
  • wp_term_taxonomywp_terms 의 각 용어를 정의하는 분류와 연결합니다. 따라서 예를 들어 이 테이블은 일반 질문 용어가 실제로 nab_topic 분류 체계의 인스턴스라는 사실을 추적합니다.
  • wp_term_relationships 는 각 용어( term_taxonomy_id )를 "포함하는" 게시물( object_id )과 연결합니다. 예를 들어, 이 표는 Nelio A/B Testing이 일반 질문 에 대한 질문을 알려줍니다(그리고 이것이 주제를 탐색할 때 질문이 표시되는 이유입니다).

WordPress 2.5는 wp_term_relationships 테이블에 term_order 라는 새로운 숫자 필드를 추가하여 분류 내에서 특정 요소가 차지하는 위치를 지정할 수 있습니다. 이것은 우리가 주제 내에서 질문을 정렬하기 위해 찾고 있던 후보처럼 들립니다. 하지만 문제가 있습니다. 내가 말할 수 있는 한, WordPress는 (1) term_order 필드의 값을 정의하고 ( 2) 실제로 특정 분류 내에서 게시물을 정렬하는 데 사용합니다. 이 문제를 해결하자!

term_order 필드를 사용하여 분류에 포함된 게시물을 정렬하는 방법

다음 스크린샷에서 볼 수 있듯이 원하는 term_order 값을 어떻게든 설정할 수 있다고 가정해 보겠습니다.

데이터베이스에 표시되는 주문과 실제로 웹에 표시되는 주문의 스크린샷.
우리가 데이터베이스에서 보는 순서(그리고 그것이 우리가 볼 것으로 예상되는 순서)는 웹사이트를 탐색할 때 실제로 받는 순서와 다릅니다.

기본적으로 WordPress는 이 필드를 무시하고 게시물은 프런트 엔드에서 정렬되지 않습니다. 그렇기 때문에 위의 스크린샷에 표시된 세 가지 질문이 제대로 정렬되지 않은 것입니다.

운 좋게도 WordPress에 필드를 사용하여 게시물을 정렬하도록 쉽게 말할 수 있습니다. posts_orderby 필터를 사용하여 특정 용어에 속하는 게시물을 검색하는 쿼리를 조정하여 정렬 요청을 포함하기만 하면 됩니다.

 add_filter( 'posts_orderby', 'nelio_sort_questions_in_topic', 99, 2 ); function nelio_sort_questions_in_topic( $orderby, $query ) { if ( ! nelio_is_topic_tax_query( $query ) ) return; global $wpdb; return "{$wpdb->term_relationships}.term_order ASC"; } function nelio_is_topic_tax_query( $query ) { if ( empty( $query->tax_query ) ) return; if ( empty( $query->tax_query->queries ) ) return; return in_array( $query->tax_query->queries[0]['taxonomy'], [ 'nab_topic' ], true ); }

이전 스니펫이 하는 모든 일은 특정 분류법(이 경우에는 nab_topic )을 쿼리하고 있는지 확인하고 쿼리에 ORDER BY 절을 추가하여 최종 결과가 다음 값에 따라 정렬되도록 하는 것입니다. $wpdb->term_relationships 테이블에 있는 term_order 속성:

분류법 결과(순서)의 스크린샷
분류 내(정렬된) 게시물의 스크린샷.

분류의 내용을 주문하기 위한 사용자 인터페이스 구현

마지막으로 우리에게 남은 일은 단 하나입니다. 이전 섹션에서 우리는 term_order 필드에 올바른 값을 어떻게든 설정할 수 있다고 가정했습니다. 하지만 어떻게? 이 값을 사용자 친화적인 방식으로 설정할 수 있는 화면이나 옵션이 있습니까? 제가 알기로는 없습니다. 하지만 우리는 하나를 만들 수 있습니다.

제 생각에 이 문제에 대한 가장 좋은 해결책은 정렬하려는 분류를 선택한 다음 모든 질문을 끌어다 놓아 순서를 설정할 수 있는 UI를 갖는 것입니다. 다음과 같이 이동하십시오.

특정 분류에 있는 게시물을 쉽게 정렬할 수 있는 사용자 인터페이스.
특정 분류에 있는 게시물을 쉽게 정렬할 수 있는 사용자 인터페이스.

원하는 효과를 얻으려면 다음 단계를 구현해야 합니다.

  • WordPress 대시보드에 새 페이지 등록
  • 택소노미 선택자와 선택된 택소노미 내의 포스트를 렌더링할 기능을 구현합니다.
  • UI가 반응할 수 있도록 작은 JavaScript 스니펫을 추가합니다.
  • 게시물 정렬이 완료되면 결과 순서를 저장하기 위해 새 콜백을 만듭니다.

새로운 WordPress 개발 스택을 사용하여 이 인터페이스를 원하는 만큼 복잡하게 만들 수 있습니다. 하지만 오늘은 작업을 완료하는 빠르고 더러운 솔루션을 간략하게 설명하겠습니다.

내가 말했듯이, 가장 먼저 우리가 인터페이스를 넣을 페이지를 등록하는 것입니다. admin_menu 작업 중에 add_submenu_page 함수를 사용하여 이 작업을 쉽게 수행할 수 있습니다.

 add_action( 'admin_menu', function() { add_submenu_page( 'edit.php?post_type=nab_help', 'Sort', 'Sort', 'edit_others_posts', 'nab-help-question-sorter', __NAMESPACE__ . '\render_question_sorter' ) } );

render_question_sorter 메소드도 매우 간단합니다.

 function render_question_sorter() { echo '<div class="wrap"><h1>Sort Questions</h1>'; $terms = get_terms( 'nab_topic' ); render_select( $terms ); foreach ( $terms as $term ) { render_questions_in_term( $term ); } render_script(); echo '</div>'; }

보시다시피, nab_topic 분류 체계에서 모든 용어를 검색한 다음 (1) 선택기를 렌더링하고, (2) 각 범주의 질문을 렌더링하고, (3) 모든 것을 만들기 위해 작은 스크립트를 추가하는 세 가지 보조 기능에 의존합니다. 동적.

선택기를 렌더링하는 것은 각 용어를 반복하고 option 을 렌더링하는 것만큼 쉽습니다.

 function render_select( $terms ) { echo '<select>'; foreach ( $terms as $term ) { printf( '<option value="%s">%s</option>', esc_attr( $term->slug ), esc_html( $term->name ) ); } echo '</select>'; }

분류법의 각 용어에 대한 질문을 렌더링하기 위해 데이터베이스에 대한 쿼리를 시작하고 모든 항목을 반복합니다.

 function render_questions_in_term( $term ) { printf( '<div class="term-block" data-term->', esc_attr( $term->slug ), esc_attr( $term->term_id ) ); echo '<div class="sortable">' $query = new WP_Query( array( 'post_type' => 'nab_help', 'post_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'nab_topic', 'field' => 'term_id', 'terms' => $term->term_id, 'orderby' => 'term_order', ), ), ) ); while ( $query->have_posts() ) { $query->the_post(); global $post; printf( '<div class="question" data-question->%s</div>', esc_attr( $post->ID ), esc_html( $post->post_title ) ); } echo '</div>'; printf( '<input type="button" data-term- value="%s" />', esc_attr( $term->term_id ), esc_attr( 'Save' ) ); echo '</div>'; }

이 함수는 현재 $termslug 를 ID로 사용하는 div 를 렌더링하고, 또 다른 div 요소의 질문을 그룹화하고, 마지막으로 저장 버튼을 포함합니다. 이 모든 세부 정보는 앱을 연결하는 스크립트를 마침내 렌더링할 때 유용할 것입니다.

모든 것이 준비되면 JavaScript 마법을 추가하기만 하면 됩니다. 특히 이 빠르고 더러운 UI에는 끌어서 놓기 기능을 구현한 후 다음 JS 스니펫을 구현하기 위해 두 개의 스크립트( jqueryjquery-ui )가 필요합니다.

 ( function() { // MAKE QUESTIONS SORTABLE $( '.sortable' ).sortable(); // TERM SELECTOR const select = document.getElementById( 'topic' ); const termBlocks = [ ...document.querySelectorAll( '.term-block' ) ]; select.addEventListener( 'change', showSelectedTermBlock ); // Helper function function showSelectedTermBlock() { /* ... */ } // SAVE BUTTONS [ ...document.querySelectorAll( '.term-block input[type="button"]' ) ].forEach( addButtonLogic ); // Helper function function addButtonLogic( button ) { const termId = button.getAttribute( 'data-term-id' ); button.addEventListener( 'click', () => { button.disabled = true; const selector = `div[data-term-] .question`; const ids = [ ...document.querySelectorAll( selector ) ] .map( ( question ) => question.getAttribute( 'data-question-id' ); $.ajax( { url: ajaxurl, method: 'POST', data: { action: 'nelio_save_tax_sorting', objectIds: ids, termId, }, } ).always( () => button.disable = false ); } } } )()

언뜻 보면 이전 스니펫이 복잡해 보일 수 있습니다. 하지만 약속합니다. 그렇지 않습니다. 먼저 jQuery UI의 sortable 기능을 사용하여 질문을 "정렬 가능"하게 만듭니다. 그런 다음 도우미 함수를 사용하여 적절한 질문 세트를 표시하거나 숨기는 select 구성 요소에 리스너를 추가합니다. 마지막으로 저장 버튼에 click 리스너를 추가하여 사용자가 버튼을 클릭하면 질문이 정렬된 순서가 데이터베이스에 저장됩니다.

보시다시피, 이 새 주문을 저장하는 것은 AJAX 요청을 통해 수행됩니다. 즉, PHP 콜백 대응을 구현해야 합니다.

 add_action( 'wp_ajax_nelio_save_tax_sorting', __NAMESPACE__ . '\save_tax_sorting' ); function save_tax_sorting() { $term_id = isset( $_POST['termId'] ) ? absint( $_POST['termId'] : 0 ); if ( ! $term_id ) die(); $object_ids = isset( $_POST['objectIds'] ) ? $_POST['objectIds'] : []; if ( ! is_array( $object_ids ) || empty( $object_ids ) ) die(); $object_ids = array_values( array_map( 'absint', $object_ids ) ); global $wpdb; foreach ( $object_ids as $order => $object_id ) { $wpdb->update( $wpdb->term_relationships, array( 'term_order' => $order + 1 ), array( 'object_id' => $object_id, 'term_taxonomy_id' => $term_id, ), ); } die(); }

그리고 그게 다야! 아주 쉽죠?

요약하자면

WordPress는 특정 분류 내에서 게시물을 정렬하는 기본 메커니즘을 제공하지 않습니다. 하지만 괜찮아! 직접 구현할 수 있습니다. WordPress 분류 체계에서 게시물을 정렬하기 위해 해야 할 일은 term_relationships 데이터베이스 테이블에서 term_order 필드를 설정한 다음 해당 필드를 사용하도록 posts_orderby 필터로 WordPress를 확장하는 것입니다.

마지막으로 특정 분류에 포함된 게시물을 드래그 앤 드롭하여 term_order 필드를 쉽게 채울 수 있는 간단한 UI를 설명했습니다.

이 튜토리얼이 마음에 드셨기를 바라며, 마음에 드셨다면 친구 및 동료와 공유해 주십시오. 그리고 항상 그렇듯이 질문이 있는 경우 아래 댓글 섹션에 남겨주세요. 기꺼이 답변해 드리겠습니다.

Unsplash에서 Steve Johnson의 추천 이미지.