Come posso rendere una bozza di post accessibile a tutti?


13

Ho diversi post non pubblicati nel mio sito Web Wordpress e sto cercando di renderlo accessibile agli utenti normali (che non hanno effettuato l'accesso) utilizzando i normali post slug ( site.com/post-here). Capisco che potrebbe non essere la migliore pratica, ma per il mio scopo speciale, questo deve essere fatto.

Ho provato ad aggiungere il seguente frammento di codice nel mio functions.phpfile:

function enable_view_drafts() {
$role = get_role( 'subscriber' ); 
$role->add_cap( 'read_private_posts' ); 
$role->add_cap( 'edit_posts' );
}
add_action( 'after_setup_theme', 'enable_view_drafts');

Ho anche provato ad initagganciare invece di after_setup_theme. Senza fortuna.

La mia comprensione è che le modifiche ai ruoli vengono salvate nel database, quindi è necessario solo una volta. Ecco perché sto usando after_setup_themehook per chiamare la funzione.

Ma quando provo ad accedere alla pagina come utente normale, mi viene mostrata una pagina 404 invece di mostrare il contenuto del post. Ho anche provato a caricare l'URL di anteprima ( site.com/?p=212&preview=true) ma non ha funzionato neanche.

Queste sono le mie ipotesi:

  • l'utente normale non ha abbastanza capsper leggere il post delle bozze.
  • non è possibile testare e visualizzare bozze di post sul front-end per nessun utente (inclusi gli amministratori).

Quali modifiche devo apportare per realizzare ciò che sto cercando di fare? Se non è possibile, quali soluzioni alternative suggerisci?

Nota: non sto cercando soluzioni basate su plug-in.


2
Penso che ci sia un po 'di confusione qui. Se qualcuno non è connesso, lui / lei è non è un utente, in modo da lui / lei ha non tutte le coperture. Gli abbonati sono utenti, quindi devono essere registrati ed effettuare l'accesso per essere riconosciuti come abbonati. Non puoi offrire funzionalità a qualcuno che non ha effettuato l'accesso. Se desideri che qualcuno non abbia effettuato l'accesso visualizzi i tuoi post, semplicemente non sono affatto diversi dai post pubblicati. Quindi, perché non pubblicarlo? Oppure vuoi mostrare la bozza agli abbonati (accedi come abbonati)?
gmazzap

@GM: sto cercando di rendere i post non pubblicati accessibili a tutti coloro che conoscono il permalink diretto al post. Può sembrare uno strano requisito, ma ne ho bisogno per un progetto. Come ho accennato nella mia domanda, se ciò non è possibile, puoi suggerire altre soluzioni alternative (se ne conosci una, ovviamente)?
Amal Murali,

@GM: conosci un plugin che lo fa?
Amal Murali,

Hai letto la risposta appena sotto con 3 voti? Spiega come farlo e alla fine della risposta trovi un link per scaricare un plugin funzionante da Github.
gmazzap

2
Per i lettori successivi: c'è questo plugin di Dominik Schilling disponibile su GitHub.
Kaiser,

Risposte:


12

Non è possibile assegnare funzionalità a utenti sconosciuti. Se vuoi rendere un post visibile a tutti, crea un URL separato per questi post e aggiungi un elemento di controllo all'editor dei post per abilitare l'anteprima solo sui post selezionati.
Quando viene chiamato tale URL, controlla se è consentita un'anteprima per il post e se il post non è già stato pubblicato. Assicurati anche che i motori di ricerca ignorino questo URL.

Per l'URL utilizzerei un endpoint :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Ora puoi creare URL come ...

http://example.com/post-preview/123

... dov'è 123l'ID postale.

Quindi utilizzare un gestore di callback per ispezionare l'ID post, verificare se è valido e sovrascrivere la query principale. Questo è probabilmente l'unico caso d'uso accettabile per query_posts(). :)

Diciamo che l'endpoint è una classe T5_Endpoint(un modello) e il gestore di output è una classe T5_Render_Endpoint(una vista) che ottiene il modello passato in precedenza. Quindi c'è probabilmente un metodo render()chiamato template_redirect:

public function render()
{
    $post_id = $this->endpoint->get_value();

    if ( ! $post_id )
        return;

    if ( 1 !== $this->meta->get_value( $post_id )
        or 'publish' === get_post_status( $post_id )
        )
    {
        wp_redirect( get_permalink( $post_id ) );
        exit;
    }

    $query = array (
        'suppress_filters' => TRUE,
        'p'                => $post_id,
        'post_type'        => 'any'
    );

    query_posts( $query );

    add_action( 'wp_head', 'wp_no_robots' );
}

$this->metaè un altro modello (classe T5_Post_Meta) per il meta valore post che controlla se è consentita un'anteprima. Il controllo è impostato nella casella Pubblica ( azionepost_submitbox_misc_actions ), reso da un'altra vista che ottiene la stessa meta classe.

immagine dello schermo

Quindi T5_Post_Metasa dove e quando memorizzare il meta-valore, le viste fanno qualcosa con esso.
Inoltre, agganciatransition_post_status per eliminare il meta campo post quando il post viene pubblicato. Non vogliamo sprecare risorse, giusto?

Questo è solo uno schema. Ci sono molti dettagli da trattare ... Ho scritto un piccolo plugin che mostra come implementarlo: Anteprima pubblica T5 .


Grazie mille. Ho finalmente raggiunto il mio obiettivo con alcune modifiche. Eccezionale. : D
Amal Murali,

6

Ho risolto questo problema in quello che pensavo fosse un modo più semplice rispetto alla risposta di @ toscho sopra.

Il mio caso d'uso è che sto usando lo stesso database per un sito di gestione temporanea intranet interno e un sito pubblico, e il flusso di lavoro è che gli autori scrivono bozze e lo condividono con altri utenti che visualizzano tali bozze sul sito Intranet, prima della pubblicazione. In particolare, non volevo richiedere ai revisori di accedere per vedere le bozze, quindi dipendo solo da una costante, ENV_PRODUCTIONche è impostata nel file wp-config in base al nome host in $_SERVER['SERVER_NAME']. Ecco cosa ENV_PRODUCTIONstanno facendo i controlli qui; cortocircuitando tutti questi filtri se il sito di produzione viene visualizzato.

Questo è un po 'strano, perché devi collegarti dopo che WP_Query ha rimosso tutti i post dall'array $ wp_query-> posts, ma mi sembra stabile e sicuro.

/*
 * On staging site home and archives, drafts should be visible.
 */
function show_drafts_in_staging_archives( $query ) {
    if ( ENV_PRODUCTION )
        return;

    if ( is_admin() || is_feed() )
        return;

    $query->set( 'post_status', array( 'publish', 'draft' ) );
}

add_action( 'pre_get_posts', 'show_drafts_in_staging_archives' );


/*
 * Make drafts visible on staging site single views.
 *
 * (Because on single views, WP_Query goes through logic to make sure the 
 * current user can edit the post before displaying a draft.)
 */
function show_single_drafts_on_staging( $posts, $wp_query ) {
    if ( ENV_PRODUCTION )
        return $posts;

    //making sure the post is a preview to avoid showing published private posts
    if ( ! is_preview() )        
        return $posts;

    if ( count( $posts ) )
        return $posts;

    if ( !empty( $wp_query->query['p'] ) ) {
        return array ( get_post( $wp_query->query['p'] ) );
    }
}

add_filter( 'the_posts', 'show_single_drafts_on_staging', 10, 2 );

Ci sono due parti separate per i filtri.

  • Un filtro sull'hook "pre_get_posts" imposta il post_status predefinito su "pubblica, bozza" sul sito di gestione temporanea. Ciò restituirà i progetti di bozze negli elenchi degli archivi.
  • È necessario un filtro separato per le viste singole, poiché nella classe WP_Query è presente una cattiva logica per rimuovere le bozze dai risultati della query, a meno che l'utente corrente non possa modificarle. Ho risolto il problema filtrando "the_posts" e aggiungendo il post che volevo tornare ai risultati.

2
È incredibile , grazie mille per averlo condiviso. Assolutamente perfetto ed esattamente ciò di cui avevo bisogno.
Christian Varga,

Dove metto questo codice? (quale file?)
Joelio

@Joelio Puoi essere specifico sul problema che stai risolvendo? Come semplice approccio, ho appena aggiunto questo codice al mio function.php e aggiunto una semplice definizione al mio wp-config.php che imposta la costante ENV_PRODUCTION su true o false a seconda del dominio della richiesta.
goldenapples,

@goldenapples Ho aggiunto questo pezzo di codice al mio function.php, cosa devo aggiungere a wp-config? Grazie per l'aiuto
Graham Slick,

@MatthiasGrahamSlick - Hai solo bisogno di qualcosa che imposti la ENV_PRODUCTIONcostante se sei in produzione. Stavo usando domain.com per la produzione e staging.domain.com per la messa in scena, quindi la mia linea era define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );Aiuta?
goldenapples,

0

Penso che il plug-in "User Role Editor" disponibile sul sito Web di WordPress.org potrebbe essere quello che stai cercando. A proposito, perché vuoi dare accesso alle tue bozze a tutti? Personalmente non riesco a pensare a un'istanza in cui ciò sarebbe richiesto.


No, come indicato nella domanda, non sto cercando soluzioni basate su plug-in. Il caso d'uso è leggermente complicato ma sono sicuro che questa sia la soluzione migliore per questo compito specifico che sto cercando di realizzare. :-)
Amal Murali,

Sono perplesso anche per il motivo. Se vuoi che tutti vedano il post, perché non pubblicare semplicemente il post? Puoi utilizzare i campi personalizzati sul post per tenere traccia di qualsiasi stato speciale che desideri definire.
KenB,

Sto permettendo agli utenti di vedere il contenuto, ma per qualche motivo specifico non voglio che i post vengano pubblicati.
Amal Murali,

0

Puoi semplicemente cambiare la visibilità della pagina / post in "Privato", che è visibile solo a redattori e amministratori e non a visitatori pubblici, motori di ricerca, feed RSS, ecc.


0

Penso che il commento di GM sia il migliore qui. Presumo che tu stia provando a fare quanto segue:

  1. Scrivi un post
  2. Salva come bozza
  3. Consenti a un utente esterno (non connesso) di visualizzare la bozza per l'approvazione
  4. Pubblicare

È corretto?

Sfortunatamente, non riesco a pensare a un modo semplice per farlo. È possibile pubblicarlo come un post privato in modo che debbano inserire una password per visualizzarlo, ma è necessario aver effettuato l'accesso per questo. Potresti anche proteggerlo con password, ma poi apparirà nel tuo feed e nella lista di post recenti, ecc. Non potresti creare un account utente ospite e dare loro il nome utente / password quando gli dai l'URL?

Leggi qui per maggiori informazioni: http://codex.wordpress.org/Content_Visibility

In alternativa, esiste un plug-in che potrebbe soddisfare le tue esigenze: http://wordpress.org/extend/plugins/shareadraft/ Ho dato una rapida occhiata al codice e sembra che lo sviluppatore stia modificando il valore restituito da get_post_status, quindi potresti essere in grado di giocare con quello:

http://codex.wordpress.org/Function_Reference/get_post_status

HTH


0

Se non ti interessa se il post è "pubblicato" o meno, vuoi solo che sia accessibile a chiunque tramite l'URL normale pubblicato e non venga visualizzato nella pagina principale / nei risultati di ricerca / nei feed rss ecc., Questo plug-in ha funzionato con WP 4.6. 1 e ti permette di mettere a punto dove appare un post:

https://wordpress.org/plugins/wp-hide-post/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.