Bir WordPress Taksonomisinde Gönderiler Nasıl Sıralanır?
Yayınlanan: 2020-12-18Şimdiye kadar Nelio, WordPress.org deposunda birkaç eklenti yayınladı. Bazıları tamamen ücretsizdir ve örneğin sayfalarınıza veya Gutenberg ile oluşturulan yayınlarınıza bir Google haritası eklemenize izin veren Nelio Haritalar ve eklemenize izin veren Nelio Resimleri Karşılaştırma gibi yaygın sorunlara zarif çözümler sunar. adından da anlaşılacağı gibi, iki görüntüyü yan yana karşılaştırmak için bir blok. Ayrıca faturaları ödememize yardımcı olan birkaç premium eklenti yayınladık: Nelio Content ve Nelio A / B Testing.
Web sitemize bir göz atarsanız, her ikisinde de birkaç açılış ve fiyatlandırma sayfası bulunduğundan ve her ikisinin de kullanıcıların sorularına yanıt bulabilecekleri ilgili bir bilgi tabanına sahip olduklarından, iki premium eklentimizin önemli bir yer işgal ettiğini göreceksiniz. Bugün, Nelio A/B Testi ve Nelio İçeriği için belge sayfalarını nasıl oluşturduğumuzdan ve soruları istediğimiz gibi sıralamak için ne yapmamız gerektiğinden bahsedeceğiz.
WordPress'te özel gönderi türleri nasıl oluşturulur?
İlk olarak, bilgi tabanımızın içereceği tüm soruları takip etmek için özel bir gönderi türü oluşturalım. Sonucu, Nelio A/B Testing'in bilgi tabanı için bu yeni gönderi türünün bir örneğinin bulunduğu aşağıdaki ekran görüntüsünde görebilirsiniz:

Özel bir gönderi türü oluşturmak için tek yapmanız gereken WordPress register_post_type işlevini aşağıdaki gibi kullanmaktır:
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' );ve işte! Özel gönderi türlerinin arayüzünü oluşturmanıza ve özelleştirmenize yardımcı olan Gelişmiş Özel Alanlar gibi eklentiler olduğunu zaten biliyor olabilirsiniz, ancak bunun böyle basit bir örneği uygulamasını önermem.
Bu arada, bu snippet'in nereye yerleştirilmesi gerektiğini merak ediyorsanız, WordPress'i özel eklentilerle nasıl özelleştireceğinize dair eğiticimizi kaçırmayın.
İçeriği düzenlemek için yeni bir sınıflandırma nasıl oluşturulur?
Aşağıdaki ekran görüntüsünde görebileceğiniz gibi, bilgi tabanımız “Konular” ve “Anahtar Kelimeler” şeklinde düzenlenmiştir:

Konular ve Anahtar Sözcükler, WordPress gönderilerinde varsayılan olarak sahip olduğunuz Kategoriler ve Etiketlerin eşdeğeridir. İkincisi tamamen aynı olduğu için sadece birincisine odaklanalım.
Tahmin edebileceğiniz gibi, Konu, özel içerik türümüz için oluşturduğumuz özel bir sınıflandırmadır. Bir WordPress gönderi türüne yeni bir sınıflandırma eklemek için register_taxonomy işlevini aşağıdaki gibi kullanmanız yeterlidir:
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' ); İşlevin kullanımı oldukça basittir. İlk olarak, taksonomiyi adlandırın ( nab_topic ). Ardından, ilişkili olduğu gönderi türlerini belirtirsiniz (yalnızca bir tane var: nab_help ). Son olarak, sınıflandırmayı özelleştirmek için birkaç argüman daha eklersiniz. Sonuç, bilgi tabanımızdaki soruları kategorize etmek için ihtiyaç duyduğumuz somut Konuları oluşturmak için yeni bir sınıflandırmadır:

Bir Taksonomideki gönderiler nasıl sıralanır
Artık özel bir taksonomiye sahip olduğumuza ve oluşturduğumuz her Konuya sorular ekleyebildiğimize göre, bu soruları belirli bir konu içinde nasıl sıralayabiliriz? Şey, korkarım biraz kodlamamız gerekecek…
Veritabanına bir göz atmak
WordPress ve gönderilerinizle olan ilişkileri dört farklı veritabanı tablosunda saklanır:
-
wp_terms, belirli bir sınıflandırma içinde oluşturduğunuz tüm terimleri içerir. Örneğin, konu sınıflandırmamızda Genel Sorular , Uyumluluk ve Ödemeler ve Faturalandırma gibi terimlerimiz vardır. -
wp_termmeta, her terimle ilgili ek verileri depolamamıza yardımcı olur.wp_postmetaoldukça benzer. -
wp_term_taxonomy,wp_termsiçindeki her terimi, tanımlayıcı sınıflandırmasıyla ilişkilendirir. Bu nedenle, örneğin, bu tablo, Genel Soru teriminin aslındanab_topicsınıflandırmasının bir örneği olduğu gerçeğini takip eder. -
wp_term_relationships, her terimi (term_taxonomy_id) "içerdiği" gönderilerle (object_id) ilişkilendirir. Örneğin, bu tablo bize Nelio A/B Testinin ne olduğuyla ilgili sorunun Genel Bir Soru olduğunu söyler (ve bu nedenle, konuya göz atılırken soru ortaya çıkar).
WordPress 2.5, wp_term_relationships tablosuna term_order adlı yeni bir sayısal alan ekledi; bu, sınıflandırma içinde belirli bir öğenin kapladığı konumu belirtmemize olanak tanır. Bu, konumuzdaki sorularımızı sıralamak için aradığımız adaya benziyor… ama bir yakalama var: Anladığım kadarıyla, WordPress (1) term_order alanının değerini tanımlamak ve ( 2) gönderileri belirli bir sınıflandırma içinde gerçekten sıralamak için kullanın. Bunu düzeltelim!
Bir sınıflandırmaya dahil edilen gönderileri sıralamak için term_order alanı nasıl kullanılır?
Aşağıdaki ekran görüntüsünde de görebileceğiniz gibi, istediğimiz term_order değerlerini bir şekilde ayarlayabildiğimizi varsayalım:

Varsayılan olarak, WordPress bu alanı yok sayar ve gönderiler ön uçta sıralanmaz. Bu nedenle, yukarıdaki ekran görüntüsünde gösterilen üç soru düzgün şekilde sıralanmamıştır.
Neyse ki, WordPress'e, gönderileri sıralamak için alanı kullanmasını kolayca söyleyebiliriz. Bir sıralama isteği içerecek şekilde belirli bir terime ait gönderileri alan sorguyu ince ayar yapmak için posts_orderby filtresini kullanın:
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 ); } Önceki snippet'in tek yaptığı, belirli bir sınıflandırmayı sorguladığımızı kontrol etmektir (bizim durumumuzda, nab_topic ) ve yaptığımızda, nihai sonucun değerine göre sıralanması için sorguya bir ORDER BY yan tümcesi ekleriz. $wpdb->term_relationships tablosunda bulunan term_order özelliği:


Bir sınıflandırmanın içeriğini sıralamak için bir kullanıcı arayüzünün uygulanması
Son olarak, yapmamız gereken tek bir şey kaldı. Bir önceki bölümde, term_order alanında bir şekilde doğru değeri ayarlayabildiğimizi varsaymıştık. Ama nasıl? Bu değeri kullanıcı dostu bir şekilde ayarlamak için bir ekran veya seçenek var mı? Bildiğim kadarıyla yok. Ama bir tane yaratabiliriz.
Bence bu soruna en iyi çözüm, sıralamak istediğim taksonomiyi seçmeme izin veren bir kullanıcı arayüzüne sahip olmak ve ardından sıralamalarını oluşturmak için tüm soruları sürükleyip bırakmak olacaktır. Bunun gibi bir şey, git:

İstenen etkiyi elde etmek için aşağıdaki adımları uygulamamız gerekir:
- WordPress kontrol panelinde yeni bir sayfa kaydedin
- Taksonomi seçiciyi ve seçilen taksonomi içindeki gönderileri oluşturacak işlevi uygulayın
- Kullanıcı arayüzünün duyarlı olması için küçük bir JavaScript pasajı ekleyin
- Gönderileri sıralamayı bitirdikten sonra ortaya çıkan siparişi kaydetmek için yeni bir geri arama oluşturun
Yeni WordPress geliştirme yığınını kullanarak bu arayüzü istediğiniz kadar karmaşık hale getirebilirsiniz. Ama bugün işi bitiren hızlı ve kirli bir çözümün ana hatlarını vereceğim.
Dediğim gibi ilk iş arayüzü koyacağımız sayfaya kayıt olmak. Bunu admin_menu eylemi sırasında add_submenu_page işleviyle kolayca yapabiliriz:
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 yöntemi de son derece basit:
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>'; } Gördüğünüz gibi, nab_topic sınıflandırmasındaki tüm terimleri alıyoruz ve ardından (1) seçiciyi oluşturmak, (2) her kategorideki soruları oluşturmak ve (3) her şeyi yapmak için küçük bir komut dosyası eklemek için üç yardımcı fonksiyona güveniyoruz. dinamik.
Seçiciyi oluşturmak, her terimi yinelemek ve bir option oluşturmak kadar kolaydır:
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>'; }Taksonominin her teriminde sahip olduğumuz soruları işlemek için, veritabanına bir sorgu başlatır ve hepsini tekrar ederiz:
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>'; } Bu işlevin, kimliği olarak geçerli $term slug kullanan bir div oluşturduğuna, soruları başka bir div öğesinde gruplandırdığına ve sonunda bir Kaydet düğmesi içerdiğine dikkat edin. Tüm bu ayrıntılar, uygulamamızı bağlayan komut dosyasını nihayet oluşturduğumuzda faydalı olacaktır.
Her şey hazır olduğunda, sadece biraz JavaScript büyüsü eklememiz gerekiyor. Özellikle, bu hızlı ve kirli kullanıcı arabirimi, sürükle ve bırak işlevini uygulamak için iki komut dosyası ( jquery ve jquery-ui ) ve ardından aşağıdaki JS parçacığını gerektirir:
( 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 ); } } } )() İlk bakışta, önceki pasaj karmaşık görünebilir. Ama söz veriyorum: değil. Öncelikle jQuery UI'nin sortable fonksiyonunu kullanarak sorularımızı “sortable” yapıyoruz. Ardından, bir yardımcı işlevi kullanarak uygun soru dizisini gösteren/gizleyen select bileşenimize bir dinleyici ekleriz. Son olarak, click dinleyicilerini Kaydet butonlarımıza ekliyoruz, böylece kullanıcı üzerlerine tıkladığında soruların sıralandığı sıra veritabanında saklanıyor.
Gördüğünüz gibi, bu yeni siparişin kaydedilmesi bir AJAX isteği ile yapılıyor, bu da onun PHP geri arama karşılığını uygulamamız gerektiği anlamına geliyor:
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(); }Ve bu kadar! Oldukça kolay, ha?
Özetle
WordPress, gönderileri belirli bir sınıflandırma içinde sıralamak için varsayılan bir mekanizma sunmaz. Ama sorun değil! Birini kendimiz uygulayabiliriz: Bir WordPress sınıflandırmasındaki gönderileri sıralamak için tek yapmamız gereken, term_relationships veritabanı tablosundaki term_order alanını ayarlamak ve ardından WordPress'i söz konusu alanı kullanacak şekilde posts_orderby filtresiyle genişletmek.
Son olarak, belirli bir sınıflandırmaya dahil edilen gönderileri sürükleyip bırakarak term_order alanını kolayca doldurmak için basit bir kullanıcı arayüzü belirledik.
Umarım bu öğreticiyi beğenmişsinizdir ve beğendiyseniz, lütfen arkadaşlarınızla ve iş arkadaşlarınızla paylaşın. Ve her zaman olduğu gibi, herhangi bir sorunuz varsa, bunları aşağıdaki yorum bölümünde bırakın, onlara memnuniyetle cevap vereceğim.
Unsplash'ta Steve Johnson tarafından öne çıkan görsel.
