Как безопасно изменить имя пользовательского типа сообщения?

19

Я сделал собственный тип поста под названием «портфолио», но я хочу изменить его на «проекты». Какие точные шаги мне нужно предпринять, чтобы безопасно сменить имя и предотвратить исчезновение сообщений пользовательского типа на панели инструментов?

Примечание: уже есть сообщения, portfolioпоэтому я не могу просто переключиться portfolioс projects.

/* Register Portfolio Post Type */
add_action('init', 'create_portfolio');

function create_portfolio() {

    $labels = array(
        'name' => __('Portfolio', 'post type general name'),
        'singular_name' => __('Project', 'post type singular name'),
        'add_new' => __('Add New', 'portfolio item'),
        'add_new_item' => __('Add New Project'),
        'edit_item' => __('Edit Project'),
        'new_item' => __('New Project'),
        'view_item' => __('View Project'),
        'search_items' => __('Search Projects'),
        'not_found' =>  __('Nothing found'),
        'not_found_in_trash' => __('Nothing found in Trash'),
        'parent_item_colon' => ''
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'hierarchical' => false,
        'menu_position' => null,
        'supports' => array('title','editor','thumbnail')
      ); 

    register_post_type( 'portfolio' , $args );
}

/* Register Skills Taxonomy */
register_taxonomy("Skills", array("portfolio"), array("hierarchical" => true, "label" => "Skills", "singular_label" => "Skill", "rewrite" => true));

/* Add Fields */
add_action("admin_init", "add_portfolio_fields");

function add_portfolio_fields(){
    add_meta_box("website_url", "Website URL", "website_url", "portfolio", "side", "low");
    add_meta_box("view_more", "View More", "view_more", "portfolio", "side", "low");
    add_meta_box("screenshot_name", "Screenshot Name", "screenshot_name", "portfolio", "side", "low");
    add_meta_box("thumbnail_name", "Thumbnail Name", "thumbnail_name", "portfolio", "side", "low");
    add_meta_box("thumbnail_alt", "Thumbnail Alt", "thumbnail_alt", "portfolio", "side", "low");
}

function website_url(){
    global $post;
    $custom = get_post_custom($post->ID);
    $website_url = $custom["website_url"][0];
    ?>
    <label>Website URL:</label>
    <input size="50" name="website_url" value="<?php echo $website_url; ?>" />
    <?php
}

function view_more() {
    global $post;
    $custom = get_post_custom($post->ID);
    $view_more = $custom["view_more"][0];
    ?>
    <label>View More:</label>
    <input size="50" name="view_more" value="<?php echo $view_more; ?>" />
    <?php
}

function screenshot_name() {
    global $post;
    $custom = get_post_custom($post->ID);
    $screenshot_name = $custom["screenshot_name"][0];
    ?>
    <label>Screenshot Name:</label>
    <input name="screenshot_name" value="<?php echo $screenshot_name; ?>" />
    <?php
}

function thumbnail_name() {
    global $post;
    $custom = get_post_custom($post->ID);
    $thumbnail_name = $custom["thumbnail_name"][0];
    ?>
    <label>Thumbnail Name:</label>
    <input name="thumbnail_name" value="<?php echo $thumbnail_name; ?>" />
    <?php
}

function thumbnail_alt() {
    global $post;
    $custom = get_post_custom($post->ID);
    $thumbnail_alt = $custom["thumbnail_alt"][0];
    ?>
    <label>Thumbnail Alt:</label>
    <input name="thumbnail_alt" value="<?php echo $thumbnail_alt; ?>" />
    <?php
}

add_action('save_post', 'save_portfolio_details');

function save_portfolio_details(){
    global $post;

    update_post_meta($post->ID, "website_url", $_POST["website_url"]);
    update_post_meta($post->ID, "view_more", $_POST["view_more"]);
    update_post_meta($post->ID, "screenshot_name", $_POST["screenshot_name"]);
    update_post_meta($post->ID, "thumbnail_name", $_POST["thumbnail_name"]);
    update_post_meta($post->ID, "thumbnail_alt", $_POST["thumbnail_alt"]);
}

/* Custom Columns */
add_action("manage_posts_custom_column",  "portfolio_custom_columns");
add_filter("manage_edit-portfolio_columns", "portfolio_edit_columns");

function portfolio_edit_columns($columns){
    $columns = array(
        "cb" => "<input type=\"checkbox\" />",
        "title" => "Project Title",
        "description" => "Description",
    );

    return $columns;
}

function portfolio_custom_columns($column){
    global $post;

    switch ($column) {
        case "description":
        the_excerpt();
        break;
    }
}
Дези
источник
как насчет замены только ярлыков?
Bainternet
Просто ярлыки? Я не совсем уверен, что вы имеете в виду, но я бы предпочел полностью изменить это повсюду.
Дези

Ответы:

2

Если у вас еще нет сообщений в вашем портфолио.

Это было бы действительно просто. Переименуйте все с помощью «Портфолио» в «Проекты». Вы ничего не потеряете и поменяете имя.

Редактировать :

Попробуйте использовать этот плагин http://wordpress.org/extend/plugins/ptypeconverter/, чтобы безопасно экспортировать текущие сообщения и импортировать его в свой новый тип сообщений.

Итак, шаги:

1 Загрузите и используйте плагин: http://wordpress.org/extend/plugins/ptypeconverter/

2 Скопируйте свой файл поста типа «портфолио» куда-нибудь и сохраните. назовите его, например, portfolio_post_typeBACKUP.php

3 Теперь вы уверены, что этот метод не работает. Вы можете восстановить это.

4 Измените « портфолио » на « проекты »

5 Импортируйте посты с помощью плагина и альта!

Надеюсь, это работает.

Уэсли Чунг
источник
Ах, извините, должен был упомянуть. Там уже много постов portfolio.
Дези
я отредактировал ответ. удачи!
Уэсли Чунг
Это фантастический плагин!
Realph
1
этот плагин больше не работает должным образом. Я попробовал это, и это не изменило все «старые» типы сообщений. но решение mysql (ответ от Will) работает нормально.
honk31
Плагин не обновлялся в течение двух лет.
rhand
18

Вы можете сделать это напрямую с MySQL.

UPDATE `wp_posts`
SET 
    # Update the post_type column
    `post_type` = REPLACE(`post_type`,'name_of_old_post_type','name_of_new_post_type'),
    # Update the urls
    `guid` = REPLACE(`guid`,'name_of_old_post_type','name_of_new_post_type')
WHERE `post_type` = 'name_of_old_post_type'

Следует отметить две вещи:

  1. Вам нужно будет обновить любые ссылки на этот тип поста в вашем коде (скажем, шаблоны, определения CMB2 или определения таксономии).
  2. Если вы сохранили какие-либо ссылки на этот тип записей wp_postmetaв сериализованных массивах, вы не хотите делать простое ОБНОВЛЕНИЕ / ЗАМЕНА, потому что это взорвет их! Ну, разве что строки как нового, так и старого типа записей имеют одинаковую длину.
Будет
источник
7

Расширяем ответ Уилла немного дальше ... и особенно если вы делаете это из своего плагина:

global $wpdb;
$old_post_types = array('old_type' => 'new_type');
foreach ($old_post_types as $old_type=>$type) {
    $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_type = REPLACE(post_type, %s, %s) 
                         WHERE post_type LIKE %s", $old_type, $type, $old_type ) );
    $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET guid = REPLACE(guid, %s, %s) 
                         WHERE guid LIKE %s", "post_type={$old_type}", "post_type={$type}", "%post_type={$type}%" ) );
    $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET guid = REPLACE(guid, %s, %s) 
                         WHERE guid LIKE %s", "/{$old_type}/", "/{$type}/", "%/{$old_type}/%" ) );
}

Здесь изменение заключается в том, чтобы не заменять старый тип в guid напрямую, а заменять только в том случае, если присутствует «post_type = old_type» или «/ old_type /». Это позволяет избежать замены действительных слагов по ошибке. (например, ваш пользовательский тип поста - портфолио, а в слаге страницы тоже есть портфолио)

Другая альтернатива - сделать что-то вроде этого:

global $wpdb, $wp_rewrite;
foreach ($old_post_types as $old_type=>$type) {
    $q = 'numberposts=-1&post_status=any&post_type='.$old_type;
    $items = get_posts($q);
    foreach ($items as $item) {
        $update['ID'] = $item->ID;
        $update['post_type'] = $type;
        wp_update_post( $update );
    }
}
$wp_rewrite->flush_rules();

НТН!

Нирав Мехта
источник
Благодарю. Это работает. Одна небольшая вещь: последняя часть второго запроса в цикле должна быть «% post_type = {$ old_type}%», а не «% post_type = {$ type}%».
Бетти
3

Используйте запрос к базе данных WordPress, но не забывайте о последовательных параметрах данных

Метод, который работал для меня, заключался в поиске и замене в базе данных WordPress, но при этом следил за тем, чтобы в процессе не испортились данные сериализованных опций. Лучший способ, который я нашел, - использовать утилиту безопасного поиска и замены базы данных от interconnect / it . Никогда не SETвыполняйте = REPLACE(запрос ,'old_post_type','new_post_type')типа post_type post_type, не зная, что вы делаете, или сериализованные данные прервутся, поскольку они сохраняют контрольную сумму и не смогут правильно десериализоваться.

Прочтите раздел «Возможные проблемы», прежде чем слепо следовать этому

Шаг 1 - Безопасное обновление вашей базы данных с новым именем

  1. сделайте резервную копию вашей базы данных, потому что следующие изменения могут привести к ее повреждению.
  2. скачать и разархивировать безопасный поиск и заменить утилиту базы данных от interconnect / it
  3. добавьте извлеченный каталог в ваш webroot (он также работает в подкаталогах)
  4. перейдите в каталог, например: /mywebsite.com/path/to/utility/directory/
  5. следуйте инструкциям. нажмите «пробный запуск», если вы пароноид, чтобы увидеть изменения (их будет сотни, если у вас будет даже несколько постов с измененным типом поста)
  6. нажмите «Live Run», чтобы завершить изменения.
  7. удалить каталог безопасного поиска из вашего каталога WordPress, так как это проблема безопасности

Шаг 2. Сбросьте ваши постоянные ссылки

Если вы используете постоянные ссылки, обновления в вашей базе данных испортят ваши перенаправления на ваши пользовательские типы сообщений. Однако это легко исправить, просто зайдите в настройки / постоянные ссылки WordPress и запомните текущие настройки (у меня было «имя поста»). Затем вернитесь к настройкам по умолчанию, нажмите «Сохранить», затем вернитесь к предыдущим настройкам и сохраните снова. Вы только что исправили проблемы с перенаправлением.

Шаг 3 - переименуйте пользовательские шаблоны типов сообщений вашей темы

Если вы похожи на меня, и вы создали собственные шаблоны типов сообщений, вам нужно будет переименовать их, иначе ваши собственные сообщения будут выглядеть испорченными. Просто зайдите в свою тему и найдите любой файл, в названии которого есть старое имя типа сообщения, и переименуйте файл, используя новое имя сообщения. Например, мне пришлось изменить single-project-portfolio.phpна, single-before-after.phpкогда я изменил свой тип сообщения с project-portfolioна before-after.

Шаг 5 - Обновите любой код

Выполните поиск файла и замените свое старое имя пользовательского типа в папке темы и плагинов. Для меня у меня было несколько пользовательских шорткодов, которые основывались на принятии решения о том, использую ли я один из своих пользовательских типов записей.

Все проверить

Потенциальные проблемы (прочитайте перед началом этой процедуры)

Проблемы синдикации

Если ваши пользовательские типы сообщений были синдицированы, помните, что при первоначальном поиске и замене также будут изменены направляющие ваших сообщений, что заставит всех подписчиков видеть старые сообщения как новые. Мне не приходилось сталкиваться с этим, но если вам нужно, подумайте о том, чтобы вручную выбрать таблицы, которые обрабатывает утилита safesearch, а затем вручную обновить все несериализованные данные, используя следующий запрос:

SET `post_type` = REPLACE(`post_type`,'old_post_type','new_post_type')
WHERE `post_type` LIKE '%old_post_type%';
AndrewD
источник
очень аккуратно перечислить все это. за исключением того, что запрос sql в конце не завершен, так как вы забыли о guid, но они перечислены в ответе Wills. Кроме того, я бы не пошел WHERE 'post_type' LIKE '%old_post_type%', я бы использовал WHERE 'post_type' = 'old_post_type', так как ваш путь также может привести к изменению некоторых других типов
записей
0

У меня нет репутации, чтобы комментировать, поэтому я поставлю это здесь. Расширяя пример Уилла. Я изменил LIKE на "=", и они оба указывают на ГДЕpost_type

UPDATE `wp_posts`
    SET `guid` = REPLACE(`guid`,'old_post_type','new_post_type')
    WHERE `post_type` = 'old_post_type'    

UPDATE `wp_posts`
    SET `post_type` = REPLACE(`post_type`,'old_post_type','new_post_type')
    WHERE `post_type` = 'old_post_type'

Также не забудьте зайти в Admin> Настройки> Постоянные ссылки и нажать «Сохранить изменения». В противном случае ваши ссылки, вероятно, будут сломаны.

Вам также необходимо отредактировать любые имена шаблонов типа «один пост».

Это должно быть все, что вам нужно сделать.

Bullyen
источник
0

Вот действительно простой способ:

  1. Запустите Wordpress Exporter (Инструменты> Экспорт) - экспортируйте только тот тип записи, название которого вы хотите изменить.
  2. Откройте сгенерированный файл .xml и замените все упоминания старого имени типа записи новым именем (в мета «custom_post_type», а также в поле «Постоянная ссылка»).
  3. Создайте новый тип записи с тем же именем, что и в отредактированном XML-файле (но сохраните старый, если он не удастся)
  4. Импортируйте отредактированный XML-файл через Wordpress Importer (плагин доступен прямо из Сервис> Импорт)
  5. Убедитесь, что содержимое присутствует в новом типе записи, а затем удалите старый
Дагоберт Ренуф
источник