How to display taxonomy parent for selected taxonomy - php

I want to show on the site the parent of the selected taxonomy. For that I have the above code but the problem with this is that it is showing all the selected taxonomy in a list with now structure.
global $post;
$features = get_the_terms( $post->ID, 'property-feature' );
if ( !empty( $features ) && is_array( $features ) && !is_wp_error( $features ) ) {
?>
<div class="property-features">
<?php
global $inspiry_options;
$property_features_title = $inspiry_options[ 'inspiry_property_features_title' ];
if( !empty( $property_features_title ) ) {
?><h4 class="fancy-title"><?php echo esc_html( $property_features_title ); ?></h4><?php
}
?>
<ul class="property-features-list clearfix">
<?php
foreach( $parent_term as $single_feature ) {
echo '<li>'. $single_feature->name . '</li>';
}
?>
</ul>
</div>
<?php
}
Example:
Parent: option 1, option 2
Parent 2 : option 3, option 4
If I select option 2 and option 3 I want to see
Parent: option 2
Parent 2 : option 3
Updare 2
global $post;
$features = get_the_terms( $post->ID, 'property-feature' );
$featuresss = get_the_terms( $post->ID, 'property-feature' );
// determine the topmost parent of a term
function get_term_top_most_parent($term_id, $taxonomy){
// start from the current term
$parent = get_term_by( 'id', $term_id, $taxonomy);
// climb up the hierarchy until we reach a term with parent = '0'
while ($parent->parent != '0'){
$term_id = $parent->parent;
$parent = get_term_by( 'id', $term_id, $taxonomy);
}
return $parent;
}
// so once you have this function you can just loop over the results returned by wp_get_object_terms
function hey_top_parents($taxonomy, $results = 1) {
// get terms for current post
$terms = wp_get_object_terms( get_the_ID(), $taxonomy );
$y = get_the_terms($terms->term_id, $taxonomy);
// set vars
$top_parent_terms = array();
foreach ( $terms as $term ) {
//get top level parent
$top_parent = get_term_top_most_parent( $term->term_id, $taxonomy );
//check if you have it in your array to only add it once
if ( !in_array( $top_parent, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}
// build output (the HTML is up to you)
foreach( $top_parent_terms as $single_feature ) {
echo '<li>'. $single_feature->name . '</li>';
foreach( $terms as $single ) {
echo '<ul><li>'. $single->name . '</li></ul>';
}
}
//return $top_parent_terms;
}
I managed to display the top parent for the selected taxonomy but now the problem is that I need now to display in the top parent anly the selected taxonomy from that parent

global $post;
$taxonomy = "property-feature";
// determine the topmost parent of a term
function get_term_top_most_parent($term_id, $taxonomy){
// start from the current term
$parent = get_term_by( 'id', $term_id, $taxonomy);
// climb up the hierarchy until we reach a term with parent = '0'
while ($parent->parent != '0'){
$term_id = $parent->parent;
$parent = get_term_by( 'id', $term_id, $taxonomy);
}
return $parent;
}
// so once you have this function you can just loop over the results returned by wp_get_object_terms
function hey_top_parents($taxonomy, $results = 1) {
// get terms for current post
$terms = wp_get_object_terms( get_the_ID(), $taxonomy );
// set vars
$top_parent_terms = array();
foreach ( $terms as $term ) {
//get top level parent
$top_parent = get_term_top_most_parent( $term->term_id, $taxonomy );
//check if you have it in your array to only add it once
if ( !in_array( $top_parent, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}
// build output (the HTML is up to you)
foreach( $top_parent_terms as $single_feature )
{
echo '<li>'. $single_feature->name . '</li>';
foreach( $terms as $single ) {
if( $single_feature->term_id == $single->parent ) {
echo '<ul><li>'. $single->name . '</li></ul>';
}
}
}
//return $top_parent_terms;
}
CHANGES:
1) Moved taxonomy name to variable (used in echo's).
$taxonomy = "property-feature";
2) Added if condition to the code responsible for displaying sub terms.
if( $single_feature->term_id == $single->parent ) {
echo '<ul><li>'. $single->name . '</li></ul>';
}
REMOVED (not used lines of codes):
1)
$features = get_the_terms( $post->ID, 'property-feature' );
$featuresss = get_the_terms( $post->ID, 'property-feature' );
2)
$y = get_the_terms($terms->term_id, $taxonomy);
CONSIDER:
1) Removing $results variable from:
function hey_top_parents($taxonomy, $results = 1) {
it is not used anywhere or maybe should be to determine if results should be returned or displayed by the function.

Related

Adding an attributes column to WooCommerce admin products list

I was given code from someone on the Wordpress forum, but it isn't quite right.
It has created a column in my Product Admin called Attributes, and it is bringing in the name of the attributes, but not options. i.e. it looks like
"coloursizeyearcountry"
And I would like
"Colour = Red, Size = large, Year = 2020, Country = UK"
or something like it.
The code I have so far is:
function add_product_column( $columns ) {
//add column
$columns['new_column'] = __( 'New column', 'woocommerce' );
return $columns;
}
add_filter( 'manage_edit-product_columns', 'add_product_column', 10, 1 );
function add_product_column_content( $column, $postid ) {
if ( $column == 'new_column' ) {
// Get product object
$product = wc_get_product( $postid );
// Get Product Variations
$product_attributes = $product->get_attributes();
foreach ( $product_attributes as $product_attribute ) {
$attribute_name = $product_attribute->get_name();
echo str_replace( 'pa_', '', $attribute_name );
}
}
}
add_action( 'manage_product_posts_custom_column', 'add_product_column_content', 10, 2 );
The following code will help you get what you want. Explanation via the comment tags added in the code
function add_product_column( $columns ) {
//add column
$columns['new_column'] = __( 'New column', 'woocommerce' );
return $columns;
}
add_filter( 'manage_edit-product_columns', 'add_product_column', 10, 1 );
function add_product_column_content( $column, $postid ) {
if ( $column == 'new_column' ) {
// output variable
$output = '';
// Get product object
$product = wc_get_product( $postid );
// Get Product Variations - WC_Product_Attribute Object
$product_attributes = $product->get_attributes();
// Not empty, contains values
if ( !empty( $product_attributes ) ) {
foreach ( $product_attributes as $product_attribute ) {
// Get name
$attribute_name = str_replace( 'pa_', '', $product_attribute->get_name() );
// Concatenate
$output = $attribute_name . ' = ';
// Get options
$attribute_options = $product_attribute->get_options();
// Not empty, contains values
if ( !empty( $attribute_options ) ) {
foreach ($attribute_options as $key => $attribute_option ) {
// WP_Term Object
$term = get_term($attribute_option); // <-- your term ID
// Not empty, contains values
if ( !empty( $term ) ) {
$term_name = $term->name;
// Not empty
if ( $term_name != '' ) {
// Last loop
end($attribute_options);
if ( $key === key($attribute_options) ) {
// Concatenate
$output .= $term_name;
} else {
// Concatenate
$output .= $term_name . ', ';
}
}
}
}
}
echo $output . '<br>';
}
}
}
}
add_action( 'manage_product_posts_custom_column', 'add_product_column_content', 10, 2 );

Show Woocommerce subcategories on single page by their parents slug or ID

I am trying to add Publisher, Topic and Author to a Single Product with help of categories/subcategories. This is how it looks after hours of coding/and copying (very fresh with WooCommerce tbh)
This is what I am getting, but it shows ALL subcategories, not only the ones associated to the Product, this is the code I am using
function get_product_subcategories_list( $category_slug ){
$terms_html = array();
$taxonomy = 'product_cat';
// Get the product category (parent) WP_Term object
$parent = get_term_by( 'slug', $category_slug, $taxonomy );
// Get an array of the subcategories IDs (children IDs)
$children_ids = get_term_children( $parent->term_id, $taxonomy );
// Loop through each children IDs
foreach($children_ids as $children_id){
$term = get_term( $children_id, $taxonomy ); // WP_Term object
$term_link = get_term_link( $term, $taxonomy ); // The term link
if ( is_wp_error( $term_link ) ) $term_link = '';
// Set in an array the html formated subcategory name/link
$terms_html[] = '' . $term->name . '';
}
return '<span class="subcategories-' . $category_slug . '">' . implode( ', ', $terms_html ) . '</span>';
}
add_action('woocommerce_single_product_summary','monolith_cat_scan', 31);
function monolith_cat_scan() {
echo '<p>Topic : ';
echo get_product_subcategories_list( 'topics' );
echo '</p>';
echo '<p>Publisher : ';
echo get_product_subcategories_list( 'publishers' );
echo '</p>';
echo '<p>Author: ';
echo get_product_subcategories_list( 'authors' );
echo '</p>';
}
But I can't get the whole thing to work like I want to and get the subcategories of the Single Product, in this example only Spirituality, SOUNDS TRUE INC (only sub cat in Publishers), and Allan Watts should be there.
I'd appreciate every help!
I got a working code (it doesn't look beautiful I know but it's the best I could do and it does the trick.
add_action('woocommerce_single_product_summary','monolith_cat_scan', 31);
function monolith_cat_scan() {
global $post;
$cats = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $cats ) ) {
foreach ( $cats as $term ) {
if( $term->parent == 30 ) {
echo '<p>Topic : ' . $term->name . '';
}
}
}
}
add_action('woocommerce_single_product_summary','monolith_cat_scan2', 32);
function monolith_cat_scan2() {
global $post;
$cats = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $cats ) ) {
foreach ( $cats as $term ) {
if( $term->parent == 31 ) {
echo '<p>Author : ' . $term->name . '';
}
}
}
}
add_action('woocommerce_single_product_summary','monolith_cat_scan3', 33);
function monolith_cat_scan3() {
global $post;
$cats = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $cats ) ) {
foreach ( $cats as $term ) {
// If parent cat ID = 116 echo subcat name...
if( $term->parent == 32 ) {
echo '<p>Publisher : ' . $term->name . '';
}
}
}
}

Display terms for multiple Woocommerce custom taxonomies

I need an imploded list of terms from three custom Woocommerce taxonomies including the taxonomy name to display in the product loop. I'll also need to be able to display multiple terms for each taxonomy. However, I can only get it to work with one taxonomy. And I can't figure out how to display the corresponding taxonomy name.
My custom taxonomies are 'artists', 'illustrators' and 'authors'. Here's what I'm trying to accomplish:
Robert Douglas (Author), Bill Johnston (Illustrator), Kyle McBeth (Artist)
function list_author_terms() {
global $post;
$person = get_the_terms(get_the_ID(), 'authors', 'artists', 'illustrators');
if ( $person
&& !is_wp_error( $person )
) {
#usort( $person, function ( $a, $b )
{
return strcasecmp(
$a->slug,
$b->slug
);
});
// Display your terms as normal
$term_list = [];
foreach ( $person as $term )
$term_list[] = '' . esc_html( $term->name ) . '<span class="attribute"> (Author)</span> ';
$term_names[] = $term->name;
echo implode( ', ', $term_list);
echo '<br>';
}
}
Add follows code snippet to achieve your task -
add_action( 'woocommerce_after_shop_loop_item', 'list_author_terms', 6 );
function list_author_terms(){
$taxonomies = array( 'authors', 'artists', 'illustrators' );
$pro_list_terms = array();
foreach ( $taxonomies as $taxonomy ) {
$term_obj_list = get_the_terms( get_the_ID(), $taxonomy );
$tax_obj = get_taxonomy( $taxonomy );
if( $term_obj_list && ! is_wp_error( $term_obj_list ) ){
foreach ( $term_obj_list as $term ) {
$link = get_term_link( $term, $taxonomy );
$pro_list_terms[] = '' . $term->name . ' (' .$tax_obj->labels->singular_name . ')';
}
}
}
echo join( ', ', $pro_list_terms );
}

2 Layouts for a WooCommerce shop

I have to categories named "Collectie" and "Shop", what I want is different layouts for the children of both categories.
I already tried this with the template_include function like this:
function lab5_template_include( $template ) {
if ( category_has_children('collectie')) {
$template = get_stylesheet_directory() . '/woocommerce/archive-product-collectie.php';
}elseif ( is_product_category('shop')) {
$template = get_stylesheet_directory() . '/woocommerce/archive-product-shop.php';
}
return $template;
}
How do I do that?
EDIT
I solved it with the solution from https://wordpress.org/support/topic/different-page-layouts-for-category-vs-subcategory
i added the next lines to taxonomy-product_cat.php
// We need to get the top-level category so we know which template to load.
$get_cat = $wp_query->query['product_cat'];
// Split
$all_the_cats = explode('/', $get_cat);
// How many categories are there?
$cat_count = count($all_the_cats);
//
// All the cats say meow!
//
// Define the parent
$parent_cat = $all_the_cats[0];
// Collectie
if ( $parent_cat == 'collectie' ) woocommerce_get_template( 'archive-product-collectie.php' );
// Shop
elseif ( $parent_cat == 'shop' ) woocommerce_get_template( 'archive-product.php' );
I think you'd be better off running a while loop to determine the parent level category name. Then you can match it against the different parent categories you want to display differently.
edit lab5_template_include() should use is_product_category() instead of is_product_taxonomy() which returns true on product category and tag archives.
function lab5_template_include( $template ) {
if( is_product_category()){
$slug = get_query_var('product_cat');
$cat = get_term_by( 'slug', $slug, 'product_cat' );
$catParent = so_top_product_category_slug($cat);
// locate the new templates
if ( 'collectie' == $catParent ) {
$new_template = locate_template( array( 'woocommerce/archive-product-collectie.php' ) );
} elseif ( 'shop' == $catParent ) ) {
$new_template = locate_template( array( 'woocommerce/archive-product-shop.php' ) );
}
// set the new template if found
if ( '' != $new_template ) {
$template = $new_template ;
}
}
return $template;
}
add_filter('template_include', 'lab5_template_include', 20 );
edit bug fixes and improved efficiency of so_top_product_category_slug(). Now tested and working.
// get the top-level parent product category from a term object or term slug
function so_top_product_category_slug($cat) {
if( is_object( $cat ) ){
$catid = $cat->term_id;
} else {
$cat = get_term_by( 'slug', $cat, 'product_cat' );
$catid = $cat->term_id;
}
$parentId = $cat->parent;
$parentSlug = $cat->slug;
while ($parentId > 0) {
$cat = get_term_by( 'id', $parentId, 'product_cat' );
$parentId = $cat->parent; // assign parent ID (if exists) to $catid
$parentSlug = $cat->slug;
}
return $parentSlug;
}

Getting Wordpress category name from post ID not working

The problem is that I cannot display the category of a post:
http://screencast.com/t/hdQjpSV0Q
I have the following code in a function.php file:
// GET FEATURED IMAGE
function ST4_get_featured_image($post_ID) {
$custom_meta = get_post_custom(get_the_ID());
return $custom_meta["lumen_portfolio_preview_image_image"][0];
}
add_filter('manage_posts_columns', 'ST4_columns_head');
add_action('manage_posts_custom_column', ('ST4_columns_content'), 10, 2);
// ADD NEW COLUMN
function ST4_columns_head($defaults) {
$defaults['featured_image'] = 'Featured Image';
$defaults['categories_portfolio'] = 'Category';
return $defaults;
}
// SHOW THE FEATURED IMAGE
function ST4_columns_content($column_name, $post_ID) {
if ($column_name == 'featured_image') {
$post_featured_image = ST4_get_featured_image($post_ID);
if ($post_featured_image) {
echo '<img style="width:300px;height:200px;" src="' . $post_featured_image . '" />';
}
}
elseif ($column_name == 'categories_portfolio') {
$terms = get_the_terms( $post->ID , 'category' );
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, 'category' );
if( is_wp_error( $term_link ) )
continue;
echo '' . $term->name . '';
}
}
}
I have empty results, NULL, but I want to have the post category field. I used many wordpress functions, but no success.
I've noticed that your using the $post->ID as your parameter in your get_the_terms function, anyways I assume that the problem is you can't retrieve the category of the post, I would recommend using the get_the_category function in place of the get_the_terms in your code:
// SHOW THE FEATURED IMAGE
function ST4_columns_content($column_name, $post_ID) {
if ($column_name == 'featured_image') {
$post_featured_image = ST4_get_featured_image($post_ID);
if ($post_featured_image) {
echo '<img style="width:300px;height:200px;" src="' . $post_featured_image . '" />';
}
}
elseif ($column_name == 'categories_portfolio') {
//replace this $terms = get_the_terms( $post->ID , 'category' );
$terms = get_the_category($post_ID); //should you be using this instead of $post->ID?
foreach ( $terms as $term ) {
//replace this $term_link = get_term_link( $term, 'category' );
$term_link = get_category_link($term->term_id);
if( is_wp_error( $term_link ) )
continue;
echo '' . $term->name . '';
}
}
}
You can do a var_dump($terms) to further see the values being returned by this function, hope it helps, cheers!
I think you are using custom post type "Portfolio" as shown in attached screenshot.
Use wp_get_post_terms rather than get_the_terms
Update following code:
$terms = get_the_terms( $post->ID , 'category' );
to
$terms = wp_get_post_terms( $post->ID , 'category', array("fields" => "all") );
Note that 2nd parameter is the taxonomy name you are using while registering taxonomy.
See an example below where 'testimonials-cat' is used to register taxonomy.
register_taxonomy('testimonials-cat', 'testimonials', $args);
Your code for above taxonomy will be:
$terms = wp_get_post_terms($post->id, 'testimonials-cat', array("fields" => "all"));

Categories