Bagaimana cara membuat draft posting dapat diakses oleh semua orang?

13

Saya memiliki beberapa posting yang tidak dipublikasikan di situs Wordpress saya dan saya mencoba membuatnya dapat diakses oleh pengguna normal (yang tidak masuk log) menggunakan siput posting normal ( site.com/post-here). Saya mengerti ini mungkin bukan praktik terbaik tetapi untuk tujuan khusus saya, ini perlu dilakukan.

Saya telah mencoba menambahkan potongan kode berikut ke functions.phpfile saya :

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

Saya juga sudah mencoba inithook after_setup_theme. Tidak berhasil

Pemahaman saya adalah bahwa perubahan peran disimpan ke database sehingga hanya perlu dilakukan sekali. Itu sebabnya saya menggunakan after_setup_themehook untuk memanggil fungsi.

Tetapi ketika saya mencoba mengakses halaman sebagai pengguna normal, saya ditunjukkan halaman 404 alih-alih menunjukkan konten posting. Saya juga mencoba memuat URL pratinjau ( site.com/?p=212&preview=true) tetapi itu tidak berhasil.

Ini tebakan saya:

  • pengguna biasa tidak memiliki cukup capsuntuk membaca posting konsep.
  • menguji dan melihat postingan konsep di front-end tidak dimungkinkan untuk semua pengguna (termasuk administrator).

Perubahan apa yang harus saya lakukan untuk mencapai apa yang saya coba lakukan? Jika tidak memungkinkan, solusi alternatif apa yang Anda sarankan?

Catatan: Saya tidak mencari solusi berbasis plugin.

Amal Murali
sumber
2
Saya pikir ada sedikit kebingungan di sini. Jika seseorang tidak masuk, ia bukan pengguna, jadi ia tidak memiliki batasan apa pun. Para pelanggan adalah pengguna, sehingga mereka harus terdaftar dan membuat login untuk diakui sebagai pelanggan. Anda tidak dapat memberikan kemampuan kepada seseorang yang belum masuk. Jika Anda ingin orang yang belum masuk, lihat kiriman Anda sama sekali tidak berbeda dengan kiriman yang dipublikasikan. Jadi, mengapa tidak mempublikasikannya? Atau Anda ingin menunjukkan konsep kepada pelanggan (masuk sebagai pelanggan)?
gmazzap
@ GM: Saya mencoba membuat posting yang tidak dipublikasikan dapat diakses oleh semua orang yang mengetahui tautan langsung ke posting tersebut. Ini mungkin tampak seperti persyaratan aneh, tetapi saya membutuhkan ini untuk sebuah proyek. Seperti yang saya sebutkan dalam pertanyaan saya, jika ini tidak mungkin - dapatkah Anda menyarankan solusi lain (jika Anda tahu, tentu saja)?
Amal Murali
@ GM: Apakah Anda tahu plugin yang melakukan itu?
Amal Murali
Sudahkah Anda membaca jawaban tepat di bawah ini dengan 3 upvotes? Ini menjelaskan cara melakukannya dan di akhir jawaban Anda menemukan tautan untuk mengunduh plugin yang berfungsi penuh dari github.
gmazzap
2
Untuk pembaca selanjutnya: Ada plugin ini oleh Dominik Schilling yang tersedia di GitHub.
kaiser

Jawaban:

12

Anda tidak dapat menetapkan kemampuan untuk pengguna yang tidak dikenal. Jika Anda ingin membuat posting terlihat untuk semua orang, buat URL terpisah untuk posting ini dan tambahkan elemen kontrol ke editor posting untuk mengaktifkan pratinjau hanya pada posting yang dipilih.
Ketika URL semacam itu dipanggil, periksa apakah pratinjau diizinkan untuk kiriman dan apakah kiriman tersebut belum diterbitkan. Pastikan juga mesin pencari mengabaikan URL ini.

Untuk URL saya akan menggunakan titik akhir :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Sekarang Anda dapat membuat URL seperti ...

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

... di mana 123ID pos.

Kemudian gunakan penangan panggilan balik untuk memeriksa ID posting, periksa apakah valid dan timpa permintaan utama. Ini mungkin satu-satunya kasus penggunaan yang dapat diterima untuk query_posts(). :)

Katakanlah titik akhir adalah kelas T5_Endpoint(model), dan output handler adalah kelas T5_Render_Endpoint(tampilan) yang membuat model melewati sebelumnya. Lalu mungkin ada metode yang render()dipanggil 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->metaadalah model lain (kelas T5_Post_Meta) untuk nilai meta pos yang mengontrol jika pratinjau diizinkan. Kontrol diatur ke dalam kotak Publikasikan ( tindakanpost_submitbox_misc_actions ), diberikan oleh tampilan lain yang mendapatkan kelas meta yang sama.

tangkapan layar

Jadi T5_Post_Metatahu di mana dan kapan untuk menyimpan nilai meta, pandangan melakukan sesuatu dengannya.
Selain itu, kaitkan ke dalamtransition_post_status untuk menghapus kolom meta pos saat posting dipublikasikan. Kami tidak ingin menyia-nyiakan sumber daya, bukan?

Ini hanya garis besar. Ada banyak detail yang harus dibahas ... Saya telah menulis sebuah plugin kecil yang menunjukkan cara mengimplementasikan ini: T5 Public Preview .

fuxia
sumber
Terima kasih banyak. Saya akhirnya mencapai tujuan saya dengan beberapa penyesuaian. Luar biasa. : D
Amal Murali
6

Saya memecahkan masalah ini dengan cara yang menurut saya lebih sederhana daripada jawaban @ toscho di atas.

Kasus penggunaan saya adalah saya menggunakan database yang sama untuk situs pementasan intranet internal dan situs yang menghadap publik, dan alur kerjanya adalah bahwa penulis menulis konsep dan membaginya dengan pengguna lain yang melihat draft tersebut di situs intranet, sebelum diterbitkan. Saya secara khusus tidak ingin meminta pengulas untuk masuk untuk melihat konsep, jadi saya hanya bergantung pada konstanta, ENV_PRODUCTIONyang diatur dalam file wp-config berdasarkan nama host di $_SERVER['SERVER_NAME']. Thats melakukan pemeriksaan di ENV_PRODUCTIONsini; hanya menyingkat semua filter ini jika situs produksi sedang dilihat.

Ini agak aneh, karena Anda harus terhubung setelah WP_Query menghapus semua postingan dari array $ wp_query-> posts, tetapi tampaknya stabil dan aman bagi saya.

/*
 * 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 );

Ada dua bagian terpisah untuk filter.

  • Filter pada kait "pre_get_posts" menetapkan post_status default menjadi 'publish, draft' di situs pementasan. Ini akan mengembalikan draft postingan dalam daftar arsip.
  • Filter terpisah diperlukan untuk tampilan tunggal, karena ada beberapa logika tidak enak di kelas WP_Query untuk menghapus draf posting dari hasil kueri kecuali pengguna saat ini dapat mengeditnya. Saya menyiasatinya dengan memfilter 'the_posts', dan menambahkan postingan yang saya inginkan segera kembali ke hasil.
lempengan emas
sumber
2
Ini luar biasa , terima kasih banyak telah berbagi ini. Benar-benar sempurna dan persis apa yang saya butuhkan.
Christian Varga
Di mana saya meletakkan kode ini? (file mana?)
Joelio
@ Joelio Bisakah Anda lebih spesifik tentang masalah yang Anda selesaikan? Sebagai pendekatan sederhana, saya baru saja menambahkan kode ini ke functions.php saya, dan menambahkan definisi sederhana ke wp-config.php saya yang mengatur ENV_PRODUCTION konstan ke true atau false tergantung pada domain permintaan.
goldenapples
@goldenapples Saya menambahkan kode ini ke function.php saya, apa yang harus saya tambahkan ke wp-config? Terima kasih atas bantuan Anda
Graham Slick
@MatthiasGrahamSlick - Anda hanya perlu sesuatu yang akan menetapkan ENV_PRODUCTIONkonstanta jika Anda sedang berproduksi. Saya menggunakan domain.com untuk produksi dan staging.domain.com untuk pementasan, jadi baris saya adalah define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );Apakah itu membantu?
goldenapples
0

Saya pikir plugin "Editor Peran Pengguna" yang tersedia di situs web WordPress.org mungkin yang Anda cari. Ngomong-ngomong, mengapa Anda ingin memberikan akses ke draft Anda untuk semua orang? Saya pribadi tidak bisa memikirkan contoh di mana ini akan diperlukan.

Georgi Demirev
sumber
Tidak, seperti yang disebutkan dalam pertanyaan, saya tidak mencari solusi berbasis plugin. Usecase sedikit rumit, tetapi saya yakin ini adalah solusi terbaik untuk tugas khusus yang saya coba selesaikan ini. :-)
Amal Murali
Saya bingung tentang alasannya juga. Jika Anda ingin semua orang melihat posting, mengapa tidak mempublikasikan posting? Anda dapat menggunakan bidang khusus pada pos untuk melacak keadaan khusus yang mungkin ingin Anda tetapkan.
KenB
Saya membiarkan pengguna melihat konten, tetapi untuk alasan tertentu saya tidak ingin posting dipublikasikan.
Amal Murali
0

Anda hanya dapat mengubah visibilitas pada halaman / posting ke "Pribadi" yang hanya dapat dilihat oleh Editor dan Administrator dan bukan pengunjung umum, mesin pencari, rss feed, dll.

NickJAB
sumber
0

Saya pikir komentar GM adalah yang terbaik di sini. Saya berasumsi Anda mencoba melakukan hal berikut:

  1. Tulis posting
  2. Simpan sebagai draf
  3. Izinkan pengguna eksternal (tidak login) melihat konsep untuk disetujui
  4. Menerbitkan

Apakah itu benar?

Sayangnya, saya tidak bisa memikirkan cara sederhana untuk melakukan ini. Anda dapat mempostingnya sebagai pos pribadi sehingga mereka perlu memasukkan kata sandi untuk melihatnya tetapi Anda harus masuk untuk ini. Anda juga bisa melindunginya dengan kata sandi, tetapi kemudian kata sandi itu masih akan muncul di feed dan daftar posting terbaru Anda, dll. Tidak bisakah Anda membuat akun pengguna tamu dan memberi mereka nama pengguna / kata sandi saat Anda memberikan URL?

Baca di sini untuk info lebih lanjut: http://codex.wordpress.org/Content_Visibility

Atau, ada plugin yang mungkin sesuai dengan kebutuhan Anda: http://wordpress.org/extend/plugins/shareadraft/ Saya melihat kode dengan cepat dan tampaknya pengembang memodifikasi nilai yang dikembalikan oleh get_post_status sehingga Anda mungkin dapat bermain-main dengan itu:

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

HTH

TomC
sumber
0

Jika Anda tidak peduli apakah posting itu "diterbitkan" atau tidak, hanya ingin diakses oleh siapa saja di URL yang diterbitkan secara teratur dan tidak muncul di halaman utama / hasil pencarian / rss feed dll, plugin ini berfungsi dengan WP 4.6. 1 dan memungkinkan Anda menyempurnakan di mana posting muncul:

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

Sarah Northway
sumber