Jak na WP przekierować kategorię do pierwszego posta


Uwaga! Wszystkie informacje i solucje zawarte w postach typu DYI mogą z czasem przestać być aktualne. Niektóre publikowane kody źródłowe, będąc zależnymi od używanych konfiguracji platform i sprzętu, mogą nie działać, lub działać nieprawidłowo u niektórych użytkowników. Stosując opisane rozwiązania przyjmujesz do wiadomości i zgadzasz się, że nie ponoszę odpowiedzialności za ich finalne efekty.


Czasem przydaje się funkcjonalność, w której zamiast odsyłać linkiem do zbiorówki postów w danej kategorii, chcielibyśmy kierować ją do pierwszego postu. W tym celu stworzyłem prosty kod pluginu:

<?php
/*
Plugin Name: Category to post redirect
Description: Przekierowanie zbiorówki do pierwszego postu w danej kategorii
Version: 1.0
Author: Dariusz Staropiętka
*/
function redirect_category_to_first_post() {
    if (is_category()) {
        $category = get_queried_object();

        // Pobierz pierwszy post z danej kategorii
        $args = array(
            'category_name'  => $category->slug,
            'posts_per_page' => 1,
            'orderby'        => 'date', // sortuj po dacie postów lub po id
            'order'          => 'DESC' // lub ASC jeśli pierwszym postem ma być pierwszy w ogóle opublikowany
        );

        $first_post = new WP_Query($args);

        if ($first_post->have_posts()) {
            $first_post->the_post();
            $first_post_url = get_permalink();

            // Przekieruj do pierwszego posta
            wp_redirect($first_post_url);
            exit;
        }
    }
}

add_action('template_redirect', 'redirect_category_to_first_post');
?>

Plugin ma ustawione automatyczne sortowanie postów w danej kategorii (ostatnie są na samym początku).

Pierwszy lub drugi kod musisz oczywiście zapakować do pliku php, np. o nazwie 'category-to-post-redirect.php’, plik wrzucić do folderu najlepiej o tej samej nazwie, a całość wrzucić do /wp-content/plugins/. Plugin należy włączyć w panelu administracyjnym w panelu wtyczek.

Update:

Wymyśliłem sobie, że chciałbym mieć plugin do przekierowywania kategorii do pierwszego posta. Zdarza się jednak czasem, że posty w niektórych kategoriach powinny być posortowane alfabetyczne, a inne po id lub dacie. Jakkolwiek nie udało mi się jeszcze wymyślić sposobu na niedziałające sortowanie po tytule po przekierowaniu na daną kategorię (poprosiłem o pomoc w rozwiązaniu problemu użytkowników Stack Exchange; na liście postów z danej kategorii sortowanie działa bezbłędnie), tak sortowanie po id i dacie działa bezbłędnie. Plugin dodaje dodatkowe funkcjonalności w panelu edycji kategorii, po ustawieniu sortowania przekierowuje posty do pierwszego posta wynikającego z sortowania. Wydaje się, że w tej wersji wtyczki skorygowałem problemy występujące w związku z pamięcią podręczną przeglądarki, pojawiające się po dodaniu nowego posta w danej kategorii.

Oto kod wtyczki:

<?php
/*
Plugin Name: Custom Category Settings & Redirect
Description: Rozszerza panel edycji kategorii o dodatkowe pola sortowania oraz przekierowania 301.
Version: 2.6
Author: Dariusz Staropiętka
*/

// Dodawanie pól do panelu edycji kategorii
function custom_category_add_fields($tag) {
    // Pobieranie obecnych wartości metadanych
    $sort_by = get_term_meta($tag->term_id, 'sort_by', true);
    $sort_direction = get_term_meta($tag->term_id, 'sort_direction', true);
    $redirect_301 = get_term_meta($tag->term_id, 'redirect_301', true);
    ?>

    <tr class="form-field">
        <th scope="row" valign="top"><label for="sort_by"><?php _e('Sortuj po'); ?></label></th>
        <td>
            <select name="sort_by" id="sort_by">
                <option value="id" <?php selected($sort_by, 'id'); ?>>Id</option>
                <option value="date" <?php selected($sort_by, 'date'); ?>>Data (Domyślny)</option>
                <option value="title" <?php selected($sort_by, 'title'); ?>>Tytuł</option>
            </select>
        </td>
    </tr>

    <tr class="form-field">
        <th scope="row" valign="top"><label for="sort_direction"><?php _e('Kierunek sortowania'); ?></label></th>
        <td>
            <select name="sort_direction" id="sort_direction">
                <option value="asc" <?php selected($sort_direction, 'asc'); ?>>Rosnąco</option>
                <option value="desc" <?php selected($sort_direction, 'desc'); ?>>Malejąco (Domyślny)</option>
            </select>
        </td>
    </tr>

    <tr class="form-field">
        <th scope="row" valign="top"><label for="redirect_301"><?php _e('Przekierowanie 301'); ?></label></th>
        <td>
            <input type="text" name="redirect_301" id="redirect_301" value="<?php echo esc_attr($redirect_301); ?>">
        </td>
    </tr>
    <?php
}
add_action('category_edit_form_fields', 'custom_category_add_fields');

// Zapis wartości metadanych
function custom_category_save_fields($term_id) {
    if (isset($_POST['sort_by'])) {
        update_term_meta($term_id, 'sort_by', sanitize_text_field($_POST['sort_by']));
    }
    if (isset($_POST['sort_direction'])) {
        update_term_meta($term_id, 'sort_direction', sanitize_text_field($_POST['sort_direction']));
    }
    if (isset($_POST['redirect_301'])) {
        update_term_meta($term_id, 'redirect_301', esc_url($_POST['redirect_301']));
    }
}
add_action('edited_category', 'custom_category_save_fields', 10, 2);

// Przekierowanie kategorii na podstawie ustawień
function custom_category_redirect() {
    if (is_category()) {
        $term = get_queried_object();
        $sort_by = get_term_meta($term->term_id, 'sort_by', true);
        $sort_direction = get_term_meta($term->term_id, 'sort_direction', true);
        $redirect_301 = get_term_meta($term->term_id, 'redirect_301', true);

        // Jeśli jest ustawione przekierowanie 301
        if ($redirect_301) {
            // Ustawienie nagłówków do wymuszenia odświeżenia
            header("Cache-Control: no-cache, no-store, must-revalidate");
            header("Pragma: no-cache");
            header("Expires: 0");

            wp_redirect($redirect_301, 301);
            exit();
        }

        // Parametry zapytania
        $args = array(
            'cat' => $term->term_id,
            'posts_per_page' => 1,
            'orderby' => $sort_by ? $sort_by : 'date',
            'order' => $sort_direction ? $sort_direction : 'desc',
        );

        $query = new WP_Query($args);
        if ($query->have_posts()) {
            $query->the_post();
            // Ustawienie nagłówków do wymuszenia odświeżenia
            header("Cache-Control: no-cache, no-store, must-revalidate");
            header("Pragma: no-cache");
            header("Expires: 0");

            wp_redirect(get_permalink(), 301);
            exit();
        }
        wp_reset_postdata();
    }
}
add_action('template_redirect', 'custom_category_redirect');