web-dev-qa-db-fra.com

Comment rendre un brouillon accessible à tout le monde?

J'ai plusieurs messages non publiés sur mon site Wordpress et j'essaie de le rendre accessible aux utilisateurs normaux (qui ne sont pas connectés) en utilisant les messages normaux (site.com/post-here). Je comprends que ce n’est peut-être pas la meilleure pratique, mais mon but particulier est de le faire.

J'ai essayé d'ajouter l'extrait de code suivant dans mon fichier 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');

J'ai aussi essayé init hook au lieu de after_setup_theme. Pas de chance.

Si j'ai bien compris, les modifications apportées aux rôles sont enregistrées dans la base de données; elles ne doivent donc être effectuées qu'une seule fois. C'est pourquoi j'utilise after_setup_theme hook pour appeler la fonction.

Mais lorsque j'essaie d'accéder à la page en tant qu'utilisateur normal, on me montre une page 404 au lieu d'afficher le contenu du message. J'ai également essayé de charger l'URL de prévisualisation (site.com/?p=212&preview=true), mais cela n'a pas fonctionné non plus.

Ce sont mes suppositions:

  • l'utilisateur normal n'a pas assez de caps pour lire le brouillon.
  • tester et afficher des brouillons sur le front-end n'est possible pour aucun utilisateur (y compris les administrateurs).

Quels changements dois-je faire pour accomplir ce que j'essaie de faire? Si ce n'est pas possible, quelles solutions alternatives suggérez-vous?

Note: Je ne cherche pas de solutions à base de plugin.

12
Amal Murali

Vous ne pouvez pas attribuer de fonctionnalités à des utilisateurs inconnus. Si vous souhaitez rendre une publication visible pour tout le monde, créez une URL distincte pour ces publications et ajoutez un élément de contrôle à l'éditeur de publication pour permettre l'aperçu des publications sélectionnées uniquement.
Lorsqu’une telle URL est appelée, vérifiez si un aperçu est autorisé pour le message et si le message n’a pas déjà été publié. Assurez-vous également que les moteurs de recherche ignorent cette URL.

Pour l'URL, j'utiliserais un endpoint :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Maintenant, vous pouvez créer des URL comme…

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

… Où 123 est l'identifiant de la publication.

Utilisez ensuite un gestionnaire de rappel pour inspecter l'ID de publication, vérifier s'il est valide et écraser la requête principale. C’est probablement le seul cas d’utilisation acceptable pour query_posts(). :)

Supposons que le point final est une classe T5_Endpoint (un modèle) et que le gestionnaire de sortie est une classe T5_Render_Endpoint (une vue) qui obtient le modèle passé plus tôt. Ensuite, il existe probablement une méthode render() appelée sur 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 est un autre modèle (class T5_Post_Meta) pour la méta-valeur post qui contrôle si un aperçu est autorisé. Le contrôle est défini dans la zone Publish ( action post_submitbox_misc_actions ), rendue par une autre vue qui obtient la même méta classe.

screen shot

Donc, T5_Post_Meta sait où et quand stocker la méta-valeur, les vues en font quelque chose.
En outre, raccordez-le à transition_post_status pour supprimer le champ méta de la publication lorsque la publication est publiée. Nous ne voulons pas gaspiller des ressources, non?

Ceci est juste un aperçu. Il y a beaucoup de détails à couvrir… J'ai écrit un petit plugin qui montre comment implémenter ceci: T5 Public Preview .

12
fuxia

J'ai résolu ce problème d'une manière qui me semblait plus simple que la réponse de @ toscho ci-dessus.

Mon cas d'utilisation est que j'utilise la même base de données pour un site intermédiaire intranet interne et un site destiné au public. Le workflow consiste en ce que les auteurs écrivent des brouillons et les partagent avec d'autres utilisateurs qui les visualisent sur le site intranet avant la publication. En particulier, je ne voulais pas obliger les relecteurs à se connecter pour voir les brouillons. Je ne suis donc fondé que sur une constante, ENV_PRODUCTION, définie dans le fichier wp-config en fonction du nom d'hôte dans $_SERVER['SERVER_NAME']. C’est ce que font les vérifications pour ENV_PRODUCTION ici; court-circuiter tous ces filtres si le site de production est visualisé.

C'est un peu bizarre, car vous devez vous connecter après que WP_Query ait supprimé toutes les publications du tableau $ wp_query-> posts, mais cela me semble stable et sécurisé.

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

Les filtres comportent deux parties distinctes.

  • Un filtre sur le crochet "pre_get_posts" définit le post_status par défaut sur "publier, brouillon" sur le site intermédiaire. Cela renverra les brouillons dans les listes d'archives.
  • Un filtre distinct est nécessaire pour les vues uniques, car la classe WP_Query contient une logique assez désagréable pour supprimer les brouillons des résultats de la requête, à moins que l'utilisateur en cours ne puisse les modifier. J'ai contourné ce problème en filtrant "the_posts" et en ajoutant le message que je voulais revenir directement aux résultats.
5
goldenapples

Je pense que le plugin "User Role Editor" disponible sur le site Web de WordPress.org pourrait être ce que vous cherchez. Au fait, pourquoi voulez-vous donner accès à vos brouillons à tout le monde? Personnellement, je ne peux penser à un cas où cela serait nécessaire.

0
Georgi Demirev

Si vous ne vous souciez pas de savoir si le message est "publié" ou pas, voulez-le être accessible à quiconque à l'adresse URL publiée régulièrement et ne pas apparaître sur la page principale/résultats de la recherche/flux rss, etc., ce plugin a fonctionné avec WP 4.6.1 et vous permet d’ajuster précisément l’affichage d’un message:

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

0
Sarah Northway

Je pense que le commentaire de G.M. est le meilleur ici. Je suppose que vous essayez de faire ce qui suit:

  1. Écrire un post
  2. Enregistrer comme brouillon
  3. Autoriser un utilisateur externe (non connecté) à afficher le brouillon pour approbation
  4. Publier

Est-ce exact?

Malheureusement, je ne vois pas de moyen simple de faire cela. Vous pouvez le poster en tant que message privé pour qu'il soit nécessaire de saisir un mot de passe pour le consulter, mais vous devez être connecté pour cela. Vous pouvez également le protéger par mot de passe, mais il apparaîtra toujours dans votre flux et votre liste de publications récentes, etc. Ne pouvez-vous pas créer un compte d'utilisateur invité et leur donner le nom d'utilisateur/mot de passe lorsque vous leur donnez l'URL?

Lisez ici pour plus d'informations: http://codex.wordpress.org/Content_Visibility

Alternativement, il existe un plugin qui pourrait répondre à vos besoins: http://wordpress.org/extend/plugins/shareadraft/ J'ai jeté un coup d'œil au code et il semble que le développeur modifie la valeur renvoyée par get_post_status afin que vous puissiez jouer avec ça:

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

HTH

0
TomC

Vous pouvez simplement changer la visibilité de la page/de la publication sur "Privée" qui n'est visible que pour les éditeurs et les administrateurs et non les visiteurs publics, les moteurs de recherche, les flux rss, etc.

0
NickJAB