I have a wordpress app locally setup in my computer. In the wordpress admin i have a Countries tab under the Posts. I'll attach an image for better understanding.
I want to write a function to get the country values for my front-end. For that i have written a function like this
public function get_destinations()
{
$bookings = get_posts(
array(
'taxonomy'=> 'country',
'numberposts' => -1,
)
);
return $bookings;
}
But for some reason this function returns all the posts in the database. I want to get only the country names.
i found the taxonomy from my local url which is
http://localhost/my_project/wp-admin/edit-tags.php?taxonomy=country
I'm very new to wordpress and dont have a clue on how to retrieve these data to my front end. What am i doing wrong here?
If you want to show the only category or taxonomy name instead of get_posts you have to use get_terms
check this code.
// Get the taxonomy's terms
$terms = get_terms(
array(
'taxonomy' => 'country',
'hide_empty' => false, // show category even if dont have any post.
)
);
// Check if any term exists
if ( ! empty( $terms ) && is_array( $terms ) ) {
// Run a loop and print them all
foreach ( $terms as $term ) { ?>
<a href="<?php echo esc_url( get_term_link( $term ) ) ?>">
<?php echo $term->name; ?>
</a><?php
}
}
Related
I am new to Stackoverflow and relatively new to WordPress as well. I have been trying to build a custom WordPress theme that also allows you to insert images for categories in the WordPress Dashboard. So far, I have been able to get the image URL saved into the database using the following code:
update_term_meta($term_id, 'custom_image_data', $image_data);
($image_data is an array with the elements: ID, and URL for the image)
However, now I would like to retrieve these two pieces of information and share them with my coresponding Javascript file. So far I have this code:
function image_uploader_js() {
wp_register_script('image_file_uploader_js', get_template_directory_uri() . '/js/image_uploader.js', array('jquery', 'media-upload'));
wp_enqueue_script('image_file_uploader_js');
wp_localize_script('image_file_uploader_js', 'customUploads', array('imageData' => get_term_meta(get_queried_object_id(), 'custom_image_data', true)) ); //**
}
add_action('admin_footer', 'image_uploader_js');
However, when I go into the Google Chrome console and type in CustomUploads it just shows an empty string. But if I were to replace the code get_queried_object_id() with a static number 1 (which corresponds to the $term_id of the category) I get CustomUploads { id: ##, URL: HTTPS://..... } which is the desired result.
My question is why doesn't the original code work and how would I be able to share the id and URL or my category image with my Javascript file?
Make sure that you are on the category page then get_queried_object_id() will return term id. in other pages you will get a different id corresponding to that page.
You can use is_category() to check whether you are on the category page.
function image_uploader_js() {
if( is_category() ){
wp_register_script('image_file_uploader_js', get_template_directory_uri() . '/js/image_uploader.js', array('jquery', 'media-upload'));
wp_enqueue_script('image_file_uploader_js');
wp_localize_script('image_file_uploader_js', 'customUploads', array('imageData' => get_term_meta(get_queried_object_id(), 'custom_image_data', true)) ); //**
}
}
add_action('admin_footer', 'image_uploader_js');
Or you can get all terms and push to an array and then you can access to js file.
function image_uploader_js() {
$category = get_terms( array(
'taxonomy' => 'category', // your custom taxonomy name
'hide_empty' => false
) );
$imageData = array();
if( !empty( $category ) ){
foreach ( $category as $key => $cat ) {
$imageData[$cat->term_id] = get_term_meta( $cat->term_id, 'custom_image_data', true );
}
}
wp_register_script( 'image_file_uploader_js', get_template_directory_uri() . '/js/image_uploader.js', array('jquery', 'media-upload') );
wp_enqueue_script( 'image_file_uploader_js');
wp_localize_script( 'image_file_uploader_js', 'customUploads', array( 'imageData' => $imageData ) ); //**
}
add_action('admin_footer', 'image_uploader_js');
I Need to Redirect a Custom Page If the Product Count is Zero in a Woocommerce Category Kindly Help me
Assuming that you are accessing the product categories via one of the taxonomy term pages:
Add this to your functions.php file. Make sure you replace SOME_PATH . '/some-custom-file.php'; with the path to the template you would like to load.
add_filter( 'template_include', 'redirect_on_empty_product_category' );
function redirect_on_empty_product_category( $template ){
if ( ( $taxonomy_id = get_query_var( 'taxonomy' ) ) && ( $term_id = get_query_var( 'term' ) ) && is_tax( $taxonomy_id, $term_id ) ){
$term = get_term_by( 'slug', $term_id, $taxonomy_id );
if ( $term->count === 0 ){
$page_url = get_permalink($some_post_id);
echo sprintf('<script type="text/javascript"> window.location = "%s" </script>', $page_url);
}
}
return $template;
}
You just need to add $cat->count to get the count of all products in that category. Hope this helps you out.
$args = array(
'number' => $number,
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
'include' => $ids
);
$product_categories = get_terms( 'product_cat', $args );
foreach( $product_categories as $cat ) {
echo $cat->name.' ('.$cat->count.')';
}
Thanks
My question is regarding suggestions for improvements of a feature I created on a Wordpress site that changes the phone number displayed to user in the header based on their IP address. The default is a 1-866 number to be displayed if area does not appear to be serviced etc.
In my functions.php file I created the below functions to use ipinfo.io to find the city of the user, compare it to the field of city I created to be associated with each location post and then if there is a match the second function returns the phone number field associated with that location. See functions below:
//Returns users city based on IP address
function get_the_user_ip() {
if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
//Checks if IP is from shared internet
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
//Checks if IP is passed from proxy
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else {
//Most trustworthy source of IP address
$ip = $_SERVER['REMOTE_ADDR'];
}
//$ip='104.238.96.194'; //--used this to test different IP addresses--
//Uses ipinfo.io to find location information based on IP address
$details = json_decode(file_get_contents("https://ipinfo.io/{$ip}"));
//Returns city value from the details array
$city=$details->city;
return apply_filters('wpb_get_ip', $city );
}
//Returns correct phone number based on a user's location
function zip_display(){
$args = array(
'posts_per_page' => -1,
'post_type' => 'Locations',
'post_status' => ('publish')
);
$wp_query = new WP_Query($args);
//var_dump($wp_query);
if( $wp_query->have_posts() ): while( $wp_query->have_posts() ) : $wp_query->the_post();
$userCity=get_the_user_ip();
$stateField=get_field('state');
$cityField=get_field('city');
$phoneField=get_field('phone_number');
if($userCity==$cityField){
return ( '<span class="phone-span">' . $phoneField . '</span>');
}
endwhile;
wp_reset_postdata();
endif;
}
To display the correct phone number in the header I inserted a <div> element with the id of phone directly into an auxiliary header like so:
Then to target this div id I inserted the below JavaScript directly into my footer.php
<script>document.getElementById("phone").innerHTML = '<?php echo zip_display(); ?>';</script>
Is this an acceptable way to go about doing this? Everything is working correctly more or less right now. The only issue I am having so far is it seems for at least one person neither the default 1-866 number is being displayed to them nor a specific number based on their location? Does anyone have any ideas why that would be? Does it possibly have to do with a browser setting that does not allow JavaScript scripts to be shown in the way I constructed it?
The zip_display() function in your posted code will only return a span element if the $userCity matches the $cityField. You need to return the span containing the default phone number if the cities do not match. Change your condition to something like this:
if($userCity==$cityField){
return ( '<span class="phone-span">' . $phoneField . '</span>');
}else{
return ( '<span class="phone-span">' . $defaultPhoneNumber . '</span>');
}
In order to improve the functionality of this feature I did the following:
In my get_the_user_ip function I decided to use the free WordPress plugin GeoIP Detection, instead of ipinfo.io
See modification to get_the_user_ip function below:
`//Returns users city based on IP address`
function get_the_user_ip() {
if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
//Checks if IP is from shared internet
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
//Checks if IP is passed from proxy
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else {
//Most trustworthy source of IP address
$ip = $_SERVER['REMOTE_ADDR'];
}
$record = geoip_detect2_get_info_from_ip($ip, NULL);
$city=$record->city->name;
return apply_filters('wpb_get_ip', $city );
}
In my zip_display function I added a return statement outside of while loop. In order to return a default phone number if the user's city cannot be matched to a location. This works better than an if/else statement because it will only execute once the loop has completed all iterations.
function zip_display(){
$args = array(
'posts_per_page' => -1,
'post_type' => 'Locations',
'post_status' => ('publish')
);
$wp_query = new WP_Query($args);
if( $wp_query->have_posts() ): while( $wp_query->have_posts() ) : $wp_query->the_post();
$userCity=get_the_user_ip();
$cityField=get_field('city');
$phoneField=get_field('phone_number');
if($userCity==$cityField){
return ('<a class="phone-span" href="tel:1-'. $phoneField . '">' . $phoneField . '</a>');
}
endwhile;
return('<a class="phone-span" href="tel:1-866-000-0000">1-866-000-0000</a>');
wp_reset_postdata();
endif;
}
Lastly I modified my footer.php file, separating my JavaScript script into a variable so that the script would not throw an Uncaught TypeErron: Cannot read property '....' of null.
<script>
var ipphone = '<?php echo zip_display(); ?>'
if(ipphone){document.getElementById("phone").innerHTML = ipphone;}
</script>
I am trying to apply a "Load more posts" function to a post loop, but I am dealing with a 400 Bad request, when admin-ajax.php is referred to.
The reference I used is this - https://rudrastyh.com/wordpress/load-more-posts-ajax.html
Following function (in functions.php) is passing query parameters to javascript:
function wordpress_my_load_more_scripts()
{
global $wp_query;
wp_enqueue_script('jquery');
wp_register_script( 'my_loadmore', get_stylesheet_directory_uri() . '/myloadmore.js', array('jquery') );
wp_localize_script( 'my_loadmore', 'wordpress_loadmore_params', array(
'ajaxurl' => admin_url() . 'admin-ajax.php',
'posts' => json_encode( $wp_query->query_vars ),
'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
'max_page' => $wp_query->max_num_pages
) );
wp_enqueue_script( 'my_loadmore' );
}
add_action( 'wp_enqueue_scripts', 'wordpress_my_load_more_scripts' );
Parameters are passed to following jQuery script named "myloadmore.js":
jQuery(function($){
$('.wordpress_loadmore').click(function()
{
var button = $(this),
data = {
'action': 'loadmore',
'query': wordpress_loadmore_params.posts,
'page' : wordpress_loadmore_params.current_page
};
console.log(wordpress_loadmore_params.ajaxurl);
$.ajax({
url : wordpress_loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr )
{
button.text('Loading...');
},
success : function( data ){
if( data ) {
button.text( 'More posts' ).prev().before(data);
wordpress_loadmore_params.current_page++;
if ( wordpress_loadmore_params.current_page == wordpress_loadmore_params.max_page )
button.remove(); // if last page, remove the button
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});
});
Following function inside functions.php is expected to provide three more posts inside while loop:
function wordpress_loadmore_ajax_handler()
{
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_status'] = 'publish';
query_posts( $args );
if(have_posts() ) :
echo "We have post(s)!";
while( have_posts() ): the_post();
echo "A post!";
endwhile;
endif;
die;
}
add_action('wp_ajax_loadmore', 'wordpress_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmore', 'wordpress_loadmore_ajax_handler');
The post loop is this:
<ul class="products columns-3">
<?php
$query_params = array(
'post_type' => 'post',
'posts_per_page' => 3
);
$wp_query = new WP_Query( $query_params);
if( $wp_query->have_posts() ) :
while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<li class="product post-item">
<span class="post-image">
<a href="<?php the_permalink(); ?>">
<?php
if ( has_post_thumbnail())
{
the_post_thumbnail();
}
?>
</a>
</span>
<h2 class="post-title"><?php the_title(); ?></h2>
<span class="post-category"><?php the_category(', ');?></span>
</li>
<?php endwhile; ?>
<?php endif; ?>
</ul>
<nav>
<?php
global $wp_query; // you can remove this line if everything works for you
// don't display the button if there are not enough posts
if ( $wp_query->max_num_pages > 1 )
echo '
<div class="wordpress_wrapper">
<div class="wordpress_loadmore">More posts</div>
</div>'; // you can use <a> as well
?>
</nav>
<?php wp_reset_postdata(); ?>
Clicking the button to load more posts results in following message:
https://www.uvjagtpro.dk/wp-admin/admin-ajax.php
jquery.js?ver=1.12.4:4 POST https://www.uvjagtpro.dk/wp-admin/admin-ajax.php 400 ()
send # jquery.js?ver=1.12.4:4
ajax # jquery.js?ver=1.12.4:4
(anonymous) # myloadmore.js:13
dispatch # jquery.js?ver=1.12.4:3
r.handle # jquery.js?ver=1.12.4:3
Why can't I parse variable in Array named "wordpress_loadmore_params.ajaxurl" without it causing a 400 bad request?
Link to page is here - https://www.uvjagtpro.dk/arkiv/
There are only 3 cases where WordPress will return a 400 on an AJAX request to
.../wp-admin/admin-ajax.php
$_REQUEST['action'] variable is empty
has_action( 'wp_ajax_' . $_REQUEST['action'] ) is false
has_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] ) is false
So, you should verify that your code
add_action('wp_ajax_loadmore', 'wordpress_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmore', 'wordpress_loadmore_ajax_handler');
is really executed and the query does contain a $_REQUEST['action'] with contents 'loadmore'. This is easiest to do if you know how to use a PHP debugger otherwise I would use error_log() to display relevant messages after the add_action statements. You can also display the value of the has_action() functions.
Your code looks correct to me so I think the error is not the code itself but maybe its location.
On my wordpress page, I have the following loop, which successfully outputs an attachment's caption.
<?php
$the_query = new WP_Query(array( 'post_type' => 'attachment'));
while ( $the_query->have_posts() ) : $the_query->the_post();
$attachment_data = wp_prepare_attachment_for_js();
echo '<h2>'.$attachment_data['caption'].'</h2>'
;?>
Now, I also need to call the attachment caption outside of the loop. This is what I'm trying in functions.php:
function custom_info()
{
global $wp_query;
$query_id = $wp_query->post->ID;
$attachment_data_query = wp_prepare_attachment_for_js( $query_id );
wp_register_script( 'custom_data_info');
$info = array(
'data_query' => $attachment_data_query['caption']
);
wp_enqueue_script( 'custom_data_info' );
wp_localize_script('custom_data_info', 'info', $info);
}
if ( !is_admin() ) add_action( "wp_enqueue_scripts", "custom_info", 10 );
And then it would be called in the external javascript file like so:
return info.data_query
I know the custom_info function and javascript file are talking with each other correctly. The problem is with how I am defining $query_id
EDIT: Almost fixed. The problem was that I didn't include a foreach statement, and so the first item in the loop was being repeated over and over again.
I've adjusted below, but for some reason, now the array is empty upon output of info.data_query...
function custom_info(){
global $wp_query;
wp_register_script( 'custom_data_info');
$info = array('data_query' => array());
foreach ( $wp_query->posts as $query_id) {
$attachment_data_query = wp_prepare_attachment_for_js( $query_id );
$info['data_query'][$query_id] = $attachment_data_query['caption'];
}
Are you sure $wp_query will return the correct post ID? In my experience, it's better to use global $post instead. Pass that into wp_prepare_attachment_js() instead:
global $post;
$post_id = $post->ID;
$attachment_data_query = wp_prepare_attachment_for_js( $post_id );