[ WordPress ]

Home » WordPress » Como criar um custom post types de eventos para WordPress
Inscreva-se em nosso canal no Youtube Daviwp


Como criar um custom post types de eventos para WordPress

06/11/2012 WordPress (11) comentários

Um dos recursos mais interessantes (e úteis) do WordPress são os custom post types. Como o nome sugere, o WordPress permite que você defina seus próprios tipos de posts, que são tratados como os já existentes (ou seja, mensagens e páginas).

Por exemplo, recentemente eu estava desenvolvendo um site que precisava criar e publicar eventos. Depois de pesquisar, encontrei um ótimo artigo do Noel Tock sobre como usar os custom post types para criar eventos.

Mesmo que o Noel tenha feito um grande trabalho explicando o conceito e o layout da abordagem, ele deixou algumas coisas de fora. Então, decidi escrever meu próprio guia um pouco mais abrangente para o uso de custom post types para criar eventos.

Como os eventos deveriam funcionar?

Antes de mergulhar nos detalhes da implementação, vamos falar primeiro sobre requisitos. Vamos imaginar que você está construindo um site para alguém que gostaria de criar e publicar eventos. Como ele poderia ser?

Bem, antes de qualquer coisa, existiria uma nova categoria de coisas em WordPress chamada Eventos:

Segundo, não existiria uma maneira fácil de ver o que os Eventos criaram (como posts ou páginas):

E é claro que existiria uma maneira fácil de adicionar um novo evento e especificar os detalhes dele, como data e local:

Também seria bom ser capaz de incorporar uma lista de eventos dentro de uma página ou um post, talvez usando o código que tenha esta aparência:

<h2>upcoming events</h2>
[events daterange="current"]
 
<h2>past events</h2>
[events daterange="past"]

Finalmente, seria ótimo ter um template separado para exibir eventos individuais.
Ok, mas como podemos fazer isso?

A fim de construir uma funcionalidade abrangente e amigável para gerenciar eventos, precisaremos implementar o seguinte:

Registrar um novo custom post type chamado Eventos
Adicionar suporte para a exibição de listas de Eventos
Adicionar suporte para adição e a edição de Eventos individuais
Adicionar um shortcode para incluir listas de eventos em posts e páginas
Adicionar uma página especial que possa exibir um evento individual

Vamos discutir cada uma delas em detalhes.
1. Registrar events post type

A primeira coisa que você precisa fazer é registrar event post type com WordPress. Para isso, vamos precisar modificar o arquivo functions.php e adicionar o seguinte código:

add_action('init', 'event_register');
 
function event_register() {
 
$labels = array(
'name' => _x('Events', 'post type general name'),
'singular_name' => _x('Event', 'post type singular name'),
'add_new' => _x('Add New', 'event'),
'add_new_item' => __('Add New Event'),
'edit_item' => __('Edit Event'),
'new_item' => __('New Event'),
'view_item' => __('View Event'),
'search_items' => __('Search Events'),
'not_found' =>  __('Nothing found'),
'not_found_in_trash' => __('Nothing found in Trash'),
'parent_item_colon' => ''
);
 
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','thumbnail')
);
 
register_post_type( 'events' , $args );
}

O array $labels diz ao WordPress como várias novas ações em torno de eventos devem ser chamadas, enquanto o array $args especifica como os eventos devem ser tratados. Por uma questão de brevidade, não vou entrar em detalhes sobre os parâmetros que você precisa especificar (você pode encontrar isso aqui).
2. Exibir listas de eventos

Para exibir uma lista de eventos para o usuário, nós precisamos fazer o seguinte:

definir quais colunas mostrar à lista que o WordPress usa para exibir posts, páginas e custom posts types
definir quais colunas mostrar quando os eventos são exibidos

Para a minha lista de eventos, eu queria mostrar a data do evento, juntamente com início e término, localização e cidade. Aqui está o código para fazer isso:

add_action("manage_posts_custom_column",  "events_custom_columns");
add_filter("manage_events_posts_columns", "events_edit_columns");
 
function events_edit_columns($columns){
$columns = array(
"cb" => "<input type=\"checkbox\" />",
"title" => "Event",
"event_date" => "Event Date",
"event_location" => "Location",
"event_city" => "City",
);
return $columns;
}
 
function events_custom_columns($column){
global $post;
$custom = get_post_custom();
 
switch ($column) {
case "event_date":
echo format_date($custom["event_date"][0]) . '<br /><em>' .
$custom["event_start_time"][0] . ' - ' .
$custom["event_end_time"][0] . '</em>';
break;
 
case "event_location":
echo $custom["event_location"][0];
break;
 
case "event_city":
echo $custom["event_city"][0];
break;
}
}

O código é bastante simples. A primeira função atribui etiquetas e nomes de cada uma das colunas que eu pretendo exibir, enquanto a segunda função formata o conteúdo de cada coluna.
Adicionar colunas classificáveis

Para tornar a lista ainda melhor, poderíamos fazer colunas classificáveis. Nesse caso, a possibilidade de ordenar a data do evento é um recurso muito útil. Para isso, temos que:

adicionar um filtro para indicar qual a coluna é classificável
definir como a classificação deve acontecer

Aqui está o código:

add_filter("manage_edit-events_sortable_columns", "event_date_column_register_sortable");
add_filter("request", "event_date_column_orderby" );
 
function event_date_column_register_sortable( $columns ) {
$columns['event_date'] = 'event_date';
return $columns;
}
 
function event_date_column_orderby( $vars ) {
if ( isset( $vars['orderby'] ) && 'event_date' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => 'event_date',
'orderby' => 'meta_value_num'
) );
}
return $vars;
}

3. Editar eventos

Ok, a próxima coisa que precisamos fazer é adicionar a capacidade de editar eventos. Mais especificamente, nós precisamos adicionar propriedades personalizadas para a tela normal de edição de posts para que o usuário possa obter detalhes adicionais de entrada do evento (como data e local). Eis do que você precisa:

adicionar uma meta box Event Details
adicionar ação para salvar detalhes do evento

O código para adicionar a meta box Event Details se parece com este:

add_action("admin_init", "events_admin_init");
 
function events_admin_init(){
add_meta_box("event_meta", "Event Details", "event_details_meta", "events", "normal", "default");
}
 
function event_details_meta() {
 
$ret = '<p><label>Date: </label><input type="text" name="event_date" value="' . format_date(get_event_field("event_date")) . '" /><em>(mm/dd/yyy)</em>';
$ret = $ret . '</p><p><label>Start Time: </label><input type="text" name="event_start_time" value="' . get_event_field("event_start_time") . '" /><em>(hh:mm pm)</em></p>';
$ret = $ret . '<p><label>End Time: </label><input type="text" name="event_end_time" value="' . get_event_field("event_end_time") . '" />    <em>(hh:mm pm)</em> </p>';
$ret = $ret . '<p><label>Location: </label><input type="text" size="70" name="event_location" value="' . get_event_field("event_location") . '" /></p>';
$ret = $ret . '<p><label>Street: </label><input type="text" size="50" name="event_street" value="' . get_event_field("event_street") . '" /></p>';
$ret = $ret . '<p><label>City: </label><input type="text" size="50" name="event_city" value="' . get_event_field("event_city") . '" /></p>';
$ret = $ret . '<p><label>Location URL: </label><input type="text" size="70" name="event_location_url" value="' . get_event_field("event_location_url") . '" /></p>';
$ret = $ret . '<p><label>Register URL: </label><input type="text" size="70" name="event_register_url" value="' . get_event_field("event_register_url") . '" /></p>';
 
echo $ret;
}

A ação admin_init diz ao WordPress também chamar events_admin_init() sempre que um evento é adicionado ou editado. Isso, por sua vez, adiciona uma meta box Event Details por meio da chamada add_meta_box(). Finalmente, o evento real da caixa de Event Details é exibido usando a função event_details_meta().

Para tornar o código um pouco mais legível, eu defini uma função get_event_field(), que retorna o valor de um campo de evento, se ele existir:

function get_event_field($event_field) {
global $post;
 
$custom = get_post_custom($post->ID);
 
if (isset($custom[$event_field])) {
return $custom[$event_field][0];
}
}

Salvando detalhes do evento

Nós também precisamos adicionar código para salvar os detalhes do evento inseridos pelo usuário. Isso é realizado através da adição de uma ação para save_post:

add_action('save_post', 'save_event_details');
 
function save_event_details(){
global $post;
 
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
 
if ( get_post_type($post) == 'event')
return;
 
if(isset($_POST["event_date"])) {
update_post_meta($post->ID, "event_date", strtotime($_POST["event_date"]));
}
 
save_event_field("event_start_time");
save_event_field("event_end_time");
save_event_field("event_location");
save_event_field("event_street");
save_event_field("event_city");
save_event_field("event_location_url");
save_event_field("event_register_url");
}

A função de memória não é complicada, mas faz algumas coisas muito importantes. Primeiro, assegura que o recurso autosave do WordPress não perca campos personalizados. Em segundo lugar, ele garante que este save não vai funcionar se o tipo de evento não for post-type (ou seja, mensagens normais e páginas).

A propósito, note que eu converti o campo event_time dentro de um timestamp Unix antes de salvá-lo (isso foi uma das ótimas dicas do artigo do Noel). Fazer isso torna muito mais fácil trabalhar com datas posteriores, especialmente para coisas como classificação.

Por último, escrevi uma pequena função helper para tornar mais fácil salvar os campos:

function save_event_field($event_field) {
global $post;
 
if(isset($_POST[$event_field])) {
update_post_meta($post->ID, $event_field, $_POST[$event_field]);
}
}

4. Exibir eventos

A maneira mais simples para permitir que listas de eventos sejam facilmente incluídas nas páginas ou nos posts é através da definição um shortcode. E porque shortcodes podem ser parametrizados, você pode usar o mesmo para retornar os eventos que virão e os passados. Aqui está o código para fazê-lo:

add_shortcode( 'events', 'get_events_shortcode' );
 
function get_events_shortcode($atts){
global $post;
 
// get shortcode parameter for daterange (can be "current" or "past")
extract( shortcode_atts( array(
'daterange' => 'current',
), $atts ) );
 
ob_start();
 
// prepare to get a list of events sorted by the event date
$args = array(
'post_type' => 'events',
'orderby'   => 'event_date',
'meta_key'  => 'event_date',
'order'     => 'ASC'
);
 
query_posts( $args );
 
$events_found = false;
 
// build up the HTML from the retrieved list of events
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
$event_date = get_post_meta($post->ID, 'event_date', true);
 
switch ($daterange) {
case "current":
if ($event_date >= time() ) {
echo get_event_container();
$events_found = true;
}
break;
 
case "past":
if ($event_date < time() ) {
echo get_past_event_summary();
$events_found = true;
}
break;
}
}
}
 
wp_reset_query();
 
if (!$events_found) {
echo "<p>no events found.</p>";
}
 
$output_string = ob_get_contents();
ob_end_clean();
 
return $output_string;
}

Há um monte de coisas acontecendo nessa função, e a maioria é bem feia. Algumas coisas que vale a pena ressaltar:

Eu estou usando o buffer de saída com ob_start() para capturar a saída e exibi-la de uma só vez (outra grande dica do Noel).
Porque eu armazeno event_time como um timestamp Unix, classificar eventos usando o campo de data é tão simples como especificar como o valor order_by.

A propósito, aqui estão as funções helper get_event_container() e get_past_event_summary():

function get_event_container() {
global $post;
$ret = '<section>';
$ret =  $ret . get_event_calendar_icon() . '<section>';
$ret = $ret .  get_event_details(false, true);
$ret =  $ret . '</section></section>';
 
return $ret;
}
 
function get_past_event_summary() {
global $post;
$ret = '<section>';
$ret =  $ret . '<h3>' . $post->post_title . '</h3><p>';
$ret = $ret . '<h4>' . get_post_meta($post->ID, 'event_city', true) .'</h4>';
$ret = $ret .  '<em>' . format_date(get_post_meta($post->ID, 'event_date', true)) . '</em>';
$ret =  $ret . '</p></section>';
 
return $ret;
}

5. Exibir eventos individuais

Por fim, para exibir um evento individual, é possível definir um template especial chamado single-events.php. Eis o que pode parecer:

<?php get_header(); ?>
 
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
 
<article id="event-<?php the_ID(); ?>">
<h1><?php the_title(); ?></h1>
<section>
<?php echo get_event_calendar_icon(); ?>
<section>
<?php the_content('Read more on "'.the_title('', '', false).'" &raquo;'); ?>
<?php echo get_event_details(true, false); ?>
</section>
</section>
</article>
<?php endwhile; endif; ?>
 
<?php get_footer(); ?>

Depois de ir para o loop padrão do WordPress, eu fiz um article que contém o nome do evento como o cabeçalho, um pequeno pedaço de código HTML para exibir a data e algumas informações adicionais sobre o evento.

Apenas para completar a imagem, aqui estão as funções helper get_event_calendar_icon() e get_event_details():

function get_event_calendar_icon() {
global $post;
$unixtime = get_post_meta($post->ID, 'event_date', true);
$month = date("M", $unixtime);
$day = date("d", $unixtime);
$year = date("y", $unixtime);
return  '<div>' . $day . '<em>' . $month . '</em></div>';
}
 
function get_event_details($include_register_button, $include_title) {
global $post;
$unixtime = get_post_meta($post->ID, 'event_date', true);
$location_url = get_post_meta($post->ID, 'event_location_url', true);
$register_url = get_post_meta($post->ID, 'event_register_url', true);
 
$ret = '';
if ($include_title) {
$ret =  $ret . '<h3><a href="' . get_permalink() . '">' . $post->post_title . '</a></h3>';
}
 
$ret = $ret . '<p><h4>'.get_post_meta($post->ID, 'event_location', true) . '</h4>';
$ret = $ret . format_possibly_missing_metadata('event_street');
$ret = $ret . format_possibly_missing_metadata('event_city');
$ret = $ret . '</p><p>';
$ret = $ret . date("F d, Y", $unixtime) . '<br/>';
$ret = $ret . '<em>' . get_post_meta($post->ID, 'event_start_time', true) . ' - ';
$ret = $ret . get_post_meta($post->ID, 'event_end_time', true) . '</em>';
 
if (!empty($register_url) && $include_register_button && $unixtime > time()) {
$ret = $ret .'<a href="' . $register_url . '">register</a>';
}
 
return $ret;
}
 
function format_possibly_missing_metadata($field_name) {
global $post;
$field_value = get_post_meta($post->ID, $field_name, true);
 
if (!empty($field_value)) {
return $field_value.'<br/>';
}
}

Sem entrar em muitos detalhes, cada função apenas retorna uma parte de HTML contendo metadados sobre os eventos. agora o style você pode utilizar do seu jeito !

Post: Alex Tatiyants post original tatiyants

daviwp

Meu nome é Davi Alves desenvolvedor web e WordPress developer, residente de Belo Horizonte, sou um dos organizadores do WordCamp evento oficial do WordPress em BH e co-fundador do Belo Horizonte WordPress Group juntamente com o fundador Mateus Neves, sou articulista de alguns sites, e fundador do daviwp.com, aqui compartilho conhecimentos para toda galera aficionada em WordPress.

  • Marcos César

    Parabéns pela iniciativa, wordpress é fantástico estou aproveitando bem suas dicas! Forte abraço.

    • Davi

      Olá Marcos obrigado volte sempre abraço!

  • Lincoln Lemos

    O código add_action(‘save_post’, ‘save_event_details’);
    ta gerando um erro aqui. Ta deixando o admin inacessível :/

    • Davi

      Olá Lincoln, você tem que inserir todos os codigos no seu functions tirando o quinto codigo pois é o loop que vai listar os eventos ok? qualquer coisa me passa o seu functions para ver como esta inserido!

  • D. Leal

    Olá amigo, antes de mais parabéns pelo seu site.

    Infelizmente ainda não consegui preceber bem os costom type post e ainda não foi desta. Precisava de fazer algo simples, adicionar uma página que funcionasse tipo blogue, mas nem isso estou a conseguir fazer. Se você tiver alguma forma de connetar-se com os leitores, nem que seja o skype para acompanhar o trabalho, agradecia a sua ajuda.

  • daviwp

    Show

  • daviwp

    Olá Rafael, UTF no servidor não vou saber explicar brother, solicita o seu suporte de hospedagem veja o que ele tem a falar sobre isso.
    Obrigado !

  • douglas88

    Em qual parte do código faz aparecer na tela de edição do post , o campo para preencher a data do evento ?

    • daviwp

      Olá Douglas,

      Só é possível editar a data dentro da edição do post.

      Att;
      Davi.

  • daviwp

    Olá Aline.

    Na parte 5 você tem o código para chamar os eventos na pagina.

    Abraço.

  • daviwp

    Olá Emerson.

    Provavelmente esta função format_date(get_event_field não foi colocada no functions verifica mais acima o código do functions.php que usa essa função.

    Abraço.

Facebook

Publicidade