Wordpress custom field info in nav menu? - php

I'm trying to get custom field info from a page into the nav menu. I've had problems with this before... I just don't "get" the walker menu and how it works.
Basically, In addition to the title of the page, I want to have it output the URL of an image and image description from the custom fields and create a menu item linked to a normal WP page.
In the nav-menu-template.php file, I've tried modifying the start_el function by adding get_post_custom_keys() like this with no success:
$item_output .= '<a'. $attributes .'>';
$item_output .= get_post_custom_values("product_image", $item->ID);
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
I've also tried get_post_meta(); and others with limited success. The best I've been able to do is either get one of the images repeating in all the links by specifying a a hard integer value. Or, I've been able to get it to output the correct post/page value in text but without an image.
Anyone know of a solution.. what I'm doing wrong?

It would probably be easier to iterate through your nav menu and render it dynamically. The below code will let you iterate through a given nav menu assigned to a nav menu location you would have registered in your functions.php file:
<ul id="some-menu-id" class="my-fancy-menu">
<?php
$menu_name = 'primary';
if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) {
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menu_items = wp_get_nav_menu_items($menu->term_id);
foreach ( (array) $menu_items as $key => $menu_item ) {
// at this point you can get the custom meta from the page
$image = get_post_meta($menu_item->object_id, '_custom_field_image_url', true);
$image_description = get_post_meta($menu_item->object_id, '_custom_field_image_description', true);
// here we are getting the title and URL to the page
$title = $menu_item->title;
$url = $menu_item->url;
$slug = basename($menu_item->url);
// this allows us to add a current class
if (basename($_SERVER['REQUEST_URI']) == $slug) { $current = ' current-menu-item'; } else { $current = ''; }
$menu_list .= '<li class="page-id-'.$menu_item->object_id.$current.'">' . $title . '<br /><p>'.$image_description.'<br />'.$image.'</p></li>';
}
}
echo $menu_list;
?>
</ul>

Related

get parent element title using wp_get_nav_menu_items

I need the parent element's title as a variable and also the submenu of it.
Currently I have:
function navigation_footer() {
$menu_name = 'footer_nav';
if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name])) {
$menu = wp_get_nav_menu_object($locations[$menu_name]);
$menu_items = wp_get_nav_menu_items($menu->term_id);
foreach ((array) $menu_items as $key => $menu_item) {
$title = $menu_item->title;
$url = $menu_item->url;
$type = get_post_meta( $item->menu_item_parent, '_menu_item_type', true );
$title_parent = get_post( $object_id )->post_title;
$menu_list .= "\t\t\t\t". '<div class="fl-links"><h2>'. $title_parent .'</h2>' ."\n";
$menu_list .= "\t\t\t\t\t". '<p>'. $title .'</p></div>' ."\n";
}
}
echo $menu_list;
}
The variable type gets me the title of a post which was kinda workaround.
Still, it's in a foreach so I'm getting a mess instead of what I actually want.
As I'm a fairly beginner in PHP I am stuck.
Each element in WP is going to be an individual link. The parent is only being used as a placeholder for the title followed by the links.
[Current output](https://i.stack.imgur.com/xsGRS.png)
[My desired output](https://i.stack.imgur.com/SP14p.png)
[WP Menu Parent/Child](https://i.stack.imgur.com/Z5d8K.png)

Display a ACF Category Taxonomy Field With a List of all Categories

I added a Text field to the Category taxonomy using ACF so that I can add a font awesome icon code to be displayed in a list of all categories.
The end result I am looking for is a list of all categories names linked to their respective category pages (if they have posts or not) with the icon from the custom field before each category name.
Reviewing the ACF documents and looking around for a solution I have only been able to display one icon at a time or just create errors.
Is there a more straight forward way I can loop through all of the categories and include the name, link and icon from my ACF custom field in the way I would do so for posts that have a custom field added on to it?
Here is the code I have so far but it only shows one at a time even though I am trying to use a foreach to loop through them all:
<?php
$categories = get_the_category();
$separator = ' ';
$output = '';
foreach( $categories as $category ) {
$terms = get_the_terms( get_the_ID(), 'category');
if($terms) {
$term = array_pop($terms);
$icon = get_field('cat_icon', $term );
}
echo $icon;
$output .= '' . esc_html( $category->name ) . '' . $separator;
}
echo trim( $output, $separator ); ?>
Any help is appreciated, thank you!
As requested here is a screenshot, you can see it is displaying the icon from my custom field but only one category out of the 3 I currently have added.
You can use get_terms. try the below code.
<?php
$categories = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => false
) );
$separator = ' ';
$output = '';
foreach( $categories as $category ) {
if($category) {
$icon = get_field('cat_icon', $category );
}
echo $icon;
$output .= '' . esc_html( $category->name ) . '' . $separator;
}
echo trim( $output, $separator );
?>

WooCommerce - not linking to products using "single product shortcode"

I would like to use the WooCommerce shortcode
[product id="99"]
However I would like to have both the product image and product name itself not link to the individual product page. All I want is the "Add to Cart" button working as intended but nothing else being clickable.
Is this possible? What template would I need to edit?
This doesn't need to be applicable to only a specific shortcode if it's easier. I never want to have people be able to get to product pages at all, so if there is a "global" way to do this, it'll work too.
Here it the logic you need to do in your functions.php, I have created a custom shortcode to get the product as you explained.
function get_c_product($atts){
$params = shortcode_atts(array(
'id' => '0',
), $atts );
$args = array('post_type'=>'product','post__in'=>array($params['id']));
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
$return = '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$_product = wc_get_product( get_the_ID() );
$return .= '<li>' . woocommerce_get_product_thumbnail() . '</li>';
$return .= '<li>' . get_the_title() . '</li>';
$return .= '<li>' . do_shortcode('[add_to_cart id='.get_the_ID().']') . '</li>';
}
$return .= '</ul>';
/* Restore original Post Data */
wp_reset_postdata();
} else {
// no posts found
}
return $return;
}
add_shortcode('product_custom','get_c_product');
Then use the shortcode like this : echo do_shortcode('[product_custom id="99"]'); or [product_custom id="99"]

Is there any way to have a menu with images and a custom navwalker?

I am trying to create a menu with an image, title and description.
So far, the decription and title are working great, so, I found this plugin
https://wordpress.org/plugins/menu-image/
works very good and shows the image + the title, but not the description.
So, I guess I need, somehow to show the description without losing the image.
I create a custom navwalk, but seems like I cannot just call the attached image. Looking at the code of the plugin couldnt find anything that helps.
Any idea? have anybody done this before?
My navwalker so far looks like this:
<?php
class Ext_Walker extends Walker {
var $tree_type = array('post_type', 'taxonomy', 'custom');
var $db_fields = array('parent' => 'menu_item_parent', 'id' => 'db_id');
function start_el(&$output, $object, $depth = 0, $args = array(), $current_object_id = 0) {
$classes = "";
foreach ($object->classes as $cl){
$classes.=" $cl";
}
$output .="<div class='col-lg-15 bottom-pad'>
<div class='vertical_item'>
<div class='col-lg-60'>
<div class='$classes'></div>
</div>
<div class='clear'></div>
<div class='desc_vertical'>
<h2 class='vertical_title'>{$object->title}</h2>";
if($object->post_content != ""){
$output .="<p class='item_description'>{$object->post_content}</p>";
}else{
}
$output .="</div>";
$output .="<button class='btn btn-link'>View More</button>";
}
function end_el(&$output, $object, $depth = 0, $args = array()) {
$output.='</div></div>';
}
}
?>
When WordPress is creating the menu, it is creating the menu items with links of the form
<a>Some Title</a>
The Walker runs the title through the "the_title" filter. The plugin you reference does the same thing.
So there are at least two possibilities for accomplishing you want without developing your own Walker extension:
1) Extend the plugin
Since the plugin is using the the_title filter, you could add a filter of that type to add the description (the plugin is already adding an image). So
function add_description( $title, $id ) {
if ( 'nav_menu_item' == get_post_type( $id ) ) {
$title = '<span class="title">' . $title . '</span>;
$title .= '<span class="desc">' . description from wherever you get it . '</span>;
}
return $title;
}
add_filter( 'the_title', 'add_description', 10, 2 );
This changes the text inside to link to be both title and description. You would want to check the post type, since the filter is called in other circumstances also.
2) Use just the filter
You could use a variant of the above filter to add both and image and the description, avoiding the need for the plugin. For example:
function add_img_and_desc( $title, $id ) {
if ( 'nav_menu_item' == get_post_type( $id ) ) {
// Get the image for the menu item (say in $img)
$title = $img . '<span class="title">' . $title . '</span>;
$title .= '<span class="desc">' . description from wherever you get it . '</span>;
}
return $title;
}
add_filter( 'the_title', 'add_img_and_desc', 10, 2 );
How you would get the image would depend on your approach. For example, it could be as simple as a switch statement that is based on the title.

Different Menus on Different Pages

Trying to have different navigation menus on different pages. My theme doesn't let me edit the functions page. I created a new header template and page template. I want to change the menu used in the new header template, but I don't understand what the code below means so I'm not exactly sure what to change.
I'm trying to learn so could someone help translate what this code means?
<ul id="menu-hosting-menu" class="curved">
<?php if ( is_page() ) $highlight = 'page_item'; else $highlight = 'page_item
current_page_item'; ?>
<li class="<?php echo $highlight; ?> menu-item menu-item-type-custom menu-item-object-custom">Home</li>
<?php wp_list_pages( 'sort_column=menu_order&depth=3&title_li=&exclude=' ); ?>
</ul><!-- /#nav -->
<?php } ?>
<select>
<option value="" selected="selected">Select</option>
<?php
$menu_name = 'primary-menu'; //same as theme_location
if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[
$menu_name ] ) ) {
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menu_items = wp_get_nav_menu_items($menu->term_id);
var_dump($menu_items);
foreach ( (array) $menu_items as $key => $menu_item ) {
$title = $menu_item->title;
$url = $menu_item->url;
if($menu_item->menu_item_parent){
$title = '-- '.$title;
}
$menu_list .= '<option value="' . $url . '">' . $title .
'</option>';
}} else {
$menu_list .= '<option value="">Menu "' . $menu_name . '" not
defined.</option>';
}
echo $menu_list;
?>
</select>
</nav>
Are you trying to load the menu on an entirely new template, or just a particular page?
I imagine one (simple) approach to this would be to create both a new page template, and a new header. You would simply then tell the new page template (selectable in your Admin panel in the CMS) to call the new (custom) header as well.
A great explanation on how this can be done is found here:
http://reflectingthedesigner.com/wordpress/2011/10/24/creating-a-new-wordpress-page-template/
Hope this helps.
Figured it out. I just deleted all of that code above and replaced it with
<?php wp_nav_menu( array('menu' => 'Hosting' )); ?>
Worked like a charm.

Categories