Pouco tempo atrás, para adicionar informações extras a um post ou a uma página (a fonte de um texto ou um link para um vídeo do YouTube que se queira destacar, por exemplo), usávamos diretamente os custom fields, os campos personalizados do WordPress. Bastava atribuir uma chave e um valor para esta chave e depois trata-los dentro dos arquivos do seu tema. Em 2008, a versão 2.5 apresentou as meta boxes, as caixas arrastáveis já conhecidas do WordPress, que permitem a adição de novas informações a posts, custom post types, páginas e links. E elas funcionam perfeitamente com os custom fields.
Surge a ideia: você quer, além de publicar o post, permitir que seus leitores façam o download de algum material relacionado. Há algumas soluções possíveis para esse problema:
- Você pode fazer o upload do arquivo, copiar a URL e criar um link manual (Faça o download do arquivo, ou algo parecido) dentro do seu post;
- Fazer o upload, copiar a URL e joga-la dentro de um custom field (com uma chave chamada upload_file, por exemplo) e criar, dentro do tema, uma área para download do arquivo, usando as funções dos campos personalizados;
- Criar uma meta box e nela inserir a URL do arquivo;
Só que você não quer copiar links de um lado pro outro. Isso é chato e, para muitos clientes, complicado. O interessante seria criar uma meta box com um botão que leve diretamente para o media uploader padrão do WordPress, e assim evitar que você e o seu cliente percam tempo com coisas desnecessárias. E é isso que faremos.
Criando a meta box
Em primeiro lugar, vamos criar a meta box de upload. Ela vai conter um campo de texto, onde será mostrada a URL do arquivo, e um botão que levará ao media uploader do WordPress. Para isso, criamos uma ação dentro do hook add_meta_boxes, responsável por chamar a função my_meta_box(). Dentro dela, a função add_meta_box() cria a nova seção do nosso post / página.
[php]
<?php
/*
* Adiciona a meta box para upload do arquivo
*/
add_action( ‘add_meta_boxes’, ‘my_meta_box’ );
function my_meta_box()
{
add_meta_box( ‘my_meta_uploader’, ‘Upload de arquivo’, ‘my_meta_uploader_setup’, ‘post’, ‘normal’, ‘high’ );
}
/*
* Adiciona os campos para a meta box de upload
*/
function my_meta_uploader_setup()
{
global $post;
// Procura o valor da chave ‘upload_file’
$meta = get_post_meta( $post->ID, ‘upload_file’, true );
?>
<p>
Clique no botão para fazer o upload de um documento. Após o término do upload, clique em <em>Inserir no post</em>.
</p>
<p>
<input id="upload_file" type="text" size="80" name="upload_file" style="width: 85%;" value="<?php if( ! empty( $meta ) ) echo $meta; ?>" />
<input id="upload_file_button" type="button" class="button" value="Fazer upload" />
</p>
<?php
}
?>
[/php]
A nossa meta box ficará da seguinte forma:
Salvando os dados
Agora, precisamos fazer três coisas: procurar se há algum valor dentro da chave upload_file, atualizar este valor quando o campo for modificado e salvar estes dados dentro do post através da função my_meta_uploader_save(), que será executada quando na chamada do hook save_post:
[php]
<?php
/*
* Salva os dados da nossa custom meta box
*/
add_action( ‘save_post’, ‘my_meta_uploader_save’ );
function my_meta_uploader_save( $post_id ) {
if ( ! current_user_can( ‘edit_post’, $post_id ) ) return $post_id;
// Recebe o valor que foi enviado pelo media uploader
$arquivo = $_POST[‘upload_file’];
// Adiciona a chave upload_file ou atualiza seu valor
add_post_meta( $post_id, ‘upload_file’, $arquivo, true ) or update_post_meta( $post_id, ‘upload_file’, $arquivo );
return $post_id;
}
?>
[/php]
A integração com o media uploader do WordPress
Enfim, o media uploaders. A ideia é simples: duplicamos a função original e chamamos a sua cópia apenas quando o botão Fazer upload for clicado. Dessa forma, quando fizermos o upload ou procurarmos algum arquivo, o botão Inserir no post preencherá o campo da meta box com a URL do arquivo, e não o editor de texto padrão do WordPress. É necessário avisar no código que usaremos o script quando a área de administração for chamada, representada aqui pelo hook admin_init:
[php]
<?php
/*
* Adiciona o script que replica o uploader padrão do WordPress
*/
add_action( ‘admin_head’, ‘my_meta_uploader_script’ );
/*
* O novo media uploader, baseado no post e nas discussões do site abaixo
* http://www.webmaster-source.com/2010/01/08/using-the-wordpress-uploader-in-your-plugin-or-theme/
*/
function my_meta_uploader_script() { ?>
<script type="text/javascript">
jQuery(document).ready(function() {
var formfield;
var header_clicked = false;
jQuery( ‘#upload_file_button’ ).click( function() {
formfield = jQuery( ‘#upload_file’ ).attr( ‘name’ );
tb_show( ”, ‘media-upload.php?TB_iframe=true’ );
header_clicked = true;
return false;
});
// Guarda o uploader original
window.original_send_to_editor = window.send_to_editor;
// Sobrescreve a função nativa e preenche o campo com a URL
window.send_to_editor = function( html ) {
if ( header_clicked ) {
fileurl = jQuery( html ).attr( ‘href’ );
jQuery( ‘#upload_file’ ).val( fileurl );
header_clicked = false;
tb_remove();
}
else
{
window.original_send_to_editor( html );
}
}
});
</script>
<?php
}
?>
[/php]
Por último, filtramos o the_content utilizando a função get_post_meta(). O objetivo é criar uma pequena área de download dentro do nosso tema:
[php]
<?php
/*
* Download do arquivo
* Adiciona um parágrafo com um link para o arquivo salvo na meta box
*/
add_filter( ‘the_content’, ‘insert_meta_data’ );
function insert_meta_data( $content ) {
global $post;
$meta = get_post_meta( $post->ID, ‘upload_file’, true );
if ( $meta ) {
$content .= ‘<p class="download-revista">’;
$content .= ‘<a href="’ . $meta . ‘" title="Clique para iniciar o download">’;
$content .= ‘Faça o download do arquivo’;
$content .= ‘</a>’;
$content .= ‘</p>’;
}
return $content;
}
?>
[/php]
E, finalmente, a nossa singela área de download:
Mais informações
- Custom Fields / Campos personalizados no Codex, a documentação oficial do WordPress
- Hooks, actions e filters
- A função add_meta_box()
- Using the WordPress Uploader in Your Plugin or Theme, com a discussão sobre formas de usar o media uploader nativo
Por Willy Chagas em 9 de dezembro de 2011 as 14:44.
Cara estou criando um plugin de posts favoritos e pretendo usar meta boxes para relacionar vários usuários a um post, preciso que os dados sejam inseridos quando o usuário clicar em um link, no seu caso você usou a action save_post, qual devo usar?
Abraço
Por Pedro Vidal em 26 de março de 2012 as 10:10.
Grato pela atenção!
Pedro Vidal
Por Vinicius Martin em 12 de abril de 2012 as 14:41.
Testei o código e funcionou perfeitamente. Tu sabes como faço para adicionar mais campos de upload no mesmo box?
Obrigado!
Por Samuel em 8 de maio de 2012 as 6:05.
Por Geovane Krüger em 9 de fevereiro de 2013 as 0:12.
Obrigado.
add_filter('upload_mimes', 'custom_upload_mimes');
function custom_upload_mimes ( $existing_mimes=array() ) {
// add your extension to the array
$existing_mimes['kml'] = 'application/vnd.google-earth.kml+xml';
// add as many as you like
// removing existing file types
unset( $existing_mimes['exe'] );
// add as many as you like
// and return the new full result
return $existing_mimes;
}