Come rendere accessibile a tutti un articolo in bozza?

18 lug 2013, 23:14:37
Visualizzazioni: 16.8K
Voti: 14

Ho diversi articoli non pubblicati nel mio sito WordPress e sto cercando di renderli accessibili agli utenti normali (che non sono loggati) utilizzando gli slug normali degli articoli (sito.it/articolo-qui). Capisco che non sia la migliore pratica, ma per il mio scopo specifico, questo deve essere fatto.

Ho provato ad aggiungere il seguente snippet di codice nel mio file functions.php:

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

Ho anche provato con l'hook init invece di after_setup_theme. Senza successo.

La mia comprensione è che le modifiche ai ruoli vengono salvate nel database quindi devono essere fatte solo una volta. Ecco perché sto usando l'hook after_setup_theme per chiamare la funzione.

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

Queste sono le mie ipotesi:

  • l'utente normale non ha sufficienti cap per leggere gli articoli in bozza.
  • testare e visualizzare articoli in bozza sul front-end non è possibile per nessun utente (inclusi gli amministratori).

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

Nota: Non cerco soluzioni basate su plugin.

5
Commenti

Penso ci sia un po' di confusione qui. Se qualcuno non è loggato, lui/lei non è un utente, quindi lui/lei non ha alcun cap. I subscribers sono utenti, quindi devono essere registrati e fare il login per essere riconosciuti come subscribers. Non puoi dare capacità a qualcuno che non ha effettuato il login. Se vuoi che chiunque non loggato possa vedere i tuoi post, questi non sono diversi dai post pubblicati. Quindi, perché non pubblicarli? O vuoi mostrare le bozze ai subscribers (loggati come subscribers)?

gmazzap gmazzap
3 set 2013 03:13:14

@G.M.: Sto cercando di rendere i post non pubblicati accessibili a tutti coloro che conoscono il permalink diretto del post. Potrebbe sembrare un requisito strano, ma ne ho bisogno per un progetto. Come ho menzionato nella mia domanda, se questo non è possibile -- puoi suggerire altre soluzioni alternative (se ne conosci una, ovviamente)?

Amal Amal
4 nov 2013 16:14:09

@G.M.: Conosci un plugin che fa questo?

Amal Amal
4 nov 2013 16:26:37

Hai letto la risposta qui sotto con 3 voti positivi? Spiega come fare e alla fine della risposta trovi un link per scaricare un plugin funzionante completo da GitHub.

gmazzap gmazzap
4 nov 2013 17:04:05

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

kaiser kaiser
27 nov 2013 14:32:58
Tutte le risposte alla domanda 5
1
13

Non puoi assegnare capacità a utenti sconosciuti. Se vuoi rendere un articolo visibile a tutti, crea un URL separato per questi articoli e aggiungi un elemento di controllo nell'editor degli articoli per abilitare l'anteprima solo su quelli selezionati.
Quando viene chiamato un URL di questo tipo, verifica se l'anteprima è consentita per l'articolo e se l'articolo non è già stato pubblicato. Assicurati inoltre 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

…dove 123 è l'ID dell'articolo.

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

Supponiamo che l'endpoint sia una classe T5_Endpoint (un modello) e che il gestore dell'output sia una classe T5_Render_Endpoint (una vista) a cui viene passato il modello precedentemente. Allora probabilmente c'è un metodo render() chiamato su 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 valore meta dell'articolo che controlla se è consentita un'anteprima. Il controllo è impostato nel box Pubblica (azione post_submitbox_misc_actions), reso da un'altra vista che riceve la stessa classe meta.

screenshot

Quindi T5_Post_Meta sa dove e quando memorizzare il valore meta, le viste fanno qualcosa con esso.
Inoltre, agganciati a transition_post_status per eliminare il campo meta dell'articolo quando viene pubblicato. Non vogliamo sprecare risorse, vero?

Questo è solo uno schema. Ci sono molti dettagli da coprire… Ho scritto un piccolo plugin che mostra come implementarlo: T5 Public Preview.

3 ott 2013 20:05:44
Commenti

Grazie mille. Alla fine ho raggiunto il mio obiettivo con qualche modifica. Fantastico. :D

Amal Amal
6 nov 2013 21:07:45
7

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

Il mio caso d'uso è che sto utilizzando lo stesso database per un sito di staging intranet interno e un sito pubblico, e il flusso di lavoro prevede che gli autori scrivano bozze e le condividano con altri utenti che le visualizzano sul sito intranet, prima della pubblicazione. Specificamente non volevo richiedere ai revisori di effettuare il login per vedere le bozze, quindi mi affido semplicemente a una costante ENV_PRODUCTION che viene impostata nel file wp-config in base all'hostname in $_SERVER['SERVER_NAME']. Questo è ciò che fanno i controlli per ENV_PRODUCTION qui; escludono semplicemente tutti questi filtri se il sito in produzione viene visualizzato.

È un po' strano, perché devi agganciarti dopo che WP_Query rimuove tutti i post dall'array $wp_query->posts, ma mi sembra stabile e sicuro.

/*
 * Nelle pagine home e archivio del sito di staging, le bozze dovrebbero essere visibili.
 */
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' );


/*
 * Rendi visibili le bozze nelle visualizzazioni singole del sito di staging.
 *
 * (Perché nelle visualizzazioni singole, WP_Query applica una logica per assicurarsi che 
 * l'utente corrente possa modificare il post prima di mostrare una bozza.)
 */
function show_single_drafts_on_staging( $posts, $wp_query ) {
    if ( ENV_PRODUCTION )
        return $posts;

    //assicurarsi che il post sia un'anteprima per evitare di mostrare post privati pubblicati
    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 nei filtri:

  • Un filtro sull'hook "pre_get_posts" imposta il post_status predefinito a 'publish,draft' sul sito di staging. Questo farà sì che le bozze vengano incluse negli elenchi degli archivi.
  • È necessario un filtro separato per le visualizzazioni singole, perché c'è una logica complessa nella classe WP_Query che rimuove le bozze dai risultati della query a meno che l'utente corrente non possa modificarle. Ho aggirato questo problema filtrando 'the_posts' e riaggiungendo il post desiderato direttamente ai risultati.
10 ott 2014 23:38:01
Commenti

Questo è incredibile, grazie mille per aver condiviso questo. Assolutamente perfetto e esattamente ciò di cui avevo bisogno.

Christian Christian
4 feb 2015 08:30:23

Dove devo inserire questo codice? (in quale/i file?)

Joelio Joelio
27 apr 2015 23:21:51

@Joelio Puoi essere specifico riguardo al problema che stai risolvendo? Come approccio semplice, ho semplicemente aggiunto questo codice al mio functions.php e ho aggiunto una semplice definizione al mio wp-config.php che imposta la costante ENV_PRODUCTION a true o false in base al dominio della richiesta.

goldenapples goldenapples
29 apr 2015 01:59:09

@goldenapples Ho aggiunto questo pezzo di codice al mio function.php, cosa dovrei aggiungere a wp-config? Grazie per il tuo aiuto

Graham Slick Graham Slick
26 set 2015 13:04:04

@MatthiasGrahamSlick - Hai solo bisogno di qualcosa che imposti la costante ENV_PRODUCTION se sei in produzione. Io usavo domain.com per la produzione e staging.domain.com per lo staging, quindi la mia riga era define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) ); Ti aiuta?

goldenapples goldenapples
28 set 2015 15:58:37

@goldenapples dove nella tua funzione show_single_drafts_on_staging controlli di mostrare solo i post con post_status=draft? Per quanto ho testato il tuo codice, mostra qualsiasi post (anche quelli cestinati) nelle pagine singole. O sto facendo qualcosa di sbagliato?

Sebastian Sebastian
17 feb 2016 01:36:25

Questo è esattamente ciò di cui avevo bisogno per un sito in cui gli utenti non loggati possono inviare contenuti; la seconda funzione ha funzionato per permettere loro le anteprime (ho rimosso il controllo per ENV_PRODUCTION)

cogdog cogdog
16 ott 2019 03:37:37
Mostra i restanti 2 commenti
3

Penso che il plugin "User Role Editor" disponibile sul sito WordPress.org potrebbe essere quello che stai cercando. A proposito, perché vuoi dare accesso ai tuoi bozze a tutti? Personalmente non riesco a pensare a un caso in cui questo sarebbe necessario.

19 lug 2013 04:27:03
Commenti

No, come menzionato nella domanda, non sto cercando soluzioni basate su plugin. L'uso è leggermente complicato ma sono sicuro che questa sia la soluzione migliore per questo specifico compito che sto cercando di realizzare. :-)

Amal Amal
19 lug 2013 04:32:53

Anch'io sono perplesso riguardo al motivo. Se vuoi che tutti vedano il post, perché non semplicemente pubblicarlo? Potresti usare campi personalizzati sul post per tenere traccia di qualsiasi stato speciale che desideri definire.

KenB KenB
26 lug 2013 03:11:28

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

Amal Amal
26 lug 2013 10:20:52
0

Penso che il commento di G.M. sia il migliore qui. Presumo tu stia cercando di fare quanto segue:

  1. Scrivere un articolo
  2. Salvarlo come bozza
  3. Permettere a un utente esterno (non autenticato) di visualizzare la bozza per approvazione
  4. Pubblicare

È corretto?

Sfortunatamente, non riesco a pensare a un modo semplice per farlo. Potresti pubblicarlo come articolo privato in modo che debbano inserire una password per visualizzarlo, ma devi essere autenticato per questo. Potresti anche proteggerlo con password, ma in questo caso apparirà comunque nel tuo feed e nell'elenco degli articoli recenti, ecc. Non potresti creare un account utente ospite e fornirgli nome utente/password quando gli dai l'URL?

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

In alternativa, c'è un plugin che potrebbe fare al caso tuo: 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 giocarci un po':

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

Spero sia d'aiuto

24 set 2013 09:01:57
1
-1

Potresti semplicemente cambiare la visibilità della pagina/articolo in "Privato", che sarà visibile solo agli Editor e agli Amministratori e non ai visitatori pubblici, ai motori di ricerca, ai feed RSS, ecc.

3 set 2013 01:09:25
Commenti

Questa non è una soluzione valida per una pagina già pubblicata. Puoi apportare modifiche a una pagina attualmente online e salvarle come bozza. Se segui questo approccio su una pagina live, rimuoverebbe gradualmente la pagina dai risultati di ricerca e potrebbe causare altri problemi.

Hunter Nelson Hunter Nelson
13 dic 2021 17:39:01