I need to conditionally show information in the wordpress admin based on what locations a menu has been added to. So to achieve this I must be able to get all locations assigned to a nav menu but I am really struggling to find out how.
When a menu is created it creates and entry for that menu in wp_terms and a taxonomy entry of nav_menu associated to this term in wp_term_taxonomy. When an item is created on that menu it creates a post of type nav_menu_item. It also creates and entry in wp_term_relationships linking it to the correct nav_menu.
Where does it save the menu location?
I have checked wp_postmeta, wp_termmeta and wp_options but I cannot see it. I cannot figure out any way to achieve my goal.
get_nav_menu_locations() sets the array key to the ID of the menu. This code worked for me:
$locations = get_registered_nav_menus();
$menu_locations = get_nav_menu_locations();
$nav_menu_selected_id = isset( $_REQUEST['menu'] ) ? (int) $_REQUEST['menu'] : 0;
$selected_menus = array();
foreach($locations as $location => $description){
$checked = isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] === $nav_menu_selected_id;
if($checked) $selected_menus[] = $location;
}
Related
I am trying to get a multi-level menu with Corcel within WordPress. I have read the documentation about it, but do not exactly understand how to manage this.
The documentation tells me group the items within the $menu->items collection by their parent ID. But how?
The documentation part can be found here: https://github.com/corcel/corcel#multi-levels-menus
What i tried so far: ( I only get a "Call to a member function offsetSet() on null")
$menu = Menu::location( 'main' )->first();
$items = Menu::location( 'main' )->first()->items;
$parent = $items->first()->parent();
$menu->items->groupBy( $parent->ID );
foreach ( $menu->items as $item ) {
$title = $item->instance()->title;
}
Has anyone done this before?
I have ACF with a relationship field to choose posts from a custom post type (artworks). Instances of the relationship field occur on multiple pages but with different post entries chosen.
It works fine to display the chosen posts as a list but when I get down to the single-artworks template level how can I get the prev and next links to adhere to only the chosen posts in the parent relationship field?
next_post_link()
previous_post_link()
on the single template seems to traverse all entries in the post type, ignoring the choices and order of the relationship field.
Seems like a need to provide the single template with an array of postIDs from the relationship field to choose from, or is there a better way?
You can define your custom pagination to show next and prev links as below:
$args = 'get you relationship query';
$curr_id = $post->ID;
unset($args['paged']);
$args['posts_per_page'] = -1;
$tempposts = query_posts($args);
$post_ids = array();
if($tempposts):
foreach($tempposts as $post){
$post_ids[] = $post->ID;
}
endif;
$current_index = array_search($curr_id, $post_ids);
// Find the index of the next/prev items
$prev = $current_index - 1;
$next = $current_index + 1;
//Prev post
get_permalink($post_ids[$prev]);
//Next post
get_permalink($post_ids[$next]);
Suppose I have parent pages A1 and B1. A1 has child pages A1.1, A1.2,A1.3 and B1 has child pages B1.1, B1.2.
When I am on page A1.1 I shall be able to display A1.2 and A1.3.
Same for A1.2, I shall be able to see A1.1 and A1.3.
If I am on page B1.1, I shall see B1.2 and vice versa.
Note: Every page has an image and a title. I want to get a solution using views.
This thread may be linked to this link if we need the child pages: How to list all child pages of current parent page in drupal 7?
Add a contextual filter nid on both pages, in default select content id from url, then down below in advance section check exclude option.
I managed to do it by creating a view with the following php code in contextual filter
$sibbling = array();
$current = db_query("select menu_name, mlid from {menu_links} where link_path = :node", array(':node' => $_GET['q']));
$current_info = array();
foreach ($current as $value) {
$current_info[] = $value;
}
if($current_info) {
$result = db_query("select mlid, plid, link_path, link_title from {menu_links} where link_path != :node and plid = ( select plid FROM {menu_links} WHERE link_path =:node)", array(':node' => $_GET['q']));
foreach ($result as $row) {
$sibbling[] = $row;
}
}
$nids = array();
foreach ($sibbling as $value){
if( substr( $value->link_path, 0, 5 ) == 'node/' ){
$nids[] = substr( $value->link_path, 5 );
}
}
return implode('+',$nids);
And finally in the plus options we got to check "Allow multiple values "
Save and its done ;-)
Suppose I have parent pages A1 and B1. A1 has child pages A1.1, A1.2,A1.3 and B1 has child pages B1.1, B1.2. I want to list all the respective child pages on A1 and B1. In every child page I have an image and a title. These 2 information needs to be listed in the form of a teaser on the parent page. I need help in doing this whether by coding or by using views, I don't mind as far as I get the proper results. Thank you
You can do this is views by creating a view displaying the fields you require or a teaser. Then add a "Content Nid" contextual filter, in the configeration for this filter under "WHEN THE FILTER VALUE IS NOT AVAILABLE" select "Provide default value" and then "PHP Code" then the code I use is as follows
$children = array();
$current = db_query("select menu_name, mlid from {menu_links} where link_path = :node", array(':node' => $_GET['q']));
$current_info = array();
foreach ($current as $value) {
$current_info[] = $value;
}
if($current_info) {
$result = db_query("select mlid, plid, link_path, link_title from {menu_links} where menu_name=:menu and plid=:mlid and hidden=0 order by weight, link_title", array(':menu' => $current_info[0]->menu_name, ':mlid' => $current_info[0]->mlid));
foreach ($result as $row) {
$children[] = $row;
}
}
$nids = array();
foreach ($children as $value){
if( substr( $value->link_path, 0, 5 ) == 'node/' ){
$nids[] = substr( $value->link_path, 5 );
}
}
return implode('+',$nids);
The last thing to do, under "more" at the bottom of the page sellect "Allow multiple values"
I'm using menu_tree_all_data() to get whole menu structure and then I'm "manually" crawling menu tree.
Also just after reading the tree, I'm calling menu_tree_add_active_path() which will add active trail indicator. It's part of menu block module so you'll have to install it and don't forget to add dependencies for menu block in your module.
$tree = menu_tree_all_data($menu);
menu_tree_add_active_path($tree);
I'm trying to get Wordpress to give me a menu item to go to "latest posts." They come up on the frontpage, but once I navigate away, I want a menu item to get back there. It seems so obvious, but several hours later, the best I could do was create a custom menu with a link to "uncategorised" as a workaround. There MUST be a better way! And this way, I get a box saying "Archive of posts filed under the Uncategorized category. " Not wanted!
Create a custom page in your template directory (http://codex.wordpress.org/Pages#Page_Templates) with a custom query (check at http://codex.wordpress.org/Class_Reference/WP_Query, http://codex.wordpress.org/Function_Reference/query_posts or http://codex.wordpress.org/Template_Tags/get_posts).
Create a page in your admin and select the template you created.
Add a link to this page in your menu and you're done.
Maybe this will help: http://www.viper007bond.com/2011/09/20/code-snippet-add-a-link-to-latest-post-to-wordpress-nav-menu/
It's a filter that will 'search and replace' placeholder anchors such as '#latestpost1' with the actual url of the latest post, and thus dynamically modify the menu before it's rendered.
I'm not sure how this is for SEO, but it's a clever solution.
Give all your posts a category name. Use something generic like "News", "Articles" or "Blogs". Then, choose the category with the name you picked from the menu page under categories. Add this category link to your menu. Rename the link whatever you wish - "Blog" - for example. And, viola - all your posts will appear when people click on that link.
Try this plugin: https://de.wordpress.org/plugins/dynamic-latest-post-in-nav-menu/ works really well and code is open sourced here: https://github.com/hijiriworld/dynamic-latest-post-in-nav-menu
simple solution:
I took this guy's code: http://www.viper007bond.com/2011/09/20/code-snippet-add-a-link-to-latest-post-to-wordpress-nav-menu/
Basically what he wrote is for the menu item to link to the latest post, not posts (plural), so I just modified it and it's working:
<?php
if ( ! is_admin() ) {
// Hook in early to modify the menu
// This is before the CSS "selected" classes are calculated
add_filter( 'wp_get_nav_menu_items', 'replace_placeholder_nav_menu_item_with_latest_post', 10, 3 );
}
// Replaces a custom URL placeholder with the URL to the latest post
function replace_placeholder_nav_menu_item_with_latest_post( $items, $menu, $args ) {
// Loop through the menu items looking for placeholder(s)
foreach ( $items as $item ) {
// Is this the placeholder we're looking for?
if (!strpos(($item->url), 'latestpost'))
continue;
// if ( 'latestpost' != $item->url )
// continue;
// Get the latest post
$latestpost = get_posts( array(
'numberposts' => 1,
) );
if ( empty( $latestpost ) )
continue;
// Replace the placeholder with the real URL
$new_link = $item->url;
$new_link = substr($new_link, 0, strlen($new_link) - 12);
$item->url = $new_link;
}
// Return the modified (or maybe unmodified) menu items array
return $items;
}