Manually highlight Wordpress admin menu item - wordpress

Under Pages menu in Wordpress Admin page, I got this layout:
Pages
Edit (url: edit-pages.php)
Add New (url: page-new.php)
Special Pages (url: edit-pages.php?special-pages=true)
as you can see, I've added a new submenu item called Special Pages which is pretty much a link to to Edit page with custom filter. Because Wordpress use file name to identify and highlight the submenu item, so whenever I click on Special Pages, the Edit submenu item is selected. Is there anyway to force Wordpress to select Special Pages menu item instead?
Cheers

better solution:
add_filter('parent_file', 'my_plugin_select_submenu');
function my_plugin_select_submenu($file) {
global $plugin_page;
if ('__my-current-submenu-slug__' == $plugin_page) {
$plugin_page = '__my-submenu-slug-to-select__';
}
return $file;
}

To further clarify Ken Vu's answer, edit the global variables $submenu_file and $parent_file. E.g., to highlight your page:
global $submenu_file;
$submenu_file = "edit-pages.php?special-pages=true";
If you need to change the top-level item highlighted, use $parent_file. E.g., highlight the "Writing" setting page:
global $parent_file;
global $submenu_file;
$parent_file = 'options-general.php';
$submenu_file = 'options-writing.php';

Solution: use $submenu_file variable
$submenu_file = "edit-pages.php?special-pages=true"

Thanks Ken Vu and Jonathan Brinley. Using your answers, I finally got the highlighting of my admin menu to work properly. As I struggled a bit to get it to work, I though I would post the entire result here, so other people can find it more easily :
The idea is to call the parent_file filter (undocumented, as many Wordpress parts unfornatunately). In my case, I was adding a custom menu instead of the default generated when creating a custom post type.
In my custom post code, I call the add_meta_boxes action. Within this hook, I issue my call to the parent_file filter :
add_filter('parent_file', array(&$this, 'highlight_admin_menu'));
_
Then this is how my hightlight_admin_menu function looks like :
function highlight_admin_menu($some_slug){
global $parent_file;
$parent_file = 'post.php?post=149&action=edit';
return $parent_file;
}
_
This got my menu to highlight properly. Try playing around with you own code to know where to issue the add_filter('parent_file', ...) code. Find a bit of code executed only on that particular page load, but soon enough that it is still possible to modify the $parent_file variable.
I hope this helps!

For changing the highlighted menu item for a submenu item, the proper filter is submenu_file.
add_filter('submenu_file', 'menuBold');
static function menuBold($submenu_file)
{
if ( checkProperPage($_GET) ) {
// The address of the link to be highlighted
return 'post-new?post_type=foobar&foo=bar';
}
// Don't change anything
return $submenu_file;
}
The check happens in WP's ~/wp-admin/menu-header.php file on line 194 (Wordpress 4.5.3):
if ( isset( $submenu_file ) ) {
if ( $submenu_file == $sub_item[2] )
$class[] = 'current';
...
}

You can modify this code to work for you. You can change both parent and submenu with that. Tested code.
function change_active_parent($submenu_file)
{
global $parent_file;
$zone = 'edit-tags.php?taxonomy=zone&post_type=product';
$storefront = 'edit-tags.php?taxonomy=storefront&post_type=product';
$container = 'edit-tags.php?taxonomy=container&post_type=product';
if (esc_html($zone) == $submenu_file) {
$parent_file = 'parent';
$submenu_file = $zone;
}
elseif (esc_html($storefront) == $submenu_file) {
$parent_file = 'parent';
$submenu_file = $storefront;
}
elseif (esc_html($container) == $submenu_file) {
$parent_file = 'parent';
$submenu_file = $container;
}
return $submenu_file;
}
add_filter( 'submenu_file', 'change_active_parent' );

Use the load-{$page_hook} action hook and modify the necessary globals:
/**
* For giggles, lets make an admin page that is not "in the menu" to play with.
*/
add_action('admin_menu', 'mort1305_admin_menu');
function mort1305_admin_menu() {
add_submenu_page(
NULL,
'Page Title',
'',
'administrator',
'my_slug',
'mort1305_page_content'
);
}
/**
* The menu item to highlight and the submenu item to embolden.
*/
add_action('load-admin_page_my_slug', 'mort1305_on_page_load');
function mort1305_on_page_load(){
global $plugin_file, $submenu_file, $title;
$plugin_page = 'slug-of-menu-item-to-be-highlighted';
$submenu_file = 'slug-of-submenu-item-to-be-bold';
foreach($submenu[NULL] as $submenu_arr) {
if($submenu_arr[2] === 'test_page_slug') {
$title = $submenu_arr[3];
break;
}
}
}
/**
* Page content to display.
*/
function mort_1305_page_content() {
echo This is the '. get_admin_page_title() .' page. The slug of my parent is '. get_admin_page_parent() .'.';
}

Related

Why WP_Screeen doesn't show all options with admin_body_class

I was trying to add a specific class to the admin section. I created a new top-level menu page and now I want to add a specific class to this top-level menu and its submenu items.
What I have tried so far is that I used WP_Screen to get the data of the current screen.
If I check the submenu page and I did var_dump(get_current_screen()). It shows every detail.
But now the case is that If I use get_current_screen() with admin_body_class why it doesn't work.
As far as I know, the hook is early called before the submenu page details are loaded.
Now I want to ask, how it is possible to check if the submenu has a specific parent base,
Here is the code that I tried so far.
add_filter('admin_body_class', 'tw_admin_body_class');
function tw_admin_body_class( $classes ) {
$screen = get_current_screen();
var_dump($screen);
if ( $screen->parent_base == 'tw-top' ) {
return $classes . ' raashid';
}
}
But parent_base is set to null. Any idea how to add class to submenu pages if it is under the specific yop-level menu.
It worked by using the Id option.
Here is the working option.
add_filter( 'admin_body_class', 'my_admin_body_class' );
function my_admin_body_class( $classes ) {
$screen = get_current_screen();
$classes .= ' raashid';
if ( get_plugin_page_hook( 'tw-top', '' ) === $screen->id ) {
return $classes;
}
}

Selecting child pages with a specific parent page doesn't work

I need to add a specific function when child pages of a specific parent page are visualized.
My parent page has ID= 115 and it hase a 7 child pages. I used the following code
global $post; // load details about this page
if(is_page()&&($post->post_parent== '115)) {
echo ' This is a subpage';
}
else {
echo 'This is not a subpage';
}
Though it should work, the output echo, when I visualize one of the child pages, is "This is not a subpage" -> it means that it doesn't recognize it as a child page.
What is wrong? Thank you very much
Want to detect whether a specific Page on a WordPress has children or not?
This function comes in handy, just add it to your functions.php:
function has_subpage() {
global $post;
if($post->post_parent){
$children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0");
} else {
$children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
} if ($children) {
echo ' This is a subpage';
} else {
echo ' This is a not subpage';
}
}
You can achieve the desired result by taking the following steps listed below...
Within your child theme, on your page.php first check if your are on a sub page via $post->post_parent.
Then within that, you can return an array of ancestors via get_post_ancestors
Then setup a condition to get the ID of the top level parent page
Once you have the ID, you can easily target the parent page by name. I recommend this so that when your theme travels for your development environment to our live environment, or if you had to manually create pages in any of these environments, the names will be the same.
Finally, enter your code for the sub page that targets its specific parent page location.
if (is_page() && $post->post_parent) :
$parents = get_post_ancestors($post->ID);
$id = ($parents) ? $parents[count($parents) - 1] : $post->ID;
$parent = get_post($id);
$parent_slug = $parent->post_name;
if ($parent_slug == "slug-of-your-specific-parent-page") {
//TEST
echo "this is custom text displaying on my sub page for a specific parent page";
//OR ADD YOUR SPECIFIC FUNCTION
...
}
endif;

How do you assign a specific order for a category in Wordpress?

I am having a small problem which I believe to be related to a syntax issue.
I have a specific script for home which calls the bloginfo("name") for the page title then an else statement below which titles pages based on the name of the first category associated them and it works fine:
else{
$category = get_the_category();
echo $category[0]->cat_name;
}
However, I also have a default "home" category for most posts(with a few exceptions) and I do not want this category to be picked up as the page title if it happens to come first in the list of categories associated for this page.
There are two ways I can think of making this possible but I do not know how to code them. The first would be to exclude the home category in the code above but don't know how to implement it. The second would be to somehow force wordpress to always add the category "home" after the first chosen category for a particular post.
I hope that this is clear. Anyone come up with a basic solution?
Many thanks.
This plugin does most of what you want out of the box:
http://wordpress.org/extend/plugins/sem-opt-in-front/
Alternatively, do something like:
function the_main_topic_link($link = '', $id = '')
{
if (!$id || $id != get_option('default_category')) return $link;
if (get_option('show_on_front') == 'page' && get_option('page_on_front')) {
if ($blog_page_id = get_option('page_for_posts')) {
return apply_filters('the_permalink', get_permalink($blog_page_id));
} else {
return $link;
}
} else {
return home_url('/');
}
}
add_filter('category_link', 'the_main_topic_link', 10, 2);
function pre_get_posts_redirect_main_topic($q)
{
global $wp_the_query;
if ($q !== $wp_the_query) return;
if ($q->is_category(get_option('default_category'))) {
wp_redirect(home_url('/'));
die;
}
}
if (!is_admin()) add_action('pre_get_posts', 'pre_get_posts_redirect_main_topic');
It'll treat linking to your default category as linking to your front page.

wordpress subpage tag

I'm building a wordpress theme right now and I'm using conditionals in the sidebar to display different information for each page like so:
if (is_page('services')) {
etc.....
} elseif (etc....
However, some of the subpages do not have their own specific conditional. How can I make it so that a conditional for a parent page applies to its subpages as well?
Thanks!
You could do this a number of ways. There might be an easier way, but this is what I would do:
On the page itself, check if it is a child page:
if ( is_page() && $post->post_parent )
{
// This is a subpage
return true;
}
else
{
// This is not a subpage
return false;
}
which will check if the page is a child, in which case you can fetch the conditional from the parent the same way you are currently, except specify the parent instead of the current page when checking.
You can also put this snippet of code in your functions.php file and use it anywhere on your wp code.
function is_subpage() {
global $post; // load details about this page
if ( is_page() && $post->post_parent ) { // test to see if the page has a parent
$parentID = $post->post_parent; // the ID of the parent is this
return $parentID; // return the ID
} else { // there is no parent so...
return false; // ...the answer to the question is false
};
};
Source: http://codex.wordpress.org/Conditional_Tags

Is it possible to *optionally* override a theme in Drupal 6?

I want to override the theming of only one (custom) menu. I can do this with phptemplate_menu_tree() but - of course - it overrides the rendering of all menus.
I've tried returning FALSE (an obvious technique IMO) if the menu is not the specific one I want to override - but this doesn't cause the overridden theme function to be called.
My only alternative (when the menu is anything other than the specific one) is to call the overridden function from within phptemplate_menu_tree() - but this seems to defeat the whole point of the override system, since the default rendering function will be hard-coded therein.
I hope the explanation is clear, and any help is greatly appreciated - tks.
UPDATE
For the sake of future reference, I'll explain how I solved this.
First off, the menu rendering starts with this function in menu.module:
function menu_block($op = 'list', $delta = 0) {
$menus = menu_get_menus();
// The Navigation menu is handled by the user module.
unset($menus['navigation']);
if ($op == 'list') {
$blocks = array();
foreach ($menus as $name => $title) {
// Default "Navigation" block is handled by user.module.
$blocks[$name]['info'] = check_plain($title);
// Menu blocks can't be cached because each menu item can have
// a custom access callback. menu.inc manages its own caching.
$blocks[$name]['cache'] = BLOCK_NO_CACHE;
}
return $blocks;
}
else if ($op == 'view') {
$data['subject'] = check_plain($menus[$delta]);
$data['content'] = menu_tree($delta);
return $data;
}
}
If you only want to override how individual item (links) are rendered then you can use the theme system (there are loads of references on how do this) - but if you want complete control on how the entire menu tree is rendered (for example, wrapping the output in nested DIVs so it can be centred on the page) then there is no way to override menu_block().
Therefore, I removed the menu I wanted to render differently from the administer blocks page (site building->blocks) and rendered the menu directly in my page.tpl.php using code something like this: (angle brackets removed)
$m = menu_tree_page_data('my-menu-id');
$o = "DIV";
foreach($m as $k => $v){
$o .= "SPAN {$v['link']['title']} /SPAN";
}
$o .= "/DIV";
echo $o;
I hope this helps.
I've had mixed success doing template.php menu overrides to force CSS classes and ids or HTML into the output.
You could make use of Block Theme when enabling the menu as a block, but I've never tried it.
http://drupal.org/project/blocktheme
If you want to tackle the template way, here are the zen menu override funcitons...
function zen_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
// If an item is a LOCAL TASK, render it as a tab
if ($link['type'] & MENU_IS_LOCAL_TASK) {
$link['title'] = '<span class="tab">' . check_plain($link['title']) . '</span>';
$link['localized_options']['html'] = TRUE;
}
return l($link['title'], $link['href'], $link['localized_options']);
}
function zen_menu_local_tasks() {
$output = '';
if ($primary = menu_primary_local_tasks()) {
$output .= '<ul class="tabs primary clear-block">' . $primary . '</ul>';
}
if ($secondary = menu_secondary_local_tasks()) {
$output .= '<ul class="tabs secondary clear-block">' . $secondary . '</ul>';
}
return $output;
}
You could use sections module, or look at how it switches theme for certain menu-items.
what I did was register a new theme function in my template.php called primary_links (because I wanted to only customize this menu in certain way) created the function mytheme_primary_links() in my template.php refreshed the cache so Drupal would add my theme function to the system then changed theme function on primary_links from links to my custom theme function primary_links - this allows me to customize only this 1 menu - could you do this and hook into where ever to change the theme function being called for your links?
Chris

Resources