Установка куки для URL параметра и передача между страницами для изменения поста

7 авг. 2019 г., 09:33:37
Просмотры: 14.9K
Голосов: 0

У меня есть функция, которая делает пост многостраничным на основе URL параметра с определенным значением:

?content=multipage

Проблема в том, что когда пользователь переходит на следующую страницу, URL параметр исчезает и пост возвращается к одностраничному формату.

Если я вручную добавлю URL параметр на следующую страницу, пост становится многостраничным

Исходя из моего исследования, лучший способ решить проблему - установить куки, когда:

?content=multipage

Таким образом, этот URL параметр будет передаваться со страницы на страницу и не будет виден в адресной строке.

Я пробовал несколько методов установки куки, нашел функцию setcookie(), которая, по-видимому, должна решить проблему.

Вот моя текущая реализация:

    function onepage() {
    //**Удаляем шорткоды**//
    function remove_shotcode($content) {
        return str_replace('[/shortcode1]', '', $content);    
        return str_replace('[shortcode2]', '', $content);
    }
    add_filter( 'the_content', 'remove_shotcode'); 

/*
*Удаляет <!--nextpage-->
*@see http://wordpress.stackexchange.com/a/183587/26350
*/

    add_action( 'the_post', function( $post )
    {
        if ( false !== strpos( $post->post_content, '<!--nextpage-->' ) ) 
        {
            // Сбрасываем глобальную $pages:
            $GLOBALS['pages']     = [ $post->post_content ];

            // Сбрасываем глобальную $numpages:
            $GLOBALS['numpages']  = 0;

           // Сбрасываем глобальную $multipage:
            $GLOBALS['multipage'] = false;
        }

    });
    }

    //**Условный оператор, который должен устанавливать куки**//
    if ( empty( $_GET['content'] ) || "multipage" !== $_GET['content'] ) {
        //**Удаляет onepage() только при content=multipage**//
        add_action('wp','onepage');
        //**Должен устанавливать куки только при content=multipage**//
        setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
    }

Код, который делает пост многостраничным, приведен ниже:


    //**РАЗДЕЛ PAGEBREAK - НАЧАЛО**//
    function pagebreak( $args = '' ) {
        global $page, $numpages, $multipage, $more;

        $defaults = array(
            'before'           => '<p class="post-nav-links">' . __( 'Страницы:' ),
            'after'            => '</p>',
            'link_before'      => '',
            'link_after'       => '',
            'aria_current'     => 'page',
            'next_or_number'   => 'next',
            'separator'        => ' ',
            'nextpagelink'     => __( 'Следующая страница' ),
            'eog'              => '<a href="http://127.0.0.1:10080/wordpress/">',
            'previouspagelink' => __( 'Предыдущая страница' ),
            'pagelink'         => '%',
            'echo'             => 1,
        );

        $params = wp_parse_args( $args, $defaults );

        /**
         * Фильтрует аргументы, используемые при получении ссылок на страницы для постов с разбивкой на страницы.
         *
         * @since 3.0.0
         *
         * @param array $params Массив аргументов для ссылок на страницы постов с разбивкой на страницы.
         */
        $r = apply_filters( 'wp_link_pages_args', $params );

        $output = '';
        if ( $multipage ) {
            if ( 'number' == $r['next_or_number'] ) {
                $output .= $r['before'];
                for ( $i = 1; $i <= $numpages; $i++ ) {
                    $link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'];
                    if ( $i != $page || ! $more && 1 == $page ) {
                        $link = _wp_link_page( $i ) . $link . '</a>';
                    } elseif ( $i === $page ) {
                        $link = '<span class="post-page-numbers current" aria-current="' . esc_attr( $r['aria_current'] ) . '">' . $link . '</span>';
                    }
                    /**
                     * Фильтрует HTML вывод отдельных ссылок с номерами страниц.
                     *
                     * @since 3.6.0
                     *
                     * @param string $link HTML вывод номера страницы.
                     * @param int    $i    Номер страницы для ссылок на страницы постов с разбивкой на страницы.
                     */
                    $link = apply_filters( 'wp_link_pages_link', $link, $i );

                    // Используем пользовательский разделитель ссылок, начиная со второй ссылки.
                    $output .= ( 1 === $i ) ? ' ' : $r['separator'];
                    $output .= $link;
                }
                $output .= $r['after'];
            } elseif ( $more ) {
                $output .= $r['before'];
                $prev    = $page - 1;

                $next = $page + 1;
                if ( $next <= $numpages ) {
                    if ( $prev ) {
                        $output .= $r['separator'];
                    }
                    $link = _wp_link_page( $next ) . $r['link_before'] . $r['nextpagelink'] . $r['link_after'] . '</a>';

                    /** Этот фильтр документирован в wp-includes/post-template.php */
                    $output .= apply_filters( 'wp_link_pages_link', $link, $next );
                }           elseif ( $next  = $numpages ) {
                $link = _wp_link_page( $next ) . $r['eog'] . $r['nextpagelink'] . $r['link_after'] . '</a>';
                }


                $output .= $r['after'];
            }
        }

        /**
         * Фильтрует HTML вывод ссылок на страницы для постов с разбивкой на страницы.
         *
         * @since 3.6.0
         *
         * @param string $output HTML вывод ссылок на страницы постов с разбивкой на страницы.
         * @param array  $args   Массив аргументов.
         */
        $html = apply_filters( 'wp_link_pages', $output, $args );

        if ( $r['echo'] ) {
            echo $html;
        }
        return $html;
    }

    /**
     * Заменяет [nextpage] на <!--nextpage--> через фильтр 'the_posts'.
     *
     * @see http://wordpress.stackexchange.com/a/183980/26350
     */

    ! is_admin() && add_filter( 'the_posts', function( $posts )
    {
        $posts = array_map( function( $p )
        {
            if ( false !== strpos( $p->post_content, '[pagebreak]' ) )
                $p->post_content = str_replace( '[pagebreak]', '<!--nextpage-->', $p->post_content ); 
            return $p;
        }, $posts );
        return $posts;
    });
    //**РАЗДЕЛ PAGEBREAK - КОНЕЦ**//

Я проверил список куки в браузере, и, по-видимому, это действительно устанавливает куки content со значением multipage.

Однако, похоже, что куки устанавливается независимо от наличия URL параметра.

И когда я перехожу на следующую страницу, макет сбрасывается на одностраничный, поэтому я предполагаю, что сайт не читает куки.

Возможно ли сохранить ?content=multipage в куки, чтобы сайт становился multipage для этого пользователя, или параметр ?content=multipage должен передаваться со страницы на страницу?

2
Комментарии

Cookies — не лучший выбор в данном случае. Это означает, что вы не сможете использовать кеширование, так как PHP должен выполняться для оценки cookie и генерации страницы для каждого пользователя. Лучшим решением будет либо добавление параметра запроса к ссылкам пагинации, как вы уже пробовали, либо использование URL пагинации для установки режима multipage для записи. Если вы сможете предоставить код, который использует параметр URL для перевода страницы в режим multipage, будет проще помочь.

Jacob Peattie Jacob Peattie
7 авг. 2019 г. 11:26:34

Спасибо! Возможно, я ошибаюсь, но одна проблема, которую я вижу в вашем решении, заключается в том, что если пользователь перейдет к другой записи, она не будет в режиме multipage, потому что только кнопка nextpage для записи X будет содержать параметр URL, и он не будет передан для записи Y. Есть ли способ обойти это, чтобы хотя бы на оставшуюся часть сессии все записи были в режиме multipage?

Discover Discover
7 авг. 2019 г. 19:29:08
Все ответы на вопрос 1
2

Я согласен, что передача строки запроса с одной страницы на другую является наиболее надежным решением, и вы можете, например, использовать фильтры такие как post_link и term_link, чтобы добавить строку запроса content к ссылкам записей/категорий.

Однако, это требует подключения к различным фильтрам, как вы можете увидеть здесь. Кроме того, URL-адреса с многостраничной навигацией, такие как example.com/page/2?content=multipage, не будут работать без дополнительного кодирования.

Поэтому, вероятно, будет лучше/проще для вас хранить статус многостраничности в cookies браузера, как вы и пытались сделать — проблема в вашем коде заключается в том, что вы только устанавливаете cookie, но нигде не считываете его. Вы можете использовать $_COOKIE['content'] для чтения значения cookie, как показано в примере ниже.

Код/Решение

Для начала удалите это из вашего кода:

//**IF Statement that should set the cookie**//
if ( empty( $_GET['content'] ) || "multipage" !== $_GET['content'] ) {
    //**Only removes onepage() when content=multipage**//
    add_action('wp','onepage');
    setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
}

И добавьте следующий код после //**PAGEBREAK SECTION - END**// в вашем коде:

add_action( 'init', 'set_check_content_cookie', 0 );
function set_check_content_cookie() {
    if ( is_admin() ) {
        return;
    }

    $is_multipage = false;
    // Если строка запроса "content" не установлена, проверяем, равно ли значение cookie "content" точно "multipage".
    if ( ! isset( $_GET['content'] ) && isset( $_COOKIE['content'] ) && 'multipage' === $_COOKIE['content'] ) {
        $is_multipage = true;
    }
    // Если строка запроса "content" установлена и её значение равно "multipage", устанавливаем cookie.
    elseif ( isset( $_GET['content'] ) && 'multipage' === $_GET['content'] ) {
        setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
        $is_multipage = true;
    }

    // Подключаем onepage() к `wp`, если необходимо.
    if ( ! $is_multipage ) {
        add_action( 'wp', 'onepage' );
    }
}

Примечание: Следует помнить, что использование этого решения подразумевает, что cookies должны быть включены в браузере (т.е. поддерживаться и приняты пользователем).

10 авг. 2019 г. 14:49:37
Комментарии

Надеюсь, вы не против, что я переопубликовал ответ как новый ответ, и дайте мне знать, как всё пройдёт. :)

Sally CJ Sally CJ
10 авг. 2019 г. 14:53:19

Потрясающе! Работает замечательно!

Discover Discover
11 авг. 2019 г. 02:34:56