first of all I know which my problem is not at all related to the sage project but I know that your advanced wordpress knowledge can help me to get through that.
p.s. I've been creating my shortcodes upon sage scaffolding.
I built two shortcodes for nested using:
[outdoor]
[outdoor_item title="My title 1" color="orange"]<strong>The</strong> 1st Content[/outdoor]
[outdoor_item title="My title 2" color="blue"]<strong>The</strong> 2nd Content[/outdoor]
[outdoor_item title="My title 3" color="green"]<strong>The</strong> 3rd Content[/outdoor]
[outdoor_item title="My title 4" color="red"]<strong>The</strong> 4th Content[/outdoor]
[/outdoor]
After lots of hours searching something in stackoverflow and google I figured it out that I had to apply do_shortcode() in my RAW outdoor shortcontent content... something like this:
add_shortcode('outdoor', function($atts, $content, $tag) {
return '<div class="outdoor">' . do_shortcode($content) . '</div>';
});
and then my problem comes out... the function do_shortcode() renders ONLY my first outdoor_item and ignores every outdoor_item else. It outputs something like this:
<div class="outdoor">
<div class="outdoor-item" style="background-color: orange">
<h1>My title 1</h1>
<div class="outdoor-item-content">
<strong>The</strong> 1st Content
</div>
</div>
</div>
p.s. I've tried do_shortcode(), apply_filters('the_content', $content) and even call wp_reset_postdata() after each outdoor_item. What else could I try?
Recently I had similar issue.
I needed to wrap elements into the bootstrap table so the shortcode should be the following:
[table]
[fb_review href="" name="" date=""][/fb_review]
[fb_review href="" name="" date=""][/fb_review]
[fb_review href="" name="" date=""][/fb_review]
[fb_review href="" name="" date=""][/fb_review]
[fb_review href="" name="" date=""][/fb_review]
[/table]
and this should produce the following html:
<div class="row">
<div class="col-md-6"><div class="fb-review">Some content</div></div>
<div class="col-md-6"><div class="fb-review">Some content</div></div>
</div>
<div class="row">
<div class="col-md-6"><div class="fb-review">Some content</div></div>
<div class="col-md-6"><div class="fb-review">Some content</div></div>
</div>
<div class="row">
<div class="col-md-6"><div class="fb-review">Some content</div></div>
</div>
I looked for different ways how to handle this but then decided to parse the $content string by myself
here is the part of functions.php:
//this function just wraps the compiled nested shortcode elements
function responsive_table($attrs, $items = []) {
if (count($items) > 0) {
$result = '';
$counter = 0;
foreach ($items as $item) {
if (!($counter % 2)) {
$result .= '<div class="row">';
}
$result .= '<div class="col-md-6">' . $item . '</div>';
if ($counter % 2) {
$result .= '</div>';
}
$counter++;
}
if ($counter % 2) {
$result .= '</div>';
}
return $result;
} else {
return '';
}
}
// this function parses the content, fetches internal shortcodes, compiles them and passes to responsive_table
function responsive_table_for($attrs, $content=null) {
if ($content != null && $content != '') {
$content_matches = [];
preg_match_all('/\[.+?\[.+?\]/', $content, $content_matches); // TODO: this doesn't support nested shortcodes
$content_array = [];
foreach ($content_matches[0] as $item) {
$content_array[] = do_shortcode($item);
}
return responsive_table($attrs, $content_array);
} else {
return '';
}
}
add_shortcode('table', 'responsive_table_for');
Maybe this way is not the best but it works for me.
Related
Just a vanilla call to product-category shortcode in functions.php is confusing me.
I'm trying to get a columns-3 of text sitting next to a columns-9 of products.
My code:
<div class="content">
<div class="columns-3">
<?php $home_kit = get_term(30, 'product_cat', ARRAY_A); ?>
<h2 class="section-title"><?php echo $home_kit['name']; ?></h2>
<p><?php echo $home_kit['description']; ?></p>
All Products »
</div>
<?php echo do_shortcode('[product_category category="home-kits" per_page="3" orderby="price" order="desc" columns="9"]'); ?>
</div>
The shortcode generates:
<div class="homepage-home-kit-category">
<div class="content">
<div class="columns-3">
<h2...</h2>
<p>...</p>
<a ...</a>
</div>
<div class="woocommerce columns-9 ">
<ul class="products columns-9">
<li></li>
</ul>
</div>
</div>
</div>
Note the repeat of the columns-9 on both the generated <div> and <ul>.
If both the <div> and <ul> have class columns-9 then I get 3/4 of the available 3/4.
Surely the class columns-9 only needs to be on either the WooComerce <div> or the <ul>.
How can I remove this addition from the <ul> element?
I am gratefull for the answers I received which are all valid and work well.
I suppose my underlying problem is that I cannot see the usefulness of the product_category shortcode as it does not obey the columns parameter faithfully.
Am I alone?
There are several options to remove/modify the columns-9 class from the <ul> element
Solution 1 - Through the use of a filter hook.
function filter_woocommerce_product_loop_start( $loop_start ) {
// New output
$loop_start = '<ul class="products">';
return $loop_start;
}
add_filter( 'woocommerce_product_loop_start', 'filter_woocommerce_product_loop_start', 10, 1 );
Solution 2 - Overwriting the template file.
You could overwrite the templates/loop/loop-start.php template file
This template can be overridden by copying it to yourtheme/woocommerce/loop/loop-start.php.
Replace
<ul class="products columns-<?php echo esc_attr( wc_get_loop_prop( 'columns' ) ); ?>">
With
<ul class="products">
Solution 3 - overwriting the existing function.
Since woocommerce_product_loop_start uses function_exits, see: includes/wc-template-functions.php on line 1110-1134 #version 2.5.0
More info: What's "function_exists" in Wordpress
/**
* Output the start of a product loop. By default this is a UL.
*
* #param bool $echo Should echo?.
* #return string
*/
function woocommerce_product_loop_start( $echo = true ) {
$loop_start = '<ul class="products">';
if ( $echo ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $loop_start;
} else {
return $loop_start;
}
}
I have a banner on my Wordpress website that I want to be updated when the cart is not empty by Ajax.
Here is the non Ajaxified version:
function dynamic_banner() {
$atts = '<div class="woofc-shipping">' . alg_wc_get_left_to_free_shipping('<span style="color:#F79917"><i class="fas fa-shipping-fast" style="margin-left: 5px;"></i>Add %amount_left_for_free_shipping% more for Free shipping</span> <div class="woofc-total-right"></div>') . '</div>';
if ( ! WC()->cart->is_empty() ) {
?>
<script>
jQuery(function($){
$(".ban-text").replaceWith('<?php echo $atts; ?>')});
</script>
<?php
}
}
add_action('wp_head', 'dynamic_banner');
This is the HTML
<div class="head_strip over--hide" style="display: block;">
<p><strong>Free fast delivery*</strong> in purchases over <span class="special-price">295 NIS</span> even during the closure period!</span></p>
</div>
Have found a solution thanks to those threads by LoicTheAztec
Functions.php Code:
// Shortcode for the banner
function display_free_shipping_progress() {
return get_free_shipping_progress();
}
add_shortcode('fs_progress', 'display_free_shipping_progress');
// Function that makes calculations and display
function get_free_shipping_progress() {
$atts = '<div class="woofc-shipping">' . alg_wc_get_left_to_free_shipping('<span style="color:#F79917"><i class="fas fa-shipping-fast" style="margin-left: 5px;"></i>הוסיפי עוד %amount_left_for_free_shipping% למשלוח חינם</span> <div class="woofc-total-right"></div>') . '</div>';
$prodgress = WC()->cart->total;
//Check if cart has something else show default
if( $prodgress > 0 ) {
return '<div class="head_strip over--hide" style="display: block;">' . $atts . '</div>';
} else {
return '<div class="head_strip over--hide" style="display: block;"><span class="ban-text"><strong>*משלוח מהיר חינם</strong > בקניה מעל<span class="special-price">295₪</span> גם בתקופת הסגר!</span></div>';
}
}
// Refreshing "free shipping" progress on cart ajax events
add_filter( 'woocommerce_add_to_cart_fragments', 'refresh_free_shipping_progress' );
function refresh_free_shipping_progress( $fragments ){
$fragments['.head_strip'] = get_free_shipping_progress();
return $fragments;
}
Have passed all HTML needed to shortcode for simplicity like was recommended.
A client is using WPBakery and a form is being pulled into the description attribute of a shortcode. Ordinarily you would pull the form by its shortcode but the boiler plate demo has the form being pulled with a string beginning with a hashtag.
E-8_JTVCbWM0d3BfZm9ybSUyMGlkJTNEJTIyNDc0JTIyJTVE
[trx_sc_title title_style="accent" title_align="left" link_style="default" title="Stay Tuned for Our Updates" subtitle="newsletter signup" description="#E-8_JTVCbWM0d3BfZm9ybSUyMGlkJTNEJTIyNDc0JTIyJTVE"]
is equivalent to:
[trx_sc_title title_style="accent" title_align="left" link_style="default" title="Stay Tuned for Our Updates" subtitle="newsletter signup" description="[mc4wp_form id="474"]"]
I need to pull a different form from ninjaforms( [ninja_form id=3] ) instead of the mailchimp form in the example. How do I convert the shortcode in the same manner they did?
Thanks in advance for any insight as to what is going on here.
use two shortcodes. so that it won't be complicated.
function kp_shortcode1($atts, $content = null)
{
ob_start();
?>
<div class="sc1-section">
<?php echo do_shortcode($content); ?>
</div>
<?php
$output = ob_get_clean();
return $output;
}
add_shortcode('kp_shortcode1', 'kp_shortcode1');
function kp_shortcode2($atts, $content = null)
{
ob_start();
?>
<div class="sc2-section">
<h1>shortcode 2 content</h1>
</div>
<?php
$output = ob_get_clean();
return $output;
}
add_shortcode('kp_shortcode2', 'kp_shortcode2');
Inside the wordpress backend use
[kp_shortcode1]
[kp_shortcode2]
[kp_shortcode2]
[kp_shortcode2]
[/kp_shortcode1]
Output would be :
<div class="sc1-section">
<div class="sc2-section">
<h1>shortcode 2 content</h1>
</div>
<div class="sc2-section">
<h1>shortcode 2 content</h1>
</div>
<div class="sc2-section">
<h1>shortcode 2 content</h1>
</div>
</div>
How Show Success Message After form submit in word press ? This code is used for review submission .I need to show success message(Your review has been successfully submitted) after submit my review.My html code :
<div class="container">
<div class="row">
<div class="reviews">
<?php
if (is_user_logged_in()) {
?>
<h2>REVIEWS ON <?php echo get_the_title(); ?> </h2>
<div class="message-box">
<form method="post">
<div class="rating">
<div class="rating-inner">
<div id="rateYo1"></div><p>Rate the store</p>
</div>
</div>
<textarea class="review_message" name="message_review" id="message" placeholder="Type your review here..." required></textarea>
<button class="review_submit_button" name="review_submit" value="Submit Review">Submit Review</button>
<input type="hidden" id="data-rating" name="data-rating" >
</form>
</div>
<?php }?>
</div>
</div>
</div>
<?php
$img = showImage();
$user_avatar=$img[0]->mem_photo;
if (isset($_POST['review_submit'])) {
$review_content = $_POST['message_review'];
$data_rating = $_POST['data-rating'];
$shop_id = get_the_ID();
add_user_review($review_content, $data_rating, $shop_id, $user_avatar);
}
?>
Function code:
function add_user_review($review,$data_rating,$shop_id,$user_avatar){
global $wpdb;
$current_user=wp_get_current_user();
$current_user_id=$current_user->ID;
$username=$current_user->display_name;
$user_email=$current_user->user_email;
$review_date= date("m/d/Y");
$in=$wpdb->insert("wp_user_reviews" ,array(
"review_content"=>$review,
"review_rating"=>$data_rating,
"wp_user_id"=>$current_user_id,
"user_name"=>$username,
"product_id"=>$shop_id,
"review_date"=>$review_date,
"user_email"=>$user_email,
"user_avatar"=>$user_avatar,
));
}
please help.Thanks :)
Change your if condition to this
if (isset($_POST['review_submit'])) {
$review_content = $_POST['message_review'];
$data_rating = $_POST['data-rating'];
$shop_id = get_the_ID();
if(add_user_review($review_content, $data_rating, $shop_id, $user_avatar)){
echo "<script>alert('success')</script>";
} else {
echo "<script>alert('fail to insert')</script>";
}
}
or you can write this in functions.php aswell
<script>
$( ".review_submit_button" ).click(function() {
alert( "success" );
});
</script>
This is always work for :)
I use shortcode to output the following html in a variable, but there are too many redundant code such as br and p tags, how to remove them? Thanks!
My shortcode function:
add_shortcode('portfolios', 'van_portfolios_shortcode');
function van_portfolios_shortcode( $atts, $content) {
extract(shortcode_atts(array(
'number'=>'9',
'slug'=>''
), $atts));
$str=van_portfolios($slug,$number,false);
return $str;
}
function van_process_shortcode($content) {
global $shortcode_tags;
// Backup current registered shortcodes and clear them all out
$orig_shortcode_tags = $shortcode_tags;
$shortcode_tags = array();
add_shortcode('portfolios', 'van_portfolios_shortcode');
// Do the shortcode (only the one above is registered)
$content = do_shortcode($content);
// Put the original shortcodes back
$shortcode_tags = $orig_shortcode_tags;
return $content;
}
add_filter('the_content', 'van_process_shortcode', 7);
Correct makeup is
<div class="portfolio-item">
<a class="overlay" href="#">
<h3>...</h3>
<p>...</p>
</a>
<div class="tools">ZoomInInfo</div>
...
</div>
Output:
<div class="portfolio-item">
<a class="overlay" href="#">
<br /><!--This <br />is redundant code-->
<h3>...</h3>
<p>...</p><p><!--This <p> is redundant code-->
</a>
<div class="tools">ZoomInInfo</div>
<p><!--This <p> is redundant code-->...
</div>
Try adding this code before content is displayed:
UPDATED
// From your question
$content = do_shortcode($content);
// Put the original shortcodes back
$shortcode_tags = $orig_shortcode_tags;
// Add this code
$content = preg_replace( '%<p> \s*</p>%', '', $content ); // Remove all instances of "<p> </p>" to avoid extra lines.
$Old = array( '<br />', '<br>' );
$New = array( '','' );
$content = str_replace( $Old, $New, $content );
// From your question
return $content;