Tym razem pytanie od znajomego otrzymane bezpośrednio. Mam jednak wrażenie, że z tym problemem spotkać można się dość często, a dotyczy ono modyfikowania liczby wpisów wyświetlanych na stronie w zależności od tego, na jakiej stronie aktualnie jesteśmy. Ale po kolei – zacznijmy od pytania:

Na stronie głównej 4 wpisy wyświetlam w sliderze, a potem resztę normalnie. Co zrobić, żeby paginacja działała poprawnie?

Podejrzewam, że przyda się kilka dodatkowych wyjaśnień. Na czym dokładnie polegał problem? Otóż na stronie listy wpisów wyświetlane było po 9 wpisów. Na stronie głównej bloga, wyświetlać miał się slider, a w nim 4 najnowsze wpisy, a poniżej 9 następnych wpisów (razem 13). Gdy przechodziliśmy na stronę drugą, to niektóre wpisy wyświetlały się ponownie.

Jak to naprawić? Prosto – musimy wytłumaczyć WordPressowi, ile wpisów gdzie chcemy wyświetlać. A możemy to zrobić tak:

function prefiks_change_posts_number_on_home( $query ) {
    if ( is_home() && $query->is_main_query() ) {
        $posts_per_page = get_query_var('posts_per_page', get_option('posts_per_page'));  // <- domyślna liczba wpisów do wyświetlenia
        $additional_posts = 4;  // <- liczba dodatkowych wpisów na pierwszej stronie

        if ( get_query_var('paged') < 2 ) {
            $query->set( 'posts_per_page', $posts_per_page + $additional_posts );
        } else {
            $query->set( 'offset', $additional_posts + ( get_query_var( 'paged' ) - 1 ) * $posts_per_page );
        }
    }
}
add_action( 'pre_get_posts', 'prefiks_change_posts_number_on_home' );

(więcej…)

Dzisiaj na jednej z grup supoprtowych pojawiło się następujące pytanie:

Czy da się jakoś zmienić domyślne ustawienia galerii? Chciałbym mieć na start ustawione 4 kolumny oraz linkowanie do pliku, a nie strony załącznika.

No właśnie, da się? Oczywiście, że się da, a potrzebujemy w tym celu poniższych dwóch funkcji:

function prefiks_print_media_templates() {
    ?>
    <script>
        jQuery(document).ready(function() {
            _.extend(wp.media.galleryDefaults, {
                columns: '4',
                link: 'file',
            });
        });
    </script>
    <?php
}
add_action('print_media_templates', 'prefiks_print_media_templates');

function prefiks_shortcode_atts_gallery($out, $pairs, $atts) {
    if ( ! array_key_exists('columns', $atts) || ! intval( $atts['columns'] ) ) {
        $out['columns'] = 4;
    }

    if ( ! array_key_exists('link', $atts) ) {
        $out['link'] = 'file';
    }

    return $out;
}
add_filter('shortcode_atts_gallery', 'prefiks_shortcode_atts_gallery', 10, 3);

(więcej…)

Dzisiaj na Facebookowej grupie WordPress PL pojawiło się następujące pytanie:

… potrzebuję plugin, który bez różnicy czy hasło będzie wpisywane z dużych czy z małych liter, będzie otwierał dostęp do danego wpisu, widział ktoś może coś takiego? …

Na pierwszy rzut oka takie rozwiązanie może wydawać się kiepskim pomysłem – przecież po to ustawiamy hasło, żeby dostanie się do wpisu nie było zbyt proste, a ignorując wielkość liter, dość znacznie zmniejszamy złożoność hasła. Ale… przecież ta złożoność nadal pozostanie całkiem spora, a poza tym, hasło do wpisu to nie to samo, co hasło do panelu administracyjnego.

Jeśli więc rzeczywiście mamy z tym problem i możemy w ten sposób ułatwić życie naszych czytelników, to czemu by nie spróbować? Tym bardziej, że wcale nie będzie to nas kosztowało tak wiele wysiłku.

Wystarczy użyć poniższego kodu (tym razem musimy użyć aż dwóch funkcji):

function prefiks_uppercase_post_password_before_hashing() {
    if ( isset($_POST['post_password']) && ! empty($_POST['post_password']) ) {
        $_POST['post_password'] = mb_strtoupper($_POST['post_password']);
    }
}
add_action( 'login_form_postpass', 'prefiks_uppercase_post_password_before_hashing' );

function prefiks_uppercase_post_password_before_saving($data, $postarr) {
    if ( array_key_exists('post_password', $data) && ! empty($data['post_password']) ) {
        $data['post_password'] = mb_strtoupper($data['post_password']);
    }
    return $data;
}
add_filter( 'wp_insert_post_data', 'prefiks_uppercase_post_password_before_saving', 10, 2 );

(więcej…)

Jeśli używasz WordPressa dłużej niż miesiąc, to pewnie przynajmniej raz dowiedziałeś się o jakiejś aktualizacji – wtyczki, motywu, albo WordPressa. Oprogramowanie jest rozwijane, pojawiają się nowe funkcje, wykrywane są błędy, które następnie są poprawiane. W ciągu ostatnich 12 miesięcy sam WordPress zmieniał wersję 14 razy, choć dzięki aktualizacjom automatycznym, część z nich mogłeś przeoczyć (WordPress wykonał je za Ciebie).

Do tego, aby aktualizować zawsze i to jak najszybciej nawołują zazwyczaj autorzy, blogi i serwisy newsowe, a także Twój WordPress, który o aktualizacjach przypomina na każdym kroku i zachęca do nich informując, że to tylko jedno kliknięcie.

Jeśli dodatkowo uświadomisz sobie, że znakomita większość kodu związanego z WordPressem rozwijana jest jawnie – czyli każdy ma dostęp do kodu poszczególnych wersji, a w większości przypadków także do informacji o zawartych w nich poprawkach (czyli o błędach zawartych w wersjach poprzednich), to chęć jak najszybszej aktualizacji powinna być wręcz naturalna.

Tyle w teorii. A jak to wygląda w praktyce?

(więcej…)

Wyobraźmy sobie, że tworzymy nieco bardziej rozbudowany serwis, w którym użytkownicy mogą się rejestrować. Niekoniecznie jednak chcemy, aby byli oni świadomi, że serwis bazuje na WordPressie, albo chcemy wzbogacić i uprzyjemnić ich doświadczenie i stworzyć specjalny panel administracyjny. Tak czy inaczej nie chcemy, aby „szwędali” się nam po panelu administracyjnym WordPressa.

Żeby nie rozmieniać się na drobne, załóżmy, że zalogowanych użytkowników, którzy mają określoną rolę (w naszym przypadku subscriber, chcemy przekierowywać na określoną stronę (naszserwis.pl/uzytkownik/). I taką właśnie funkcjonalność realizuje poniższy kod:

function prefiks_restrict_wpadmin_access() {
    if ( ! defined('DOING_AJAX') || ! DOING_AJAX ) {
        $user = wp_get_current_user();

        if ( in_array('subscriber', $user->roles) ) {
            wp_redirect( site_url( '/uzytkownik/' ) );  // <- dostosuj swoich potrzeb
            die;
        }
    }
}
add_action( 'admin_init', 'prefiks_restrict_wpadmin_access' );

(więcej…)

Gdy korzystamy z parametru s WP_Query, WordPress wyszuka wpisów, które zawierają podane słowa w tytule lub treści. Zdarza się jednak, że chcemy wyszukiwać jedynie po tytule (bo jest to w danej chwili bardziej intuicyjne – np. jeśli tworzymy pole z automatycznym podpowiadaniem tytułu wpisu).

Poniższy kod pozwoli nam osiągnąć właśnie taki efekt.

function prefiks_search_by_title_only( $search, $query ) {
    global $wpdb;

    if ( empty( $search ) ) {
        return $search;
    }
    $q = $wp_query->query_vars;
    $n = ! empty( $q['exact'] ) ? '' : '%';

    $search = $searchand = '';

    foreach ( (array) $q['search_terms'] as $term ) {
        $term = esc_sql( like_escape( $term ) );
        $search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
        $searchand = ' AND ';
    }

    if ( ! empty( $search ) ) {
        $search = " AND ({$search}) ";
        if ( ! is_user_logged_in() ) {
            $search .= " AND ($wpdb->posts.post_password = '') ";
        }
    }
    return $search;
}
add_filter( 'posts_search', 'prefiks_search_by_title_only' );

(więcej…)

Czy zdarzyło Ci się kiedyś, że na stronie z rozbudowanym drzewem kategorii, chciałeś ukryć wpisy z podkategorii w widoku archiwum danej kategorii? Z pytaniem tym spotykam się dość często, więc może warto pokazać, jak należy się za to zabrać.

Poniżej znajdziesz kod, który realizuje dokładnie takie zadanie:

function prefiks_exclude_subcategory_from_category_archive( $query ) {
    if ( !is_admin() && $query->is_main_query() && is_category() ) {
        $category_not_in = $query->get( 'category__not_in', array() );

        if ( $query->get('cat', false) ) {
            $query->set('tax_query', array( array(
                'taxonomy' => 'category',
                'operator' => 'IN',
                'terms' => $query->get('cat'),
                'include_children' => false,
            ) ));
        }
    }
}
add_filter( 'pre_get_posts', 'prefiks_exclude_subcategory_from_category_archive' );

(więcej…)