I have this php code used for a milestone wordpress shortcode :
function rocknrolla_milestone_box_shortcode( $atts, $content = null ){
extract( shortcode_atts(array(
"count" => '90%',
"title" => ''
), $atts) );
echo htmlentities($count);
$rnr_milestone_box = '<div class="milestone-counter" data-perc="'. $count .'">';
$rnr_milestone_box .= '<span class="milestone-count highlight">'. $count .'</span>';
$rnr_milestone_box .= '<h6 class="milestone-details">'. $title .'</h6>';
$rnr_milestone_box .= '</div>';
return $rnr_milestone_box;
}
add_shortcode('milestone_box', 'rocknrolla_milestone_box_shortcode');
Now, when I add on "data-perc" attribute 99% for example this is displaying a weird text like:
<span class="milestone-count highlight">NaN</span>
If I add just the number like 99 the output is correct:
<span class="milestone-count highlight">99</span>
How can I append the % sign after the count variable here:
$rnr_milestone_box .= '<span class="milestone-count highlight">'. $count .'</span>';
?
Thanks!
Try this optimal option:
<?php
$count = "99%";
echo htmlentities($count);
// output: 99%
?>
Thanks.
Related
I am using ACF and CPT cooperatively. I created a shortcode to be placed in a text module in my theme. It works well. Yet, when I call ACF get_field(), it's not returning any value. I tried looking into this question and also this one, but neither works.
I double-checked ACF fields name. Also tried to change the input type from text to number but still no hope.
Development Environment
WordPress Version: 5.2.2 (Latest at the moment)
Theme/Child Theme Version: Divi 3.25.3
The shortcode I created:
<?php
add_shortcode('RESTAURANT_MENU', 'fetch_menu_products');
function fetch_menu_products($atts)
{
$atts = shortcode_atts(array(
'category_name' => ''
), $atts);
$category_name = $atts['category_name'];
$args = array(
'category_name' => $category_name,
'post_type' => 'menu',
'numberposts' => -1,
'post_status' => 'publish'
);
$output = '';
$menu_products = get_posts($args);
foreach ($menu_products as $menu_product) {
setup_postdata($menu_product);
$output .= '<section class="menu-item-wrapper">';
$output .= '<h3 class="menu-item__title">' . $menu_product->post_title . '</h3>';
$output .= '<div class="menu-item">';
$output .= '<div class="menu-item-description">';
$output .= '<p class="menu-item-description__text">' . $menu_product->post_content . '</p>';
$output .= '</div>';
$output .= '<ul class="menu-prices-list">';
if (get_field("regular_size_price") || get_field("large_size_price")) {
$output .= '<li class="menu-prices-list--item">R ' . get_field("regular_size_price", $menu_product->ID) . ' Currency</li>';
$output .= '<li class="menu-prices-list--item">L ' . get_field("large_size_price", $menu_product->ID) . ' Currency</li>';
}
if (get_field("price")) {
$output .= '<li class="menu-prices-list--item">' . get_field("price", $menu_product->ID) . ' Currency</li>';
}
$output .= '</ul>';
$output .= '</div>';
$output .= '</section>';
}
wp_reset_postdata();
return $output;
}
Can any help me find out why isn't it returning any value, please? Thank you.
Update: The ACF Location Rules
Try to use get_post_meta() instead of get_field(). As you are already using ACF then use this code to get value from post meta
get_post_meta($menu_product->ID, 'regular_size_price')[0]
For more help on get_post_meta() you can check this link
If my assumption is correct, your li elements are not being printed when you return the $output variable. That should be the case since you are using get_field function outside of theloop without passing post id in if statement.
Below is the corrected code:
if (get_field("regular_size_price", $menu_product->ID) || get_field("large_size_price", $menu_product->ID)) {
$output .= '<li class="menu-prices-list--item">R ' . get_field("regular_size_price", $menu_product->ID) . ' Currency</li>';
$output .= '<li class="menu-prices-list--item">L ' . get_field("large_size_price", $menu_product->ID) . ' Currency</li>';
}
I hope this helps.
I'm working on a shortcode to show my authors list on WordPress; I managed to make the social networks fields work, but I can't hide them, if the field is empty.
I imagine I need the if statement, but I can't seem to find a way to make it works.
Here is the code I am currently using:
function pippin_list_authors() {
$authors = get_users(array(
'orderby' => 'display_name',
'count_totals' => false,
'who' => 'authors',
'id' => ''
)
);
$list = '';
if($authors) :
$list .= '<div class="author-list">';
foreach($authors as $author) :
$list .= '<table>';
$archive_url = get_author_posts_url($author->ID);
$list .= '<tr>' . get_avatar($author->user_email, 100);
$list .= '<br><br><a class="author-list-name" href="'. $archive_url . '" title="' . __('Vedi tutti i post ', 'pippin') . $author->display_name . '">' . $author->display_name . '</a><br>';
$list.= '<br><br><div class="author-social"><i class="fa fa-facebook"><p style="font-size: 0; color: transparent;">'.A.'</p></i>';
$list .= '<i class="fa fa-twitter"><p style="font-size: 0; color: transparent;">'.A.'</p></i>';
$list .= '<p class="author-bio" style="max-height: 103px; overflow: hidden; ">' . get_user_meta($author->ID, 'description', true) . '</p>';
$list .= '<div class="author-archive" style="text-align: center;">' . __('Vedi tutti i post', 'pippin') . '</div>';
$list .= '</tr></table>';
endforeach;
$list .= '</div>';
endif;
return $list;
}
add_shortcode('authors', 'pippin_list_authors');
If you want to check if the variable $authors is empty use the empty() function.
Try this:
if(!empty($authors)) {
...
}
I would suggest you change your functions if possible.
Create function for every social link and other user metas like this:
$facebook_link = get_user_meta( $author->ID, 'facebook', true);
then call it in this way:
<?php if ($facebook_link !=='') { ?>
<p><i class="fa fa-facebook"></p>
<?php } ?>
If get_user_meta exist in DB, but isn't value, it still return no empty array so empty($our_meta) - will not help.
Bcz return array( [0] => string("") );
Empty string, but this empty value is in the array, so it will show
that the array is not empty.
Use get_user_meta($id, $key, true) it return '' and empty() will work as it should.
get_user_meta( $user_id, $key, $single );
$single(boolean) If set to true, the function will return the value of the meta field, if left false, then the value of the meta
field will be returned in an array. This parameter has no meaning if
the $key parameter has not been specified.
Default: false
- If $single = true
string/array - if the meta field exists.
'' - when the metafield does not exist.
If $single = false
an array of all metafield values - when the metafield exists.
array() - when the meta field does not exist.
I'm trying to use shortcodes to execute tag-specific content loops on different pages of my website. I know my shortcode function is working properly, because when I hardcode do_shortcode into my page template, it shows up perfectly.
But when I try to add a [shortcode] directly into the Wordpress editor instead, it shows as plain text. Any ideas how I can fix this?
You can see what I'm talking about here - the [showtag tag="seefour"] you see as plain text is written directly into the Wordpress text editor. It's not working correctly. Just below it, you'll see the <?php echo do_shortcode("[showtag tag='seefour']"); ?> properly executing my content loop from the page template.
Any ideas how I can fix this? Hardcoding do_shortcode is not sustainable for me. The site currently only has two active plugins, but this problem persists after deactivating them, so I'm at a loss.
For good measure, this is the content loop I'm trying to execute:
function showtag_shortcode( $atts ) {
$atts = shortcode_atts( array(
'tag' => '', // Default value.
), $atts );
$posts = get_posts( 'tag=' . $atts['tag'] );
if ( $posts ) {
$output .= '<div class="jd-container">';
$output .= '<section class="jd-grid jd-pad1">';
foreach ( $posts as $post ) {
setup_postdata( $post );
$output .= '<div class="jd-box">';
$output .= '<a href="' . get_the_permalink( $post ) . '">';
$output .= get_the_post_thumbnail( $post );
$output .= '<div class="jd-overlay"></div>';
$output .= '<div class="jd-overlay-text">';
$output .= get_the_title( $post );
$output .= '</div>';
$output .= '</a>';
$output .= '</div>';
}
$output .= '</section>';
$output .= '</div>';
} else {
$output = 'no data';
}
wp_reset_postdata();
return $output;
}
add_shortcode( 'showtag', 'showtag_shortcode' );
And here's my page.php template code:
<?php get_header(); ?>
<section class="jd-backdrop">
<div class="jd-trans-row jd-container">
<h2 class=""><?php the_title(); ?></h2>
<br>
<p class=""><?= get_post_field('post_content', $post->ID) ?></p>
</div>
<?php echo do_shortcode("[showtag tag='seefour']"); ?>
</section>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
None of the solutions I've found so far have worked, so I'm open to suggestions...
It seems that your theme does not execute do_shortcode() with the content of the post.
Try to add the following to functions.php
function the_content_filter( $content) {
return do_shortcode( $content);
}
add_filter( 'the_content', 'the_content_filter', 1000);
UPDATE
From the code of your theme we can see that you use get_post_field to output content of the post. Unlike to the_content(), this function does not invoke any filters. That is why code above does not work in your case.
You have to use get_post_field() in the following manner:
<?php echo do_shortcode( get_post_field( 'post_content', $post->ID ) ); ?>
P. S. You should also avoid to use <= as it doesn't work on most hostings and is discouraged.
See this code from a plugin that I am worked on, this was ages ago but you can see that the "do_shortcode()" function is included, try add it to your $output.
function rir_row( $params, $content = null ) {
extract( shortcode_atts( array(
'class' => 'rir-row'
), $params ) );
$content = preg_replace( '/<br class="nc".\/>/', '', $content );
$result = '<div class="' . $class . '">';
$result .= do_shortcode( $content );
$result .= '</div>';
return force_balance_tags( $result );
}
add_shortcode('rir_row', 'rir_row');
function rir_item( $params, $content=null ) {
extract( shortcode_atts( array(
'class' => 'col-sm-1'
), $params ) );
$result = '<div class="' . $class . '">';
$result .= do_shortcode( $content );
$result .= '</div>';
return force_balance_tags( $result );
}
add_shortcode( 'rir_item', 'rir_item' );
I am creating a shortcode to display the most recent posts in the homepage, however I cannot get the pagination working.
When you click on 'older posts' the page refreshes but the same 2 original posts are displayed.
if ( ! function_exists('vpsa_posts_shortcode') ) {
function vpsa_posts_shortcode( $atts ){
$atts = shortcode_atts( array(
'per_page' => 2,
'order' => 'DESC',
'orderby' => 'date'
), $atts );
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'posts_per_page' => $atts["per_page"],
'order' => $atts["order"],
'orderby' => $atts["orderby"],
'paged' => $paged
);
$query = new WP_Query($args);
if($query->have_posts()) : $output;
while ($query->have_posts()) : $query->the_post();
$output .= '<article id="post-' . get_the_ID() . '" class="' . implode(' ', get_post_class()) . '">';
$output .= '<h4 class="post-title"><span>' . the_title('','',false) . '</span></h4>';
$output .= '<div class="row">';
$output .= '<div class="col-md-3">';
$output .= '<a href="' . get_permalink() . '" title="' . the_title('','',false) . '">';
if ( has_post_thumbnail() ) {
$output .= get_the_post_thumbnail( get_the_id(), 'featured', array('class' => 'img-responsive aligncenter'));
} else {
$output .= '<img class="img-responsive aligncenter" src="' . get_template_directory_uri() . '/images/not-available.png" alt="Not Available" height="150" width="200" />';
}
$output .= '</a>';
$output .= '</div>';
$output .= '<div class="col-md-9">';
$output .= get_the_excerpt();
$output .= '<span class="post-permalink">Read More</span>';
$output .= '</div>';
$output .= '</div>';
$output .= '<div class="post-info">';
$output .= '<ul>';
$output .= '<li>Posted: ' . get_the_time("F j, Y") . '</li>';
$output .= '<li>By: ' . get_the_author() . '</li>';
$output .= '<li>Categories: ' . get_the_category_list(", ") . '</li>';
$output .= '</ul>';
$output .= '</div>';
$output .= '</article>';
endwhile;
$output .= '<div class="post-nav">';
$output .= '<div class="prev-page">' . get_previous_posts_link( "« Newer Entries" ) . '</div>';
$output .= '<div class="next-page">' . get_next_posts_link( "Older Entries »", 3 ) . '</div>';
$output .= '</div>';
else:
$output .= '<p>Sorry, there are no posts to display</p>';
endif;
wp_reset_postdata();
return $output;
}
}
add_shortcode('vpsa_posts', 'vpsa_posts_shortcode');
You need to call paginate function.Try following code:
if ( ! function_exists('vpsa_posts_shortcode') ) {
function vpsa_posts_shortcode( $atts ){
$atts = shortcode_atts( array(
'per_page' => 2,
'order' => 'DESC',
'orderby' => 'date'
), $atts );
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'posts_per_page' => $atts["per_page"],
'order' => $atts["order"],
'orderby' => $atts["orderby"],
'paged' => $paged
);
$query = new WP_Query($args);
if($query->have_posts()) : $output;
while ($query->have_posts()) : $query->the_post();
$output .= '<article id="post-' . get_the_ID() . '" class="' . implode(' ', get_post_class()) . '">';
$output .= '<h4 class="post-title"><span>' . the_title('','',false) . '</span></h4>';
$output .= '<div class="row">';
$output .= '<div class="col-md-3">';
$output .= '<a href="' . get_permalink() . '" title="' . the_title('','',false) . '">';
if ( has_post_thumbnail() ) {
$output .= get_the_post_thumbnail( get_the_id(), 'featured', array('class' => 'img-responsive aligncenter'));
} else {
$output .= '<img class="img-responsive aligncenter" src="' . get_template_directory_uri() . '/images/not-available.png" alt="Not Available" height="150" width="200" />';
}
$output .= '</a>';
$output .= '</div>';
$output .= '<div class="col-md-9">';
$output .= get_the_excerpt();
$output .= '<span class="post-permalink">Read More</span>';
$output .= '</div>';
$output .= '</div>';
$output .= '<div class="post-info">';
$output .= '<ul>';
$output .= '<li>Posted: ' . get_the_time("F j, Y") . '</li>';
$output .= '<li>By: ' . get_the_author() . '</li>';
$output .= '<li>Categories: ' . get_the_category_list(", ") . '</li>';
$output .= '</ul>';
$output .= '</div>';
$output .= '</article>';
endwhile;global $wp_query;
$args_pagi = array(
'base' => add_query_arg( 'paged', '%#%' ),
'total' => $query->max_num_pages,
'current' => $paged
);
$output .= '<div class="post-nav">';
$output .= paginate_links( $args_pagi);
// $output .= '<div class="next-page">' . get_next_posts_link( "Older Entries »", 3 ) . '</div>';
$output .= '</div>';
else:
$output .= '<p>Sorry, there are no posts to display</p>';
endif;
wp_reset_postdata();
return $output;
}
}
add_shortcode('vpsa_posts', 'vpsa_posts_shortcode');
WP_Query with pagination inside a shortcode
Here I will show you how to create a [shortcode] containing a custom new WP_Query with pagination links.
To create a [shortcode] with a new WP_Query post loop with pagination links built in to turn any is_singular() page or single post into a custom archive based on the WP_Query arguments you set. Lets call it [wp_query_pagination_inside_shortcode], so we add with the following add_shortcode() in functions.php.
Or in my case I create separate /functions/ folder for files to stay organized with the appropriates names and have a require_once include file structure.
root/functions.php ->
require_once 'functions/shortcode-wp-query-pagination-inside-shortcode.php';
root/functions/shortcode-wp-query-pagination-inside-shortcode.php->
add_shortcode('wp_query_pagination_inside_shortcode', 'my_shortcode_function_tag');
if (!function_exists('my_shortcode_function_tag')) {
function my_shortcode_function_tag($atts)
{
ob_start(); // Turn output buffering on, helps with complicated template and theme structures
// Note: https://developer.wordpress.org/reference/functions/get_query_var/#used-by
// Custom query_vars translates to Getting an "archive" on any current page that contains a query with corresponding pagination number in the url
// example.com/page-shortcodes-on/page/2/ ...etc see below how to manipulate this
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$atts = shortcode_atts(
array(
'post_type' => 'post',
// Set attributes here you want in your shortcode
// like [shortcode post_types="post"]
),
$atts
);
// set up the default args you wont change and the ones you will by accessing the value of $atts passed into the shortcode function from your WYSIWYG content editor
$args = array(
'posts_per_page' => 3,
'paged' => $paged, // Important to receive page data
'post_type' => $atts['post_type'], // This is how you get the values of your shortcode attributes passed in
'orderby' => 'date',
'order' => 'DESC',
);
$the_query = new WP_Query($args);
// Da loop
// match your themes loop structure this below is just boiler plate stuff ignore or use your choice its not important how you create the post loop, just do it
if ($the_query->have_posts()) {
while ($the_query->have_posts()) {
$the_query->the_post();
get_template_part('template-parts/loop');
} //end while
} // endif
$big = 999999999; // need an unlikely integer for how many pages are possible
// I've tested example.com/page-shortcodes-on/page/999999999999999999/ and the custom query_var still works
echo paginate_links(
array(
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), // referrence the url
'format' => '?paged=%#%', // used for replacing the page number
'current' => max(1, get_query_var('paged')), // grabs the page data
'total' => $the_query->max_num_pages //$the_query is your custom query
)
);
return ob_get_clean(); // Silently discard the buffer contents
wp_reset_query(); // Lets go back to the main_query() after returning our buffered content
}
}
In a WYSIWYG Content editor in pages or posts content editor
[wp_query_pagination_inside_shortcode post_type="posts"]
URL structure for this query_var 'paged'
example.com/page-shortcode-is-on/page/2/
You will need to stylize the pagination links a bit to be acceptable but this should give you a highly useful tool to build custom WP_Query loops with multiple different post_types from anywhere in your site through your WYSIWYG editor. Add more attributes to really make this thing valuable.
// Ignore below, these are just possible search queries for this issue
WP_Query pagination inside a shortcode / add_shortcode with pagination / shortcode with custom attributes / Paginated custom post type wp_query shortcode / custom post type wp_query archive posts per page / page / pagination wont work
I'm relatively new to PHP and don't even really know how to ask the question for which i need help with, so please excuse my lack of technical knowledge - or referring to terms correctly for that matter.
I cannot figure out a way to add the "if(function_exists("the_ratings"))" code below to a string as in the PHP i have below. I know that the way it is below is not correct, but i've placed it there to show how and where i need it to display - help is greatly appreciated.
function latestreleases() {
$args = array( 'posts_per_page' => 30, 'cat' => '-1, -2' );
$last_5_posts_query = new WP_Query( $args );
while($last_5_posts_query->have_posts()) :
$last_5_posts_query->the_post();
$link = get_permalink();
$title = get_the_title();
$description = excerpt(16);
$details = 'Watch ';
$readmore = 'Read more...';
$content .= '<div class="all-latest-movies">';
$content .= '<h3>'.$title.'</h3>';
$content .= '<div class="thumbnail"><a href=" '.$link. ' ">'
. get_the_post_thumbnail( null, "home-movie-thumbnail")
. '</a></div>';
$content .= '<div class="description">' .$description. ' <a href= '.$link.' >' .$readmore. '</div>';
$content .= '<div class="view-listing"><a href= '.$link.' target="_blank" >' .$details. $title. '</a></div>';
$content .= '<div class="ratings">' if(function_exists("the_ratings")) { the_ratings(); } '</div>';
$content .= '</div><!-- .fetured-movies -->';
endwhile;
return $content;
}
add_shortcode('LatestReleases', 'latestreleases' );
Use a ternary operator:
$content .= '<div class="ratings">'. ( function_exists("the_ratings") ? the_ratings() : '' ) .'</div>';
If you want to do it inline you can use the ternary operator
$content .= '<div class="ratings">'.(function_exists("the_ratings")?the_ratings():'').'</div>';
If you want to use the if syntax
$content .= '<div class="ratings">';
if(function_exists("the_ratings")){
$content.=the_ratings();
}
$content.='</div>';