Apply_filters () i the_excerpt dają nieoczekiwane wyniki

10

Wydaje mi się, że tutaj brakuje mi czegoś oczywistego, ale wydaje mi się, że nie mogę zmusić WordPress do współpracy.

Generuję tagi OG na Facebooku z funkcją. Wszystko działa dobrze, z wyjątkiem fragmentu.

Czy od czasu wycofania get_the_excerpt($post->ID)istnieje inny sposób na utworzenie fragmentu bez konieczności tworzenia zupełnie nowej pętli? Wydaje mi się to przesadne.

Moim pierwszym instynktem było użycie apply_filters():

$description = apply_filters('the_excerpt', get_post($post->ID)->post_content);

To daje mi pełny post wraz z treścią w formacie HTML. Okej, musi się mylić. Wypróbowałem więc kolejny logiczny pomysł:

$description = apply_filters('get_the_excerpt', get_post($post->ID)->post_content);

Nie ma kości. Teraz nie ma HTML, ale wciąż jest to pełny post (co jest bardzo mylące).

Jasne, nie ma problemu. Pomińmy wszystkie fantazyjne rzeczy i po prostu przejdźmy do przyciętego wpisu:

$description = wp_trim_excerpt(get_post($post->ID)->post_content);

Bez zmiany.

Więc moje pytanie brzmi: co się do cholery dzieje? Czy czegoś tu brakuje?

Wszedłem do rdzenia WP, aby dowiedzieć się, jak the_excerpt()działa, i wygląda na to, że jest identyczny z moim wywołaniem:

/**
 * Display the post excerpt.
 *
 * @since 0.71
 * @uses apply_filters() Calls 'the_excerpt' hook on post excerpt.
 */
function the_excerpt() {
    echo apply_filters('the_excerpt', get_the_excerpt());
}

Mam kilka pytań opartych na moich ustaleniach:

  1. Dlaczego filtr nie jest stosowany zgodnie z oczekiwaniami?
  2. Czy istnieje sposób na wyciągnięcie fragmentu poza pętlę bez tworzenia nowej pętli?
  3. Czy jestem szalony?

Z góry dziękuję za obejrzenie. Jestem dość zakłopotany.

jlengstorf
źródło
get_the_excerpt()nie jest przestarzałe, tylko dodatkowy parametr, który był do niego przekazywany, nie jest już używany.
Milo
Przepraszam, o to mi chodziło. Dzięki za wytłumaczenie.
jlengstorf
Jesteś szalony! . . . as am
Iol

Odpowiedzi:

16

Okazuje się, że odpowiedź była wp_trim_excerpt().

Jest zdefiniowany w wp-includes/functions.php:1879:

/**
 * Generates an excerpt from the content, if needed.
 *
 * The excerpt word amount will be 55 words and if the amount is greater than
 * that, then the string ' [...]' will be appended to the excerpt. If the string
 * is less than 55 words, then the content will be returned as is.
 *
 * The 55 word limit can be modified by plugins/themes using the excerpt_length filter
 * The ' [...]' string can be modified by plugins/themes using the excerpt_more filter
 *
 * @since 1.5.0
 *
 * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated.
 * @return string The excerpt.
 */
function wp_trim_excerpt($text = '') {
    $raw_excerpt = $text;
    if ( '' == $text ) {
        $text = get_the_content('');

        $text = strip_shortcodes( $text );

        $text = apply_filters('the_content', $text);
        $text = str_replace(']]>', ']]>', $text);
        $excerpt_length = apply_filters('excerpt_length', 55);
        $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
        $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
    }
    return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}

Tak więc żaden przekazany tekst nie jest przetwarzany; działa tylko wtedy, gdy jest wywoływany z pustym parametrem.

Aby rozwiązać ten problem, dodałem szybki filtr do mojego motywu, który rozwiązuje problem:

/**
 * Allows for excerpt generation outside the loop.
 * 
 * @param string $text  The text to be trimmed
 * @return string       The trimmed text
 */
function rw_trim_excerpt( $text='' )
{
    $text = strip_shortcodes( $text );
    $text = apply_filters('the_content', $text);
    $text = str_replace(']]>', ']]>', $text);
    $excerpt_length = apply_filters('excerpt_length', 55);
    $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
    return wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
add_filter('wp_trim_excerpt', 'rw_trim_excerpt');

Jest nieco zbędny, ale podoba mi się to bardziej niż otwieranie nowych pętli za każdym razem, gdy chcę wygenerować fragment.

jlengstorf
źródło
1
Ach, nie było dla mnie jasne, że szukasz tylko operacji tekstowej (nie pobieranie z DB).
hakre
Bez obaw. Zawsze boję się, że nie mam sensu, gdy zadaję pytania. I został ciągnięcie z bazy danych, ale nie chcę, aby otworzyć zupełnie inna pętli, ponieważ mam takie rzeczy get_the_title($post->ID)dostępne. Końcowa linia kodu było$description = wp_trim_excerpt(get_post($post->ID)->post_content);
jlengstorf
Czuję się głupio pytając o to, ale jak nazwać ten nowy filtr? Próbowałem tego jak $content = apply_filters( 'rw_trim_excerpt', $content );i $content = rw_trim_excerpt($content);, ale żaden z nich nie działał (pierwszy nie przyciął wyjścia, a później wystąpił błąd).
Eric K
2
@QuantumDynamix ten jest przeznaczony do modyfikowania get_the_excerptobchodzenia się naśladować the_excerpt, tak można nazwać: apply_filters('get_the_excerpt', $content);.
jlengstorf
uff! fajny z punktu widzenia wpress noob, dzięki
pythonian29033
1

Próbować:

   get_post($post->ID)->post_excerpt
                        ^^^^^^^^^^^^

Zobacz: get_postKodeks dla wszystkich dostępnych członków powrotu.

hakre
źródło
4
Zwraca puste, jeśli nie wpisano żadnego fragmentu posta. Muszę naśladować działania get_the_excerpt () (tworzenie fragmentu, jeśli nie istnieje).
jlengstorf
Zastosowanie filtra tego nie zrobi, więc zadajesz złe pytanie. Nie mam pojęcia, dlaczego szukasz fragmentu, jeśli go nie ma. get_the_excerpt()nie naśladuje tego, sprawdź źródło, tylko uzyskuje dostęp do zmiennej członka, $postktórej jest post_excerpt. Zobacz także link do kodu w odpowiedzi.
hakre
3
Od wpisu w Kodeksie the_excerpt: „wyświetli automatyczny fragment, który odnosi się do pierwszych 55 słów treści postu”. Chcę naśladować to zachowanie poza pętlą.
jlengstorf
Cóż, tymczasowo utwórz drugą pętlę i przeszukaj ten plik według jego identyfikatora, prawdopodobnie w celu szybkiego rozwiązania. Patrz Secondary Loops - codex.wordpress.org/Function_Reference/…
hakre
1
Dzięki za link. Wiedziałem, że mogę założyć dodatkową pętlę, ale wydaje się, że to przesada. Moim rozwiązaniem było dodanie filtra. Widzę to teraz jako trochę smaru na łokieć, aby później znacznie mniej kodu.
jlengstorf
0

Możesz użyć mojej funkcji niestandardowej do usunięcia zawartości (pochodzi z frameworka NARGA )

  • Jeśli post ma niestandardowy fragment, wyświetl go zamiast zawartości
  • Automatycznie generuj fragment z treści, jeśli post nie ma niestandardowego szablonu
  • Automatyczne przycinanie krótkiego kodu, kodu HTML, usuwanie [...], dodawanie tekstu „Czytaj więcej” (do przetłumaczenia)

        /**
        * Auto generate excerpt from content if the post hasn't custom excerpt
        * @from NARGA Framework - http://www.narga.net/narga-core
        * @param $excerpt_lenght  The maximium words of excerpt generating from content
        * @coder: Nguyễn Đình Quân a.k.a Narga - http://www.narga.net
        **/  
        function narga_excerpts($content = false) {
        # If is the home page, an archive, or search results
        if(is_front_page() || is_archive() || is_search()) :
            global $post;
        $content = $post->post_excerpt;
        $content = strip_shortcodes($content);
        $content = str_replace(']]>', ']]>', $content);
        $content = strip_tags($content);
        # If an excerpt is set in the Optional Excerpt box
        if($content) :
            $content = apply_filters('the_excerpt', $content);
        # If no excerpt is set
        else :
            $content = $post->post_content;
            $excerpt_length = 50;
            $words = explode(' ', $content, $excerpt_length + 1);
        if(count($words) > $excerpt_length) :
            array_pop($words);
            array_push($words, '...<p><a class="more-link" href="' . get_permalink() . '" title="' . the_title_attribute('echo=0') . '">  ' . __( 'Read more &#187;', 'narga' ) . ' </a></p>');
            $content = implode(' ', $words);
        endif;
        $content = '<p>' . $content . '</p>';
        endif;
        endif;
        # Make sure to return the content
        return $content;
        }
        // Add filter to the_content
        add_filter('the_content', 'narga_excerpts');
Narga
źródło