Woocommerce 3.0 get variation name - woocommerce

Hi I had the following code that was working with old versions of Woocommerce to get an extract of the variation name and its price, which now doesn't work anymore after the WC upgarde to 3.0
function shortcode_handler($atts, $content = "", $shortcodename = "", $meta = "")
{
$output = "";
$meta['el_class'];
global $woocommerce, $product;
if(!is_object($woocommerce) || !is_object($woocommerce->query) || empty($product)) return;
// $product = wc_get_product();
$output .= "<div class='av-woo-calendar-button ".$meta['el_class']."'>";
ob_start();?>
<table cellspacing="0" cellpadding="2">
<thead>
<tr>
<th scope="col" style="text-align:left; background-color:rgba(155, 199, 239, 0.5); vertical-align:middle;"><?php _e('Cruise', 'whale_dolphins'); ?></th>
<th scope="col" style="text-align:center;background-color:rgba(155, 199, 239, 0.5);"><?php _e('Places<br/>available', 'whale_dolphins'); ?></th>
</tr>
</thead>
<tbody>
<?php
$args = array(
'post_type' => 'product_variation',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => '_stock',
'value' => array('', false, null),
'compare' => 'NOT IN'
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$product = new WC_Product_Variation( $loop->post->ID );
if (get_the_title( $loop->post->post_parent ) == 'CSR Expeditions Payment' || get_the_title( $loop->post->post_parent ) == 'Pagamento Spedizioni CSR')
{
$variation_formatted_name = $product->get_formatted_name();
$variation_name_array = explode("–", $variation_formatted_name);
$variation_name = $variation_name_array[2];
$variation_price = $variation_name_array[3];
$variation_sku = $variation_name_array[0];
$variation_name_only = explode(":", $variation_name);
$variation_name_only = $variation_name_only[1];
?>
<tr>
<td><?php echo $variation_name_only ."–" . $variation_price; ?></td>
<?php
if (intval ($product->stock) >0)
{ ?>
<td style="text-align:center; font-size: 13px; background-color:#70C940; color:rgba(255,255,255,1);"><?php echo intval ($product->stock); ?></td>
<?php
}
else
{ ?>
<td style="text-align:center; font-size: 13px; background-color:#D11E1B;color:rgba(255,255,255,1);"> <?php echo intval ($product->stock); ?></td>
<?php
}
?>
</tr>
<?php
}
endwhile;
?>
</tbody>
</table>
<?php
$output .= ob_get_clean();
$output .= "</div>";
return $output;
}
In particular I imagine that the following part of code is to be modified
$product = new WC_Product_Variation( $loop->post->ID );
if (get_the_title( $loop->post->post_parent ) == 'CSR Expeditions Payment' || get_the_title( $loop->post->post_parent ) == 'Pagamento Spedizioni CSR')
{
$variation_formatted_name = $product->get_formatted_name();
$variation_name_array = explode("–", $variation_formatted_name);
$variation_name = $variation_name_array[2];
$variation_price = $variation_name_array[3];
$variation_sku = $variation_name_array[0];
$variation_name_only = explode(":", $variation_name);
$variation_name_only = $variation_name_only[1];
Any suggestion on how can I fix it? Thank you very much

RESOLVED
I found the solution which is posted here below for anyboduìy may need it.
With the new Woocommerce the command $product->get_formatted_name(); returns a string as follows "product-name (#variation_id)"
With the variation_id however it is possible to get the attribute element slug from the postmeta table. With the slug you can get the attribute element name from the terms table.
$product = new WC_Product_Variation ($loop->post->ID);
if (get_the_title( $loop->post->post_parent ) == 'CSR Expeditions Payment' || get_the_title( $loop->post->post_parent ) == 'Pagamento Spedizioni CSR')
{
//1) I need to get the variation id == post id in wp_postmeta table
// get the name and id of the variation in a string
$variation_formatted_name = $product->get_formatted_name();
//explode the string to get an array of the string
$variation_formatted_name_array = explode("#", $variation_formatted_name);
//get only the variation id (which comes along with a closed parenthesis
$variation_id_ = $variation_formatted_name_array[1];
//explode the string in an array made by the variation id and the parenthesis
$variation_id = explode(")", $variation_id_);
//get only variation id
$variation_id_only = $variation_id[0];
//2)
//get the taxonomy needed
$taxonomy = 'pa_csr-dates';
//get the meta value (= attribute slug) from the postmeta table through the variation_id (= post_id)
$meta = get_post_meta($variation_id_only, 'attribute_'.$taxonomy, true);
//get the variation name from the terms table through the slug (=$meta)
$term = get_term_by('slug', $meta, $taxonomy);
//get the variation name (attribute element custom name)
$variation_name_only = $term->name;
$variation_price = $product->get_price();
}

Related

Add optional additional fee to checkout

i am using this following code to show the option to add an additional fee (product) to the cart on the "cart" page. It is working great but it is now showing on the cart page, but how do i get it to show on the checkout page additionally:
<?php
/* ADD custom theme functions here */
add_filter( 'woocommerce_price_trim_zeros', 'wc_hide_trailing_zeros', 10, 1 );
function wc_hide_trailing_zeros( $trim ) {
return true;
}
add_action('woocommerce_cart_totals_after_shipping', 'wc_shipping_insurance_note_after_cart');
function wc_shipping_insurance_note_after_cart() {
global $woocommerce;
$product_id = 971;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found ):
?>
<tr class="shipping">
<th><?php _e( 'Gift wrapper', 'woocommerce' ); ?></th>
<td><?php _e( 'Add ($3)' ); ?> </td>
</tr>
<?php else: ?>
<tr class="shipping">
<th><?php _e( 'Gift wrapper', 'woocommerce' ); ?></th>
<td>$3</td>
</tr>
<?php endif;
}
I have tried different methods, and it should be pretty basic but i am rusty on my Functions.php skills.
You could try copying the function and giving it a new name. Then change the hook depending on where you want it on the checkout page.
Here is a great visual guide to the hooks on the checkout page: https://www.businessbloomer.com/woocommerce-visual-hook-guide-checkout-page/
Try something like this:
Notice how I changed the hook from woocommerce_cart_totals_after_shipping to woocommerce_before_checkout_form here you can experiment using the hooks on the guide I linked to. I also changed the name of the function from wc_shipping_insurance_note_after_cart to wc_shipping_insurance_note_after_checkout to avoid conflicts.
add_action('woocommerce_before_checkout_form', 'wc_shipping_insurance_note_after_checkout');
function wc_shipping_insurance_note_after_checkout() {
global $woocommerce;
$product_id = 971;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found ):
?>
<tr class="shipping">
<th><?php _e( 'Gift wrapper', 'woocommerce' ); ?></th>
<td><?php _e( 'Add ($3)' ); ?> </td>
</tr>
<?php else: ?>
<tr class="shipping">
<th><?php _e( 'Gift wrapper', 'woocommerce' ); ?></th>
<td>$3</td>
</tr>
<?php endif;
}
Edit per comment. You could try something like this if you only want to add the table row if a product in the cart has a certain category.
You will have to change "example-category" in $categories = array('example-category'); to your category slug.
add_action('woocommerce_before_checkout_form','wc_shipping_insurance_note_after_checkout');
function wc_shipping_insurance_note_after_checkout() {
global $woocommerce;
$categories = array('example-category');
$found = false;
//loop trough cart items
foreach ( WC()->cart->get_cart_contents() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
//Check if product has category
if ( has_term( $categories, 'product_cat', $product_id ) ) {
$found = true;
}
}
// Do this if product has category
if ( $found ) {
?>
<tr class="shipping">
<th><?php _e( 'Gift wrapper', 'woocommerce' ); ?></th>
<td><?php _e( 'Add ($3)' ); ?> </td>
</tr>
<?php
} else {
//If product does not have category do this instead
?>
<tr class="shipping">
<th><?php _e( 'Gift wrapper', 'woocommerce' ); ?></th>
<td>$3</td>
</tr>
<?php
}
}

Woocommerce - how to display only on-hold orders using a shortcode

By default Woocommerce orders table displays all available order status on the My Account page which is not sortable by customer, therefore I need to have a separate table for every unique order statue (example : 'on-hold' ) to display orders table based on only required statue.
I tried this code but it doesn't output the table:
/* Shortcode To Display Only On-hold Orders On A Custom Page */
add_shortcode('account_on_hold', 'get_customer_orders_on_hold');
function get_customer_orders_on_hold() {
if( $user = wp_get_current_user() ){
// Get 'on-hold' customer ORDERS
$on_hold_orders = wc_get_orders( array(
'limit' => -1,
'customer_id' => $user->ID,
'status' => array('on-hold'),
) );
}
return $on_hold_orders ;
}
Related Topic : Get customer “on-hold” order status total amount in Woocommerce
Your advice would be appreciated!
Ruvee's way is good to customize.
Alternatively, if you want output just the same as "my-account/orders", there is also the method to call the template.
add_shortcode('account_on_hold', 'get_customer_orders_on_hold');
function get_customer_orders_on_hold() {
if( $user = wp_get_current_user() ){
$customer_orders = wc_get_orders(
array(
'customer' => $user->ID,
'limit' => -1,
'page' => 1,
'paginate' => true,
'status' => array('on-hold'),
)
);
ob_start();
wc_get_template(
'myaccount/orders.php',
array(
'current_page' => 1,
'customer_orders' => $customer_orders,
'has_orders' => 0 < $customer_orders->total,
)
);
return ob_get_clean();
}
}
(Addition) The way to add custom menu on the myaccount.
// Add custom endpoint
add_action( 'init', function () {
add_rewrite_endpoint( 'on-hold-orders', EP_ROOT | EP_PAGES );
});
// Add custom menu
add_filter( 'woocommerce_account_menu_items', function ( $items ) {
$new_items = array();
foreach( $items as $key => $item ){// Loop menu items
$new_items[$key] = $item;
if( 'orders' == $key ) $new_items['on-hold-orders'] = __( 'On hold orders' );
}
return $new_items;
}, 20 );
// Output custom menu page template
add_action( 'woocommerce_account_on-hold-orders_endpoint', function( $current_page ) {
$current_page = empty( $current_page ) ? 1 : absint( $current_page ); // With paginate
$customer_orders = wc_get_orders( array(
'customer' => get_current_user_id(),
'page' => $current_page,
'paginate' => true,
'status' => array('on-hold'),
));
wc_get_template(
'myaccount/orders.php',
array(
'current_page' => absint( $current_page ),
'customer_orders' => $customer_orders,
'has_orders' => 0 < $customer_orders->total,
)
);
} );
You could use woocommerce table template to generate the html table. You only need to put a conditional check before generating it.
woocommerce table template
+
if("On hold" == esc_html(wc_get_order_status_name($order->get_status())))
So you could set this up in multiple ways, for example it could be something like this:
add_shortcode('account_on_hold', 'get_customer_orders_on_hold');
function get_customer_orders_on_hold()
{
if ($user = wp_get_current_user()) {
$on_hold_orders = wc_get_orders(array(
'limit' => -1,
'customer_id' => $user->ID,
'status' => array('on-hold'),
));
if ($on_hold_orders) :
?>
<table class="woocommerce-orders-table woocommerce-MyAccount-orders shop_table shop_table_responsive my_account_orders account-orders-table">
<thead>
<tr>
<?php foreach (wc_get_account_orders_columns() as $column_id => $column_name) : ?>
<th class="woocommerce-orders-table__header woocommerce-orders-table__header-<?php echo esc_attr($column_id); ?>"><span class="nobr"><?php echo esc_html($column_name); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php
foreach ($on_hold_orders as $order) {
$order = wc_get_order($order);
$item_count = $order->get_item_count() - $order->get_item_count_refunded();
if ("On hold" == esc_html(wc_get_order_status_name($order->get_status()))) :
?>
<tr class="woocommerce-orders-table__row woocommerce-orders-table__row--status-<?php echo esc_attr($order->get_status()); ?> order">
<?php foreach (wc_get_account_orders_columns() as $column_id => $column_name) : ?>
<td class="woocommerce-orders-table__cell woocommerce-orders-table__cell-<?php echo esc_attr($column_id); ?>" data-title="<?php echo esc_attr($column_name); ?>">
<?php if (has_action('woocommerce_my_account_my_orders_column_' . $column_id)) : ?>
<?php do_action('woocommerce_my_account_my_orders_column_' . $column_id, $order); ?>
<?php elseif ('order-number' === $column_id) : ?>
<a href="<?php echo esc_url($order->get_view_order_url()); ?>">
<?php echo esc_html(_x('#', 'hash before order number', 'woocommerce') . $order->get_order_number()); ?>
</a>
<?php elseif ('order-date' === $column_id) : ?>
<time datetime="<?php echo esc_attr($order->get_date_created()->date('c')); ?>"><?php echo esc_html(wc_format_datetime($order->get_date_created())); ?></time>
<?php elseif ('order-status' === $column_id) : ?>
<?php echo esc_html(wc_get_order_status_name($order->get_status())); ?>
<?php elseif ('order-total' === $column_id) : ?>
<?php
echo wp_kses_post(sprintf(_n('%1$s for %2$s item', '%1$s for %2$s items', $item_count, 'woocommerce'), $order->get_formatted_order_total(), $item_count));
?>
<?php elseif ('order-actions' === $column_id) : ?>
<?php
$actions = wc_get_account_orders_actions($order);
if (!empty($actions)) {
foreach ($actions as $key => $action) {
echo '' . esc_html($action['name']) . '';
}
}
?>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php
endif;
}
?>
</tbody>
</table>
<?php endif; ?>
<?php }
}
Tested and works.

Get product custom attribute Woocommerce

I have a single product custom variation table template in functions.php and I'm trying to get product custom attribute. I have two them (date and location).
I'm found a lot of solutions, but none didn't work for me.
Woocommerce version 3.2.6.
With this code below I get
Notice: Only variables should be passed by reference.
And I get type 'Null' of $date.
<td class="date">
<?php
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
$date = array_shift( wc_get_product_terms( $product_id, 'pa_date', array( 'fields' => 'names' ) ) );
?>
</td>
This is my full product variation table code in function.php
function woocommerce_variable_add_to_cart(){
global $product, $post, $woocommerce;
$attributes = $product->get_attributes();
$variations = find_valid_variations();
// Check if the special 'price_grid' meta is set, if it is, load the default template:
if ( get_post_meta($post->ID, 'price_grid', true) ) {
wp_enqueue_script( 'wc-add-to-cart-variation' );
wc_get_template( 'single-product/add-to-cart/variable.php', array(
'available_variations' => $product->get_available_variations(),
'attributes' => $product->get_variation_attributes(),
'selected_attributes' => $product->get_variation_default_attributes()
) );
return;
}
?>
<table class="variations variations-grid" cellspacing="0">
<thead>
<tr>
<td> Date | Location </td>
<td> Price </td>
<td> Quantity </td>
<td> Availability </td>
<td> </td>
</tr>
</thead>
<tbody>
<?php
foreach ($variations as $key => $value) {
if( !$value['variation_is_visible'] ) continue;
?>
<tr>
<td class="date">
<?php
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id; // Added WC 3+ support
$date = array_shift( wc_get_product_terms( $product_id, 'pa_date', array( 'fields' => 'names' ) ) );
?>
</td>
<td class="price">
<?php echo '<span>£</span>' . $product->get_price(); ?>
</td>
<td class="quantity">
<?php woocommerce_quantity_input(); ?>
</td>
<td class="stock">
<?php if (!$value['is_in_stock'] ) { ?>
<p class="stock out-of-stock"><?php _e( 'Places Not Available', 'woocommerce' ); ?></p>
<?php } else { ?>
<p class="stock in-stock"><?php _e( 'Places Available', 'woocommerce' ); ?></p>
</td>
<td class="add-to-cart">
<form class="cart" action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" method="post" enctype='multipart/form-data'>
<?php
if(!empty($value['attributes'])){
foreach ($value['attributes'] as $attr_key => $attr_value) {
?>
<input type="hidden" name="<?php echo $attr_key?>" value="<?php echo $attr_value?>">
<?php
}
}
?>
<button type="submit" class="single_add_to_cart_button button alt"><span class="glyphicon glyphicon-tag"></span> Add to cart</button>
<input type="hidden" name="variation_id" value="<?php echo $value['variation_id']?>" />
<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $post->ID ); ?>" />
</form>
<?php } ?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
}
function find_valid_variations() {
global $product;
$variations = $product->get_available_variations();
$attributes = $product->get_attributes();
$new_variants = array();
foreach( $variations as $variation ) {
// Peruse the attributes.
// 1. If both are explicitly set, this is a valid variation
// 2. If one is not set, that means any, and we must 'create' the rest.
$valid = true; // so far
foreach( $attributes as $slug => $args ) {
if( array_key_exists("attribute_$slug", $variation['attributes']) && !empty($variation['attributes']["attribute_$slug"]) ) {
// Exists
} else {
// Not exists, create
$valid = false; // it contains 'anys'
foreach( explode( '|', $attributes[$slug]['value']) as $attribute ) {
$attribute = trim( $attribute );
$new_variant = $variation;
$new_variant['attributes']["attribute_$slug"] = $attribute;
$new_variants[] = $new_variant;
}
}
}
// This contains ALL set attributes, and is itself a 'valid' variation.
if( $valid )
$new_variants[] = $variation;
}
return $new_variants;
}
UPDATE
I got this code working, but I get both attribute values (date location) in one tag.
How to seperate attributes?
<td>
<?php
foreach($value['attributes'] as $key => $val ) {
$val = str_replace(array('-','_'), ' ', $val);
printf( '<span class="attr attr-%s">%s</span>', $key, ucwords($val) );
}
?>
</td>
UPDATE
Finally I get date and location but with extra warnings, notices, and single characters.
Code
<?php
foreach($value as $date ) {
printf($date['attribute_date']);
}
?>
** SOLVED **
Maybe not the best method, but it's working.
<td class="date">
<?php
$i = 0;
foreach($value['attributes'] as $key => $val ) {
if($i == 0 ) {
echo $val;
}
$i++;
}
?>
</td>
<td class="location">
<?php
$i = 0;
foreach($value['attributes'] as $key => $val ) {
if($i !== 0) {
echo $val;
}
$i++;
}
?>
</td>
Use the method get_attributes() and function wc_get_product_terms() described here
<?php
// Get the attributes
$attributes = $product->get_attributes();
// Start the loop
foreach ( $attributes as $attribute ) : ?>
<?php
// Check and output, adopted from /templates/single-product/product-attributes.php
if ( $attribute['is_taxonomy'] ) {
$values = wc_get_product_terms( $product->id, $attribute['name'], array( 'fields' => 'names' ) );
echo apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
} else {
// Convert pipes to commas and display values
$values = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) );
echo apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
}
?>
<?php endforeach; ?>
If you look at the template \templates\single-product\product-attributes.php you can see how to get the individual attribute names.
if ( $attribute->is_taxonomy() ) {
$attribute_taxonomy = $attribute->get_taxonomy_object();
$attribute_values = wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'all' ) );
foreach ( $attribute_values as $attribute_value ) {
$value_name = esc_html( $attribute_value->name );
if ( $attribute_taxonomy->attribute_public ) {
$values[] = '' . $value_name . '';
} else {
$values[] = $value_name;
}
}
}
Here's how to get specific Custom Attribute:
// Get the custom attribute
$svd_attribute = array_shift( wc_get_product_terms( $product->id, 'your_custom_attribute', array( 'fields' => 'names' ) ) );
// Display if String
if ( is_string( $svd_attribute ) ) {
echo wp_kses_post( "$svd_attribute" );
}
Just replace "your_custom_attribute"
Working on WooCommerce: 3.8.0

Get Wordpress child category from specific parent

I'm building a small thumbnail gallery with posts from a category that has the ID 406.
Some of the posts are in multiple categories and I'm not sure how to grab the category name that is a child of 406. $post_cat[0]->name; returns a category, but I only need it to return children of 406.
$thumbnails = get_posts('posts_per_page=10&cat=406');
foreach ($thumbnails as $thumbnail) {
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => 406,
);
$categories = get_categories ( $args );
foreach ( $categories as $category) {
$cat_name = $category->name;
$cat_slug = $category->slug;
}
echo $cat_name;
echo $cat_slug;
}
*EDIT**
$thumbnails = get_posts('posts_per_page=10&cat=406');
foreach ($thumbnails as $thumbnail) {
$post_cat = get_the_category( $thumbnail->ID );
echo '<li><a class="side-thumb" href="' . get_permalink( $thumbnail->ID ) . '" title="' . esc_attr( $thumbnail->post_title ) . '">';
if ( has_post_thumbnail($thumbnail->ID)) {
echo get_the_post_thumbnail($thumbnail->ID, 'thumbnail');
$upload_dir = wp_upload_dir();
$art_image = ''.$upload_dir['basedir'].'/icons/'.$post_cat[0]->slug.'.png';
if (file_exists($art_image)) {
echo '<p class="artist-latest"><img src="http://site.com/wp-content/uploads/icons/'.$post_cat[0]->slug.'.png" alt="'.$post_cat[0]->slug.'"/>'.$post_cat[0]->name.'</p>';
} else{
echo '<p class="artist-latest">'.$post_cat[0]->name.'</p>';
}
} else {
}
echo '</a></li>';
}
So now I'm fetching a list of category and its child, then I fetch posts having parent category assigned to it, after I get posts array, I loop into it and get all the categories assigned to the post, If there are additional categories other than the required category and its child I skip the post, otherwise do whatever I want to do.
$category = get_category_by_slug( 'category-name' );
$args = array(
'type' => 'post',
'child_of' => $category->term_id,
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => FALSE,
'hierarchical' => 1,
'taxonomy' => 'category',
);
$child_categories = get_categories($args );
$category_list = array();
$category_list[] = $category->term_id;
if ( !empty ( $child_categories ) ){
foreach ( $child_categories as $child_category ){
$category_list[] = $child_category->term_id;
}
}
$posts_args = array(
'posts_per_page' => 10,
'cat' => $category->term_id,
'post_type' => 'post',
'post_status' => 'publish',
'suppress_filters' => true
);
$posts = new WP_Query ( $posts_args );
if ( $posts->have_posts() ){
while ( $posts->have_posts() ){
$posts->the_post();
$category_array = array();
$post_categories = get_the_category ( get_the_ID() );
if ( !empty ( $post_categories ) ){
foreach ( $post_categories as $post_category ) {
$category_array[] = $post_category->term_id;
}
}
//Checks if post has an additional category
$result = array_diff( $category_array, $category_list );
if ( empty ( $result ) ) { ?>
<li>
<a href="<?php the_permalink(); ?>" class="side-thumb" title="<?php the_title(); ?>"> dfdf<?php
if ( has_post_thumbnail() ){
echo get_the_post_thumbnail();
}
//Put your default icon code here
?>
</a>
</li> <?php
}
}
}
wp_reset_postdata();
Above answer is as per your explanation, but I think what you want is, like you have a category Artists and there are subcategories each having a specific name, So for Artist gallery you want to display list of all the artists with their pictures.
I also needed to get list of child categories of selected parent category with url,
I found following code so useful
<?php
$categories = get_categories( array(
'orderby' => 'name',
'parent' => 5
) );
foreach ( $categories as $category ) {
printf( '<li><a class="btn btn-light btn-light-custom mt-2" href="%1$s">%2$s</a></li>',
esc_url( get_category_link( $category->term_id ) ),
esc_html( $category->name )
);
}
?>
Replace "5" with your selected parent category ID

Custom parent category and subcategory

I really need your help. i just created a WordPress page template that display all the post but my problem is the display of the custom parent taxonomy/category and it's children. My post look like this.
<table>
<tr>
<td>Title</td>
<td>Parent Category</td>
<td>Sub Category</td>
<td>Excerpt</td>
</tr>
<tr>
<td>a title</td>
<td>USA custom category</td>
<td>Hawaii uder USA</td>
<td>this is a sample description.</td>
</tr>
</table>
My only problem is to display the sub category. Anyone can help me?
This is my code on how i display the parent custom category:
<?php
$term_list = '';
$terms = get_the_terms( $post->ID, 'origincity' );
foreach( $terms as $term ) {
$parent_term = get_term( $term->parent, 'origincity' );
$term_list .= $parent_term->name ;
}
echo $term_list;
?>
I tried to display the sub category by this code :
<?php $terms2 = wp_get_post_terms($post->ID, 'origincity', array("fields" => "all"));
foreach ($terms2 as $term1) {
echo $term1->name.'<br>';
} ?>
but it also return the parent. :(
Your help is highly appreciated. Thanks.
I dont suggest using your method you are currently using because you don't have enough control over what's showing.
In future use get_posts();
It's really simple to use! For example:
<ul>
<?php
global $post;
$args = array( 'posts_per_page' => 5, 'offset'=> 1, 'category' => 1 );
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post); ?>
<li>
<?php the_title(); ?>
</li>
<?php endforeach; ?>
</ul>
As you can see you can set how many posts, the category and many more arguments for the posts displayed.
Find out more about the arguments here http://codex.wordpress.org/Template_Tags/get_posts
Already solve the problem by this code:
function print_taxonomic_ranks( $terms ){
// set id variables to 0 for easy check
$order_id = $family_id = $subfamily_id = 0;
// get family
foreach ( $terms as $term ) {
if ( $family_id || $order_id != $term->parent )
continue;
$family_id = $term->term_id;
$family = $term->name;
}
// get subfamily
foreach ( $terms as $term ) {
if ( $subfamily_id || $family_id != $term->parent )
continue;
$subfamily_id = $term->term_id;
$subfamily = $term->name;
}
// output
echo "$subfamily";
}
Thanks by the way.

Resources