Configurar una cookie para parámetro URL y pasarla entre páginas para modificar posts

7 ago 2019, 09:33:37
Vistas: 14.9K
Votos: 0

Tengo una función que convierte el post en multipágina basado en un parámetro URL con un valor específico:

?content=multipage

El problema es que cuando un usuario hace clic en la siguiente página, el parámetro URL desaparece y el post vuelve al formato de una sola página.

Si agrego manualmente el parámetro URL a la siguiente página, el post se muestra como multipágina

Según mi investigación, la mejor solución es establecer una cookie cuando:

?content=multipage

Así este parámetro URL se mantendrá entre páginas sin ser visible en la barra de direcciones.

Probé varios métodos para establecer cookies, encontré la función setcookie() que aparentemente debería funcionar.

Este es mi avance:

    function onepage() {
    //**Elimina shortcodes**//
    function remove_shotcode($content) {
        return str_replace('[/shortcode1]', '', $content);    
        return str_replace('[shortcode2]', '', $content);
    }
    add_filter( 'the_content', 'remove_shotcode'); 

/*
*Elimina <!--nextpage-->
*@see http://wordpress.stackexchange.com/a/183587/26350
*/

    add_action( 'the_post', function( $post )
    {
        if ( false !== strpos( $post->post_content, '<!--nextpage-->' ) ) 
        {
            // Reinicia la variable global $pages:
            $GLOBALS['pages']     = [ $post->post_content ];

            // Reinicia la variable global $numpages:
            $GLOBALS['numpages']  = 0;

           // Reinicia la variable global $multipage:
            $GLOBALS['multipage'] = false;
        }

    });
    }

    //**IF que debería establecer la cookie**//
    if ( empty( $_GET['content'] ) || "multipage" !== $_GET['content'] ) {
        //**Solo elimina onepage() cuando content=multipage**//
        add_action('wp','onepage');
        //**Debería establecer cookie solo cuando content=multipage**//
        setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
    }

El código que convierte el post en multipágina es este:


    //**SECCIÓN PAGEBREAK - INICIO**//
    function pagebreak( $args = '' ) {
        global $page, $numpages, $multipage, $more;

        $defaults = array(
            'before'           => '<p class="post-nav-links">' . __( 'Páginas:' ),
            'after'            => '</p>',
            'link_before'      => '',
            'link_after'       => '',
            'aria_current'     => 'page',
            'next_or_number'   => 'next',
            'separator'        => ' ',
            'nextpagelink'     => __( 'Siguiente página' ),
            'eog'              => '<a href="http://127.0.0.1:10080/wordpress/">',
            'previouspagelink' => __( 'Página anterior' ),
            'pagelink'         => '%',
            'echo'             => 1,
        );

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

        /**
         * Filtra los argumentos usados para los enlaces de páginas en posts paginados.
         *
         * @since 3.0.0
         *
         * @param array $params Array de argumentos para enlaces de páginas.
         */
        $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>';
                    }
                    /**
                     * Filtra el HTML de enlaces individuales de páginas.
                     *
                     * @since 3.6.0
                     *
                     * @param string $link HTML del enlace de página.
                     * @param int    $i    Número de página.
                     */
                    $link = apply_filters( 'wp_link_pages_link', $link, $i );

                    // Usa el separador personalizado desde el segundo enlace
                    $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>';

                    /** Este filtro está documentado en 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'];
            }
        }

        /**
         * Filtra el HTML de los enlaces de páginas para posts paginados.
         *
         * @since 3.6.0
         *
         * @param string $output HTML de los enlaces.
         * @param array  $args   Array de argumentos.
         */
        $html = apply_filters( 'wp_link_pages', $output, $args );

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

    /**
     * Reemplaza [nextpage] con <!--nextpage--> usando el filtro '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;
    });
    //**SECCIÓN PAGEBREAK - FIN**//

Revisé las cookies en mi navegador y aparentemente esto sí establece la cookie content con valor multipage.

Sin embargo, parece que establece la cookie sin importar si la URL tiene el parámetro o no.

Y cuando voy a la siguiente página, el diseño vuelve a una sola página, así que supongo que el sitio no lee la cookie.

¿Es posible almacenar ?content=multipage en una cookie para que el sitio sea multipage para ese usuario o el parámetro debe pasarse manualmente entre páginas?

2
Comentarios

Las cookies no son una buena opción aquí. Significa que no puedes usar caché porque PHP necesita ejecutarse para evaluar la cookie y generar la página para cada usuario. La mejor solución sería agregar el parámetro de consulta a los enlaces de paginación, como ya has intentado, o usar la URL de paginación para también establecer el post en modo multipage. Si puedes incluir el código que usas para hacer que la página sea multipage usando el parámetro de URL, será más fácil ayudar.

Jacob Peattie Jacob Peattie
7 ago 2019 11:26:34

¡Gracias! Podría estar equivocado, pero el único problema que veo con tu solución es que si un usuario elige ir a otra publicación, ya no será multipage porque solo el botón nextpage de la publicación X tendrá el parámetro de URL y no se pasará a la publicación Y. ¿Hay alguna manera de evitar eso para que al menos por el resto de la sesión todas las publicaciones sean multipage?

Discover Discover
7 ago 2019 19:29:08
Todas las respuestas a la pregunta 1
2

Estoy de acuerdo en que pasar la cadena de consulta de una página a otra es la solución más confiable, y puedes, por ejemplo, usar filtros como post_link y term_link para añadir la cadena de consulta content a los enlaces de entradas/categorías.

Sin embargo, requiere enganchar varios filtros como puedes ver aquí. Además, las URLs multipágina como example.com/page/2?content=multipage no funcionarán sin código adicional.

Así que probablemente sea mejor/más fácil para ti almacenar el estado multipágina en las cookies del navegador, justo como lo has intentado — el problema en tu código es que solo estás configurando la cookie, pero en ningún lado la estás leyendo. Y puedes usar $_COOKIE['content'] para leer el valor de la cookie, como puedes ver en el ejemplo a continuación.

El Código/Solución

Primero, elimina esto de tu código:

//**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 );
}

Y añade este código después de //**PAGEBREAK SECTION - END**// en tu código:

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

    $is_multipage = false;
    // Si la cadena de consulta "content" no está configurada, verifica si el valor de la cookie "content" es exactamente "multipage".
    if ( ! isset( $_GET['content'] ) && isset( $_COOKIE['content'] ) && 'multipage' === $_COOKIE['content'] ) {
        $is_multipage = true;
    }
    // Si la cadena de consulta "content" está configurada y su valor es "multipage", establece la cookie.
    elseif ( isset( $_GET['content'] ) && 'multipage' === $_GET['content'] ) {
        setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
        $is_multipage = true;
    }

    // Engancha onepage() a `wp`, si aplica.
    if ( ! $is_multipage ) {
        add_action( 'wp', 'onepage' );
    }
}

Nota: Debes recordar que usar esta solución significa que las cookies deben estar habilitadas en el navegador (es decir, que sean compatibles y que el usuario acepte las cookies).

10 ago 2019 14:49:37
Comentarios

Espero que no te importe que haya vuelto a publicar la respuesta como una nueva respuesta, y avísame cómo te va. :)

Sally CJ Sally CJ
10 ago 2019 14:53:19

¡Increíble! ¡Funciona maravillosamente!

Discover Discover
11 ago 2019 02:34:56