Comment rendre un brouillon de publication accessible à tous?


13

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 slugs de publication normaux ( site.com/post-here). Je comprends que ce n'est peut-être pas la meilleure pratique, mais pour mon objectif particulier, cela doit être fait.

J'ai essayé d'ajouter l'extrait de code suivant dans mon functions.phpfichier:

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 également essayé le initcrochet au lieu de after_setup_theme. Pas de chance.

D'après ce que je comprends, les modifications apportées aux rôles sont enregistrées dans la base de données et ne doivent donc être effectuées qu'une seule fois. C'est pourquoi j'utilise after_setup_themehook pour appeler la fonction.

Mais lorsque j'essaie d'accéder à la page en tant qu'utilisateur normal, une page 404 s'affiche 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 capspour lire le brouillon.
  • tester et afficher les brouillons de messages sur le front-end n'est possible pour aucun utilisateur (y compris les administrateurs).

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

Remarque: je ne recherche pas de solutions basées sur des plugins.


2
Je pense qu'il y a un peu de confusion ici. Si quelqu'un n'est pas connecté, il / elle n'est pas un utilisateur, donc il / elle n'a pas de plafond. Les abonnés sont des utilisateurs, ils doivent donc être enregistrés et effectuer la connexion pour être reconnus comme abonnés. Vous ne pouvez pas donner des capacités à une personne qui ne s'est pas connectée. Si vous voulez que quelqu'un non connecté affiche vos messages, ils ne sont tout simplement pas différents du tout des messages publiés. Alors, pourquoi ne pas le publier? Ou voulez-vous montrer le brouillon aux abonnés (connectés en tant qu'abonnés)?
gmazzap

@GM: J'essaie de rendre les publications non publiées accessibles à tous ceux qui connaissent le lien permanent vers la publication. Cela peut sembler une exigence étrange, mais j'en ai besoin pour un projet. Comme je l'ai mentionné dans ma question, si cela n'est pas possible - pouvez-vous suggérer d'autres solutions (si vous en connaissez un, bien sûr)?
Amal Murali

@GM: Connaissez-vous un plugin qui fait ça?
Amal Murali

Avez-vous lu la réponse juste en dessous avec 3 votes positifs? Il explique comment le faire et à la fin de la réponse, vous trouverez un lien pour télécharger un plugin de travail complet à partir de github.
gmazzap

2
Pour les lecteurs ultérieurs: Il y a ce plugin de Dominik Schilling disponible sur GitHub.
kaiser

Réponses:


12

Vous ne pouvez pas attribuer de capacité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 activer l'aperçu uniquement sur les publications sélectionnées.
Lorsqu'une telle URL est appelée, vérifiez si un aperçu est autorisé pour la publication et si la publication n'a pas déjà été publiée. Assurez-vous également que les moteurs de recherche ignorent cette URL.

Pour l'URL, j'utiliserais un point de terminaison :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Vous pouvez maintenant créer des URL comme…

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

… Où 123est l'identifiant du message.

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

Disons que le point de terminaison 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 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->metaest un autre modèle (classe T5_Post_Meta) pour la valeur méta post qui contrôle si un aperçu est autorisé. Le contrôle est défini dans la zone Publier ( actionpost_submitbox_misc_actions ), rendu par une autre vue qui obtient la même méta-classe.

capture d'écran

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

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


Merci beaucoup. J'ai finalement atteint mon objectif avec quelques ajustements. Impressionnant. : D
Amal Murali

6

J'ai résolu ce problème de ce que je pensais être une manière 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 de transfert intranet interne et un site accessible au public, et le flux de travail est que les auteurs rédigent des brouillons et les partagent avec d'autres utilisateurs qui consultent ces brouillons sur le site intranet, avant de les publier. Je ne voulais pas spécifiquement que les réviseurs se connectent pour voir les brouillons, donc je ne fais que dépendre d'une constante, ENV_PRODUCTIONqui est 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 ENV_PRODUCTIONici; il suffit de court-circuiter tous ces filtres si le site de production est affiché.

C'est un peu bizarre, car vous devez vous connecter après que WP_Query a supprimé tous les messages 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 projets de messages dans les listes d'archives.
  • Un filtre distinct est nécessaire pour les vues uniques, car il existe une logique désagréable dans la classe WP_Query pour supprimer les brouillons de messages des résultats de la requête, à moins que l'utilisateur actuel ne puisse les modifier. J'ai contourné cela en filtrant 'the_posts' et en ajoutant le message que je voulais directement aux résultats.

2
C'est incroyable , merci beaucoup de partager cela. Absolument parfait et exactement ce dont j'avais besoin.
Christian Varga

Où dois-je mettre ce code? (quel (s) fichier (s)?)
Joelio

@Joelio Pouvez-vous être précis sur le problème que vous résolvez? Comme une approche simple, je viens d'ajouter ce code à mon functions.php, et ajouté une définition simple à mon wp-config.php qui définit la constante ENV_PRODUCTION sur true ou false selon le domaine de la demande.
goldenapples

@goldenapples J'ai ajouté ce morceau de code à mon function.php, que dois-je ajouter à wp-config? Merci pour votre aide
Graham Slick

@MatthiasGrahamSlick - Vous avez juste besoin de quelque chose qui définira la ENV_PRODUCTIONconstante si vous êtes en production. J'utilisais domain.com pour la production et staging.domain.com pour la mise en scène, donc ma ligne était define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );Est-ce que cela aide?
goldenapples

0

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


Non, comme mentionné dans la question, je ne recherche pas de solutions basées sur des plugins. Le cas d'utilisation est légèrement compliqué, mais je suis sûr que c'est la meilleure solution pour cette tâche spécifique que j'essaie d'accomplir. :-)
Amal Murali

Je suis également perplexe quant à la raison. Si vous voulez que tout le monde voie le message, pourquoi ne pas simplement publier le message? Vous pouvez utiliser des champs personnalisés sur le post pour suivre tout état spécial que vous souhaitez définir.
KenB

Je laisse les utilisateurs voir le contenu, mais pour une raison spécifique, je ne veux pas que les messages soient publiés.
Amal Murali

0

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


0

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

  1. Rédiger un article
  2. Enregistrer comme brouillon
  3. Autoriser un utilisateur externe (non connecté) à consulter le brouillon pour approbation
  4. Publier

Est-ce exact?

Malheureusement, je ne vois pas de moyen simple de le faire. Vous pouvez le publier en tant que publication privée afin qu'ils aient besoin d'entrer un mot de passe pour le voir, 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 messages récents, etc. Ne pourriez-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 rapide coup d'œil au code et il semble que le développeur modifie la valeur retournée par get_post_status afin que vous soyez capable de jouer avec ça:

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

HTH


0

Si vous ne vous souciez pas si la publication est "publiée" ou non, vous voulez juste qu'elle soit accessible par n'importe qui à l'URL régulière publiée et n'apparaissant pas sur la page principale / les résultats de recherche / les flux rss, etc., ce plugin fonctionnait avec WP 4.6. 1 et vous permet d'affiner où apparaît un message:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.