Массовая переписывание слагов сообщений на основе значения настраиваемого поля в Wordpress

По сути, у меня есть настройка пользовательского типа сообщений под названием «Части», в которой сейчас более 5000 сообщений. С каждой деталью связано несколько настраиваемых полей, включая «номер детали». В настоящее время URL для каждой части:

http://site.com/parts/name-of-part/

Что я предпочел бы иметь:

http://site.com/parts/XXXX-608-AB/ ( Это номер детали, сохраненный как настраиваемое поле «partno».)

Я считаю, что мне нужно сделать две вещи:

1) Создайте скрипт для массового редактирования всех слагов для каждой существующей части на основе настраиваемого поля «partno».

2) Подключитесь к функции Wordpress, чтобы она всегда создавала ярлык для новых частей на основе настраиваемого поля «partno».

Кто-нибудь знает, как выполнить один или оба из этих аспектов?

ОБНОВЛЕНИЕ: ниже приведен код, который я использовал для изменения существующих сообщений

// Set max posts per query
$max = 500;
$total = 5000; 

for($i=0;$i<=$total;$i+=$max) {

$parts = get_posts(array('post_type' => 'parts', 'numberposts' => $max, 'offset' => $i));

    // loop through every part
    foreach ( $parts as $part ) {

    // get part number
    $partno = get_post_meta( $part->ID, 'partno', true );   

    $updated_post = array();
    $updated_post['ID'] = $part->ID;
    $updated_post['post_name'] = $partno;
    wp_update_post( $updated_post ); // update existing posts
    echo $part->ID;
    }
}

ОБНОВЛЕНИЕ: Ниже приведен код, который я использовал в functions.php для изменения текущих сообщений (частично благодаря https://wordpress.stackexchange.com/questions/51363/how-to-avoid-infinite-loop-in-save-post-callback)

add_action('save_post', 'my_custom_slug');
function my_custom_slug($post_id) {
     //Check it's not an auto save routine
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
        return;

 //Perform permission checks! For example:
    if ( !current_user_can('edit_post', $post_id) ) 
        return; 

    //If calling wp_update_post, unhook this function so it doesn't loop infinitely
    remove_action('save_post', 'my_custom_slug');

    //call wp_update_post update, which calls save_post again. E.g:
if($partno != '')
        wp_update_post(array('ID' => $post_id, 'post_name' =>get_post_meta($post_id,'partno',true)));

    // re-hook this function
    add_action('save_post', 'my_custom_slug');
}

person Trevor Gehman    schedule 30.07.2012    source источник


Ответы (1)


1) Создайте новую страницу и назначьте ей новый шаблон страницы, скажем, site.com/update и update.php. Внутри update.php напишите вам массовый механизм:

<?php // grab all your posts
$parts = get_posts(array('post_type' => 'parts', 'numberposts' => -1,))

// loop through every part
foreach ( $parts as $part ) {

    // get part number
    $partno = get_post_meta( $part->ID, 'parto', true );

    $updated_post = array();
    $updated_post['ID'] = $part->ID;
    $updated_post['post_name'] = $partno;
    wp_update_post( $updated_post ); // update existing posts

} ?>

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

Далее функция для изменения слага каждого вновь созданного поста:

<?php function change_default_slug($id) {

    // get part number
    $partno = get_post_meta( $id, 'parto', true );
    $post_to_update = get_post( $id );

    // prevent empty slug, running at every post_type and infinite loop
    if ( $partno == '' || $post_to_update['post_type'] != 'parts' || $post_to_update['post_name'] == $partno )
        return;

    $updated_post = array();
    $updated_post['ID'] = $id;
    $updated_post['post_name'] = $partno;
    wp_update_post( $updated_post ); // update newly created post

}
add_action('save_post', 'change_default_slug'); ?>

Приведенный выше код запускается каждый раз, когда сообщение сохраняется (например, при публикации в первый раз) и устанавливает новое имя сообщения в номер части.

person Jan Beck    schedule 01.08.2012
comment
Это выглядит великолепно! Сейчас попробую реализовать. Еще один вопрос: есть ли способ предотвратить случайное дублирование? Например, что произойдет, если номер детали будет одинаковым для двух деталей? Я предполагаю, что wp_update_post не принимает это во внимание. - person Trevor Gehman; 02.08.2012
comment
Хорошо, я узнал ответ, что wp_update_post действительно учитывает это. Он проверит post_name на наличие дубликатов. - person Trevor Gehman; 02.08.2012