Как создать/обновить XML карту сайта без плагинов?

20 апр. 2011 г., 17:40:19
Просмотры: 24K
Голосов: 4

Я предпочитаю жестко кодировать все на моих WordPress сайтах без использования плагинов. Есть ли способ генерировать или обновлять карту сайта каждый раз, когда я публикую/обновляю запись на одном из моих блогов Multisite, не используя плагины?

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

Вы понимаете, что нет реальной разницы между "хардкодом" и плагином, за исключением того, что плагины портативны и с ними проще работать?

Wyck Wyck
20 янв. 2012 г. 20:53:51

Минус за ограничение "без плагина".

Chip Bennett Chip Bennett
20 февр. 2012 г. 19:47:49

Нежелание добавлять ЕЩЁ ОДИН плагин на сайт КЛИЕНТА для такой простой задачи вполне допустимо. Код действительно одинаков, но, возможно, автор вопроса этого не знал.

JasonDavis JasonDavis
23 мая 2013 г. 06:45:45

как сказал chip, это бессмысленный вопрос, кроме того, написать код карты сайта, который не сломает сайт при генерации, нетривиально, и хороший ответ не вписывается в формат сайта

Mark Kaplun Mark Kaplun
25 мая 2017 г. 10:10:48
Все ответы на вопрос 5
0

Следующий код работает сразу после установки. Ваша карта сайта будет доступна по адресу: https://your-website-name.com/sitemap.xml

Каждый раз при создании или обновлении страницы, записи или пользовательского типа записи она будет обновляться. Убедитесь, что вы указали название вашего пользовательского типа записи:

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' следует заменить на ваш собственный Пользовательский Тип Записи (один или несколько)
        '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 янв. 2019 г. 06:18:53
4

Я не знаю, работает ли это на мультисайтах, но в одиночной установке WordPress у меня это работает идеально.

Когда вы создаёте/обновляете записи или страницы, это генерирует файл sitemap.xml и обновляет ссылки (URL), располагая самые свежие первыми (последние изменённые).

Скопируйте и вставьте приведённый ниже код в файл functions.php вашей активной темы:

/* Функция для создания файла sitemap.xml в корневой директории сайта */        
// 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 дек. 2011 г. 12:39:02
Комментарии

Я не думаю, что это будет работать на мультисайте - он записывает sitemap.xml в то же самое расположение файла на сервере, так что будет только один фактический файл sitemap.xml, который будет перезаписываться каждый раз, когда какой-либо блог вносит изменения...

Sators Sators
19 мая 2017 г. 21:50:11

Запрос всех записей на сайте при каждом сохранении - верный способ обрушить сайт, который имеет нетривиальное количество контента. Кроме того, это будет делать сохранение новых записей всё медленнее и медленнее с каждой опубликованной записью.

Mark Kaplun Mark Kaplun
25 мая 2017 г. 10:14:13

@MarkKaplun - Что бы вы порекомендовали в качестве альтернативы запросу всех записей?

Motivated Motivated
8 сент. 2022 г. 11:37:24

@Motivated не знаю, зависит от того, что именно вам нужно сделать. (карты сайта являются частью ядра с версии 5.2, так что этот ответ по крайней мере не относится к данному конкретному случаю)

Mark Kaplun Mark Kaplun
8 сент. 2022 г. 16:14:04
2

Перед использованием кода, предоставленного в ответе w3uiguru, мне пришлось внести некоторые улучшения, соответствующие общепринятым стандартам для XML-файлов. Код приведен ниже:

/* функция для создания файла sitemap.xml в корневой директории сайта */
// 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 июн. 2014 г. 01:01:39
Комментарии

Не могли бы вы объяснить ваш код и отправить [правку] для улучшения его читаемости? Спасибо

kaiser kaiser
23 июн. 2014 г. 03:10:50

@locutor-antonio-cezar @gabriel Вам нужно изменить Weekly на weekly из-за 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 авг. 2015 г. 00:28:27
0

Начиная с версии 5.5, WordPress имеет встроенную функцию XML-карты сайта, которую можно настраивать.

Подробности и несколько быстрых примеров можно найти в этой записи блога. Ознакомьтесь здесь со списком хуков, которые можно использовать для настройки стандартной карты сайта.

10 мая 2024 г. 02:30:25
1

Я немного изменил код от @locutor-antonio-cezar, так как мне нужен был очень специфический вариант использования. Мне требовалась карта сайта, специально адаптированная для Google News. В чем отличие? Вся разметка соответствует правилам. В моем конкретном случае я ограничил количество записей до 20. Также записи старше 2 дней исчезают из карты сайта. Возможно, кому-то это пригодится:

/* функция для создания файла sitemap.xml в корневой директории сайта */
// 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[ ВАШ САЙТ ]]></news:name>' . "\n";
        $sitemap .= "\t\t\t\t" . '<news:language>ВАШ ЯЗЫК</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 авг. 2020 г. 17:07:57
Комментарии

Что делать, если нужно сгенерировать вывод для всех записей? Ограничение в 20 не масштабируется. Какие есть альтернативные варианты?

Motivated Motivated
8 сент. 2022 г. 11:39:48