Cum să fac o postare draft accesibilă tuturor în WordPress?

18 iul. 2013, 23:14:37
Vizualizări: 16.8K
Voturi: 14

Am mai multe postări nepublicate pe site-ul meu WordPress și încerc să le fac accesibile pentru utilizatorii normali (care nu sunt autentificați) folosind slug-urile normale ale postărilor (site.com/post-here). Înțeleg că poate nu este cea mai bună practică, dar pentru scopul meu special, acest lucru trebuie făcut.

Am încercat să adaug următorul fragment de cod în fișierul meu functions.php:

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');

Am încercat și cu hook-ul init în loc de after_setup_theme. Fără succes.

Din câte înțeleg, modificările la roluri sunt salvate în baza de date, așa că trebuie făcute doar o singură dată. De aceea folosesc hook-ul after_setup_theme pentru a apela funcția.

Dar când încerc să accesez pagina ca utilizator normal, primesc în schimb o pagină 404 în loc să văd conținutul postării. Am încercat și cu URL-ul de previzualizare (site.com/?p=212&preview=true), dar nici asta nu a funcționat.

Acestea sunt presupunerile mele:

  • utilizatorul normal nu are suficiente capabilități pentru a citi postările draft.
  • testarea și vizualizarea postărilor draft pe front-end nu este posibilă pentru niciun utilizator (inclusiv administratori).

Ce modificări trebuie să fac pentru a realiza ceea ce încerc să fac? Dacă nu este posibil, ce soluții alternative sugerezi?

Notă: Nu caut soluții bazate pe plugin-uri.

5
Comentarii

Cred că există o mică confuzie aici. Dacă cineva nu este autentificat, el/ea nu este un utilizator, deci el/ea nu are nicio capacitate. Abonații sunt utilizatori, deci ei trebuie să fie înregistrați și să se autentifice pentru a fi recunoscuți ca abonați. Nu poți oferi capacități cuiva care nu s-a autentificat. Dacă dorești ca oricine neautentificat să îți vadă postările, ele nu sunt diferite deloc de postările publice. Deci, de ce să nu le publici? Sau vrei să afișezi ciorne abonaților (autentificați ca abonați)?

gmazzap gmazzap
3 sept. 2013 03:13:14

@G.M.: Încerc să fac postările nepublicate accesibile tuturor celor care cunosc legătura directă către postare. Poate părea o cerință ciudată, dar am nevoie de asta pentru un proiect. După cum am menționat în întrebarea mea, dacă acest lucru nu este posibil -- poți sugera alte soluții alternative (dacă știi vreuna, bineînțeles)?

Amal Amal
4 nov. 2013 16:14:09

@G.M.: Cunoști vreun plugin care face asta?

Amal Amal
4 nov. 2013 16:26:37

Ai citit răspunsul imediat de mai jos cu 3 voturi pozitive? Explică cum să faci acest lucru și la sfârșitul răspunsului găsești un link pentru a descărca un plugin funcțional de pe GitHub.

gmazzap gmazzap
4 nov. 2013 17:04:05

Pentru cititorii care ajung mai târziu: Există acest plugin creat de Dominik Schilling disponibil pe GitHub.

kaiser kaiser
27 nov. 2013 14:32:58
Toate răspunsurile la întrebare 5
1
13

Nu poți atribui capabilități utilizatorilor necunoscuți. Dacă vrei să faci un articol vizibil pentru toată lumea, creează un URL separat pentru aceste articole și adaugă un element de control în editorul de articole pentru a activa previzualizarea doar pe articolele selectate.
Când un astfel de URL este accesat, verifică dacă previzualizarea este permisă pentru articol și dacă articolul nu a fost deja publicat. De asemenea, asigură-te că motoarele de căutare ignoră acest URL.

Pentru URL aș folosi un endpoint:

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Acum poți crea URL-uri precum...

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

... unde 123 este ID-ul articolului.

Apoi folosește un handler de callback pentru a inspecta ID-ul articolului, verifică dacă este valid și suprascrie interogarea principală. Acesta este probabil singurul caz de utilizare acceptabil pentru query_posts(). :)

Să presupunem că endpoint-ul este o clasă T5_Endpoint (un model), iar handler-ul de ieșire este o clasă T5_Render_Endpoint (o vizualizare) care primește modelul transmis anterior. Atunci probabil există o metodă render() apelată pe 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 este un alt model (clasa T5_Post_Meta) pentru valoarea meta a articolului care controlează dacă o previzualizare este permisă. Controlul este setat în caseta Publicare (acțiunea post_submitbox_misc_actions), randată de o altă vizualizare care primește aceeași clasă meta.

captură de ecran

Deci T5_Post_Meta știe unde și când să stocheze valoarea meta, vizualizările fac ceva cu ea.
De asemenea, folosește hook-ul transition_post_status pentru a șterge câmpul meta al articolului când acesta este publicat. Nu vrem să irosim resurse, nu-i așa?

Acesta este doar un schiță. Există multe detalii de acoperit... Am scris un mic plugin care arată cum să implementezi acest lucru: T5 Public Preview.

3 oct. 2013 20:05:44
Comentarii

Mulțumesc mult. În sfârșit am reușit să ating scopul meu cu câteva ajustări. Minunat. :D

Amal Amal
6 nov. 2013 21:07:45
7

Am rezolvat această problemă într-un mod pe care l-am considerat mai simplu decât răspunsul lui @toscho de mai sus.

Cazul meu de utilizare este că folosesc aceeași bază de date atât pentru un site de staging intranet intern, cât și pentru un site public, iar fluxul de lucru este că autorii scriu drafturi și le împărtășesc cu alți utilizatori care le vizualizează pe site-ul intranet, înainte de publicare. Am vrut în mod special să evit necesitatea ca reviewerii să se autentifice pentru a vedea drafturile, așa că mă bazez doar pe o constantă, ENV_PRODUCTION care este setată în fișierul wp-config pe baza numelui gazdei din $_SERVER['SERVER_NAME']. Aceasta este ceea ce fac verificările pentru ENV_PRODUCTION aici; doar scurtcircuitează toate aceste filtre dacă este vizualizat site-ul de producție.

Acest lucru este puțin ciudat, deoarece trebuie să te conectezi după ce WP_Query elimină toate articolele din array-ul $wp_query->posts, dar mi se pare stabil și sigur.

/*
 * Pe site-ul de staging, pe paginile de acasă și arhive, drafturile ar trebui să fie vizibile.
 */
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' );


/*
 * Face drafturile vizibile pe vizualizările individuale de pe site-ul de staging.
 *
 * (Deoarece pe vizualizările individuale, WP_Query trece prin logica de a se asigura că
 * utilizatorul curent poate edita articolul înainte de a afișa un draft.)
 */
function show_single_drafts_on_staging( $posts, $wp_query ) {
    if ( ENV_PRODUCTION )
        return $posts;

    // verificăm dacă articolul este o previzualizare pentru a evita afișarea articolelor private publicate
    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 );

Există două părți separate ale filtrelor.

  • Un filtru pe hook-ul "pre_get_posts" setează post_status implicit la 'publish,draft' pe site-ul de staging. Acest lucru va returna drafturile în listările de arhivă.
  • Este necesar un filtru separat pentru vizualizările individuale, deoarece există o logică complicată în clasa WP_Query care elimină drafturile din rezultatele interogării, cu excepția cazului în care utilizatorul curent le poate edita. Am ocolit acest lucru prin filtrarea 'the_posts' și adăugând articolul dorit înapoi în rezultate.
10 oct. 2014 23:38:01
Comentarii

Acest lucru este uimitor, vă mulțumesc mult pentru că ați împărtășit asta. Absolut perfect și exact de ce aveam nevoie.

Christian Christian
4 feb. 2015 08:30:23

Unde introduc acest cod? (în ce fișier(e)?)

Joelio Joelio
27 apr. 2015 23:21:51

@Joelio Poți fi mai specific în legătură cu problema pe care o rezolvi? Ca o abordare simplă, eu tocmai am adăugat acest cod în functions.php și am adăugat o definiție simplă în wp-config.php care setează constanta ENV_PRODUCTION la true sau false în funcție de domeniul solicitat.

goldenapples goldenapples
29 apr. 2015 01:59:09

@goldenapples Am adăugat acest fragment de cod în fișierul meu function.php, ce ar trebui să adaug în wp-config? Mulțumesc pentru ajutor.

Graham Slick Graham Slick
26 sept. 2015 13:04:04

@MatthiasGrahamSlick - Ai nevoie doar de ceva care să seteze constanta ENV_PRODUCTION dacă ești pe producție. Eu foloseam domain.com pentru producție și staging.domain.com pentru staging, așa că linia mea era define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) ); Te ajută asta?

goldenapples goldenapples
28 sept. 2015 15:58:37

@goldenapples unde în funcția ta show_single_drafts_on_staging controlezi afișarea doar a postărilor cu post_status=draft? Din testele mele, codul tău afișează orice postare (chiar și cele șterse) pe paginile individuale. Sau fac eu ceva greșit?

Sebastian Sebastian
17 feb. 2016 01:36:25

Exact asta aveam nevoie pentru un site unde utilizatorii nelogati pot trimite conținut; a doua funcție a funcționat pentru a le permite previzualizări (am eliminat verificarea pentru ENV_PRODUCTION)

cogdog cogdog
16 oct. 2019 03:37:37
Arată celelalte 2 comentarii
3

Cred că plugin-ul "User Role Editor" disponibil pe site-ul WordPress.org ar putea fi ceea ce cauți. Apropo, de ce vrei să oferi acces la drafturile tale tuturor? Personal, nu-mi pot imagina o situație în care acest lucru ar fi necesar.

19 iul. 2013 04:27:03
Comentarii

Nu, așa cum am menționat în întrebare, nu caut soluții bazate pe plugin-uri. Cazul de utilizare este ușor complicat, dar sunt sigur că aceasta este cea mai bună soluție pentru această specifică sarcină pe care încerc să o realizez. :-)

Amal Amal
19 iul. 2013 04:32:53

Și eu sunt nedumerit de motiv. Dacă vrei ca toată lumea să vadă postarea, de ce nu o publici pur și simplu? Ai putea folosi câmpuri personalizate pe postare pentru a urmări orice stare specială pe care ai dori să o definești.

KenB KenB
26 iul. 2013 03:11:28

Permit utilizatorilor să vadă conținutul, dar dintr-un motiv anume nu vreau ca postările să fie publicate.

Amal Amal
26 iul. 2013 10:20:52
0

Cred că comentariul lui G.M. este cel mai bun aici. Presupun că încerci să faci următoarele:

  1. Scrie un articol
  2. Salvează ca draft
  3. Permite unui utilizator extern (neautentificat) să vizualizeze draftul pentru aprobare
  4. Publică

Este corect?

Din păcate, nu pot să mă gândesc la nicio metodă simplă pentru a face acest lucru. Ai putea să-l publici ca postare privată, astfel încât să fie nevoie de o parolă pentru a-l vizualiza, dar utilizatorii trebuie să fie autentificați pentru aceasta. Ai putea de asemenea să-l protejezi cu parolă, dar atunci va apărea în fluxul tău și în lista de postări recente, etc. Nu ai putea să creezi un cont de utilizator oaspete și să le dai numele de utilizator/parola când le trimiți URL-ul?

Citește aici pentru mai multe informații: http://codex.wordpress.org/Content_Visibility

Alternativ, există un plugin care ar putea să-ți corespundă nevoilor: http://wordpress.org/extend/plugins/shareadraft/ Am aruncat o privire rapidă asupra codului și se pare că dezvoltatorul modifică valoarea returnată de get_post_status, așa că ai putea să te joci cu asta:

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

Hope this helps (HTH)

24 sept. 2013 09:01:57
1
-1

Puteți pur și simplu să schimbați vizibilitatea paginii/postării la „Privat”, care este vizibilă doar pentru Editori și Administratori și nu pentru vizitatorii publici, motoarele de căutare, fluxurile RSS etc.

3 sept. 2013 01:09:25
Comentarii

Aceasta nu este o soluție viabilă pentru o pagină deja publicată. Puteți face modificări la o pagină activă și să le salvați ca draft. Dacă ați urma această abordare pe o pagină live, aceasta ar putea elimina pagina din rezultatele de căutare în timp și ar putea cauza alte probleme.

Hunter Nelson Hunter Nelson
13 dec. 2021 17:39:01