Snippets e Shortcodes

Criando um sistema de revisão de posts no WordPress

Google+ Pinterest LinkedIn Tumblr
Anúncios Google

Você que tem um site com vários autores no WordPress, sabe que pode ser difícil a tarefa de revisar envios de colaboradores, mantê-los informados sobre o status da aprovação, etc.

No meu outro site, queria algo assim. Já tinha implementado um sistema simples de status de revisão (como mostrado nesse post), em que o artigo ficava marcado com um rótulo após ser avaliado pelo administrador — algo como “Aprovado”, “Reprovado”, “Expandir”, etc. Mas não era bem o que eu precisava: queria que o colaborador tivesse uma notificação do moderador sobre o artigo que enviou, algo simples dentro do próprio editor ou na visualização do post.

Não foi difícil mudar o código do artigo indicado acima. Com um pouco de jQuery e PHP, inseri uma caixa de mensagem que pode ser editada cada vez que o post for salvo no editor, e para atender outra pequena necessidade, criei um novo status “Top” para posts que serão marcados como Artigos Destacados (aqueles de melhor qualidade dentro do site).

O código original, sem as modificações, foi publicado por Kevin Chard no WPSnipp.

Vamos ver primeiro a função comentada inteira, e depois parte por parte:

function custom_status_metabox() {
	// só admin pode mudar o select
	current_user_can ('activate_plugins') ? $dis_able = '' : $dis_able = ' disabled'; 
	
	global $post;
	// $custom é o array com todos os custom fields
	$custom = get_post_custom($post->ID);
	// $status é o custom field "_status", como "Aprovado", "Reprovado", etc.
    $status = $custom["_status"][0];
	// $why é o custom field com o motivo da avaliação
	$why = $custom["_why"][0];
	
	// preencher o select
    $i = 0;
    $custom_status = array( // array de status disponíveis
		'Fila', // ainda não avaliei totalmente
		'Reprovado', //  ...
		'Ortografia', // corrija a ortografia
		'Formato', // problemas de formatação
		'Expandir', // aprovado, mas precisa de mais conteúdo
		'Aprovado', // OK!
		'Top' // ganha selo de Artigo Destacado
	);
	
	echo '<div class="misc-pub-section custom"><br />';
	// criando o select
    echo '<label>Revisão: </label>
	<select name="status" id="statuser"'. $dis_able .'>';
    	echo '<option class="default">Selecione...</option>';
    	echo '<option>-----------------</option>';
		for ($i = 0; $i < count($custom_status); $i++) {
			// checa se status já existe, e autopreenche o select
			if ($status == $custom_status[$i]) {
				echo '<option value="' . $custom_status[$i] . '" selected="true">' . $custom_status[$i] . '</option>';
			}
			else {
				echo '<option value="' . $custom_status[$i] . '">' . $custom_status[$i] . '</option>';
			}
		}
    echo '</select>';

		// criando a textarea
		echo '<div id="why-wrapper"><label>Motivo: </label><textarea style="width:100%" id="why" name="why" cols="10" rows="5"'. $dis_able .'>'. $custom["_why"][0] .'</textarea></div>';
		// jQuery: se é Top ou Aprovado, esconda e esvazie o motivo.
		// Se o select mudar, esvazie a textarea. 
		// Se o select mudar para Top ou Aprovado, esconda a textarea, senão revele-a.
		echo '<script>var $j = jQuery.noConflict();
		$j(function($){
			$(document).ready(function () {
				var statusatual = $(\'#statuser\').val();
				if( statusatual == \'Aprovado\' || statusatual == \'Top\' ) {
					$(\'#why-wrapper\').hide();
				}
			})
			$(\'#statuser\').change(function() {
				$(\'#why\').val(\'\');
				if(this.value == \'Aprovado\' || this.value == \'Top\') {
					$(\'#why-wrapper\').hide();
				}
				else {
					$(\'#why-wrapper\').show();
				}
			});
		});
		</script>';
	echo '</div>';	
} // fim função
add_action('save_post', 'save_status');

// salva o status
function save_status() {
	global $post;
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
		return $post->ID;
	}
	update_post_meta($post->ID, "_status", $_POST["status"]);
	update_post_meta($post->ID, "_why", $_POST["why"]);
}
add_action('admin_head', 'status_css');

// estilo dos status
function status_css() {
    echo '<style type="text/css">
    .default{font-weight:bold;}
    .custom{border-top:solid 1px #e5e5e5;}
    .custom_state {font-size:9px;color:#666;background:#e5e5e5;padding:3px 6px 3px 6px;}
    .custom_state.fila{background:#e5e5e5;color:#fff;}
    .custom_state.reprovado{background:#F33;color:#fff;}
    .custom_state.ortografia{background:#FC3;color:#fff;}
    .custom_state.formato{background:#FC3;color:#fff;}
    .custom_state.expandir{background:orange;color:white}
    .custom_state.aprovado{background:#0C3;color:#333;}
    .custom_state.top{background:#ffcc00;color:white}
    </style>';
}
add_filter('display_post_states', 'custom_post_state');

// exibe o status
function custom_post_state($states) {
  global $post;
  $show_custom_state = get_post_meta($post->ID, '_status');
  if ($show_custom_state) {
  	$states[] = __('<span class="custom_state ' . strtolower($show_custom_state[0]) . '">' . $show_custom_state[0] . '</span>');
  }
  return $states;
}
add_action('post_submitbox_misc_actions', 'custom_status_metabox');

Como já deve ter imaginado, isso vai no arquivo functions.php do seu tema. Logo no começo definimos uma variável chamada “dis_able” que vai carregar o status já existe para o post (caso exista um).

current_user_can ('activate_plugins') ? $dis_able = '' : $dis_able = ' disabled';

Ou seja, se o atual usuário é um administrador (usuários com a capacidade de ativar plugins), a variável fica vazia, e para outros usuários, leva o valor ” disabled”. Este valor será usado para desativar um select mais adiante, pois não quero usuários que não sejam administradores mudando seu valor.

    $custom = get_post_custom($post->ID);
    $status = $custom["_status"][0];
    $why = $custom["_why"][0];

Em $custom, pegamos os campos do post como array, e depois os valores de campos específicos nas variáveis $status (status já definido no post) e $why (motivo já definido). Se o post é novo e não teve status e motivo definidos, as variáveis  ficarão em branco.

$custom_status = array(
        'Fila', // ainda não avaliei totalmente
        'Reprovado', //  ...
        'Ortografia', // corrija a ortografia
        'Formato', // problemas de formatação
        'Expandir', // aprovado, mas precisa de mais conteúdo
        'Aprovado', // post OK!
        'Top' // Ok e ganha selo dos melhores artigos
    );

Aqui criamos um array guardado na variável $custom_status com os valores que ficarão na caixa tipo select com os status que quero para os posts.

echo '<label>Revisão: </label>
	<select name="status" id="statuser"'. $dis_able .'>';

Aqui é onde criamos o select. Lembra da variável “dis_able”? Se o usuário não é administrador, é ali no final que ela entra desabilitando o campo.

Em seguida, tem uma sequência de foreach para preencher o select, não precisa de muita explicação.

echo '<div id="why-wrapper"><label>Motivo: </label><textarea style="width:100%" id="why" name="why" cols="10" rows="5"'. $dis_able .'>'. $custom["_why"][0] .'</textarea></div>';

Uma div contendo a textarea,  onde o revisor vai digitar a razão de sua avaliação — ou não, se o post for Aprovado ou Top. A div vai servir pra esconder todo o conteúdo dependendo do select.

echo '<script>
    var $j = jQuery.noConflict();
    $j(function($){
        $(document).ready(function () {
            var statusatual = $(\'#statuser\').val();
            if( statusatual == \'Aprovado\' || statusatual == \'Top\' ) {
                $(\'#why-wrapper\').hide();
            }
	})
	$(\'#statuser\').change(function() {
            $(\'#why\').val(\'\');
            if(this.value == \'Aprovado\' || this.value == \'Top\') {
                $(\'#why-wrapper\').hide();
            }
            else {
                $(\'#why-wrapper\').show();
            }
        });
    });
 </script>';

O script tem três funções:

  1. Assim que a página for carregada, pega o valor do status e coloca num variável. Ela é testada e se o valor for “Top” ou “Aprovado” já existe no post, a div que guarda a textarea é toda escondida, já que não tem serventia.
  2. Ao mudar o valor do select (change), o valor da textarea é esvaziado (novo status, nova mensagem).
  3. Ao mudar o valor do select, se o valor “Aprovado” ou “Top” forem escolhidos, a textarea será escondida (hide); se for outro valor (else), a caixa é exibida (show).
function save_status() {
	global $post;
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
		return $post->ID;
	}
	update_post_meta($post->ID, "_status", $_POST["status"]);
	update_post_meta($post->ID, "_why", $_POST["why"]);
}

É a função que salva o status da revisão e o motivo com o post.

function status_css() {

Alguns estilos para o rótulo do status da revisão que aparece na lista de posts do WordPress.

function custom_post_state($states) {
    global $post;
    $show_custom_state = get_post_meta($post->ID, '_status');
    if ($show_custom_state) {
        $states[] = __('<span class="custom_state ' . strtolower($show_custom_state[0]) . '">' . $show_custom_state[0] . '</span>');
    }
    return $states;
}

Se existe um status de revisão, ele será exibido na lista de posts, senão fica em branco.

Se não houver nenhum conflito com seu tema, a caixa de status já vai aparecer ao escrever um novo post. Veja como ficou no tema TwentyFifteen:

select e textarea criados

Agora vamos ao rótulo de “Artigo Destacado”, que será exibido em todos os posts marcados com o status de revisão “Top”.

“E pra que isso vai servir?” Minha ideia é que os melhores posts de colaboradores tenham um destaque, tanto como incentivo, quanto para ajudar os leitores a saber quais os artigos que consideramos mais ricos.

Abra o template single.php, loop-single.php ou qualquer outro do seu tema que guarda o loop da página de posts. É impossível dizer aqui com certeza qual é o seu caso. No TwentyFifteen, é o content.php, porque quero o aviso de artigo destacado logo acima do título do post.

Este é o código original do TwentyFifteen:

<?php
    if ( is_single() ) : the_title( '<h1 class="entry-title">', '</h1>' );
    else : the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' );
    endif;
?>

Substitua por:

<?php
if ( is_single() ) {
	the_title( '<h1 class="entry-title">', '</h1>' );
	// pega status personalizado do post 
	$the_metas = get_post_meta($post->ID, '_status', TRUE);
	if ($the_metas == 'Top') {
		echo '<span id="art-destac">Artigo Destacado</span>';
	}
} 
else {
	the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' );
	} ?>

Só mudei o bloco com uma condicional que chega o valor do campo “_status”, e se ele guarda o valor “Top”, inserimos o texto “Artigo Destacado” envolto num span com ID para fácil estilização mais tarde. Salve o arquivo, crie um post e dê-lhe o status Top. Visualize a página e se deu tudo certo, lá estará a mensagem:

artigo destacado wordpress

Uma demonstração em vídeo do uso da caixa:

Com o mesmo procedimento (checar o conteúdo do “_status”), você pode criar mais, como mensagens de correção visíveis apenas pelo autor do artigo, notas públicas de que o artigo está em expansão ou reavaliação, etc.

Dúvidas ou sugestões de melhoria, comentem.

Fundador do Tutoriart em 2010, é ex-instrutor de Photoshop, design web e gráfico. Em quase uma década de redação online, tem cerca de 1500 artigos publicados. Gerencia também o Memória BIT.

4 Comentários

  1. Olá, teria como inserir uma outra função sem ser o administrador para aprovar ou reprovar os posts?
    Seria como um revisor.

  2. Olá, no código que mostrou somente quem tem cargo de administrador pode aprovar ou reprovar, teria uma função abaixo do adm somente para aprovar ou reprovar? Como um revisor, sem precisar ser somente o adm.

  3. Quando estou como administrador coloco a opção “Ortografia”, quando entro com o usuário “Colaborador” ele não consegue consegue editar, fica desativado o post. Só aparece a opção ver.
    Se o erro é ortográfico ele precisa ter permissão para editar 🙁

Deixe um Comentário

Pin