¿Cómo establecer las publicaciones de un tipo de publicación personalizada como privadas por defecto?
Digamos que he creado un tipo de publicación personalizada llamado 'Publicaciones Privadas' ($post_type
= itsme_private_posts
) y quiero que todas las publicaciones bajo este tipo se establezcan como 'Privadas' automáticamente al publicarlas, es decir, por defecto. ¿Cómo lo hago?
Basándome en la respuesta de @brasofilo a una pregunta relacionada en StackOverflow, probé esto:
add_filter( 'wp_insert_post_data', 'itsme_cpt_private', '99', 2 );
function itsme_cpt_private( $data , $postarr ) {
if( $postarr['post_type'] == 'itsme_private_posts' ) {
$data['post_status'] = 'private';
}
return $data;
}
No funciona, es decir, no hace nada; todo sigue igual que antes de agregar la función. Es como si la función no existiera o simplemente no hiciera nada.
Luego, basándome en este artículo titulado "Forzar que un tipo de publicación personalizada sea privada", probé esto:
add_filter( 'wp_insert_post_data', 'itsme_cpt_private' );
function itsme_cpt_private( $post ) {
if( $post['post_type'] == 'itsme_private_posts' ) {
$post['post_status'] = 'private';
}
return $post;
}
Funciona, en el sentido de que cuando publico o actualizo una publicación, se vuelve privada. ¡Bien! Pero cuando creo una nueva publicación ('Añadir nueva') y me voy sin hacer nada, crea un borrador (auto-) 'privado' y lo guarda. Además, ¡ni siquiera puedo enviar eso a la papelera!
Esencialmente no puedo descubrir cómo hacerlo. Entonces, ¿cómo establezco las publicaciones de un tipo de publicación personalizada para que sean privadas por defecto?

El problema con el código en tu pregunta es que siempre intercepta. Pierdes por completo la capacidad de no publicar, no se permiten borradores. Por qué esto lleva a posts que no se pueden recuperar de la papelera es algo que no he investigado más a fondo. De todos modos, esto no es lo que uno quiere.
Me alegra que la solución con javascript te funcione, pero personalmente tengo dos problemas con ella, primero, puedes guardar el post como público, segundo, lo hace más difícil - porque el script siempre establece el botón de radio como privado - para manejar el trabajo con borradores. En cierto modo ahora hay dos soluciones a la respuesta.
1. Forzar que el tipo de post sea privado más indicación visual:
Por eso volví a mirar cómo hacerlo con transiciones de estado de post y, como dije, se puede hacer con Transiciones de Estado de Post.
Código:
add_action( 'transition_post_status', 'wpse118970_post_status_new', 10, 3 );
function wpse118970_post_status_new( $new_status, $old_status, $post ) {
if ( $post->post_type == 'itsme_private_posts' && $new_status == 'publish' && $old_status != $new_status ) {
$post->post_status = 'private';
wp_update_post( $post );
}
}
Esto fuerza que los posts publicados de tu tipo de post sean privados. Sin interferir con la capacidad de guardar borradores. Esto por sí solo sería suficiente para resolver el problema de tener un tipo de post privado.
Pero por supuesto sería bueno tener la naturaleza privada del tipo de post representada en el metabox de publicación. Para esto ajusté un poco el javascript. Principalmente al no establecer la casilla de verificación por defecto, pero aún cambiando el texto mostrado, adicionalmente añadí una nota.
Código:
add_action( 'post_submitbox_misc_actions' , 'wpse118970_change_visibility_metabox' );
function wpse118970_change_visibility_metabox(){
global $post;
if ($post->post_type != 'post')
return;
$message = __('<strong>Nota:</strong> Los posts publicados son siempre <strong>privados</strong>.');
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Privado');
?>
<style type="text/css">
.priv_pt_note {
background-color: lightgreen;
border: 1px solid green;
border-radius: 2px;
margin: 4px;
padding: 4px;
}
</style>
<script type="text/javascript">
(function($){
try {
$('#post-visibility-display').text('<?php echo $visibility_trans; ?>');
$('#hidden-post-visibility').val('<?php echo $visibility; ?>');
} catch(err){}
}) (jQuery);
</script>
<div class="priv_pt_note">
<?php echo $message; ?>
</div>
<?php
}
Fuente: ¿Cómo establecer la visibilidad de nuevos posts como privada por defecto?
Nota: Comparado con el código de abajo eliminé la verificación del botón de radio y adicionalmente añadí código para el mensaje.
Por supuesto no necesitas el javascript para hacer que tu tipo de post sea privado, pero siempre es bueno tener cosas indicadas visualmente. Por esa razón es una buena adición.
2. Hacer que privado sea la opción estándar en el metabox de publicación:
Mantengo esto porque @its_me aceptó la respuesta para esto como solución. Como dije en el comentario encontré un fragmento de código útil, se encarga de establecer la visibilidad en el metabox como privada enganchándose a post_submitbox_misc_actions
. Como dije al principio »Tengo dos problemas con ello, primero, puedes guardar el post como público, segundo, lo hace más difícil - porque el script siempre establece el botón de radio como privado - para manejar el trabajo con borradores«. Todavía es posible tener y trabajar con borradores, solo no tan intuitivo como antes, pero el estado de publicación privada no está de ninguna manera forzado.
Código:
add_action( 'post_submitbox_misc_actions' , 'wpse118970_change_visibility_metabox_value' );
function wpse118970_change_visibility_metabox_value(){
global $post;
if ($post->post_type != 'itsme_private_posts')
return;
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Privado');
?>
<script type="text/javascript">
(function($){
try {
$('#post-visibility-display').text('<?php echo $visibility_trans; ?>');
$('#hidden-post-visibility').val('<?php echo $visibility; ?>');
$('#visibility-radio-<?php echo $visibility; ?>').attr('checked', true);
} catch(err){}
}) (jQuery);
</script>
<?php
}
Fuente: ¿Cómo establecer la visibilidad de nuevos posts como privada por defecto?
Nota: Acorté el código para ajustarlo a las necesidades aquí.

¿Podrías darme un ejemplo de cómo usaría esto para hacer lo que quiero? No estoy seguro al respecto.

Ahora me has despertado la curiosidad :) Lo estoy probando yo mismo. @its_me

Me di cuenta de que $new_status
es auto-draft
y $old_status
es new
- ajusté el código en consecuencia. @its_me Además de eso encontré otro fragmento de código interesante, lo agregué a la respuesta.

La solución basada en JavaScript funcionó, pero no la primera. Marcada como respuesta porque resuelve mi problema, pero sería bueno si puedes averiguar qué está mal con el primer bloque de código. Si no puedes, por favor elimínalo (para evitar confusión para otros). ¡Muchas gracias por tu tiempo!

Actualicé la respuesta, no estoy seguro si recibes notificación después de aceptar la respuesta. @its_me

Sí, te escuché, y quería hacerte saber que la nueva solución parece estar funcionando. ¡Muchas gracias por tu tiempo!

Esta es la forma más "estándar" que he encontrado hasta ahora para establecer la visibilidad de las publicaciones como privadas por defecto:
function wp_118970_force_type_private($post) {
if ($post['post_status'] != 'trash' && $post['post_status'] != "draft" && $post['post_status'] != "auto-draft") {
$post['post_status'] = 'private';
}
return $post;
}
add_filter('wp_insert_post_data', 'wp_118970_force_type_private');
Ten en cuenta que debes asegurarte de que post_status no sea "trash" (papelera), de lo contrario no podrías eliminar tu publicación. También verificamos los estados "draft" (borrador) y "auto-draft" (borrador automático) para evitar establecer las publicaciones como "private" (privadas) mientras se redactan.
Con esto, no es necesario añadir JavaScript, la visibilidad se establecerá como privada desde el principio.
Si deseas apuntar a un tipo de publicación específico, puedes hacerlo de esta manera:
function wp_118970_force_type_private($post) {
if ($post['post_status'] != 'trash' && $post['post_status'] != "draft" && $post['post_status'] != "auto-draft" && $post['post_type'] == 'my_post_type') {
$post['post_status'] = 'private';
}
return $post;
}
add_filter('wp_insert_post_data', 'wp_118970_force_type_private');
Encontré esta solución originalmente aquí: http://wpsnipp.com/index.php/functions-php/force-custom-post-type-to-be-private/

Esa es una idea muy buena, pero hay que tener en cuenta que hace que las publicaciones recién creadas pierdan directamente su estado de "borrador" y las convierte en "publicadas en privado", en lugar de dejarlas como "borradores" con la opción "privado" preseleccionada. Esto, por ejemplo, les asigna directamente un slug (concretamente el slug auto-draft
), lo que puede resultar inconveniente.

¡Tienes toda la razón! Algún tiempo después de publicar esta respuesta, vi el problema y corregí mi código, pero olvidé actualizar mi respuesta. ¡Ahora está hecho! ¡Gracias!

Basándome en la respuesta anterior, esto es lo que implementé para la parte del cliente (javascript):
add_action( 'post_submitbox_misc_actions' , 'ourcpt_change_visibility_metabox' );
function ourcpt_change_visibility_metabox() {
global $post;
if ( 'ourcpt' != $post->post_type ) { return; }
//else
$post->post_password = '';
?>
<script type="text/javascript">
(function($){
try {
$( "<div class='misc-pub-section'><em>(cuando se publica, el estado se vuelve privado)</em></div>" ).insertAfter( $('#post-visibility-select') );
$('a.edit-visibility').css({'display': 'none'});
} catch(err){}
}) (jQuery);
</script>
<?php
}
Porque me gusta ver exactamente qué está pasando con el estado. El código para add_filter( 'wp_insert_post_data'
lo usé sin cambios.
¡Muchas gracias por tus soluciones!
