Làm thế nào để tôi thực hiện một bài viết dự thảo có thể truy cập được cho mọi người?


13

Tôi có một số bài đăng chưa được công bố trong trang web Wordpress của mình và tôi đang cố gắng làm cho nó có thể truy cập được đối với người dùng bình thường (những người không đăng nhập) bằng cách sử dụng các bài đăng bình thường ( site.com/post-here). Tôi hiểu nó có thể không phải là thực tiễn tốt nhất nhưng với mục đích đặc biệt của tôi, điều này cần phải được thực hiện.

Tôi đã thử thêm đoạn mã sau vào functions.phptệp của mình :

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

Tôi cũng đã thử inithook thay vì after_setup_theme. Không may mắn.

Hiểu biết của tôi là thay đổi vai trò được lưu vào cơ sở dữ liệu nên chỉ cần thực hiện một lần. Đó là lý do tại sao tôi sử dụng after_setup_themehook để gọi hàm.

Nhưng khi tôi cố gắng truy cập trang như một người dùng bình thường, tôi đang được hiển thị trang 404 thay vì hiển thị nội dung bài đăng. Tôi cũng đã thử tải URL xem trước ( site.com/?p=212&preview=true) nhưng cũng không hoạt động.

Đây là những dự đoán của tôi:

  • người dùng bình thường không có đủ capsđể đọc bài viết nháp.
  • kiểm tra và xem các bài viết nháp ở mặt trước là không thể đối với bất kỳ người dùng nào (bao gồm cả quản trị viên).

Tôi phải thực hiện những thay đổi nào để thực hiện những gì tôi đang cố gắng thực hiện? Nếu không thể, bạn có đề xuất giải pháp thay thế nào?

Lưu ý: Tôi không tìm kiếm các giải pháp dựa trên plugin.


2
Tôi nghĩ rằng có một chút nhầm lẫn ở đây. Nếu ai đó chưa đăng nhập, anh ấy / cô ấy không phải là người dùng, vì vậy anh ấy / cô ấy không có bất kỳ giới hạn nào. Người đăng ký là người dùng, vì vậy họ phải được đăng ký và đăng nhập để được công nhận là người đăng ký. Bạn không thể cung cấp khả năng cho ai đó chưa đăng nhập. Nếu bạn muốn bất kỳ ai không đăng nhập xem bài viết của bạn, đơn giản là không khác biệt với các bài đăng được xuất bản. Vì vậy, tại sao không pubblish nó? Hay bạn muốn hiển thị bản nháp cho người đăng ký (đăng nhập với tư cách người đăng ký)?
gmazzap

@GM: Tôi đang cố gắng làm cho các bài đăng chưa được công bố có thể truy cập được đối với mọi người biết permalink trực tiếp cho bài đăng. Nó có vẻ như là một yêu cầu kỳ lạ, nhưng tôi cần điều này cho một dự án. Như tôi đã đề cập trong câu hỏi của mình, nếu điều này là không thể - bạn có thể đề xuất các công việc khác (tất nhiên là nếu bạn biết) không?
Amal Murali

@GM: Bạn có biết một plugin nào không?
Amal Murali

Bạn đã đọc câu trả lời ngay bên dưới với 3 upvote chưa? Nó giải thích cách thực hiện và ở cuối câu trả lời, bạn tìm thấy một liên kết để tải xuống một plugin hoạt động đầy đủ từ github.
gmazzap

2
Dành cho những độc giả sau này: Có plugin này của Dominik Schilling có sẵn trên GitHub.
kaiser

Câu trả lời:


12

Bạn không thể gán khả năng cho người dùng không xác định. Nếu bạn muốn hiển thị một bài đăng cho mọi người, hãy tạo một URL riêng cho các bài đăng này và thêm một yếu tố kiểm soát vào trình chỉnh sửa bài đăng để chỉ cho phép xem trước trên các bài đăng được chọn.
Khi một URL như vậy được gọi, hãy kiểm tra xem bản xem trước có được phép cho bài đăng không và nếu bài đăng chưa được xuất bản. Cũng đảm bảo các công cụ tìm kiếm bỏ qua URL này.

Đối với URL, tôi sẽ sử dụng điểm cuối :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Bây giờ bạn có thể tạo các URL như thế

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

123Sênh nơi ist ID bài.

Sau đó sử dụng trình xử lý gọi lại để kiểm tra ID bài đăng, kiểm tra xem nó có hợp lệ không và ghi đè lên truy vấn chính. Đây có lẽ là trường hợp sử dụng duy nhất được chấp nhận cho query_posts(). :)

Giả sử điểm cuối là một lớp T5_Endpoint(một mô hình) và trình xử lý đầu ra là một lớp T5_Render_Endpoint(một khung nhìn) sẽ đưa mô hình đi qua trước đó. Sau đó, có lẽ có một phương thức render()được gọi là 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->metalà một mô hình (lớp T5_Post_Meta) khác cho giá trị meta bài kiểm soát nếu cho phép xem trước. Điều khiển được đặt vào hộp Xuất bản ( hành độngpost_submitbox_misc_actions ), được hiển thị bởi một chế độ xem khác có cùng lớp meta.

chụp màn hình

Vì vậy, T5_Post_Metabiết nơi nào và khi nào để lưu trữ giá trị meta, các lượt xem làm điều gì đó với nó.
Ngoài ra, móc vàotransition_post_status để xóa trường meta bài đăng khi bài viết được xuất bản. Chúng ta không muốn lãng phí tài nguyên, phải không?

Đây chỉ là một phác thảo. Có rất nhiều chi tiết để nói về tôi đã viết một plugin nhỏ chỉ ra cách thực hiện điều này: Bản xem trước công khai của T5 .


Cảm ơn bạn rất nhiều. Cuối cùng tôi đã đạt được mục tiêu của mình với một số điều chỉnh. Tuyệt vời. : D
Amal Murali

6

Tôi đã giải quyết vấn đề này theo cách mà tôi nghĩ là một cách đơn giản hơn câu trả lời của @ toscho ở trên.

Trường hợp sử dụng của tôi là tôi đang sử dụng cùng một cơ sở dữ liệu cho một trang dàn mạng nội bộ và một trang web công khai, và quy trình làm việc là các tác giả viết các bản nháp và chia sẻ nó với những người dùng khác xem các bản nháp đó trên trang mạng nội bộ trước khi xuất bản. Tôi đặc biệt không muốn yêu cầu người đánh giá đăng nhập để xem bản nháp, vì vậy tôi chỉ phụ thuộc vào một hằng số, ENV_PRODUCTIONđược đặt trong tệp wp-config dựa trên tên máy chủ lưu trữ $_SERVER['SERVER_NAME']. Đó là những gì kiểm tra ENV_PRODUCTIONở đây đang làm; chỉ cần rút ngắn tất cả các bộ lọc này nếu trang web sản xuất đang được xem.

Điều này hơi lạ, vì bạn phải kết nối sau khi WP_Query xóa tất cả các bài đăng khỏi mảng bài đăng $ wp_query->, nhưng nó có vẻ ổn định và an toàn với tôi.

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

Có hai phần riêng biệt cho các bộ lọc.

  • Một bộ lọc trên hook "pre_get_posts" đặt post_status mặc định thành 'xuất bản, bản nháp' trên trang web dàn dựng. Điều này sẽ trả về các bài viết dự thảo trong danh sách lưu trữ.
  • Một bộ lọc riêng là cần thiết cho các chế độ xem đơn lẻ, vì có một số logic khó chịu trong lớp WP_Query để xóa các bài đăng nháp khỏi kết quả truy vấn trừ khi trình duyệt hiện tại có thể chỉnh sửa chúng. Tôi đã khắc phục điều này bằng cách lọc 'the_posts' và thêm bài đăng tôi muốn quay lại kết quả.

2
Điều này thật khó tin , cảm ơn bạn rất nhiều vì đã chia sẻ điều này. Hoàn toàn hoàn hảo và chính xác những gì tôi cần.
Christian Varga

Tôi để mã này ở đâu? (tập tin nào?)
Joelio

@Joelio Bạn có thể nói cụ thể về vấn đề bạn đang giải quyết không? Như một cách tiếp cận đơn giản, tôi chỉ cần thêm mã này vào hàm.php của mình và thêm một định nghĩa đơn giản vào wp-config.php của tôi để đặt hằng số ENV_PRODITH thành đúng hoặc sai tùy thuộc vào miền yêu cầu.
Goldenapples

@goldenapples Tôi đã thêm đoạn mã này vào hàm.php của mình, tôi nên thêm gì vào wp-config? Cảm ơn sự giúp đỡ của bạn
Graham Slick

@MatthiasGrahamSlick - Bạn chỉ cần một cái gì đó sẽ đặt ENV_PRODUCTIONhằng số nếu bạn đang sản xuất. Tôi đã sử dụng domain.com để sản xuất và staging.domain.com để dàn dựng, vì vậy dòng của tôi là define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );Điều đó có giúp ích không?
Goldenapples

0

Tôi nghĩ rằng plugin "Trình biên tập vai trò người dùng" có sẵn trên trang web của WordPress.org có thể là thứ bạn đang tìm kiếm. Nhân tiện, tại sao bạn muốn cấp quyền truy cập vào bản nháp của mình cho mọi người? Cá nhân tôi không thể nghĩ về một trường hợp mà điều này sẽ được yêu cầu.


Không, như đã đề cập trong câu hỏi, tôi không tìm kiếm các giải pháp dựa trên plugin. Usecase hơi phức tạp nhưng tôi chắc chắn đây là giải pháp tốt nhất cho nhiệm vụ cụ thể này mà tôi đang cố gắng thực hiện. :-)
Amal Murali

Tôi cũng bối rối về lý do. Nếu bạn muốn tất cả mọi người xem bài viết, tại sao không chỉ đơn giản là xuất bản bài viết? Bạn có thể sử dụng các trường tùy chỉnh trên bài đăng để theo dõi bất kỳ trạng thái đặc biệt nào bạn có thể muốn xác định.
KenB

Tôi cho phép người dùng xem nội dung, nhưng vì một số lý do cụ thể, tôi không muốn các bài đăng được xuất bản.
Amal Murali

0

Bạn chỉ có thể thay đổi mức độ hiển thị trên trang / bài đăng thành "Riêng tư" chỉ hiển thị cho Biên tập viên và Quản trị viên chứ không phải khách truy cập công cộng, công cụ tìm kiếm, nguồn cấp dữ liệu rss, v.v.


0

Tôi nghĩ bình luận của GM là tốt nhất ở đây. Tôi giả sử bạn đang cố gắng làm như sau:

  1. Viết một bài
  2. Lưu dưới dạng bản nháp
  3. Cho phép người dùng bên ngoài (không đăng nhập) xem dự thảo để phê duyệt
  4. Công bố

Đúng không?

Thật không may, tôi không thể nghĩ ra bất kỳ cách đơn giản nào để làm điều này. Bạn có thể đăng nó dưới dạng một bài đăng riêng tư để họ cần nhập mật khẩu để xem nhưng bạn cần phải đăng nhập để làm điều này. Bạn cũng có thể bảo vệ mật khẩu, nhưng sau đó nó sẽ vẫn xuất hiện trong nguồn cấp dữ liệu và danh sách các bài đăng gần đây của bạn, v.v. Bạn không thể tạo tài khoản người dùng khách và cung cấp cho họ tên người dùng / mật khẩu khi bạn cung cấp cho họ URL?

Đọc ở đây để biết thêm: http://codex.wordpress.org/Content_Visibility

Ngoài ra, có một plugin có thể phù hợp với nhu cầu của bạn: http://wordpress.org/extend/plugins/shareadraft/ Tôi đã xem nhanh mã và có vẻ như nhà phát triển đang sửa đổi giá trị được trả về bởi get_post_status để bạn có thể có thể chơi xung quanh với điều đó:

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

HTH


0

Nếu bạn không quan tâm liệu bài đăng có được "xuất bản" hay không, chỉ muốn bất kỳ ai truy cập vào URL được xuất bản thông thường và không hiển thị trên trang chính / kết quả tìm kiếm / nguồn cấp dữ liệu rss, v.v., plugin này hoạt động với WP 4.6. 1 và cho phép bạn tinh chỉnh nơi bài đăng xuất hiện:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.