Customizing the Parents functions.php File in Child - php

I'm customizing my theme right now. The Standard is, that the logged-in Users Avatar is shown in the Menu bar but I want to display a simple Icon there. I already wright the Code and everything works fine but the Code is located in the mains functions.php File. So in order to make the Site upgradeable, I need to embed the code in the child themes function.php. I found no help there so maybe here is someone who could help me!
Thanks a lot
Below is the Code which I need to embed in the functions.php File of my Child Theme:
add_action( 'init', 'gt3_get_page_id_from_menu' );
function gt3_user_avatar_out($avatar_size=80,$show_email=false){
$user_id = get_current_user_id();
$current_user = get_user_by( 'id', $user_id );
echo "<i class='gt3_login_icon gt3_login_icon--avatar'>";
echo '<i class="fa fa-user"></i>';
echo "</i>";
if ($show_email) {
echo "<span class='gt3_login__user_email'>".esc_html( $current_user->user_email )."</span>";
}
}

If a function is declared in the parent's functions.php, declaring a function with the same name in the child theme will cause a fatal error in the child theme itself. I'd suggest doing something like this instead:
parent function .php
// This can become a filter if you'll need to manipulate the current user
function gt3_get_current_user() {
return get_user_by( 'id', get_current_user_id() );
}
add_filter( 'gt3/current_user_avatar', function( string $html = '', bool $show_email = false ) {
$html .= '<i class="gt3_login_icon gt3_login_icon--avatar"><i class="fa fa-user"></i></i>';
if( $show_email ) {
$html .= sprintf( '<span class="gt3_login__user_email">%s</span>', esc_html( gt3_get_current_user()->user_email ) );
}
return $html;
}, 10, 2 );
child theme's function .php
add_filter( 'gt3/current_user_avatar', function( string $html = '', bool $show_email = false ) {
// $html here is the one that returned from the parent's theme. You can manipulate it or replace the whole output inside here.
return $html;
}, 10, 2 );
Example usages:
echo apply_filters( 'gt3/current_user_avatar', '', false ); // This will echo the icon without the email
echo apply_filters( 'gt3/current_user_avatar', '', true ); // This will echo the icon with the email
echo apply_filters( 'gt3/current_user_avatar', '<p>Append</p>', false ); // This will echo the icon without the email and the '<p>Append</p>' html string before everything else
The result will vary depending on where you use this filter. If you are in the child theme and you altered the html adding the said filter, the result will be customized for that theme. Remember that you can use the use statement to bring in external variables ina closure. For example:
$user_name = 'Mike';
add_filter( 'gt3/current_user_avatar', function( string $html = '', bool $show_email = false ) use ( $user_name ) {
$html .= sprintf( '<p>Hello, %s!</p>', $user_name );
return $html;
}, 10, 2 );
// This will cheer the user, and it will be place at the end of the snippet.

your code is not overwritten by adding a new functions.php file in the same folder, but do not copy/paste the code from the parent theme’s file, because it needs to remain separate from any modifications you make to the child theme. Instead, create a blank file or add any new .php functions required for your child theme

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]');
}; ?>

How to wrap Wordpress wpautop in a container with a class for CSS manipulation

I have a shortcode that queries through Worpress posts by category name and displays them on the front end. If there are no posts in that category, the user can write a "no posts available" message.
The wpautop wraps the message with <p>...</p>.
I want to style this <p>. I can't simply just add CSS to the paragraph tag obviously. It's not that simple. The styling needs to be isolated to this message only. So, can someone help me modify this code below to wrap the return in a div container with a class?
Thanks
$listing = new WP_Query( apply_filters( 'display_posts_shortcode_args', $args, $original_atts ) );
if ( ! $listing->have_posts() ) {
/**
* Filter content to display if no posts match the current query.
*
*/
return apply_filters( 'display_posts_shortcode_no_results', wpautop( $no_posts_message ) );
}
Use a below sample :p
$page_cont = wpautop('YOUR_CONTENT');
$added_class = str_replace('<p>', '<p class="text-center">', $page_cont);
echo $added_class;
You can do it by creating alternative function for wpautop().
wpautop() function is coded in wp-includes/formatting.php, copy the function to the functions.php in your template directory and edit.
1) Change the function name and add a new parameter for class name,
function wpautop( $pee, $br = true ) {
as
function wpautopNew( $pee, $className = null, $br = true ) {
2) Search and change this loop in the function
// Rebuild the content as a string, wrapping every bit with a <p>.
foreach ( $pees as $tinkle ) {
$pee .= '<p>'. trim($tinkle, "\n") . "</p>\n";
}
as this
// Rebuild the content as a string, wrapping every bit with a <p>.
foreach ( $pees as $tinkle ) {
$pee .= '<div class="'.$className.'"><p>' . trim($tinkle, "\n") . "</p></div>\n";
}
3) Use the new function and give a class name as second argument.
wpautopNew( $no_posts_message, 'yourclassname' )

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]');

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