How to add a sidebar to WordPress menus - php

I need to get a widget inside a menu and I'm trying:
add_filter('wp_nav_menu_items', 'add_widget_to_menu', 10, 2);
function add_widget_to_menu($items, $args) {
if ($args->theme_location == 'mobile_menu')
return $items .
'<div id="newsletter-mobile">' .
dynamic_sidebar('sidebar-mobile' ) .
'</div>';
return $items;
}
What's wrong?

This hook is used to add a sidebar menu in WordPress:
add_action("admin_menu", "sidebar_menu_for_registration");
sidebar_menu_for_registration is a function.
This is the syntax to create a sidebar menu:
add_menu_page(string $page_title, string $menu_title, string $capability, string $menu_slug, callable $function = '', string $icon_url = '', int $position = null)

You can create a sidebar using the following
register_sidebar(array(
'name'=>'Widget_Name',
'id'=>'widget_id',
'before_widget' =>'<div class="">',
'after_widget' =>'</div>'
));
To call this in your template, you can use the following code:
if (!function_exists('dynamic_sidebar') || !dynamic_sidebar('widget_id')) :
endif;
Refer here for more details.

You will get 1 as output adding widget area to menu like that. The reason is that wp_nav_menu echoes the items. To make it work you should convert the contents of the widget area to string. I managed to solve the problem using buffering. Here is a small code sample that works for me:
function add_extra_item_to_nav_menu( $items, $args ) {
ob_start();
dynamic_sidebar( 'header-widget-area' );
$menu_widget_area = ob_get_clean();
$items .= $menu_widget_area;
return $items;
}
add_filter( 'wp_nav_menu_items', 'add_extra_item_to_nav_menu', 10, 2 );

Related

Wordpress insert shortcode into menu item

I have such a problem. In functions.php I have such code:
function Svg_Path($attr) {
$a = shortcode_atts(array(
'path' => 'Some text'
), $attr);
$svg = '<svg class="menu-item-icon"><use xlink:href=' . get_template_directory_uri(). '/img/svg/sprite.svg' . $a["path"] . '></use></svg>';
return $svg;
}
add_shortcode( 'SvgPath', 'Svg_Path' );
Normally, I can use in pageBuilder this
<div>[SvgPath path='#logo__skype']</div>
And the result will be the displayed Skype Icon. But when I try to insert this shortcode into Appearence>Menu>Link text I get the shortcode as plain text
Where do I try to input my shortcode
So can you help me wwith this, so I can recieve skype logo from svg sprite in menu item
Try the following code. The code will parse your shortcode and show you the shortcode content. It'll only work on frontend.
add_filter( 'the_title', function( $title, $item_id ) {
if ( 'nav_menu_item' === get_post_type( $item_id ) ) {
return do_shortcode( $title );
}
return $title;
}, 10, 2 );
Can you not use the updated FontAwesome to create this and add this into your menu instead?
https://fontawesome.com/icons/skype?style=brands may help you out.

render Visual Composer shortcodes onto page

I am trying to echo visual composer shortcodes onto a page.
I've tried both methods below, but they don't work:
functions.php:
Method 1
/*
* add shortcode file
*/
function include_file($atts) {
$a = shortcode_atts( array(
'slug' => 'NULL',
), $atts );
if($slug != 'NULL'){
ob_start();
get_template_part($a['slug']);
return ob_get_clean();
}
}
add_shortcode('include', 'include_file');
Method 2
function someshortocode_callback( $atts = array(), $content = null ) {
$output = "[vc_section full_width=\"stretch_row\" css=\".vc_custom_1499155244783{padding-top: 8vh !important;padding-bottom: 5vh !important;background-color: #f7f7f7 !important;}\"][vc_row 0=\"\"][vc_column offset=\"vc_col-lg-offset-3 vc_col-lg-6 vc_col-md-offset-3 vc_col-md-6\"][/vc_column][/vc_row][/vc_section]";
return $output;
}
add_shortcode('someshortocode', 'someshortocode_callback');
file_rendering_vc_shortcodes.php:
Method 1
<?php if ( is_plugin_active( 'js_composer/js_composer.php' ) ) {
wc_print_notice('js_composer plugin ACTIVE', 'notice');
echo do_shortcode('[include slug="vc_templates/shop-page"]');
}; ?>
Result
js_composer plugin ACTIVE
shortcode is on page with parentheses as is
Method 2
<?php $post = get_post();
if ( $post && preg_match( '/vc_row/', $post->post_content ) ) {
// Visual composer works on current page/post
wc_print_notice('VC ON', 'notice');
echo add_shortcode('someshortocode', 'someshortocode_callback');
} else {
wc_print_notice('VC OFF', 'notice');
//echo do_shortcode('[include slug="vc_templates/shop-page"]');
}; ?>
Result
VC OFF (obviously, since the vc_row in shortcode is not there)
shortcode is NOT on page
shop-page.php
<?php
/**
Template Name: Shop Page in theme
Preview Image: #
Descriptions: #
* [vc_row][vc_column][/vc_column][/vc_row]
*/
?>
[vc_section full_width="stretch_row" css=".vc_custom_1499155244783{padding-top: 8vh !important;padding-bottom: 5vh !important;background-color: #f7f7f7 !important;}"][vc_row 0=""][vc_column offset="vc_col-lg-offset-3 vc_col-lg-6 vc_col-md-offset-3 vc_col-md-6"][/vc_column][/vc_row][/vc_section]
Is it possible to render vc shortcodes on page, and if so, how is it done?
Use the:
WPBMap::addAllMappedShortcodes();
then as usual do_shortcode($content);
In short, page builder due to performance doesn't register shortcodes unless it isn't required.
If your element is registered by vc_map or vc_lean_map then no need to use add_shortcode function, you can do everything just by using WPBMap::addAllMappedShortcodes(); it is will call an shortcode class callback during the rendering process and then shortcode template.
Regarding Method 2.
You have to use do_shortcode() in your shortcode function.
function someshortocode_callback( $atts = array(), $content = null ) {
$output = '[vc_section full_width="stretch_row" css=".vc_custom_1499155244783{padding-top: 8vh !important;padding-bottom: 5vh !important;background-color: #f7f7f7 !important;}"][vc_row 0=""][vc_column offset="vc_col-lg-offset-3 vc_col-lg-6 vc_col-md-offset-3 vc_col-md-6"]column text[/vc_column][/vc_row][/vc_section]';
return do_shortcode( $output );
}
add_shortcode( 'someshortocode', 'someshortocode_callback' );
Working example on my test site: http://test.kagg.eu/46083958-2/
Page contains only [someshortocode]. Code above is added to functions.php.
In your code for Method 2 there is another error: line
echo add_shortcode('someshortocode', 'someshortocode_callback');
cannot work, as add_shortcode() returns nothing. This code should be as follows:
<?php $post = get_post();
if ( $post && preg_match( '/vc_row/', $post->post_content ) ) {
// Visual composer works on current page/post
wc_print_notice('VC ON', 'notice');
} else {
wc_print_notice('VC OFF', 'notice');
add_shortcode('someshortocode', 'someshortocode_callback');
echo do_shortcode('[someshortocode]');
}; ?>

Wordpress shortcodes bug in custom theme

I've created a theme from scratch and I have issues creating shortcodes. I have the following code:
functions.php
function caption_shortcode( $atts, $content = null ) {
return '<span class="caption">' . $content . '</span>';
}
add_shortcode( 'caption', 'caption_shortcode' );
in the WP Admin page editor:
[caption]My Caption[/caption]
on the page template page:
echo do_shortcode('[caption]');
The shortcode seems to be somehow working as it returns the HTML but not the $content.
My problem is that I can't seem to get my hand on the $content and display it using the shortcode. Any idea why this is happening?
P.S. I don't want to use the_content() function to display all the content, I want to use the shortcodes to divide the content the user adds in several pop-ups and child sections of the page.
Thanks!
Make sure you user shotcode same page
// [baztag]content[/baztag]
function baztag_func( $atts, $content = '' ) {
return $content;
}
add_shortcode( 'baztag', 'baztag_func' );
echo do_shortcode('[baztag]');

How are action links for posts added in WordPress?

Certain WordPress plugins add links to the little mini-menu that shows up when hovering over post names in the "All Posts" section. This is what I'm talking about, like Purge from cache or Clone.
How do I add my own?
you use the add_filter hook
so for example if you want a link to search google for the page title.
add this to your functions.php
function search_google($actions, $page_object)
{
$actions['google_link'] = '' . __('Search Google for Page Title') . '';
return $actions;
}
add_filter('page_row_actions', 'search_google', 10, 2);
for a Custom Post Type
add_filter('page_row_actions', 'search_google', 10, 2);
function search_google($actions, $post)
{
if ($post->post_type =="YOUR_POST_TYPE"){
$actions['google_link'] = '' . __('Search Google for Page Title') . '';
return $actions;
}
}
more examples can be found here
The old version is not working anymore.
Now use this one:
add_filter('post_row_actions', 'search_google', 10, 2);
function search_google($actions, $post) {
$actions['google_link'] = '' . __('Search Google for Page Title') . '';
return $actions;
}
And for a custom post type:
add_filter('post_row_actions', 'search_google', 10, 2);
function search_google($actions, $post) {
if ($post->post_type =="YOUR_POST_TYPE"){
$actions['google_link'] = '' . __('Search Google for Page Title') . '';
return $actions;
}
}
In my situation, I wanted to both alter the behavior of the current links by having edit & view open in a new tab and add my own link specific to the Divi Builder theme. I wanted this to apply to pages, posts and all custom post types.
Because I am applying this change to both pages and posts, I had to do both the post_row_actions and page_row_actions add_filter actions.
This is the code added to my child theme functions.php file.
/* Modify row actions */
/* Modify row actions */
/* Modify row actions */
// Open Edit in new
function edit_new_tab( $actions, $page_object ) {
$actions['edit'] = '' . __( 'Edit' ) . '';
return $actions;
}
add_filter( 'post_row_actions', 'edit_new_tab', 10, 2 );
add_filter( 'page_row_actions', 'edit_new_tab', 10, 2 );
// Open View in new
function view_new_tab( $actions, $page_object ) {
$actions['view'] = '' . __( 'View' ) . '';
return $actions;
}
add_filter( 'post_row_actions', 'view_new_tab', 10, 2 );
add_filter( 'page_row_actions', 'view_new_tab', 10, 2 );
// Divi Builder in new
function add_divi_link( $actions, $page_object ) {
$actions['add_divi_link'] = '' . __( 'Divi Builder' ) . '';
return $actions;
}
add_filter( 'post_row_actions', 'add_divi_link', 10, 2 );
add_filter( 'page_row_actions', 'add_divi_link', 10, 2 );
In this code, view in $actions['view'] matches a built in row type. Because of this, the row type view is overwritten with the respective code. This also applies to edit. To view the row types and how they appear in your instance you can inspect the source code of the page and pay attention to the <span> that surrounds the link you want to modify. The class of the <span> will be the name you will use in $actions['span_class_goes_here']. Therefore, $actions['edit'] will determine that the Edit link will be modified.
In the case of $actions['add_divi_link'], add_divi_link does not exist in my scenario so it will be added as a new row action.

Why does the_title() filter is also applied in menu title?

I have created below function to hide page title. But when I execute this code, it also hides the menu name.
function wsits_post_page_title( $title ) {
if( is_admin())
return $title;
$selected_type = get_option('wsits_page_show_hide');
if(!is_array($selected_type)) return $title;
if ( ( in_array(get_post_type(), $selected_type ) ) && get_option('wsits_page_show_hide') )
{
$title = '';
}
return $title;
}
add_filter( 'the_title', array($this, 'wsits_post_page_title') );
Nikola is correct:
Because menu items also have titles and they need to be filtered :).
To make this only call in the posts, and not in menus, you can add a check for in_the_loop() - if it is true, you're in a post.
So change the first line in the function to:
if( is_admin() || !in_the_loop() )
and all should be well.
It's a bit of a hack but you can solve this by adding your action to loop_start.
function make_custom_title( $title, $id ) {
// Your Code Here
}
function set_custom_title() {
add_filter( 'the_title', 'make_custom_title', 10, 2 );
}
add_action( 'loop_start', 'set_custom_title' );
By embedding the_title filter inside of a loop_start action, we avoid overwriting the menu title attributes.
You can do something like that :
In your function.php :
add_filter( 'the_title', 'ze_title');
function ze_title($a) {
global $dontTouch;
if(!$dontTouch && !is_admin())
$a = someChange($a);
return $a;
}
In your template :
$dontTouch = 1;
wp_nav_menu( array('menu' => 'MyMenu') );
$dontTouch = 0;
Posting this answer because it was the search result I ended up clicking on while searching about targeting the filter hook the_title while ignoring the filter effect for navigation items.
I was working on a section in a theme which I wanted to add buttons to the page title within the heading one tag.
It looked similar to this:
<?php echo '<h1>' . apply_filters( 'the_title', $post->post_title ) . '</h1>'.PHP_EOL; ?>
I was then "hooking in" like this:
add_filter( 'the_title', 'my_callback_function' );
However, the above targets literally everything which calls the_title filter hook, and this includes navigation items.
I changed the filter hook definition like this:
<?php echo '<h1>' . apply_filters( 'the_title', $post->post_title, $post->ID, true ) . '</h1>'.PHP_EOL; ?>
Pretty much every call to the_title filter passes parameter 1 as the $post->post_title and parameter 2 as the $post->ID. Search the WordPress core code for apply_filters( 'the_title'* and you'll see for yourself.
So I decided to add a third parameter for situations where I want to target specific items which call the_title filter. This way, I can still receive the benefit of all callbacks which apply to the_title filter hook by default, while also having the ability to semi-uniquely target items that use the_title filter hook with the third parameter.
It's a simple boolean parameter:
/**
* #param String $title
* #param Int $object_id
* #param bool $theme
*
* #return mixed
*/
function filter_the_title( String $title = null, Int $object_id = null, Bool $theme = false ) {
if( ! $object_id ){
return $title;
}
if( ! $theme ){
return $title;
}
// your code here...
return $title;
}
add_filter( 'the_title', 'filter_the_title', 10, 3 );
Label the variables however you want. This is what worked for me, and it does exactly what I need it to do. This answer may not be 100% relevant to the question asked, but this is where I arrived while searching to solve this problem. Hope this helps someone in a similar situation.
The global $dontTouch; solution didn't work for me for some reason. So I simply removed the filter around the menu thus in header.php:
remove_filter( 'the_title', 'change_title' );
get_template_part( 'template-parts/navigation/navigation', 'top' );
add_filter( 'the_title', 'change_title' );
And all is well.
I think you're looking for this:
function change_title($title) {
if( in_the_loop() && !is_archive() ) { // This will skip the menu items and the archive titles
return $new_title;
}
return $title;
}
add_filter('the_title', array($this, 'change_title'), 10, 2);

Categories