¿Cómo generar/actualizar un sitemap XML sin plugins?

20 abr 2011, 17:40:19
Vistas: 24K
Votos: 4

Me gusta programar todo manualmente en mis sitios WordPress, sin usar ningún plugin. ¿Hay alguna manera de generar o actualizar mi sitemap cada vez que publico/actualizo una entrada en uno de mis blogs de Multisite, sin usar plugins?

4
Comentarios

¿Te das cuenta de que no hay una diferencia real entre "hardcode" y un plugin, aparte del hecho de que los plugins son portables y por lo tanto más fáciles de trabajar?

Wyck Wyck
20 ene 2012 20:53:51

Voto negativo por la restricción de "sin un Plugin".

Chip Bennett Chip Bennett
20 feb 2012 19:47:49

No querer agregar OTRO plugin en un sitio de CLIENTE es perfectamente aceptable para una tarea tan simple. Es cierto que el código es el mismo, pero quizás el OP no lo sabía

JasonDavis JasonDavis
23 may 2013 06:45:45

como dijo chip, es una pregunta sin sentido, además, hacer un código de mapa del sitio que no rompa el sitio cuando se genera, no es trivial y una buena respuesta no encajaría en el formato del sitio

Mark Kaplun Mark Kaplun
25 may 2017 10:10:48
Todas las respuestas a la pregunta 5
0

El siguiente código funciona inmediatamente. Tu mapa del sitio aparecerá en: https://your-website-name.com/sitemap.xml

Cada vez que crees o actualices una página, entrada o tipo de contenido personalizado, se mostrará. Asegúrate de añadir el nombre de tu tipo de contenido personalizado:

add_action( 'publish_post', 'ow_create_sitemap' );
add_action( 'publish_page', 'ow_create_sitemap' );
add_action( 'save_post',    'ow_create_sitemap' );

function ow_create_sitemap() {
    $postsForSitemap = get_posts(array(
        'numberposts' => -1,
        'orderby'     => 'modified',
        // 'custom_post' debe ser reemplazado con tu propio Tipo de Contenido Personalizado (uno o varios)
        'post_type'   => array( 'post', 'page', 'custom_post' ),
        'order'       => 'DESC'
    ));

    $sitemap = '<?xml version="1.0" encoding="UTF-8"?>';
    $sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';

    foreach( $postsForSitemap as $post ) {
        setup_postdata( $post );

        $postdate = explode( " ", $post->post_modified );

        $sitemap .= '<url>'.
                    '<loc>' . get_permalink( $post->ID ) . '</loc>' .
                    '<lastmod>' . $postdate[0] . '</lastmod>' .
                    '<changefreq>monthly</changefreq>' .
                    '</url>';
      }

    $sitemap .= '</urlset>';

    $fp = fopen( ABSPATH . 'sitemap.xml', 'w' );

    fwrite( $fp, $sitemap );
    fclose( $fp );
}
3 ene 2019 06:18:53
4

No estoy seguro si esto funciona en multisitio, pero en una instalación única de WordPress funciona perfectamente para mí.

Cuando creas o actualizas cualquier entrada o página, generará un archivo sitemap.xml y actualizará los enlaces (URLs) con los más recientes primero (última modificación).

Copia y pega el siguiente código en el archivo functions.php de tu tema activo:

/* Función para crear el archivo sitemap.xml en el directorio raíz del sitio */        
// add_action("publish_post", "eg_create_sitemap");
// add_action("publish_page", "eg_create_sitemap");  
add_action( "save_post", "eg_create_sitemap" );   
function eg_create_sitemap() {
    $postsForSitemap = get_posts( array(
        'numberposts' => -1,
        'orderby'     => 'modified',
        'post_type'   => array( 'post', 'page' ),
        'order'       => 'DESC'
    ) );
    $sitemap = '<?xml version="1.0" encoding="UTF-8"?>';
    $sitemap .= "\n" . '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";    
    foreach( $postsForSitemap as $post ) {
        setup_postdata( $post );   
        $postdate = explode( " ", $post->post_modified );   
        $sitemap .= "\t" . '<url>' . "\n" .
            "\t\t" . '<loc>' . get_permalink( $post->ID ) . '</loc>' .
            "\n\t\t" . '<lastmod>' . $postdate[0] . '</lastmod>' .
            "\n\t\t" . '<changefreq>monthly</changefreq>' .
            "\n\t" . '</url>' . "\n";
    }     
    $sitemap .= '</urlset>';     
    $fp = fopen( ABSPATH . "sitemap.xml", 'w' );
    fwrite( $fp, $sitemap );
    fclose( $fp );
}
19 dic 2011 12:39:02
Comentarios

No creo que eso funcione en multisitio: está escribiendo sitemap.xml en la misma ubicación de archivo en el servidor, por lo que solo habría 1 archivo sitemap.xml real que se sobrescribiría cada vez que algún blog haga un cambio...

Sators Sators
19 may 2017 21:50:11

Consultar todas las publicaciones del sitio en cada guardado es una forma segura de colapsar un sitio que tiene una cantidad no trivial de contenido. Además, hará que guardar nuevas publicaciones sea cada vez más lento con cada publicación publicada

Mark Kaplun Mark Kaplun
25 may 2017 10:14:13

@MarkKaplun - ¿Qué recomendarías como alternativa a consultar todas las publicaciones?

Motivated Motivated
8 sept 2022 11:37:24

@Motivated no lo sé, depende de lo que necesites hacer. (los mapas del sitio son parte del núcleo desde la versión 5.2, así que al menos esta respuesta no es relevante para este caso de uso específico)

Mark Kaplun Mark Kaplun
8 sept 2022 16:14:04
2

Antes de utilizar el código proporcionado en la respuesta de w3uiguru, tuve que hacer algunas mejoras que siguen el estándar aceptado para archivos XML. El código está a continuación:

/* función para crear el archivo sitemap.xml en el directorio raíz del sitio */
// add_action("publish_post", "eg_create_sitemap");
// add_action("publish_page", "eg_create_sitemap");
add_action( "save_post", "eg_create_sitemap" );
function eg_create_sitemap() {
    if ( str_replace( '-', '', get_option( 'gmt_offset' ) ) < 10 ) { 
        $tempo = '-0' . str_replace( '-', '', get_option( 'gmt_offset' ) ); 
    } else { 
        $tempo = get_option( 'gmt_offset' ); 
    }
    if( strlen( $tempo ) == 3 ) { $tempo = $tempo . ':00'; }
    $postsForSitemap = get_posts( array(
        'numberposts' => -1,
        'orderby'     => 'modified',
        'post_type'   => array( 'post', 'page' ),
        'order'       => 'DESC'
    ) );
    $sitemap .= '<?xml version="1.0" encoding="UTF-8"?>' . '<?xml-stylesheet type="text/xsl" href="' . 
        esc_url( home_url( '/' ) ) . 'sitemap.xsl"?>';
    $sitemap .= "\n" . '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
    $sitemap .= "\t" . '<url>' . "\n" .
        "\t\t" . '<loc>' . esc_url( home_url( '/' ) ) . '</loc>' .
        "\n\t\t" . '<lastmod>' . date( "Y-m-d\TH:i:s", current_time( 'timestamp', 0 ) ) . $tempo . '</lastmod>' .
        "\n\t\t" . '<changefreq>daily</changefreq>' .
        "\n\t\t" . '<priority>1.0</priority>' .
        "\n\t" . '</url>' . "\n";
    foreach( $postsForSitemap as $post ) {
        setup_postdata( $post);
        $postdate = explode( " ", $post->post_modified );
        $sitemap .= "\t" . '<url>' . "\n" .
            "\t\t" . '<loc>' . get_permalink( $post->ID ) . '</loc>' .
            "\n\t\t" . '<lastmod>' . $postdate[0] . 'T' . $postdate[1] . $tempo . '</lastmod>' .
            "\n\t\t" . '<changefreq>Weekly</changefreq>' .
            "\n\t\t" . '<priority>0.5</priority>' .
            "\n\t" . '</url>' . "\n";
    }
    $sitemap .= '</urlset>';
    $fp = fopen( ABSPATH . "sitemap.xml", 'w' );
    fwrite( $fp, $sitemap );
    fclose( $fp );
}
23 jun 2014 01:01:39
Comentarios

¿Podrías explicar tu código y presentar una [edición] para reformatearlo y mejorar su legibilidad? Gracias

kaiser kaiser
23 jun 2014 03:10:50

@locutor-antonio-cezar @gabriel Necesitan cambiar Weekly por weekly debido a Error 1840: Element '{http://www.sitemaps.org/schemas/sitemap/0.9}changefreq': [facet 'enumeration'] The value 'Weekly' is not an element of the set {'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'}.

Iurie Iurie
8 ago 2015 00:28:27
0

WordPress incluye una función de mapa del sitio XML desde la versión 5.5 que puedes personalizar.

Consulta esta entrada de blog para obtener más detalles y algunos ejemplos rápidos. Echa un vistazo aquí para ver una lista de hooks que puedes utilizar para personalizar el mapa del sitio predeterminado.

10 may 2024 02:30:25
1

Modifiqué un poco el código de @locutor-antonio-cezar ya que estaba buscando un caso de uso muy específico. Necesitaba un sitemap especialmente escrito para Google News. ¿Qué tiene de diferente? Todo el marcado sigue las reglas. En mi caso específico, limité el número de publicaciones a 20. Además, las publicaciones con más de 2 días desaparecen. Tal vez alguien necesite esto:

/* función para crear el archivo sitemap.xml en el directorio raíz del sitio */
// add_action("publish_post", "eg_create_sitemap");
// add_action("publish_page", "eg_create_sitemap");
add_action( "save_post", "eg_create_sitemap" );
function eg_create_sitemap() {
    if ( str_replace( '-', '', get_option( 'gmt_offset' ) ) < 10 ) { 
        $tempo = '-0' . str_replace( '-', '', get_option( 'gmt_offset' ) ); 
    } else { 
        $tempo = get_option( 'gmt_offset' ); 
    }
    if( strlen( $tempo ) == 3 ) { $tempo = $tempo . ':00'; }
    $postsForSitemap = get_posts( array(
        'numberposts' => 20,
        'orderby'     => 'modified',
        'post_type'   => array( 'post', 'page' ),
        'order'       => 'DESC',
        'date_query' => array(
            'after' => date('Y-m-d', strtotime('-2 days')) 
        )
    ) );
    $sitemap .= '<?xml version="1.0" encoding="UTF-8"?>';
    $sitemap .= "\n" . '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">' . "\n";
    foreach( $postsForSitemap as $post ) {
        setup_postdata( $post);
        $postdate = explode( " ", $post->post_modified );
        $sitemap .= "\t" . "<url>" . "\n";
        $sitemap .= "\t\t" . "<loc>" . get_permalink( $post->ID ) . '</loc>';
        $sitemap .= "\t\t" . '<news:news>' . "\n";
        $sitemap .= "\t\t\t" . '<news:publication>' . "\n";
        $sitemap .= "\t\t\t\t" . '<news:name><![CDATA[ TU SITIO ]]></news:name>' . "\n";
        $sitemap .= "\t\t\t\t" . '<news:language>TU IDIOMA</news:language>' . "\n";
        $sitemap .= "\t\t\t" . '</news:publication>' . "\n";
        $sitemap .= "\t\t\t<news:publication_date>" . $postdate[0] . 'T' . $postdate[1] . $tempo . "</news:publication_date>\n";
        $sitemap .= "\t\t\t" . '<news:title><![CDATA[' . get_the_title( $post) . ']]></news:title>' . "\n";
        $sitemap .= "\t\t" . '</news:news>' . "\n";
        $sitemap .= "\t" . '</url>' . "\n";
    }
    $sitemap .= '</urlset>';
    $fp = fopen( ABSPATH . "sitemap_news.xml", 'w' );
    fwrite( $fp, $sitemap );
    fclose( $fp );
}
7 ago 2020 17:07:57
Comentarios

¿Qué pasa si necesitas generar una salida para todas las publicaciones? Limitar a 20 no escala. ¿Qué opciones alternativas existen?

Motivated Motivated
8 sept 2022 11:39:48