如何安全地更改自定义帖子类型的名称?

时间:2013-04-24 作者:Desi

我制作了一个名为“公文包”的自定义帖子类型,但我想将其更改为“项目”。为了安全地更改名称并防止自定义帖子类型的帖子在仪表板中消失,我需要采取哪些具体步骤?

注意:中已存在帖子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;
    }
}

6 个回复
最合适的回答,由SO网友:Wesley Cheung 整理而成

如果你的投资组合中还没有帖子。

这将非常简单。将所有带有“公文包”的内容重命名为“项目”。您将不会丢失任何内容并更改名称。

Edit :

尝试使用此插件http://wordpress.org/extend/plugins/ptypeconverter/ 安全导出当前帖子并将其导入新的自定义帖子类型。

因此,步骤如下:

1 下载并使用插件:http://wordpress.org/extend/plugins/ptypeconverter/

2 将您的自定义帖子类型“公文包”文件复制到保存位置。例如,可以将其称为portfolio\\u post\\u typeBACKUP。php

3 现在您可以确定此方法何时失败。您可以恢复它。

4 “更改”portfolio“进入”projects“”

5 导入带有插件和viola的帖子!

希望这能奏效。

SO网友:Will

您也可以直接使用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\'
需要注意两件事:

您需要在代码中更新对此帖子类型的任何引用(例如,模板、CMB2定义或分类定义)wp_postmeta 在序列化数组中,您不想进行简单的更新/替换,因为这样会使它们崩溃!除非新旧的post类型字符串的长度完全相同

SO网友:Nirav Mehta

进一步扩展Will的答案。。。,尤其是如果您是从插件执行此操作:

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={$old_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\\u type=old\\u type”或“/old\\u type/”时才替换。这样可以避免错误地替换有效的段塞。(例如,您的自定义帖子类型为公文包,页面的slug中也包含公文包)

另一种选择是这样做:

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();

SO网友:Dagobert Renouf

这里有一个非常简单的方法:

运行Wordpress Exporter(工具>导出)-仅导出要更改名称的帖子类型,打开生成的。xml文件,并用新名称替换所有提及的旧帖子类型名称(在“custom\\u post\\u type”meta和permalink字段中)

  • 使用与编辑中相同的名称创建新帖子类型。xml(但仍保留旧的,以防失败)
  • 导入已编辑的。通过Wordpress导入器(插件可直接从Tools>Import获得)检查新帖子类型中是否存在内容,然后删除旧帖子类型

  • SO网友:AndrewD

    Use a WordPress Database Query but Don\'t Forget About Serialized Option Data

    对我有效的方法是在WordPress数据库中进行搜索和替换,但确保在这个过程中不会破坏序列化的选项数据。我发现最好的方法就是使用safe search and replace database utility from interconnect/it. 永远不要只做SETpost\\U类型= REPLACE(post\\U类型,\'old_post_type\',\'new_post_type\') 在不知道您在做什么的情况下键入query,否则序列化数据将中断,因为它保留校验和,并且无法正确取消序列化。

    Read the Potential Issues section before blindly following this

    步骤1-使用新名称安全地更新数据库备份数据库,因为以下更改可能会损坏数据库safe search and replace database utility from interconnect/it
  • 将提取的目录添加到webroot(它也适用于子目录)
  • 浏览到该目录,例如:/mywebsite。com/path/to/utility/directory遵循说明。如果您是paronoid,请单击“试运行”以查看更改(如果您有几篇更改了帖子类型的帖子,将有数百篇)
  • 单击“实时运行”以完成更改
  • 从wordpress目录中删除安全搜索目录,因为这是一个安全问题。步骤2-重置永久链接。如果您使用永久链接,对数据库的更新将导致您重定向到自定义帖子类型。不过有一个简单的修复方法,只需进入WordPress设置/永久链接并注意当前的设置(我的设置是“post name”)。然后切换回默认设置,单击“保存”,然后返回到以前的设置,然后再次保存。您刚刚修复了重定向问题。

    第3步-重命名主题的自定义帖子类型模板

    如果你像我一样,并且创建了自定义帖子类型模板,你需要重命名这些模板,否则你的自定义帖子会看起来一团糟。只需进入主题,找到任何文件名中包含旧帖子类型名称的文件,然后使用新帖子名称重命名文件。例如,我必须改变single-project-portfolio.phpsingle-before-after.php 当我从project-portfoliobefore-after.

    步骤5-更新所有代码,在主题和插件文件夹中搜索并替换旧的自定义帖子类型名称。对我来说,我有几个自定义短代码,它们依赖于我是否在使用我的自定义帖子类型。

    测试所有潜在问题(在开始此过程之前阅读)

    联合问题如果您的自定义帖子类型是联合的,请意识到您最初的搜索和替换也会更改帖子的GUID,这将迫使所有订阅者将旧帖子视为新帖子。我不必处理这个问题,但如果需要,可以考虑手动选择safesearch实用程序处理的表,然后使用以下查询手动更新任何非序列化数据:

    SET `post_type` = REPLACE(`post_type`,\'old_post_type\',\'new_post_type\')
    WHERE `post_type` LIKE \'%old_post_type%\';
    

  • SO网友:Bullyen

    我没有评论的名声,所以我将把这个放在这里。扩展Will的示例。我将LIKEs改为“=”,并让它们都指向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\'
    
    还记得进入管理>设置>永久链接,点击“保存更改”。否则,您的链接可能会断开。

    您还需要编辑任何“单一帖子类型”模板名称。

    这应该是你需要做的全部。

    结束

    相关推荐