I am creating a shortcode that grabs specific content from an url which i passed as a shortcode attribute. The problem happens when this a shortcode is used more than once on a single post. Then the second shortcode overrides the first one. Here is the code. Two values are displayed on the page both both are the same and are pulled from the second shortcode attribute. There should be two separate and different values.
Here is the shortcode code:
<?php
function grabUrl_func( $atts ) {
$url = $atts['url'];
$label = $atts['label'];
$productId = $atts['id'];
?>
<script>
var urlFromSc = <?php echo json_encode($url) ?>;
var buttonLabel = <?php echo json_encode($label) ?>;
jQuery(document).ready(function() {
jQuery.get(urlFromSc, function(response) {
// grab product name
var productName = jQuery(response).find('.product-name');
var productNameContent = productName[1]['innerHTML'];
jQuery('.g-title').append(productNameContent);
// grab image
var productImage = jQuery(response).find('.product-image-gallery');
var productImageContent = productImage[0]['innerHTML'];
jQuery('.g-image').append(productImageContent);
jQuery('.g-image img').slice(1).remove();
// grab price
var productPrice = jQuery(response).find('.price-box');
var productPriceContent = productPrice[0]['innerHTML'];
jQuery('.g-price').append(productPriceContent);
// grab rating
var productRating = jQuery(response).find('.yotpo');
var productRatingContent = productRating[0]['outerHTML'];
var productId = jQuery(productRatingContent).attr('data-product-id');
var link = jQuery('<a class="productLink" href="' + urlFromSc + '">' + buttonLabel + '</a>' );
jQuery('.g-link').append(link);
});
});
</script>
<?php
$output = '<div class="g-wrapper">'
. '<div class="g-image"></div>'
. '<div class="g-title"></div>'
. '<div class="g-price"></div>'
. '<div class="g-rating">'
. '<div class="yotpo yotpo-main-widget" data-product-id="'.$productId.'"></div>'
. '</div>'
.'<div class="g-link"></div>'
.'</div>';
return $output;
}
add_shortcode( 'grabUrl', 'grabUrl_func' );
?>
Thanks in advance for your help!
Related
I am having products on backorder in a woocommerce store.
I am trying to create an error message if the value of the quantity input field is a higher/exceeds the products stock - see image below.
I also want this to go away if the customer goes below current stock.
If possible I also want the error to show in the cart page as well.
This is what I got this far:
function woocommerce_stock_now() {
global $woocommerce, $product;
?>
<script>
jQuery(function ($) {
var stocknow = <?php echo $qty = $product->get_stock_quantity()(); ?>;
var qtyinput = $('[name=quantity]').val();
var errormessagestock = '<p class="errormessagestock">'(stocknow.value - qtynow.value) . ' items are on backorder and will have a little longer delivery time.</p>';
$('#qtyinput').html(this.value);
$('[name=quantity]').change(function () {
if (qtyinput.value > $stocknow) {
$('stock').html(errormessagestock);
}
});
console.log("qtynow", this.value);
});
</script>
<?php
}
Tyr this:
add_action( 'woocommerce_single_product_summary', 'woocommerce_stock_now' );
function woocommerce_stock_now() {
global $product;
$stocknow = $product->get_stock_quantity();
?>
<script>
jQuery(document).on('input change','[name=quantity]',function() {
var stocknow = '<?php echo $stocknow; ?>';
var qtyinput = jQuery(this).val();
var overdue = parseInt(qtyinput) - parseInt(stocknow);
if (parseInt(qtyinput) > parseInt(stocknow)) {
var errormessagestock = '<p class="errormessagestock">('+overdue+') items are on backorder and will have a little longer delivery time.</p>';
console.log(errormessagestock);
//$('stock').html(errormessagestock);
}
});
</script>
<?php
}
console.log(errormessagestock) will return your message now you can set/print this message accordingly.
protected function render() {
$settings = $this->get_settings_for_display();
// Get image URL
echo '<img src="' . $settings['image']['url'] . '">';
// Get image 'thumbnail' by ID
echo wp_get_attachment_image( $settings['image']['id'], 'thumbnail' );
// Get image HTML
echo \Elementor\Group_Control_Image_Size::get_attachment_image_html( $settings );
}
protected function _content_template() {
?>
<img src="{{ settings.image.url }}">
<?php
}
I was able to get the width and height values in php, but I can't get it for the _content_template() function
$media_image = wp_get_attachment_image_src( $settings['media_image']['id'], 'full' );
$image_width = $media_image[1];
$image_height = $media_image[2];
You have to use the method add_render_attribute to add this into the backbonejs part i.e. inside the _content_template:
$this->add_render_attribute( 'image', 'src', $settings['image']['url'] );
add_render_attribute for reference
Once you added the attribute you can access it in _content_template like this:
settings.image.url
settings.image.url for reference
Therefore, the thing you need to add is add_render_attribute method inside the method render to access in _content_template
Mainly focus on this particular snippet of content template method:
var image = {
id: settings.image.id,
url: settings.image.url,
size: settings.thumbnail_size,
dimension: settings.thumbnail_custom_dimension,
model: view.getEditModel()
};
var image_url = elementor.imagesManager.getImageUrl( image );
var imageHtml = '<img src="' + image_url + '" class="elementor-animation-' + settings.hover_animation + '" />';
I want show price * quantity in woocommerce single product page. Codes below is working but until quantity does not change shows NAN for price.
add_action( 'woocommerce_before_add_to_cart_button', 'woocommerce_total_product_variation_price' );
function woocommerce_total_product_variation_price() {
global $woocommerce, $product;
// setup base html... We are going to rewrite this with the standard selected variation
echo sprintf('<div id="product_total_price" style="margin-bottom:20px; display: block;">%s %s</div>',__(' price:','woocommerce'),'<span class="price">'.$product->get_price().'</span>');
?>
<script>
jQuery(function($){
var currency = currency = ' <?php echo get_woocommerce_currency_symbol(); ?>';
function priceformat() {
var product_total = parseFloat(jQuery('.woocommerce-variation-price .amount').text().replace(/ /g ,'').replace(/€/g ,'').replace(/,/g ,'.')) * parseFloat(jQuery('.qty').val());
var product_total2 = product_total.toFixed(3);
var product_total3 = product_total2.toString().replace(/\./g, ',');
jQuery('#product_total_price .price').html( product_total3 + ' ' + currency );
}
jQuery('[name=quantity]').change(function(){
priceformat();
});
jQuery('body').on('change','.variations select',function(){
priceformat();
});
priceformat();
});
</script>
<?php }
I'm using the following function for an excerpt in Wordpress.
<?php
// Excerpt - end of sentence
function custom_wp_trim_excerpt($text) {
$raw_excerpt = $text;
if ('' == $text) {
// Retrieve the post content.
$text = get_the_content('');
// Delete all shortcode tags from the content.
$text = strip_shortcodes($text);
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$allowed_tags = '<i>,<strong>';
$text = strip_tags($text, $allowed_tags);
$excerpt_word_count = 40;
$excerpt_length = apply_filters('excerpt_length', $excerpt_word_count);
$excerpt_end = '...' . '<div class="read-more"><a class="button" href="' . get_permalink($post->ID) . '">' . 'Read More' . '</a></div>';
$excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);
$words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
if (count($words) > $excerpt_length) {
array_pop($words);
$text = implode(' ', $words);
$text = $text . $excerpt_more;
}
else {
$text = implode(' ', $words);
}
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_wp_trim_excerpt');
I want to add a second word count to use on the blog page. The above word count is being used on the front page. Advice, please? Thanks.
Try this piece of code
function custom_wp_trim_excerpt($text) {
if ( is_front_page() || is_home() ) {
// Excerpt for front page or home page
} else {
// Excerpt for rest of the site
}
}
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_wp_trim_excerpt');
By using this piece of code you have more control over the excerpt that is outputted on different pages.
If that worked mark your question as solved.
Hello i have a website and a blog, i want to display my self hosted wordpress blog on my website.
I want to show only 3 post on my website.
I want to automatically check for any new post everytime when i reload my website, so that the recent three gets displayed only.
I want to show the complete title of my wordpress blogpost but specific letters of description.
Also the description should end up with a word not some piece of non-dictionary word ending with "..."
How this can be done, i have heard that it can be done through RSS.
Can somebody help me?
To accomplish this you need to read the RSS of the blog, from RSS you need to read the Title and the description, after reading the whole description and title you need to trim the description to your desired number of letters. After that you need to check weather the description last word has been completed or not and then you need to remove a the last word if not completed and put the "...".
First we will make a script to trim the description and to put "..." in last:-
<?php
global $text, $maxchar, $end;
function substrwords($text, $maxchar, $end='...') {
if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
}
else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
}
else {
$output = $text;
}
return $output;
}
Now we will define the variables in which we store the values:-
$xml=("http://your-blog-path/rss/");
global $item_title, $item_link, $item_description;
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$x=$xmlDoc->getElementsByTagName('item');
Now, we will make an array and store values in it. I am only taking 3 because you have asked it the way. You can change it to anything (The number of post you want to show, put that in the loop)
for ($i=0; $i<3; $i++)
{
$item_title[$i] = $x->item($i)->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
$item_link[$i] = $x->item($i)->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
$item_description[$i] = $x->item($i)->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;
}
?>
Now echo all these values, Link is the value where your user will click and he will be taken to your blog:-
FIRST RECENT POST:
<?php echo $item_title[0]; ?>
<?php echo substrwords($item_description[0],70); ?>
SECOND RECENT POST:
<?php echo $item_title[1]; ?>
<?php echo substrwords($item_description[1],70); ?>
THIRD RECENT POST:
<?php echo $item_title[2]; ?>
<?php echo substrwords($item_description[2],70); ?>
Hope this can solve your problem. By the way Nice question.
Click here for the original documentation on displaying RSS feeds with PHP.
Django Anonymous's substrwords function is being used to trim the description and to insert the ... at the end of the description if the it passes the $maxchar value.
Full Code:
blog.php
<?php
global $text, $maxchar, $end;
function substrwords($text, $maxchar, $end='...') {
if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
} else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
} else {
$output = $text;
}
return $output;
}
$rss = new DOMDocument();
$rss->load('http://wordpress.org/news/feed/'); // <-- Change feed to your site
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 3; // <-- Change the number of posts shown
for ($x=0; $x<$limit; $x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
$description = substrwords($description, 100);
$date = date('l F d, Y', strtotime($feed[$x]['date']));
echo '<p><strong>'.$title.'</strong><br />';
echo '<small><em>Posted on '.$date.'</em></small></p>';
echo '<p>'.$description.'</p>';
}
?>
You can easily put this in a separate PHP file (blog.php) and call it inside your actual page.
Example:
social.php
<h3>Latest blog post:</h3>
<?php require 'blog.php' ?>
Also, this code is plug-n-play friendly.
Why not use the Wordpress REST API to retrieve posts -
API URL is : https://public-api.wordpress.com/rest/v1/sites/$site/posts/
where $site is the site id of your wordpress blog
or else simply use this plugin -
http://www.codehandling.com/2013/07/wordpress-feeds-on-your-website-with.html