Регенерировать слизняков из заголовков постов

14

Можно ли программно регенерировать слизняков после изменения заголовков поста? Многочисленные заголовки постов были обновлены, а слаг не был обновлен с заголовком, поэтому мне нужно регенерировать все эти слагы.

Никола Пелучетти
источник
Мне приходилось делать это несколько раз, и я обнаружил, что между различными серверными средами, где он не может обрабатывать большие массивы (с неограниченным числом столбцов) и не вызывать многократно wp_update_post с большим потреблением памяти, которое разбивает его на вызов WP_Query с разбиением на страницы и использует $ wpdb, чтобы он был более управляемым и производительным. Я предоставил пример кода в аналогичном посте .
codearachnid

Ответы:

17

Да, это возможно.

Пример кода, должен быть протестирован и уточнен:

// get all posts
$posts = get_posts( array (  'numberposts' => -1 ) );

foreach ( $posts as $post )
{
    // check the slug and run an update if necessary 
    $new_slug = sanitize_title( $post->post_title );
    if ( $post->post_name != $new_slug )
    {
        wp_update_post(
            array (
                'ID'        => $post->ID,
                'post_name' => $new_slug
            )
        );
    }
}

Я только что сделал это, возможно, есть некоторые ошибки и случаи egde, но это должно дать вам представление. Кроме того, это может занять некоторое время, поэтому может быть полезно разбить обновление на более мелкие фрагменты.

Фуксия
источник
1
Хм ... из моего опыта, это не работает. post_nameАргумент игнорируется wp_update_post, по крайней мере , в версии ядра 3.9
Alexandre Bourlier
В настоящее время post_nameигнорируется в wp_update_post()функции, но это учитывается, когда сообщение обновления вызывает wp_insert_post()функцию: это означает, что передача нового слага в обновление приведет к его эффективному изменению для обновляемого сообщения.
Эренор Пас
2

Этот плагин также делает свою работу: http://www.jerrytravis.com/598/wordpress-plugin-to-generate-post-slugs

Однако, поскольку он делает это только для постов, у которых еще нет слагов, если вам нужно регенерировать слагов, отредактируйте следующую строку в плагине:

if ($post->post_name == "") {

например, вы можете изменить его на:

if (true) {

Лессан Ваэзи
источник
1

Я пробовал метод, предложенный Toscho, который является «инстинктивным», но во многих случаях он не работает (см. Основной код, чтобы получить то, что я имею в виду под «многими случаями»).

Просматривая код, я обнаружил wp_insert_post_dataловушку фильтра, вызываемую wp_update_postфункцией непосредственно перед вставкой записи в базу данных.

Вызвав этот фильтр и изменив значение $data['post_name'], я смог заставить его работать правильно. Wordpress - это круто, но так плохо документировано ...

Я отредактировал документацию , чтобы больше людей могли найти этот обходной путь, если это необходимо.

Александр Бурлье
источник
Можете ли вы указать, почему wp_update_post перезаписывает post_name? единственная причина, по которой я это вижу, заключается в том, что пользователь, пытающийся изменить post_name, является только соавтором (или того же уровня), и в этом случае он не должен позволять этому пользователю изменять слаг, вы находили какие-либо другие случаи, когда post_name перезаписывается?
jnhghy - Александру Jantea
Да, это правильный способ сделать это. Спасибо @Alexandre
user88731
-1

Вы можете сделать это непосредственно в MySQL, если вам нужно. (наш сайт woocommerce имеет сотни тысяч продуктов):

update wp_posts set post_name = concat(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(lower(post_title), '"', ''), "'", ''), ",", '-'), " ", '-'), "&", ''), ";", ''), "@", ''), ".", ''), ":", ''), "/", ''), "+", ''), "(", ''), ")", ''), "--", '-'), "---", '-'), "--", '-'), "--", '-'), '-', id) where post_type = 'product';

где post_type = 'product' - это будет обновлять только продукты woocommerce; Вы должны выяснить, какие ограничения вы хотите сохранить в этом запросе.

iateadonut
источник