Como faço para tornar uma postagem de rascunho acessível a todos?

13

Eu tenho vários posts não publicados no meu site do Wordpress e estou tentando torná-lo acessível para usuários normais (que não estão logados) usando as lesmas de publicação normais ( site.com/post-here). Entendo que pode não ser a melhor prática, mas para meu objetivo especial, isso precisa ser feito.

Tentei adicionar o seguinte trecho de código ao meu functions.phparquivo:

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

Eu também tentei initgancho em vez de after_setup_theme. Sem sorte

Meu entendimento é que as alterações nas funções são salvas no banco de dados e, portanto, precisam ser feitas apenas uma vez. É por isso que estou usando o after_setup_themegancho para chamar a função.

Mas quando tento acessar a página como um usuário normal, aparece uma página 404 em vez de mostrar o conteúdo da postagem. Também tentei carregar o URL de visualização ( site.com/?p=212&preview=true), mas isso também não funcionou.

Estas são minhas suposições:

  • o usuário normal não tem o suficiente capspara ler a postagem dos rascunhos.
  • não é possível testar e visualizar postagens de rascunho no front-end para nenhum usuário (incluindo administradores).

Que mudanças eu tenho que fazer para realizar o que estou tentando fazer? Se não for possível, que soluções alternativas você sugere?

Nota: Não estou procurando soluções baseadas em plug-ins.

Amal Murali
fonte
2
Eu acho que há um pouco de confusão aqui. Se alguém não está logado, ele / ela não é um usuário, portanto, ele / ela não tem nenhum limite. Os assinantes são usuários, portanto, eles precisam ser registrados e fazer o login para serem reconhecidos como assinantes. Você não pode fornecer recursos a alguém que não fez login. Se você quiser que alguém não faça login, visualize suas postagens, elas simplesmente não são diferentes das postagens publicadas. Então, por que não publicá-lo? Ou você deseja mostrar um rascunho para os assinantes (conectado como assinantes)?
gmazzap
@ GM: Estou tentando tornar as postagens não publicadas acessíveis a todos que conhecem o link permanente direto para a postagem. Pode parecer um requisito estranho, mas eu preciso disso para um projeto. Como mencionei na minha pergunta, se isso não for possível - você pode sugerir outras soluções alternativas (se você conhece uma, é claro)?
Amal Murali
@ GM: Você conhece um plugin que faz isso?
Amal Murali
Você leu a resposta logo abaixo com 3 votos positivos? Ele explica como fazê-lo e, no final da resposta, você encontra um link para baixar um plug-in de trabalho completo no github.
gmazzap
2
Para leitores posteriores: Existe este plugin de Dominik Schilling disponível no GitHub.
Kaiser #

Respostas:

12

Você não pode atribuir recursos a usuários desconhecidos. Se você deseja tornar uma postagem visível para todos, crie um URL separado para essas postagens e adicione um elemento de controle ao editor de postagens para ativar a visualização apenas nas postagens selecionadas.
Quando esse URL é chamado, verifique se uma visualização é permitida para a postagem e se a postagem ainda não foi publicada. Verifique também se os mecanismos de pesquisa ignoram esse URL.

Para o URL, eu usaria um ponto de extremidade :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Agora você pode criar URLs como…

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

… Onde 123está o ID da postagem.

Em seguida, use um manipulador de retorno de chamada para inspecionar o ID da postagem, verifique se é válido e substitua a consulta principal. Este é provavelmente o único caso de uso aceitável para query_posts(). :)

Digamos que o terminal seja uma classe T5_Endpoint(um modelo) e o manipulador de saída seja uma classe T5_Render_Endpoint(uma visualização) que recebe o modelo passado anteriormente. Provavelmente existe um método render()chamado 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é outro modelo (classe T5_Post_Meta) para o pós-valor meta que controla se uma visualização é permitida. O controle é definido na caixa Publicar ( açãopost_submitbox_misc_actions ), renderizada por outra exibição que obtém a mesma meta classe.

captura de tela

Então, T5_Post_Metasabe onde e quando armazenar o meta-valor, as visualizações fazem algo com ele.
Além disso, conecte-setransition_post_status para excluir o meta campo da postagem quando a postagem for publicada. Não queremos desperdiçar recursos, certo?

Este é apenas um esboço. Há muitos detalhes a serem abordados ... Eu escrevi um pequeno plugin que mostra como implementar isso: Visualização pública do T5 .

fuxia
fonte
Muito obrigado. Finalmente alcancei meu objetivo com alguns ajustes. Impressionante. : D
Amal Murali
6

Resolvi esse problema da maneira que pensei ser mais simples do que a resposta de @ toscho acima.

Meu caso de uso é que estou usando o mesmo banco de dados para um site de armazenamento temporário da intranet interno e um site voltado para o público, e o fluxo de trabalho é que os autores escrevem rascunhos e o compartilham com outros usuários que visualizam esses rascunhos no site da intranet, antes da publicação. Especificamente, eu não queria exigir que os revisores fizessem login para ver rascunhos, portanto, apenas dependo de uma constante, ENV_PRODUCTIONque é definida no arquivo wp-config com base no nome do host $_SERVER['SERVER_NAME']. Isso é o que as verificações ENV_PRODUCTIONaqui estão fazendo; apenas um curto-circuito em todos esses filtros se o site de produção estiver sendo visualizado.

Isso é um pouco estranho, porque você precisa se conectar após o WP_Query remover todas as postagens da matriz $ wp_query-> posts, mas parece estável e seguro para mim.

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

Existem duas partes separadas para os filtros.

  • Um filtro no gancho "pre_get_posts" define o post_status padrão para 'publicar, rascunho' no site de preparação. Isso retornará as postagens de rascunho nas listagens de arquivo.
  • Um filtro separado é necessário para visualizações únicas, porque há alguma lógica desagradável na classe WP_Query para remover postagens de rascunho dos resultados da consulta, a menos que o usuário atual possa editá-las. Eu resolvi isso filtrando 'the_posts' e adicionando a postagem que eu queria de volta aos resultados.
maçãs douradas
fonte
2
Isso é incrível , muito obrigado por compartilhar isso. Absolutamente perfeito e exatamente o que eu precisava.
Christian Varga
Onde coloco esse código? (que arquivo (s)?)
Joelio 27/04/2015
@ Joelio Você pode ser específico sobre o problema que está resolvendo? Como uma abordagem simples, adicionei esse código ao meu functions.php e adicionei uma definição simples ao meu wp-config.php, que definiu a constante ENV_PRODUCTION como true ou false, dependendo do domínio da solicitação.
goldenapples
@oldenapples Adicionei este pedaço de código ao meu function.php, o que devo adicionar ao wp-config? Obrigado pela sua ajuda
Graham Slick
@ MatthiasGrahamSlick - Você só precisa de algo que definirá a ENV_PRODUCTIONconstante se estiver em produção. Eu estava usando domain.com para produção e staging.domain.com para teste, então minha linha foi: define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );Isso ajuda?
goldenapples
0

Eu acho que o plugin "User Role Editor" disponível no site WordPress.org pode ser o que você está procurando. A propósito, por que você deseja dar acesso a seus rascunhos para todos? Pessoalmente, não consigo pensar em um caso em que isso seria necessário.

Georgi Demirev
fonte
Não, como mencionado na pergunta, não estou procurando soluções baseadas em plug-ins. O caso de usuário é um pouco complicado, mas tenho certeza de que esta é a melhor solução para esta tarefa específica que estou tentando realizar. :-)
Amal Murali
Estou perplexo com o motivo também. Se você deseja que todos vejam a postagem, por que não simplesmente publicar a postagem? Você pode usar campos personalizados na postagem para rastrear qualquer estado especial que desejar definir.
26413 KenB
Estou permitindo que os usuários vejam o conteúdo, mas, por algum motivo específico, não quero que as postagens sejam publicadas.
Amal Murali
0

Você pode alterar a visibilidade da página / postagem para "Privado", visível apenas para editores e administradores, e não para visitantes públicos, mecanismos de pesquisa, feeds RSS, etc.

NickJAB
fonte
0

Eu acho que o comentário da GM é o melhor aqui. Presumo que você esteja tentando fazer o seguinte:

  1. Escreva uma postagem
  2. Salvar como rascunho
  3. Permitir que um usuário externo (não conectado) veja o rascunho para aprovação
  4. Publicar

Isso está correto?

Infelizmente, não consigo pensar em nenhuma maneira simples de fazer isso. Você pode publicá-la como uma publicação particular, para que eles precisem digitar uma senha para visualizá-la, mas você precisa estar logado para isso. Você também pode protegê-lo com senha, mas ele ainda aparecerá no seu feed e na lista de postagens recentes, etc. Não foi possível criar uma conta de usuário convidado e fornecer o nome de usuário / senha ao fornecer o URL?

Leia aqui para mais informações: http://codex.wordpress.org/Content_Visibility

Como alternativa, existe um plug-in que pode atender às suas necessidades: http://wordpress.org/extend/plugins/shareadraft/ Eu dei uma rápida olhada no código e parece que o desenvolvedor está modificando o valor retornado por get_post_status para que você possa capaz de brincar com isso:

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

HTH

TomC
fonte
0

Se você não se importa se a publicação é "publicada" ou não, apenas deseja que ela seja acessível por qualquer pessoa no URL normal publicado e não apareça na página principal / resultados da pesquisa / feeds RSS, etc., este plug-in funcionou com o WP 4.6. 1 e permite ajustar onde uma postagem aparece:

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

Sarah Northway
fonte