I'm developing a site for my company using wordpress+divi theme, this is hard customized due some booking system implementantations and personalized css, so I have made a child theme to avoid problems.
Now the question: Is there a way using my functions.php child file, to add a hook filter that can place content after a particular ID like
<li id="first-menu-item">home</li>
//my custom content through functions.php goes here
<li id="second-menu-item">portfolio</li>
<li id="third-menu-item">contacts</li>
I know that this is possible using jquery in this way
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery ( '#first-menu.item' ) .after( '<li>my custom content</li>' );
});
</script>
and this works but I think that this is not the right way cause what I want to place after that specific ID is note only html code but a wordpress search function and I think that It's wrong to think that I can place php tags inside a jquery.. so I have to add this
<?php get_search_form(); ?>
directly in my header.php but I want to avoid this cause the divi's develepors maybe can update the header.php file and I have to edit again my child header.php so I have to do this through my child function.php...I found that wordpress have different filter hook for making this like "wp_nav_menu_items" but what if I want to put code after a specific line/div/id/class?
This can be done using a custom helper function and adding filter on "wp_get_nav_menu_items". Following is the custom helper function you can use.
function _custom_nav_menu_item( $title, $url, $order, $parent = 0 ){
$item = new stdClass();
$item->ID = 1000000 + $order + parent;
$item->db_id = $item->ID;
$item->title = $title;
$item->url = $url;
$item->menu_order = $order;
$item->menu_item_parent = $parent;
$item->type = '';
$item->object = '';
$item->object_id = '';
$item->classes = array();
$item->target = '';
$item->attr_title = '';
$item->description = '';
$item->xfn = '';
$item->status = '';
return $item;
}
And following is how you can add filter.
add_filter( 'wp_get_nav_menu_items', 'your_custom_function', 20, 2 );
function your_custom_function( $items, $menu ){
//your logic and code for customization
return $items;
}
You will have define your own logic to identify right location. I have successfully used this with Divi theme.
Hope this will give you at least a starting point.
Well, I wonder though, why you would want to add search form in nav menus!
===== Update =====
You can customize wrapper of your menu to add something else. Please check this thread. This will be useful for you.
Also, to enable this functionality only for mobile version, you can use another plugin which detects mobile devices, mobble.
I have used this plugin many times on many websites and its results are quite reliable. You can conditionally enable the custom functionality using "is_mobile()" function from this plugin so you do not have to depend on css to hide the same on desktop devices.
really thank you for your reply, what I want to achive is to show after the last menu element in the only mobile version a search box, by default this is showed when you click an icon on top right, but I have a very strange wide logo and the languages flags that take up all the space , so I want to put the search box in a fullscreen mobile menu under the last element. I'm trying to understand your code and I'm just wondering if there is a way to put code after a specific div id in the header.php file but you are telling me to use the wp_get_nav_menu_items that is a filter for the navigation menu not for a class or id, I think that is little different from what I was asking for..I'm asking this also for other implementations
example
Related
I want to hook into the save_post function, find out what category the post is in, and then assign a different page template for posts in each category. I've tried about 30 different versions of this with no luck. Will someone please help point me in the right direction?
add_action( 'save_post', 'assign_custom_template' );
function assign_custom_template($post_id) {
$category = get_the_category($post_id);
$cat_id = $category->cat_ID;
if( $cat_id == 1 ) {
update_post_meta($post_id, "_wp_page_template", "template1.php");
}
if( $cat_id == 2 ) {
update_post_meta($post_id, "_wp_page_template", "template2.php");
}
}
You just need to create category-1.php which rendered as template1.php and category-2.php which rendered as template2.php in your theme root.
See template hierarchy for more info.
I tried to emulate the official WP hierarchy scheme among my posts & custom post types, but it just wasn't happening. I ended up using Custom Post Types so that I could assign templates to both the "list" pages and the "individual" pages. And then I wrote some javascript that looks for the post-type string in the URL, and if it's detected, it adds the current_page_parent/ancestor classes to the appropriate menu items. Not perfect or totally future-proof, but it gets the job done.
If someone comes up with a better solution, please post it!
Pretty much every guide ive come across for adding php pages to Wordpress involves adding it at the theme level. e.g. How to add a PHP page to WordPress?. I want to add a new public facing page to multiple sites via a plugin. I dont want to have to add this to dozens of themes. If i can add it ad the plugin level it will work for all sites.
I have this working, but i need some way of injecting this into a theme. In order to get the sidebar and stuff without having to add custom css for each theme.
Ive started by adding a rewrite rule
RewriteRule ^mypage /wp-content/plugins/myplugin/mypage.php [QSA,L]
Then page.php contains
require_once('../../../wp-blog-header.php');
get_header();
//custom php content
//get_sidebar(); // how to get this working.
get_footer();
This also works, but the problem im having is with sidebars. Some themes dont have them and others do. Not all sidebars are 30% etc. I dont know how to build the div structure here to make it work. Some themes are 100% page width, but this looks ugly when viewed on other themes that are a fixed width. I have been able to come up with some compromises, but id rather be able to do this right.
In summery my main question here is. Is it possible to call a method that will inject html into a theme page. e.g. generate_page($html);. This method will then go to page.php of the theme and inject $html into the content area of the theme.
Edit
In an attempt to dynamically inject content into an unknown theme ive done the following
global $post;
$post->post_content = "TEST PAGE content";
$post->post_title = "Page Title";
$post->post_name = "test-page";
include get_template_directory()."/page.php";
This works for some themes and not others. Some themes will display this post just fine, but others (the default wordpres twenty fifteen theme) are displaying this post and then every other post in the database after it. Im not sure where or why its pulling all of these posts, but if i can get it to stop it looks like this will be a valid solution.
Then u could try to load a specific template page in specific case.
function load_my_template( $template )
{
if( is_page() )
$template = plugin_dir_path(__FILE__) . "dir_to/my_template.php";
return $template;
}
Or change the content that is use on loading page
function load_my_content( $content )
{
global $post;
$id = $post->ID;
if( is_page() )
{
ob_start();
include plugin_dir_path(__FILE__) . "dir_to/my_template.php";
$content = ob_get_clean();
}
return $content;
}
In your __construct()
add_filter('template_include', array($this,'load_my_template') );
add_filter("the_content", array($this,"load_my_content" ) );
add_filter("get_the_content", array($this,"load_my_content" ) );
Hope that help u.
Tell me if it's not corresponding with your question.
Lots of people, both here on SOW and elsewhere, are having my same exact problem.
I've installed the BBpress plugin on my site here. This plugin enables a FORUM on the site.
I've wrestled for days (to no avail) on this documented issue where the plugin causes the wrong menu item to be highlighted when any Forum sub-menu item is chosen. Instead, the Blog menu item gets highlighted by default.
Check it out: Click on Forum and this resulting page highlights the "Forum" menu item okay. But click on "Test forum" (or drill down into any other Forum item) and the resulting page always has "Blog" highlighted.
Here's what I know so far:
It can't be fixed with CSS alone.
I am using Permalinks (with "Post name" selected)
PHP assigns a .current-menu-item and/or a .current_page_item class (along with their corresponding -ancestor and -parent classes) to menu items based on the page you've navigated to. For some reason, it is failing to see any Forum submenu as a current page. As a result, it is defaulting to "Blog" as the current page item.
So I know I need to do the following:
have Wordpress check the URL upon each page load
if "/forums/" is part of the URL, remove all .current-menu* and .current_page* classes (the wildcard is necessary to purge the ancestor/parent classes).
then assign .current-menu-item and .current_page_item classes to the "Forum" menu item.
The problem is, while I think i'm getting close, I don't know how - exactly - to do this.
I've tried a bunch of things.
I found this Jquery solution but don't know how to implement it, nor am I confident in this approach:
// First add a “forum-class” to your forums menu item in your custom menu
// Then add this to your js file with YOURURL = the url of your site and forums = your forums slug :
$(function() {
var forumURL = window.location.href.indexOf("YOURURL/forums/");
if(forumURL > -1){
$('li.forum-class').addClass('current-menu-item');
}
});
Then, I found this approach which seemed closer to what I wanted, but it introduces a new class and doesn't seem to clear the incorrect classes from the Blog menu. Plus, I don't know where exactly to put this code, or where to create the js file.
if (strtolower($thats_all->post_title) == "forum" || strtolower($thats_all->post_title) == "forums") {
$addclass = ' class="current_page"';
} else {
$addclass = '';
}
Finally, I found this which is what I think I need, but I'm having trouble implementing it (I've tried sticking it in my menu-primary.php and header.php but no go).
// this forces the class current-menu-item to a menu item which I named 'forums'
add_filter('nav_menu_css_class', 'remove_link_parent_menu_classes', 420 ,3);
function remove_link_parent_menu_classes($classes, $item, $args){
if(strpos($item->url, '/forums/') !== true)
return array_diff($classes, array('current_page_item', 'current-menu-item'));
return $classes;
}
I think I'm close. Really close. Just need a push in the right direction. I need to know:
will the latter solution above work?
which file, and where exactly in the file, do I need to place the code?
Thanks!
I finally cracked it! Using the above clues, I figured out this code that worked for me.
add_filter( 'nav_menu_css_class', 'namespace_menu_classes', 10, 2 );
function namespace_menu_classes( $classes , $item ){
if ( get_post_type() == 'forum' ) {
$classes = str_replace( 'current_page_parent', '', $classes );
$classes = str_replace( 'menu-item-16', 'current_page_parent', $classes );
}
return $classes;
}
Copy the above at the end of the function.php file.
Then change 'forum' to the slug name you've chosen and replace 'menu-item-16' with the correctly numbered menu item that you want highlighted (you will need to use your web browser's developer tools to inspect your site to be able to find this).
This took me a week to figure out (and learn the php required)! Good luck and hope this helps everyone else out there.
What I'm trying to do is convert my one page design in wordpress and i thought it would be nice to be able to edit, add and modify different part of the page in seperated pages. The one page website will be ordered by a menu (with id main).
Following the wp-codex i used get_template_part, it should work properly because it should:
Load a template part into a template (other than header, sidebar, footer)
get_header gets skipped but get_footer gets excecuted and the site is rendered incorrectly.
front-page.php
$pages = wp_get_nav_menu_items('main');
global $post;
foreach ($pages as $post) {
$post = get_post($post->object_id);
if($post->post_type != "page") continue;
setup_postdata( $post );
$postName = (locate_template('page-' . $post->post_name . '.php') == '') ? null : $post->post_name;
get_template_part('page', $postName);
}
wp_reset_postdata();
Is this a bug? Or did I do something wrong? What is the best way to accomplish this?
if your get_template_part() is not working, then the problem may be there is no file named as page.php in theme, check for this file.
For what it's worth, I often skip a some of the WP helpers and work more directly, but not rogue. Here is a snippet from my library :
/** Get core data for a WP post/page using ID
* #param $id : wp post/page ID
* #return array
*/
function wp_get_single_post_basic($id){
$post = get_post($id, ARRAY_A);
$ret = array();
$content = $post['post_content'];
// FILTER via WP
$content = apply_filters('the_content', $post['post_content']);
$ret['title']= $post['post_title'];;
$ret['content']= $content;
$ret['link'] = $post['post_name'];
$ret['edit_link'] = 'edit';
return $ret;
}
That function breaks down the content in a very easy to manage manner and generates the edit link (build bool for that in calling script). Also formats content.
So grab and sort the IDs you want and run this in the loop over IDs for your one page. Then all of the content will be isolated by page/post/whatever (custom taxonomy FTW).
If you had the IDs ready and sorted plus the html/css ready to go I could drop this function in and work your one page to complete in under an hour. For production line work this type of helper is great -- also perfect for sites where you want a specific post/page to be placed in some weird way in some weird place outside of the loop.
If you have a problem w/script let me know, I have not used it in a few months, wrote it a few years ago...
I think you have a problem using the global $post and storing also the $post variable in the foreach loop from the menu objects. I think probably that's the cause of the error with the template part calling.
I would recommend you to remove the global $post declaration, the reset_postdata and also the setup_postdata since you aren't using the global in your loop, you're just naming it.
You're getting the $post object from the menu so it appears that you don't need the global or the other functions that are mostly used when you want to use "Loop Style" template tags without a post_id, like the_permalink() or the_title().
I ended up copying the default page.php template as page-page.php and loaded it like this:
$postName = (locate_template('page-' . $post->post_name . '.php') == '') ? 'page' : $post->post_name;
Then in page.php just loaded page-page.php
I am using wordpress wp-admin to create the menu. It is under Appearance/menu.
I have a link that points to /members/ but what I really need is a link to /members/$logged_user...
For example /members/user_1 or /members/user_2.
How can I do that?
I dont know if it is important, but I am using buddypress plugin.
I have written a short script for adding dynamic buddypress links in wordpress menu. Hope it helps
I have added custom links in wordpress menu replacing username in link with --username--
example
http://website_name.com/members/--username--/messages/
then add this code in function.php
add_filter( 'nav_menu_link_attributes', 'menu_override', 10, 3 );
function menu_override( $atts, $item, $args ) {
$user = wp_get_current_user();
$newlink = str_replace("--username--", $user->user_login, $atts[href]);
$atts[href] = $newlink;
return $atts;
}
The default menu doesn't really have that option. But you can make your own walker function, searching for the keyword and replacing it with the current user.
See http://codex.wordpress.org/Function_Reference/wp_nav_menu#Using_a_Custom_Walker_Function
But it would probably be faster and more manageable to just place the link outside the menu call with some static html and the needed php.
You can use the BuddyPress Custom Profile Menu plugin to get close to this functionality, otherwise you will have to write custom code that uses actions/filters of wp_nav_menu().