I have a dropdown menu in header.php that I want to modify. This dropdown menu lists only parent categories.
I want to add a "selected" to the option in the menu that has the same <strong>parent category</strong> as the current url. I want the current parent category to be visible in the menu.
Here is my current code that is generating the dropdown menu.
<form name="dropdown" id="sitenav-menu">
<select name="selected" id="target" accesskey="E" onchange="goToNewPage(document.dropdown.selected)">
<?php
$args = array(
'orderby' => 'name',
'parent' => 0
);
$categories = get_categories( $args );
foreach ( $categories as $category ) {
echo '<option value="' . get_category_link( $category->term_id ) . '">' . $category->name . '</option>';
} ?>
</select>
</form>
Here is a link to a demo of the code.
[[LINK href="http://opensort.net/category/music/"]]http://opensort.net/category/music/[[/LINK]]
Let me know if you have any questions. Thank you!
Kyle answers:
Try this:
<form name="dropdown" id="sitenav-menu">
<select name="selected" id="target" accesskey="E" onchange="goToNewPage(document.dropdown.selected)">
<?php
global $wp_query;
$args = array(
'orderby' => 'name',
'parent' => 0
);
$categories = get_categories( $args );
$name = $wp_query->query_vars['category_name'];
foreach ( $categories as $category ) {
if($category->name == $name){ $selected = 'selected'; }else{ $selected = ''; }
echo '<option value="' . get_category_link( $category->term_id ) . '" '.$selected.'>' . $category->name . '</option>';
} ?>
</select>
</form>
dirtcastle comments:
@Kyle
Thank you for the code. Unfortunately, it doesn't seem to be working.
Kyle comments:
Can you add:
echo $name;
Below this line $name = $wp_query->query_vars['category_name'];
If that is incorrect add var_dump($wp_query); outside the foreach and send the result
Kyle comments:
Another possible solution is...
$cat_id = $wp_query->get_queried_object_id();
$name = get_cat_name( $cat_id );
dirtcastle comments:
When I insert the following, it outputs the current category.
echo $name;
But I think it needs to output the parent category, correct? The dropdown menu shows parents, therefore we should be comparing parents with parents.
Note the following argument in the array.
'parent' => 0
Any thoughts?
Kyle comments:
Ah, my fault
$cat_id = $wp_query->get_queried_object_id();
$child = get_category($cat_id);
$parent = $child->parent;
$parent_ob = get_category($parent);
$name = $parent_ob->name;
dirtcastle comments:
Yes! You are awesome.
It's working on subcategories. Unfortunately, it doesn't work when the category is a parent.
Any thoughts?
Kyle comments:
Ah, do you mean like http://opensort.net/category/philosophy/areas/ vs http://opensort.net/category/philosophy/
Kyle comments:
Try this:
$cat_id = $wp_query->get_queried_object_id();
$child = get_category($cat_id);
$parent = $child->parent;
$parent_ob = get_category($parent);
if($parent>0){ $name = $parent_ob->name; }else{ $name = $child->name; }
dirtcastle comments:
Yes, there are three levels of categories (parent/child/grandchild). And this menu will show up on all three.
dirtcastle comments:
Boom!
Yes!
That did it!
Thank you!
Kyle comments:
See my last post
Kyle comments:
You're welcome! Happy to help
dirtcastle comments:
Doh! I spoke too soon. It's not working in a few places.
<strong>Where it works:</strong>
1. Parent level
[[LINK href="http://opensort.net/category/music/"]]http://opensort.net/category/music/[[/LINK]]
2. Child level
[[LINK href="http://opensort.net/category/music/genres/"]]http://opensort.net/category/music/genres/[[/LINK]]
<strong>Where it's not working:</strong>
3. Grandchild level
[[LINK href="http://opensort.net/category/music/genres/hip-hop/"]]http://opensort.net/category/music/genres/hip-hop/[[/LINK]]
4. Single.php
[[LINK href="http://opensort.net/music/genres/hip-hop/new-post-test/"]]http://opensort.net/music/genres/hip-hop/new-post-test/[[/LINK]]
Kyle comments:
Sent you a PM
Kyle comments:
Was @Dbranes able to solve the single.php problem?
dirtcastle comments:
Yes. Thank you for checking back. I appreciate all your help!
Kyle comments:
No problem, Dbranes always gets it done :)
Dbranes answers:
Here's another approach:
You can try to use the <em>get_category_parents()</em> to get a support for any category child depth:
<?php
/**
* Construct the selected url for the selectbox:
*/
if( is_category() ) {
// Get the url of the top ancestor of the current category:
$ancestors = explode( ',', get_category_parents( $cat, false, ',' ) );
$select_menu_url = get_category_link( get_cat_id( array_shift( $ancestors ) ) );
}elseif( is_single() ){
// Get the url of the top ancestor of the first current post category:
$cats = get_the_category();
$ancestors = explode( ',', get_category_parents( $cats[0]->term_id, false, ',' ) );
$select_menu_url = get_category_link( get_cat_id( array_shift( $ancestors ) ) );
}else{
// Modify this to your needs:
$select_menu_url = home_url( '/' );
}
/**
* Display the selectbox:
*/
?>
<form name="dropdown" id="sitenav-menu">
<select name="selected" id="target" accesskey="E" onchange="goToNewPage(document.dropdown.selected)">
<?php
$args = array(
'orderby' => 'name',
'parent' => 0
);
$categories = get_categories( $args );
foreach ( $categories as $category ) {
$link = get_category_link( $category->term_id );
?>
<option value="<?php echo $link;?>" <?php selected( $link, $select_menu_url );?>><?php echo $category->name;?></option>
<?php
}
?>
</select>
</form>
where we use the WordPress function <em>selected()</em> to add the <em>selected</em> value.
dirtcastle comments:
Thank you! This is working on all of my category.php views.
Where it works:
1. Parent level
http://opensort.net/category/music/
2. Child level
http://opensort.net/category/music/genres/
3. Grandchild level
http://opensort.net/category/music/genres/hip-hop/
Where it's not working:
4. Single.php
http://opensort.net/music/genres/hip-hop/new-post-test/
Any thoughts on how I should get it working for single.php? Should I use an "if (is_single())" and deliver a separate form for single.php? Or should I add something to the code you've written here.
Dbranes comments:
@dirtcastle: ok sure, please see my updated the answer.
Regarding the <em>is_single(),</em> case, I find the url of the top ancestor of the first current post category (out of possible many others).
It works on my install.
ps: just let me know if this needs more adjustments, i.e. if @Kyle hasn't already solved it ;-)
dirtcastle comments:
This works for single.php! Thank you!