WordPress: add HTML to a specific nav menu - php

add_filter('wp_nav_menu_items', 'add_custom', 10, 2);
function add_custom($items, $args) {
if ($args->theme_location == 'primary') {
$items .= '<li class="custom"></li>';
}
return $items;
}
which produces:
<ul id="menu-top">
<li></li>
<li></li>
<li></li>
<li class="custom"></li> /* added custom HTML */
<ul>
but what if my WP menu doesn't have a "theme_location"? Can I target my menu by id/class instead of "theme_location", or how else can I add HTML to one specific menu?

Can you use jQuery?
jQuery(document).ready(function($) {
$('#menu-top').append('<li class="custom"></li>');
});
Or PHP + CSS - with this solution, you add it to every menu and hide it if need be via CSS.
add_filter('wp_nav_menu_items', 'add_custom', 10, 2);
function add_custom($items, $args) {
$items .= '';
return $items;
}
li.custom { display:none; } // hide originally
ul#menu-top li.custom { display:inline; } // or whatever styles

When there is no theme_location, then I guess, it falls back to wp_page_menu. So, in theory, you could filter into wp_page_menu and modify the output.
<?php
//Use this filter to modify the complete output
//You can get an argument to optionally check for the right menu
add_filter( 'wp_page_menu', 'my_page_menu', 10, 2 );
/**
* Modify page menu
* #param string $menu HTML output of the menu
* #param array $args Associative array of wp_page_menu arguments
* #see http://codex.wordpress.org/Function_Reference/wp_page_menu
* #return string menu HTML
*/
function my_page_menu( $menu, $args ) {
//see the arguments
//Do something with $menu
return $menu;
}
//Use this filter to alter the menu argument altogether
//It is fired before creating any menu html
add_filter( 'wp_page_menu_args', 'my_page_menu_pre_arg', 10, 1 );
/**
* Modify page menu arguments
* #param array $args Associative array of wp_page_menu arguments
* #see http://codex.wordpress.org/Function_Reference/wp_page_menu
* #return array modified arguments
*/
function my_page_menu_pre_arg( $args ) {
//Do something with $args
return $args;
}
Hope it helps.

Related

How to pre select Page or Post Parent (ID) from Dropdown automatically?

function autoset_parent_dropdown() {
global $pagenow;
if($pagenow == 'post-new.php') {
parent_dropdown( '477', '477', '0', null );
}
}
add_action( 'admin_init', 'autoset_parent_dropdown' );
How to pre select Page or Post Parent (ID) from Dropdown automatically?
on post-new.php, When creating new post.
I am trying above code but its not working. Its not selecting any parent post/page using parent_dropdown function.
I referred: https://developer.wordpress.org/reference/functions/parent_dropdown/
Please correct me if i am doing anything wrong.
Try this method. Tested on Wordpress 5.3.2, but should work on all versions.
add_filter('default_content', 'assign_parent_to_new_post', 10, 2);
/**
* #param string $post_content
* #param WP_Post $post
*
* #return string
*/
function assign_parent_to_new_post($post_content, $post)
{
if ($post->post_type != 'page') {
return $post_content;
}
$post->post_parent = 7; //Parent post_id goes here
wp_update_post($post);
return $post_content;
}
The idea behind it is pretty simple – hook somewhere inside blank post creation process, substitute post_parent and then push it to the database.

How to use $_GET in wordpress pages

Here's the thing...
I have created a button which on click opens a link like
https://www.something.com/something/?term=something
or [at first, I thought this is a URL problem... so I tried some other] Like:-
https://www.something.com/something.php?term=something
https://www.something.com/something?term=something
and else
now on this link, I want to echo $_GET['term']... which not happening, there is no error in the console... how to be able to echo it
I know the answer is in this document but I don't know how to use this thing... can anyone please describe the right way step by step...
https://codex.wordpress.org/Function_Reference/get_query_var
get_query_arg : Retrieve only public query variable in the WP_Query class of the global $wp_query object.
I propose for security , use rewrite class in Wordpress :
/**
* Add rewrite tags and rules
*
* #link https://codex.wordpress.org/Rewrite_API/add_rewrite_tag
* #link https://codex.wordpress.org/Rewrite_API/add_rewrite_rule
*/
/**
* Add rewrite tags and rules
*/
function myplugin_rewrite_tag_rule() {
add_rewrite_tag( '%city%', '([^&]+)' );
add_rewrite_rule( '^city/([^/]*)/?', 'index.php?city=$matches[1]','top' );
}
add_action('init', 'myplugin_rewrite_tag_rule', 10, 0);
for add to query arg :
/**
* Register custom query vars
*
* #param array $vars The array of available query variables
*
* #link https://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
*/
function myplugin_register_query_vars( $vars ) {
$vars[] = 'city';
return $vars;
}
add_filter( 'query_vars', 'myplugin_register_query_vars' );
example link in site : yoursite.com/city/45
get data in wordpress :
$city = get_query_var( 'city' );
echo $city;
That's quite simple
echo get_query_var( 'term', 'default_value');
Obviously you have to add this in functions.php for custom variables
function add_query_vars_filter( $vars ) {
$vars[] = "my_var";
return $vars;
}
add_filter( 'query_vars', 'add_query_vars_filter' );
read further details here

How to change the title on a WordPress page?

Context: WordPress 5.4.5, Yoast 3.7.1
I'm a plugin developer who has access to the client's site. The site has Yoast 3.7.1 installed and I'm wondering if that is significant because no matter what I do I can't change the 404 page's title.
Now on other pages on StackOverflow where similar questions have been posed (here, here and here for example), those answering have asked if the header.php is correctly embedding a call to wp_title(). Here's what's in the current theme's header.php at that point:
<title><?php wp_title( '|', true, 'right' ); ?></title>
Interestingly, in my 404.php page, wp_get_document_title() tells me that the document title is Page not found - XXXX even though the wp_title call above specifies the separator as |. Yoast's rewriting of titles has been disabled so I'm not at all sure where that dash is coming from.
My plugin does a REST call and pulls in content from off-site for inclusion in the page. Part of that content is the text to be used in the title.
On previous client sites, I've been able to do the following:
add_filter('wp_title', 'change_404_title');
function change_404_title($title) {
if (is_404())
{
global $plugin_title;
if (!empty($plugin_title))
{
$title = $plugin_title;
}
}
return $title;
}
However, on this site, that's not working.
I have tried, based on the version of WordPress being used, hooking the pre_get_document_title filter, viz
add_filter('pre_get_document_title', 'change_404_title');
but again to no avail. I am currently reading up on Yoast ...
wp_title deprecated since version 4.4. So we should use the new filter pre_get_document_title. Your code looks fine but I am confused about global $plugin_title. I would rather ask you to Try this first
add_filter('pre_get_document_title', 'change_404_title');
function change_404_title($title) {
if (is_404()) {
return 'My Custom Title';
}
return $title;
}
If it doesn't work then try changing the priority to execute your function lately.
add_filter('pre_get_document_title', 'change_404_title', 50);
How document title is generated has changed since Wordpress v4.4.0. Now wp_get_document_title dictates how title is generated:
/**
* Displays title tag with content.
*
* #ignore
* #since 4.1.0
* #since 4.4.0 Improved title output replaced `wp_title()`.
* #access private
*/
function _wp_render_title_tag() {
if ( ! current_theme_supports( 'title-tag' ) ) {
return;
}
echo '<title>' . wp_get_document_title() . '</title>' . "\n";
}
Here is the code from v5.4.2. These are the filters you can use to manipulate title tag:
function wp_get_document_title() {
/**
* Filters the document title before it is generated.
*
* Passing a non-empty value will short-circuit wp_get_document_title(),
* returning that value instead.
*
* #since 4.4.0
*
* #param string $title The document title. Default empty string.
*/
$title = apply_filters( 'pre_get_document_title', '' );
if ( ! empty( $title ) ) {
return $title;
}
// --- snipped ---
/**
* Filters the separator for the document title.
*
* #since 4.4.0
*
* #param string $sep Document title separator. Default '-'.
*/
$sep = apply_filters( 'document_title_separator', '-' );
/**
* Filters the parts of the document title.
*
* #since 4.4.0
*
* #param array $title {
* The document title parts.
*
* #type string $title Title of the viewed page.
* #type string $page Optional. Page number if paginated.
* #type string $tagline Optional. Site description when on home page.
* #type string $site Optional. Site title when not on home page.
* }
*/
$title = apply_filters( 'document_title_parts', $title );
// --- snipped ---
return $title;
}
So here are two ways you can do it.
First one uses pre_get_document_title filter which short-circuits the title generation and hence more performant if you are not going make changes on current title:
function custom_document_title( $title ) {
return 'Here is the new title';
}
add_filter( 'pre_get_document_title', 'custom_document_title', 10 );
Second way uses document_title_separator and document_title_parts hooks for the title and the title seperator that are executed later in the function, after title is generated using functions like single_term_title or post_type_archive_title depending on the page, and just before the title tags is about to be outputted:
// Custom function should return a string
function custom_seperator( $sep ) {
return '>';
}
add_filter( 'document_title_separator', 'custom_seperator', 10 );
// Custom function should return an array
function custom_html_title( $title ) {
return array(
'title' => 'Custom Title',
'site' => 'Custom Site'
);
}
add_filter( 'document_title_parts', 'custom_html_title', 10 );
Add this to your functions.php
function custom_wp_title($title) {
if ( is_404() ) {
$title = 'Custom 404 Title';
}
return $title;
}
add_filter( 'wp_title', 'custom_wp_title', 10, 2 );
10 - is priority change to overwrite other plugins like SEO

Adding custom <li> to Wordpress navigation menu

I just cant fully understand how custom walkers work in worpress:
Code in theme's home.php (actually all code is included from other file to not mess HTML) looks like this:
/**
* Contains wordpress function with array with parameters
* #return string HTML output
*/
function show_main_navigation() {
return wp_nav_menu(
array(
'theme_location' => 'header-menu',
'echo' => false,
'depth' => '-1',
'walker' => new Last_Item_Walker()
)
);
}
Walker looks like this:
class Last_Item_Walker extends Walker_Nav_Menu {
function end_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat("\t", $depth);
$output .= '<li class="spec">title</li>'; // my custom <li>
$output .= "$indent</ul>\n";
}
}
Overwritten method just does not work.
If I try to overwrite another method, for example:
class Last_Item_Walker extends Walker_Nav_Menu {
function end_el( &$output, $item, $depth = 0, $args = array() ) {
$output .= "<br>"; // for demonstration
$output .= "</li>\n";
}
}
This one works, adds br tag but this is not what i want, i want to customize last li before /ul.
Can somebody help me with this?
Ok it was easier to do with filters.
/**
* Hardcodes shop item in navigation
* #param string $items HTML with navigation items
* #param object $args navigation menu arguments
* #return string all navigation items HTML
*/
function new_nav_menu_items($items, $args) {
if($args->theme_location == 'header-menu'){
$shop_item = '<li class="spec">title</li>';
$items = $items . $shop_item;
}
return $items;
}
add_filter('wp_nav_menu_items', 'new_nav_menu_items', 10, 2);
If you're not too worried about IE8 and less, you can use the :last-child selector.
li.spec:last-child{
color: red;
}
If you are bothered about IE8 and less you can use a polyfill to make it work.

what is the difference between filters and hooks & how can i use them in child theme

What is the difference between filter and hooks in wordpress.
How can i use the following filter in child theme ?
<?php
foreach ( $results as $result ) {
// external plugins can modify or disable field
$result = apply_filters( 'cp_package_field', $result, 'ad' );
if ( ! $result )
continue;
?>
how can i use the following hook in child theme ?
/**
* called in cp_add_new_listing() to hook into inserting new ad process
*
* #since 3.2.1
* #param int $post_id
*
*/
function cp_action_add_new_listing( $post_id ) {
do_action( 'cp_action_add_new_listing', $post_id );
}
For the first part of your question, here is a link to an explanation I found a while back that was pretty comprehensive and it helped me to understand the difference.
https://wordpress.stackexchange.com/questions/1007/difference-between-filter-and-action-hooks
To use the hook in your child theme, you'd probably need to have the following piece of code in your child theme's functions.php file:
/**
* Our callback function to the hook
* #param int $post_id id of the post
* #return void
*/
function my_child_theme_new_listing_cb( $post_id ) {
if($post_id == 10) { //Or whatever you want
echo 'Hello World';
}
//We do not have the responsibility to return something as it is a hook
}
add_action( 'cp_action_add_new_listing', 'my_child_theme_new_listing_cb', 10, 1 );
Hope it helps.

Categories