Problemas com posts personalizados (custom-post-types)
-
Olá a todos amigos entusiastas! Venho reportar aqui um problema que não estou conseguindo resolver sozinho e se algum dos senhores estiver interessado em ajudar-me, serei muito grato! Então passemos o problema…
Estou desenvolvendo um website para um corretor de imóveis e para melhorar a utilização do corretor, eu criei o tipo de post imóveis, que é um custom_post_type. O problema está na ação de SAVE do post imóvel. Se eu não preencho todos os meta-boxes o post é salvo com valores nulos nos meta-boxes. Deixo o código abaixo para que possa ser analizado.
O código abaixo é um php que anexo ao functions.php no final do código.
// Register Custom Post Type
function cadastro_imovel() {$labels = array(
'name' => _x( 'Imóveis', 'Post Type General Name', 'imovel' ),
'singular_name' => _x( 'Cadastrar imóvel', 'Post Type Singular Name', 'imovel' ),
'menu_name' => __( 'Imóveis', 'imovel' ),
'parent_item_colon' => __( 'Item referência:', 'imovel' ),
'all_items' => __( 'Todos', 'imovel' ),
'view_item' => __( 'Vizualizar', 'imovel' ),
'add_new_item' => __( 'Cadastrar novo imóvel', 'imovel' ),
'add_new' => __( 'Adicionar novo', 'imovel' ),
'edit_item' => __( 'Editar', 'imovel' ),
'update_item' => __( 'Atualizar', 'imovel' ),
'search_items' => __( 'Buscar', 'imovel' ),
'not_found' => __( 'Não encontrado', 'imovel' ),
'not_found_in_trash' => __( 'Nada encontrado na lixeira', 'imovel' ),
);
$args = array(
'label' => __( 'imovel', 'imovel' ),
'description' => __( 'Cadastro de imóvel', 'imovel' ),
'labels' => $labels,
'supports' => array( 'title', 'editor', 'author', 'thumbnail', ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 6,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true
);
register_post_type( 'imovel', $args );}
// Hook into the 'init' action
add_action( 'init', 'cadastro_imovel', 0 );
// Register Custom Taxonomy
function localizacao_imovel() {$labels = array(
'name' => _x( 'Localidades', 'Taxonomy General Name', 'localidade-imovel' ),
'singular_name' => _x( 'Localização do imóvel', 'Taxonomy Singular Name', 'localidade-imovel' ),
'menu_name' => __( 'Localidades', 'localidade-imovel' ),
'all_items' => __( 'Todas', 'localidade-imovel' ),
'parent_item' => __( 'Localidade referência:', 'localidade-imovel' ),
'parent_item_colon' => __( 'Item referência', 'localidade-imovel' ),
'new_item_name' => __( 'Adicionar nova localidade', 'localidade-imovel' ),
'add_new_item' => __( 'Adicionar nova', 'localidade-imovel' ),
'edit_item' => __( 'Editar', 'localidade-imovel' ),
'update_item' => __( 'Atualizar', 'localidade-imovel' ),
'separate_items_with_commas' => __( 'Separe os itens com vírgulas', 'localidade-imovel' ),
'search_items' => __( 'Buscar', 'localidade-imovel' ),
'add_or_remove_items' => __( 'Adicionar ou remover item', 'localidade-imovel' ),
'choose_from_most_used' => __( 'Escolher localidade mais utilizada', 'localidade-imovel' ),
'not_found' => __( 'Não encontrado', 'localidade-imovel' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
);
register_taxonomy( 'localizacao', array( 'imovel' ), $args );}
// Hook into the 'init' action
add_action( 'init', 'localizacao_imovel', 0 );// Register Custom Taxonomy
function tags_imovel() {$labels = array(
'name' => _x( 'Tags de referência', 'Taxonomy General Name', 'tags-imovel' ),
'singular_name' => _x( 'Tags de referência', 'Taxonomy Singular Name', 'tags-imovel' ),
'menu_name' => __( 'Tags de referência', 'tags-imovel' ),
'all_items' => __( 'Todas', 'tags-imovel' ),
'parent_item' => __( 'Item referência', 'tags-imovel' ),
'parent_item_colon' => __( 'Item referência:', 'tags-imovel' ),
'new_item_name' => __( 'Adicionar nova referência', 'tags-imovel' ),
'add_new_item' => __( 'Adicionar nova', 'tags-imovel' ),
'edit_item' => __( 'Editar', 'tags-imovel' ),
'update_item' => __( 'Atualizar', 'tags-imovel' ),
'separate_items_with_commas' => __( 'Separe os itens usando vírgula', 'tags-imovel' ),
'search_items' => __( 'Buscar', 'tags-imovel' ),
'add_or_remove_items' => __( 'Adicionar ou remover itens', 'tags-imovel' ),
'choose_from_most_used' => __( 'Escolher tag mais utilizada', 'tags-imovel' ),
'not_found' => __( 'Not Found', 'tags-imovel' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
);
register_taxonomy( 'tags', array( 'imovel' ), $args );}
// Hook into the 'init' action
add_action( 'init', 'tags_imovel', 0 );
// Add custom meta box
add_action( 'add_meta_boxes', 'imovel_globalpos_box' );
function imovel_globalpos_box() {
add_meta_box(
'imovel_globalpos_box',
__( 'Localização do imóvel (GPS)', 'imovel_globalpos_box' ),
'imovel_globalpos_box_content',
'imovel',
'normal',
'high'
);
}function imovel_globalpos_box_content( $post ) {
wp_nonce_field( plugin_basename( __FILE__ ), 'imovel_globalpos_box_content_nonce' );
wp_enqueue_style( 'gmapspicker.css', get_template_directory_uri() . '/inc/gmapspicker/jquery-gmaps-latlon-picker.css');
wp_enqueue_script( 'gmapspicker', get_template_directory_uri() . '/inc/gmapspicker/jquery-gmaps-latlon-picker.js' );
wp_enqueue_script( 'gmapsapi', 'http://maps.googleapis.com/maps/api/js?sensor=false' );
echo '<label for="imovel_globalpos"></label>';
echo '<fieldset class="gllpLatlonPicker">';
echo '<div class="gllpMap">Google Maps</div>';
echo '<input type="hidden" id="imovel_globalpos_lat" name="imovel_globalpos_lat" class="gllpLatitude"/>';
echo '<input type="hidden" id="imovel_globalpos_long" name="imovel_globalpos_long" class="gllpLongitude"/>';
echo '</fieldset>';
}
add_action( 'save_post', 'imovel_globalpos_box_save' );function imovel_globalpos_box_save( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;if ( !wp_verify_nonce( $_POST['imovel_globalpos_box_content_nonce'], plugin_basename( __FILE__ ) ) )
return;if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ) )
return;
} else {
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}
$imovel_globalpos_lat = $_POST['imovel_globalpos_lat'];
update_post_meta( $post_id, 'imovel_globalpos_lat', $imovel_globalpos_lat );
$imovel_globalpos_long = $_POST['imovel_globalpos_long'];
update_post_meta( $post_id, 'imovel_globalpos_long', $imovel_globalpos_long );
}
-
Está faltando uma verificação se o campo está definido antes de você fazer a chamada à
update_post_meta
, por isso está salvando os valores nulos.// Make sure that it is set. if ( ! isset( $_POST['myplugin_new_field'] ) ) { return; }
Referência: http://codex.wordpress.org/Function_Reference/add_meta_box#Examples
Depois de ter lido a referência que o colega deixou aqui no post, consegui compreender a falha do meu código. O tratamento dos campos ficou assim:
add_action( 'add_meta_boxes', 'imovel_globalpos_box' );
function imovel_globalpos_box() {
add_meta_box(
'imovel_globalpos_box',
__( 'Localização do imóvel (GPS)', 'imovel_globalpos_box' ),
'imovel_globalpos_box_content',
'imovel',
'normal',
'high'
);
}function imovel_globalpos_box_content( $post ) {
wp_nonce_field( plugin_basename( __FILE__ ), 'imovel_globalpos_box_content_nonce' );
wp_enqueue_style( 'gmapspicker.css', get_template_directory_uri() . '/inc/gmapspicker/jquery-gmaps-latlon-picker.css');
wp_enqueue_script( 'gmapspicker', get_template_directory_uri() . '/inc/gmapspicker/jquery-gmaps-latlon-picker.js' );
wp_enqueue_script( 'gmapsapi', 'http://maps.googleapis.com/maps/api/js?sensor=false' );
//Aqui eu incluí uma verificação para não zerar os campos, conforme encontrei na referência.
$chkvalueLat = get_post_meta( $post->ID, 'imovel_globalpos_lat', true );
$chkvalueLong = get_post_meta( $post->ID, 'imovel_globalpos_long', true );
echo '<label for="imovel_globalpos"></label>';
echo '<fieldset class="gllpLatlonPicker">';
echo '<div class="gllpMap">Google Maps</div>';
echo '<input type="text" id="imovel_globalpos_lat" name="imovel_globalpos_lat" class="gllpLatitude" value="' . esc_attr( $chkvalueLat ) . '"/>';
echo '<input type="text" id="imovel_globalpos_long" name="imovel_globalpos_long" class="gllpLongitude" value="' . esc_attr( $chkvalueLong ) . '"/>';
echo '</fieldset>';
}
add_action( 'save_post', 'imovel_globalpos_box_save' );function imovel_globalpos_box_save( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;if ( !wp_verify_nonce( $_POST['imovel_globalpos_box_content_nonce'], plugin_basename( __FILE__ ) ) )
return;if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ) )
return;
} else {
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}
// Make sure that it is set.
if ( ! isset( $_POST['imovel_globalpos_lat'] ) ) {
return;
}
if ( ! isset( $_POST['imovel_globalpos_long'] ) ) {
return;
}$imovel_globalpos_lat = $_POST['imovel_globalpos_lat'];
$sanitize_dataLat = sanitize_text_field( $_POST['imovel_globalpos_lat'] );
update_post_meta( $post_id, 'imovel_globalpos_lat', $imovel_globalpos_lat );$imovel_globalpos_long = $_POST['imovel_globalpos_long'];
$sanitize_dataLong = sanitize_text_field( $_POST['imovel_globalpos_long'] );
update_post_meta( $post_id, 'imovel_globalpos_long', $imovel_globalpos_long );
}Agora o post type funciona direitinho! Gostaria de saber se o amigo Allyson teria uma sugestão de onde posso encontrar um tuto que fale sobre listar taxonomias nos metaboxes?
Bom, eu fiz uma classe para estender a classe de metabox do Odin Framework, onde justamente faço metaboxes a partir de taxonomias.
Basicamente, você precisa pegar os termos, com
get_terms()
e percorrê-los com umforeach
, utilizando o código necessário para criar o campo desejado. (Isso caso queria fazer uma metabox com termos de uma taxonomia, se no caso for fazer uma metabox com taxonomias mesmo, ai você precisa buscá-las comget_taxonomies()
)Esse é o código da classe que fiz, onde crio campos checkbox e select com termos de uma taxonomia, utilizando a classe Metabox do Odin Framework, porém você consegue utilizá-la sem estar trabalhando com o Odin. https://github.com/HasteDesign/TaxonomyMetabox
E claro, pode utilizá-la como referência para o seu próprio código.
get_terms(): http://codex.wordpress.org/Function_Reference/get_terms
get_taxonomies(): http://codex.wordpress.org/Function_Reference/get_taxonomiesEntão Allyson, vou explanar a respeito da minha necessidade mas primeiro quero falar brevemente sobre o Odin. Eu quis utilizá-lo como framework de base do meu, mas acho que não soube me expressar bem no Grupo do GitHub, pois não obtive o retorno de ajuda que eu esperava, então parti para o underscores que é razoavelmente mais simples e acessível, mas quero voltar a tentar algo usando o Odin, que me pareceu uma ótima iniciativa e com o bônus de ser uma iniciativa nacional.
Agora voltando a questão da meta-box, o que eu quero fazer é exibir a lista de todas as sub-taxonomias relacionadas a taxonomia LOCALIZAÇÃO (ex: Porto Alegre, Canoas, Caxias do Sul) em um select field (meta-box)e que possa ser selecionada apenas uma localidade. Acredito que tenha que usar o
get_taxonomies()
pois preciso que a relação da meta-box seja direta com a taxonomia Localização. Acredito que tu possas me dar uma luz de por onde ou como começar, além claro das referências citadas por tí acima.PS: Acho que tô me encontrando na Function Reference.
Odin: As vezes o pessoal não teve tempo de auxiliar, não entendeu sua dúvida, mas é um excelente framework, vale a pena dar uma olhada, de vez em quando dou uma olhada nas issues lá, mas ainda ajudo pouco. (Até por não ter pleno domínio de todo funcionamento do sistema)
Metaboxes: Não entendi muito bem o que você quis dizer com sub-taxonomias, me parece que quis falar em termos – é preciso ter isso bem claro, o que são taxonomias, e o que são termos, enquanto está desenvolvendo, até para facilitar na hora solicitar ajuda.
Taxonomias – Sistema de agrupamento, como por exemplo cargo.
Termo – Elemento de uma taxonomia. Nossa taxonomia cargo pode ter os seguintes termos: supervisor, gerente, diretor e presidente.
Os termos sim podem ser hierarquizados, gerente pode ser um cargo pai com gerente de marketing, gerente de vendas e gerente administrativo como filhos.
Para trabalhar pegando apenas os filhos de um termo, pode dar uma olhada na função
get_term_children()
.http://codex.wordpress.org/Function_Reference/get_term_children
Puts velho, agora ficou até mais fácil de raciocinar o código. Eu ainda não tinha sacado o lance de relacionar a taxonomia e os termos. Mas seguinte cara, o que eu to fazendo é colocando os termos da taxonomia LOCALIDADES dentro de um select field (ainda não consegui chamar os termos dentro dele) para que seja escolhida apenas uma localidade. A outra taxonomia REFERÊNCIAS DO IMÓVEL eu vou usar apenas como rótulos de referência para cada imóvel (Lançamento, Últimas unidades,…), então vários termos poderão ser selecionados.
Espero ter explicado o que estou fazendo e deixar meus agradecimentos pela ajuda. Não vou encerrar o tópico ainda pois quero ver se vai funcionar direito, caso funcione eu deixo a cópia do código finalizado e funcional aqui pra servir de referência. Valeu!!
- O tópico ‘Problemas com posts personalizados (custom-post-types)’ está fechado para novas respostas.