I have some custom taxonomies built in theme, and on the taxonomy dropdown, taxonomies are not showed in hierarchy. It just show a dropdown list of all taxonomies, but not in hierarchical order.
This is what I've got:
register_taxonomy(
'recipesets',
'recipe',
array(
'public'=>true,
'hierarchical' => true,
'labels'=> $labels,
'query_var' => 'recipesets',
'show_ui' => true,
'rewrite' => array( 'slug' => 'recipesets', 'with_front' => false ),
)
);
}
and calling:
<label for="edit-title" class="control-label"><i class="fa fa-folder-o"></i><?php _e('Category:', 'agrg') ?></label>
<select name="cat" id="cat" class="postform">
<?php
$terms = get_terms("recipesets", "orderby=count&hide_empty=0");
if ( !is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
echo "<option value='" . $term->name . "'>" . $term->name . "</option>";
}
}
?>
</select>
What to do?
Why not use the Wordpress function wp_dropdown_categories() which does all the work for you
$tax_args = array(
'taxonomy' => 'destination',
'orderby' => 'name',
'show_count' => 1,
'hierarchical' => 1,
);
wp_dropdown_categories($tax_args);
This is how I would do it:
<?php
/** The taxonomy we want to parse */
$taxonomy = "category";
/** Get all taxonomy terms */
$terms = get_terms($taxonomy, array(
"orderby" => "count",
"hide_empty" => false
)
);
/** Get terms that have children */
$hierarchy = _get_term_hierarchy($taxonomy);
?>
<select name="terms" id="terms">
<?php
/** Loop through every term */
foreach($terms as $term) {
/** Skip term if it has children */
if($term->parent) {
continue;
}
echo '<option value="' . $term->name . '">' . $term->name . '</option>';
/** If the term has children... */
if($hierarchy[$term->term_id]) {
/** ...display them */
foreach($hierarchy[$term->term_id] as $child) {
/** Get the term object by its ID */
$child = get_term($child, "category");
echo '<option value="' . $term->name . '"> - ' . $child->name . '</option>';
}
}
}
?>
</select>
Related
Hi I would like to add country of origin while adding products and then sort products based on country of origin
Can I achieve this?
Add these functions to your theme's 'functions.php'.
Display & Save the Custom Field in Admin
// display field in admin
add_action('woocommerce_product_options_general_product_data', 'woocommerce_product_country_field');
function woocommerce_product_country_field()
{
global $woocommerce, $post;
$countries_obj = new WC_Countries();
$options = $countries_obj->__get('countries');
echo '<div class="product_country_field">';
woocommerce_wp_select(
array(
'id' => '_country_origin',
'label' => __('Country of origin', 'woocommerce'),
'options' => $options,
'desc_tip' => 'true'
)
);
echo '</div>';
}
// save fields
add_action('woocommerce_process_product_meta', 'woocommerce_product_country_fields_save');
function woocommerce_product_country_fields_save($post_id)
{
$woocommerce_country_origin = $_POST['_country_origin'];
if (!empty($woocommerce_country_origin))
update_post_meta($post_id, '_country_origin', esc_attr($woocommerce_country_origin));
}
Sort by Custom Field in Front-End
// sort field
function custom_add_country_ordering_args( $sort_args ) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
switch( $orderby_value ) {
case '_country_origin':
$sort_args['orderby'] = 'meta_value';
$sort_args['order'] = 'asc';
$sort_args['meta_key'] = '_country_origin';
break;
case '_country_origin-desc':
$sort_args['orderby'] = 'meta_value';
$sort_args['order'] = 'desc';
$sort_args['meta_key'] = '_country_origin';
break;
}
return $sort_args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_add_country_ordering_args' );
//change sort dropdown
function custom_add_country_orderby( $sortby ) {
//remove default sorting
unset($sortby["popularity"]);
unset($sortby["rating"]);
unset($sortby["date"]);
unset($sortby["price"]);
unset($sortby["price-desc"]);
$sortby['_country_origin'] = __( 'Sort by Country of origin', 'woocommerce' );
$sortby['_country_origin-desc'] = __( 'Sort by Country of origin descending', 'woocommerce' );
return $sortby;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_add_country_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_add_country_orderby' );
Please note that the products which has 'Country of origin' will only be displayed while sorting.
Filter by Custom Field in Front-End
Add this if you want filter rather than sort.
//add custom filter
add_action( 'woocommerce_before_shop_loop', 'filter_loop_start' );
function filter_loop_start( $query ){
$countries_obj = new WC_Countries();
$options = $countries_obj->__get('countries');
?>
<form name="product_filter_form" class="woocommerce-filtering" method="get">
<select name="country_origin" class="filterby" onChange="document.product_filter_form.submit();">
<option value="">Filter by Country of origin</option>
<?php foreach ($options as $key => $value) { ?>
<option value="<?php echo $key; ?>"<?php if($_GET['country_origin']==$key) echo ' selected'; ?>><?php echo $value; ?></option>
<?php } ?>
</select>
<input name="paged" value="1" type="hidden">
</form>
<?php
}
//modify query for filter
add_filter( 'pre_get_posts', 'my_modify_main_query' );
function my_modify_main_query( $query ) {
if( ! isset( $_GET['country_origin'] ) ) return $query;
$meta_query_args = array(
'meta_query' => array(
array(
'key' => '_country_origin',
'value' => sanitize_text_field( $_GET['country_origin'] ),
'compare' => 'LIKE',
)
)
);
$query->set('meta_query', $meta_query_args);
return $query;
}
I'm trying to create the next/previous post navigation for single post on a wordpress blog.
There is a post category called "lifestyle-blog" with id 37 that is different from other posts, so the navigation on the posts in that category is supposed to display only posts from that category, while on all other posts it should display posts from all categories except from the one with id 37.
I was able to set the navigation on posts from "lifestyle-blog" category to display only the posts from that category, but I don't understand why I can't exclude "lifestyle-blog" category posts from the navigation on posts from other categories.
Here is the code I'm using at the moment.
$next_post = get_next_post();
$previous_post = get_previous_post();
if (has_category( 'lifestyle-blog', $post )) {
$in_same_term = true;
$post_ids = '';
} else {
$in_same_term = false;
$cat_post_ids = get_posts(array(
'numberposts' => -1, // get all posts.
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => '37',
),
),
'fields' => 'ids', // Only get post IDs
));
$post_ids = implode( ',', $cat_post_ids );
}
the_post_navigation( array(
'next_text' => '<div class="next-text"><span class="meta-nav">' . __( 'Next: ', 'twentyfifteen' ) . '</span> ' . '<span class="post-title">%title</span></div>' . get_the_post_thumbnail($next_post->ID,'paging-thumb'),
'prev_text' => get_the_post_thumbnail($previous_post->ID,'paging-thumb') . '<div class="prev-text"><span class="meta-nav">' . __( 'Previous: ', 'twentyfifteen' ) . '</span> ' .'<span class="post-title">%title</span></div>',
'in_same_term' => $in_same_term,
'excluded_terms' => $post_ids
) );
I tried placing print_r($post_ids) beneath the navigation, and on regular posts it prints the string of comma separated ids of posts from lifestyle-blog, so I don't understand why they are not excluded from the_post_navigation().
Can anyone help me solve this?
I ended up ditching the_post_navigation() in favor of next_post_link() and previous_post_link()
$cat_id = get_cat_ID( 'Lifestyle Blog' );
$taxonomy = array(
'category'
);
$ct_args = array(
'exclude' => array($cat_id),
'fields' => 'ids'
);
$ct_ids = get_terms( $taxonomy, $ct_args );
if (has_category( 'lifestyle-blog', $post )) {
$in_same_term = true;
$excluded_terms = $ct_ids;
$next_post = get_next_post($in_same_term, $excluded_terms);
$previous_post = get_previous_post($in_same_term, $excluded_terms);
} else {
$in_same_term = false;
$excluded_terms = $cat_id;
$next_post = get_next_post($in_same_term, $excluded_terms);
$previous_post = get_previous_post($in_same_term, $excluded_terms);
}
$prev_text = '<div class="next-text"><span class="meta-nav">' . __( 'Next: ', 'twentyfifteen' ) . '</span> ' . '<span class="post-title">%title</span></div>' . get_the_post_thumbnail($previous_post->ID,'paging-thumb');
$next_text = get_the_post_thumbnail($next_post->ID,'paging-thumb') . '<div class="prev-text"><span class="meta-nav">' . __( 'Previous: ', 'twentyfifteen' ) . '</span> ' .'<span class="post-title">%title</span></div>';
<nav class="navigation post-navigation">
<div class="nav-links">
<div class="nav-previous">
<?php next_post_link('%link', $next_text, $in_same_term, $excluded_terms); ?>
</div>
<div class="nav-next">
<?php previous_post_link('%link', $prev_text, $in_same_term, $excluded_terms); ?>
</div>
</div>
</nav>
i am going to build my own theme
I try to add select to post_type meta box, but every update post my select not on selected option but show the first option (blank value)
here is my code
function mhs_data() {
global $post;
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
$nisn = get_post_meta($post->ID, '_nisn', true);
$rel = get_post_meta($post->ID, '_rel', true);
}
echo '<p>NISN</p>';
echo '<input type="text" name="_nisn" value="' . $nisn . '" class="widefat" />';
echo '<p>Relationship</p>'; ?>
<select name="_rel" id="_rel">
<option value="">Relationship</option>
<option value="Single" <?php selected( $rel, 'Single' ); ?>>Single</option>
<option value="Marry" <?php selected( $rel, 'Marry' ); ?>>Marry</option>
</select>
<?php
}
function mhs_data_meta($post_id, $post) {
if ( !wp_verify_nonce( $_POST['eventmeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
$events_meta['_nisn'] = $_POST['_nisn'];
$events_meta['_rel'] = $_POST['_rel'];
foreach ($events_meta as $key => $value) {
if( $post->post_type == 'revision' ) return;
$value = implode(',', (array)$value);
if(get_post_meta($post->ID, $key, FALSE)) {
update_post_meta($post->ID, $key, $value);
} else {
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key);
}
}
add_action('save_post', 'mhs_data_meta', 1, 2);
Please help me to correct my code
Using Codestar Framework its very simple tu add metaboxes to your custom post, create configuration page, plugins, taxonomies and use the customizer if you prefer use it instead of a configuration page. see the documentation here for more information.
in your example, to add a select metabox shuld use a code similar to:
load the framework on your functions.php
require_once __DIR__ . '/'.$FRAMEWORK_PATH.'/cs-framework/cs-framework.php';
edit the cs-framekork.php configuration file to active only the features you need:
defined('CS_ACTIVE_FRAMEWORK') or define('CS_ACTIVE_FRAMEWORK', false); // if you need it for plugin or configuration page
defined('CS_ACTIVE_METABOX') or define('CS_ACTIVE_METABOX', true); // if you only need it for metabox
defined('CS_ACTIVE_TAXONOMY') or define('CS_ACTIVE_TAXONOMY', false);
defined('CS_ACTIVE_SHORTCODE') or define('CS_ACTIVE_SHORTCODE', false);
defined('CS_ACTIVE_CUSTOMIZE') or define('CS_ACTIVE_CUSTOMIZE', false);
and then in your function.php or as I prefer on another file included in your function.php register your metabox
function register_this_metabox($options)
{
$options = array(); // this will clean the default cs-framework configuration
$options[] = array(
'id' => 'the_metabox',
'title' => 'Meta Box title',
'post_type' => 'post', // the post type where the metabox appears
'context' => 'side', // metabox position
'priority' => 'high',
'sections' => array( // metabox fields, see the documentation
array(
'name' => 'the_metabox_fields',
'fields' => array(
array(
'id' => 'the_metabox_select_field',
'type' => 'select',
'title' => 'Select Field',
'options' => array(
'opt1' => 'Option 1',
'opt2' => 'Option 2',
'opt3' => 'Option 3',
),
'default_option' => 'Select a option',
),
),
),
),
);
return $options;
}
add_filter('cs_metabox_options', 'register_this_metabox');
And now you only have to get the values in your theme:
$post_metabox = get_post_meta($post->ID, 'the_metabox', true);
$selected_option = $post_metabox['the_metabox_select_field']
i try to get All child categories from my parent category
like my parent category is news and child is news1 news 2 news 3
Use following code for to get children category of parent category.
<?php
$parent_cat_arg = array('hide_empty' => false, 'parent' => 0 );
$parent_cat = get_terms('category',$parent_cat_arg);//category name
foreach ($parent_cat as $catVal) {
echo '<h2>'.$catVal->name.'</h2>'; //Parent Category
$child_arg = array( 'hide_empty' => false, 'parent' => $catVal->term_id );
$child_cat = get_terms( 'category', $child_arg );
echo '<ul>';
foreach( $child_cat as $child_term ) {
echo '<li>'.$child_term->name . '</li>'; //Child Category
}
echo '</ul>';
}
?>
This code will display all the child categories of selected parent category, tested and works in category.php template file...
$this_category = get_category($cat);
//echo $this_category->cat_ID;
$parent_term_id =$this_category->cat_ID; // term id of parent term
//$termchildren = get_terms('category',array('child_of' => $parent_id));
$taxonomies = array(
'taxonomy' => 'category'
);
$args = array(
// 'parent' => $parent_term_id,
'child_of' => $parent_term_id
);
$terms = get_terms($taxonomies, $args);
if (sizeof($terms)>0)
{
echo ' <div class="categories"> ';
echo '<p> Sub Categories of '. get_cat_name( $parent_term_id ) .'</p>';
foreach ( $terms as $term ) {
$term_link = sprintf( '<div class="custom-cats">%3$s</div>', esc_url( get_category_link( $term->term_id ) ),
esc_attr( sprintf( 'View all posts in %s', 'textdomain' ), $term->name ),
esc_html( $term->name ));
echo sprintf( $term_link );
}
echo '</div><!-- categories div end-->';
}
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