¿Cómo establecer las publicaciones de un tipo de publicación personalizada como privadas por defecto?

15 oct 2013, 20:44:11
Vistas: 15.9K
Votos: 7

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?

2
Comentarios

¡Además ni siquiera puedo enviar esa cosa a la papelera! La razón por la que no podías enviar las entradas a la papelera era porque siempre estabas configurando el post_status como private. Al enviar entradas a la papelera, el estado de la entrada se establece como trash, pero estabas sobrescribiendo este comportamiento. He descubierto que un enfoque mejor es solo establecer el estado de la entrada como private si el estado actual es public.

c.hill c.hill
28 mar 2015 13:23:15

Revisado: Debería establecer el estado de la entrada como private si actualmente es publish. public no es un estado de entrada.

c.hill c.hill
28 mar 2015 13:31:21
Todas las respuestas a la pregunta 3
7
15

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í.

15 oct 2013 21:26:18
Comentarios

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

its_me its_me
15 oct 2013 21:45:08

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

Nicolai Grossherr Nicolai Grossherr
15 oct 2013 22:23:09

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.

Nicolai Grossherr Nicolai Grossherr
15 oct 2013 22:56:43

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!

its_me its_me
16 oct 2013 06:48:14

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

Nicolai Grossherr Nicolai Grossherr
17 oct 2013 00:38:24

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

its_me its_me
17 oct 2013 00:42:06

Placer, me dejaste con curiosidad, eso es todo :D @its_me

Nicolai Grossherr Nicolai Grossherr
17 oct 2013 00:47:29
Mostrar los 2 comentarios restantes
3

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/

31 ago 2017 17:27:37
Comentarios

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.

cgogolin cgogolin
21 ago 2018 12:37:26

¡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!

Jonathan Pasquier Jonathan Pasquier
21 ago 2018 14:13:03

Esto funcionó para mí. Gracias

TomC TomC
27 nov 2019 12:59:02
0

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!

11 sept 2016 21:52:10