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 /* * 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 } ?>
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 /* * 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; } ?>
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 /* * 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 } ?>
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 /* * 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; } ?>
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