¿Cómo cambiar de forma segura el nombre de un tipo de entrada personalizada?
Creé un tipo de entrada personalizada llamada 'portfolio' pero quiero cambiarla a 'projects'. ¿Cuáles serían los pasos exactos que necesito seguir para cambiar el nombre de forma segura y evitar que las entradas del tipo de contenido personalizado desaparezcan del panel de administración?
Nota: Ya hay entradas en portfolio
así que no puedo simplemente cambiar portfolio
por projects
.
/* Registrar Tipo de Entrada Portfolio */
add_action('init', 'create_portfolio');
function create_portfolio() {
$labels = array(
'name' => __('Portfolio', 'nombre general del tipo de entrada'),
'singular_name' => __('Proyecto', 'nombre singular del tipo de entrada'),
'add_new' => __('Añadir Nuevo', 'elemento portfolio'),
'add_new_item' => __('Añadir Nuevo Proyecto'),
'edit_item' => __('Editar Proyecto'),
'new_item' => __('Nuevo Proyecto'),
'view_item' => __('Ver Proyecto'),
'search_items' => __('Buscar Proyectos'),
'not_found' => __('No se encontró nada'),
'not_found_in_trash' => __('No se encontró nada en la Papelera'),
'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 );
}
/* Registrar Taxonomía de Habilidades */
register_taxonomy("Skills", array("portfolio"), array("hierarchical" => true, "label" => "Habilidades", "singular_label" => "Habilidad", "rewrite" => true));
/* Añadir Campos */
add_action("admin_init", "add_portfolio_fields");
function add_portfolio_fields(){
add_meta_box("website_url", "URL del Sitio Web", "website_url", "portfolio", "side", "low");
add_meta_box("view_more", "Ver Más", "view_more", "portfolio", "side", "low");
add_meta_box("screenshot_name", "Nombre de Captura", "screenshot_name", "portfolio", "side", "low");
add_meta_box("thumbnail_name", "Nombre de Miniatura", "thumbnail_name", "portfolio", "side", "low");
add_meta_box("thumbnail_alt", "Texto Alt de Miniatura", "thumbnail_alt", "portfolio", "side", "low");
}
function website_url(){
global $post;
$custom = get_post_custom($post->ID);
$website_url = $custom["website_url"][0];
?>
<label>URL del Sitio Web:</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>Ver Más:</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>Nombre de Captura:</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>Nombre de Miniatura:</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>Texto Alt de Miniatura:</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"]);
}
/* Columnas Personalizadas */
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" => "Título del Proyecto",
"description" => "Descripción",
);
return $columns;
}
function portfolio_custom_columns($column){
global $post;
switch ($column) {
case "description":
the_excerpt();
break;
}
}

También puedes hacer esto directamente con MySQL.
UPDATE `wp_posts`
SET
# Actualizar la columna post_type
`post_type` = REPLACE(`post_type`,'nombre_del_tipo_de_entrada_antiguo','nombre_del_nuevo_tipo_de_entrada'),
# Actualizar las URLs
`guid` = REPLACE(`guid`,'nombre_del_tipo_de_entrada_antiguo','nombre_del_nuevo_tipo_de_entrada')
WHERE `post_type` = 'nombre_del_tipo_de_entrada_antiguo'
Dos cosas a tener en cuenta:
- Necesitarás actualizar cualquier referencia a este tipo de entrada en tu código (por ejemplo, plantillas, definiciones de CMB2 o definiciones de taxonomías).
- Si has almacenado referencias a este tipo de entrada dentro de
wp_postmeta
en arrays serializados, no querrás hacer un simple UPDATE/REPLACE porque ¡los arruinará! Bueno, a menos que tanto el nuevo como el antiguo tipo de entrada tengan exactamente la misma longitud.

Extendiendo un poco más la respuesta de Will..., y especialmente si lo estás haciendo desde tu plugin:
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}/%" ) );
}
El cambio aquí es no reemplazar el tipo antiguo en el guid directamente, sino reemplazarlo solo si está presente "post_type=old_type" o "/old_type/". Esto evita reemplazar slugs válidos por error. (por ejemplo, si tu tipo de post personalizado es portfolio, y el slug de una página también contiene portfolio)
Otra alternativa es hacer algo como esto:
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();

Gracias. Esto funciona. Un pequeño detalle: la última parte de la segunda consulta en el bucle debería ser "%post_type={$old_type}%", no "%post_type={$type}%".

Acabo de convertir las consultas wpdb en consultas SQL simples para simplificar.
UPDATE wp_posts SET post_type = REPLACE(post_type, old_type, type) WHERE post_type LIKE '%old_type%';
UPDATE wp_posts SET guid = REPLACE(guid, 'post_type=old_type', 'post_type=type') WHERE guid LIKE '%post_type=old_type%';
UPDATE wp_posts SET guid = REPLACE(guid, '/old_type/', '/type/') WHERE guid LIKE '%/old_type/%';

Aquí tienes una forma realmente sencilla:
- Ejecuta el Exportador de WordPress (Herramientas > Exportar) - exporta solo el tipo de publicación cuyo nombre quieres cambiar
- Abre el archivo .xml generado y reemplaza todas las menciones del nombre antiguo del tipo de publicación por el nuevo nombre (tanto en el meta "custom_post_type" como en el campo del permalink)
- Crea tu nuevo tipo de publicación con el mismo nombre que usaste en el .xml editado (pero mantén el antiguo por si falla)
- Importa el archivo .xml editado mediante el Importador de WordPress (el plugin está disponible directamente en Herramientas > Importar)
- Verifica que el contenido está presente en el nuevo tipo de publicación y luego elimina el antiguo

Muy buena idea. Recomendado para alguien que no quiera tocar la base de datos

Gracias por esto... También seguí la conversación aquí para inicializar un nuevo tipo de publicación personalizado: https://wordpress.stackexchange.com/a/252078/142039 -- pude importar todos mis datos, ¡genial!

Usa una consulta a la base de datos de WordPress pero no olvides los datos serializados de las opciones
El método que funcionó para mí fue hacer una búsqueda y reemplazo dentro de la base de datos de WordPress, pero asegurándome de no estropear los datos serializados de las opciones en el proceso. La mejor forma que encontré es usar la utilidad segura de búsqueda y reemplazo en base de datos de interconnect/it. Nunca hagas simplemente una consulta del tipo SET
post_type= REPLACE(
post_type,'tipo_de_post_antiguo','tipo_de_post_nuevo')
sin saber lo que estás haciendo o los datos serializados se romperán ya que mantienen un checksum y no podrán deserializarse correctamente.
Lee la sección de Problemas Potenciales antes de seguir esto ciegamente
Paso 1 - Actualiza tu base de datos con el nuevo nombre de forma segura
- haz una copia de seguridad de tu base de datos porque los siguientes cambios tienen un potencial real de corromperla.
- descarga y descomprime la utilidad segura de búsqueda y reemplazo en base de datos de interconnect/it
- añade el directorio extraído a tu raíz web (también funciona en subdirectorios)
- navega al directorio, ej: /misitio.com/ruta/a/directorio/utilidad/
- sigue las instrucciones. Haz clic en 'dry-run' si eres paranoico para ver los cambios (habrá cientos incluso si solo tienes unos pocos posts del tipo de post cambiado)
- haz clic en 'live run' para finalizar los cambios.
- elimina el directorio de búsqueda segura de tu directorio de WordPress ya que es un problema de seguridad
Paso 2 - Reinicia tus Permalinks
Si estás usando permalinks, las actualizaciones a tu base de datos estropearán tus redirecciones a tus tipos de posts personalizados. Hay una solución fácil, simplemente ve a Ajustes de WordPress/Permalinks y toma nota del ajuste actual (el mío era 'nombre del post'). Luego cambia a predeterminado, haz clic en 'guardar', luego vuelve al ajuste anterior y guarda de nuevo. Acabas de solucionar tus problemas de redirección.
Paso 3 - Renombra las Plantillas de Tipos de Posts Personalizados de tu Tema
Si eres como yo, y creaste plantillas para tipos de posts personalizados, necesitarás renombrarlas o tus posts personalizados se verán mal. Simplemente ve a tu tema y encuentra cualquier archivo que tenga el nombre antiguo de tu tipo de post en su nombre de archivo y renombra el archivo usando tu nuevo nombre de post. Por ejemplo, tuve que cambiar single-project-portfolio.php
a single-before-after.php
cuando cambié mi tipo de post de project-portfolio
a before-after
.
Paso 5 - Actualiza cualquier Código
Haz una búsqueda y reemplazo de archivos para tu antiguo nombre de tipo de post personalizado en la carpeta del tema y de plugins. En mi caso, tenía varios shortcodes personalizados que dependían de tomar una decisión sobre si estaba usando uno de mis tipos de posts personalizados.
Prueba Todo
Problemas Potenciales (lee antes de comenzar este procedimiento)
Problemas de SindicaciónSi tus tipos de posts personalizados estaban sindicados, ten en cuenta que tu búsqueda y reemplazo inicial también cambiará los guids de tus posts, lo que hará que todos los suscriptores vean los posts antiguos como nuevos. No tuve que lidiar con esto, pero si necesitas hacerlo, entonces considera seleccionar manualmente las tablas que procesa la utilidad safesearch, luego actualiza manualmente cualquier dato no serializado usando la siguiente consulta:
SET `post_type` = REPLACE(`post_type`,'tipo_de_post_antiguo','tipo_de_post_nuevo')
WHERE `post_type` LIKE '%tipo_de_post_antiguo%';

muy ordenado listar todo esto. excepto que la consulta SQL al final no está completa, ya que olvidaste el guid, pero están listados en la respuesta de Will. además no usaría WHERE 'post_type' LIKE '%old_post_type%'
, yo usaría WHERE 'post_type' = 'old_post_type'
, ya que tu forma podría causar que otros tipos de post también cambien..

Si aún no tienes publicaciones en tu portafolio.
Sería realmente sencillo. Renombra todo lo que diga "Portfolio" a "Proyectos". No perderás nada y solo cambiarás el nombre.
Edición:
Prueba a usar este plugin http://wordpress.org/extend/plugins/ptypeconverter/ para exportar las publicaciones actuales de forma segura e importarlas a tu nuevo tipo de publicación personalizado.
Los pasos son:
1 Descarga y usa el plugin: http://wordpress.org/extend/plugins/ptypeconverter/
2 Copia tu archivo de tipo de publicación personalizado "portfolio" en un lugar seguro. Llámalo, por ejemplo, portfolio_post_typeBACKUP.php
3 Ahora estás seguro de que, si este método falla, podrás recuperarlo.
4 Cambia "portfolio" por "projects"
5 Importa las publicaciones con el plugin y ¡voilà!
Espero que esto funcione.

Ah, lo siento, debería haber mencionado. Ya hay muchas publicaciones en portfolio
.

este plugin ya no funciona correctamente. lo probé y no cambió todos los tipos de publicaciones 'antiguas'. pero la solución con mysql (respuesta de Will) funciona bien.

No tengo la reputación para comentar, así que lo pondré aquí. Extendiendo el ejemplo de Will. Cambié los LIKE por "=" y hice que ambos apunten a WHERE 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'
También recuerda ir al Admin > Configuración > Enlaces permanentes y hacer clic en "Guardar cambios". De lo contrario, tus enlaces probablemente estarán rotos.
También necesitarás editar cualquier nombre de plantilla 'single-post-type'.
Esto debería ser todo lo que necesitas hacer.
