Output product HTML in custom shortcode for WooCommerce - php

EDIT: I've simplified my code considerably to see if I can actually get HTML to ouput, but no luck.
Here is the simplified version, removing all my custom HTML and only adding <div class="test"></div> to see if I can get my shortcode to output HTML, which it does not.
//custom shortcodes
function product_snippet( $atts ) {
// Attributes
$atts = shortcode_atts(
array(
'id' => '',
'snippet' => '',
),
$atts,
'product_snippet'
);
return $product = wc_get_product($atts['id']);
return $product_img = $product->get_image();
return $product_title = $product->get_title();
return $product_link = get_permalink($atts['id']);
return $children = $product->get_children();
return $children_array = array();
echo "<div class='test'></div>";
}
add_shortcode( 'product_snippet', 'product_snippet' );
This stops the site from crashing, but not HTML is outputted.
ORIGINAL POST:
I am trying to write a custom shortcode so that my client will be more easily able to edit their website. I've added the following code to my WordPress's functions.php file and I can't determine why it isn't working.
The idea is to input a grouped product's ID into the short code, and it will pull up the product's Title, Image, and all child products.
function product_snippet( $atts ) {
$a = shortcode_atts( array (
'id',
'snippet',
), $atts);
$product = wc_get_product($a['id']);
$product_img = $product->get_image();
$product_title = $product->get_title();
$product_link = get_permalink($a['id']);
$children = $product->get_children();
//initialize array so that child products can be sorted by price.
$children_array = array();
//Assign each child product to its price in array so that child products can be sorted by price in HTML.
foreach ($children as $key => $value) {
$children_array[$value] = wc_get_product($value)->get_price();
};
asort($children_array);
return '<div class="main_pro">
<div class="left-sd">' . do_shortcode('[product id="' . $a['id'] . '"]') . '</div>
<div class="right-sd">
<div class="info">
<h2>'. $product_title . '</h2>
<p>' . $a['snippet'] . ' More Info >></p>
</div>
<ul>
' . foreach ($children_array as $key => $value) {
$option = wc_get_product($key);
$option_title = $option->post->post_title;
. '
<li>
<div id="outer-bar">
<div class="bar-l">
' . $option_title;
if ($option->get_attribute('pa_pack-size')) {
strval(wc_get_product($key)->get_attribute('pa_pack-size'));
.'<br/>
<span class="small_pz">
' . "$" . strval(round(($option->get_price() / intval($option->get_attribute('pa_pack-size'))), 2)) . " per tray - SAVE $" . strval(round(($product->get_price() * $option->get_price() - $option->get_price()), 2)); . '
</span>
' . }
. '</div>
<div class="bar-r">' . do_shortcode('[add_to_cart id="' . $key . '"]'); . '</div>
</div>
</li>
' . }
. ' </ul>
</div>
</div>';
};
add_shortcode( 'product_snippet', 'product_snippet' );
Assume I have my opening and closing <?php ?> tags. I don't write in PHP a lot so I apologize if my code is janky. If I can get this closer to best practices (I don't think my concatenation looks right) I'm open to feedback.

There was a bunch of errors in the code. Try this.
function product_snippet($atts)
{
$a = shortcode_atts(array(
'id',
'snippet',
), $atts);
$product = wc_get_product($a['id']);
$product_img = $product->get_image();
$product_title = $product->get_title();
$product_link = get_permalink($a['id']);
$children = $product->get_children();
//initialize array so that child products can be sorted by price.
$children_array = array();
//Assign each child product to its price in array so that child products can be sorted by price in HTML.
foreach ($children as $key => $value) {
$children_array[$value] = wc_get_product($value)->get_price();
};
asort($children_array);
$string = '<div class="main_pro">
<div class="left-sd">' . do_shortcode('[product id="' . $a['id'] . '"]') . '</div>
<div class="right-sd">
<div class="info">
<h2>' . $product_title . '</h2>
<p>' . $a['snippet'] . ' More Info >></p>
</div>
<ul>';
foreach ($children_array as $key => $value) {
$option = wc_get_product($key);
$option_title = $option->post->post_title;
$string .= '
<li>
<div id="outer-bar">
<div class="bar-l">
' . $option_title;
if ($option->get_attribute('pa_pack-size')) {
strval(wc_get_product($key)->get_attribute('pa_pack-size'));
$string .= '<br/>
<span class="small_pz">
' . "$" . strval(round(($option->get_price() / intval($option->get_attribute('pa_pack-size'))), 2)) . " per tray - SAVE $" . strval(round(($product->get_price() * $option->get_price() - $option->get_price()), 2)) .
'</span>';
}
$string .= '</div>
<div class="bar-r">' . do_shortcode('[add_to_cart id="' . $key . '"]') . '</div>
</div>
</li>
';
}
$string .= ' </ul>
</div>
</div>';
return $string;
}
add_shortcode('product_snippet', 'product_snippet');

I have changed a little your code to make it work. This is just an example that you can complete. Try it and let me know:
//custom shortcodes
if( !function_exists('product_snippet') ) {
function product_snippet( $atts ) {
// Attributes
extract( shortcode_atts(
array(
'id' => '', // You will use $id to get the value of this attribute
'snippet' => '' // You will use $snippet to get the value of this attribute
),
$atts
));
// Get an instance of the product object
$product = wc_get_product( $id );
// Displays go here
return '<div class="test">'.$product->get_image().''.$product->get_title().'</div>';
}
add_shortcode( 'product_snippet', 'product_snippet' );
}
You should get an html output this time …
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Related

shortcode get all posts [ showing post's categories issues ]

I try to do a shortcode to get all posts by following this link
My shortcode code put in child theme's functions.php file.:-
function myprefix_custom_grid_shortcode( $atts ) {
$atts = shortcode_atts( array(
'posts_per_page' => '-1',
'term' => '',
), $atts, 'myprefix_custom_grid' );
extract( $atts );
$output = '';
$query_args = array(
'post_type' => 'post', // Change this to the type of post you want to show
'posts_per_page' => $posts_per_page,
);
if ( $term ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'ID',
'terms' => $term,
),
);
}
// Query posts
$custom_query = new WP_Query( $query_args );
if ( $custom_query->have_posts() ) {
$output .= '<ul class="yj-trainingcamp-list clearfix">';
while ( $custom_query->have_posts() ) {
$custom_query->the_post();
$categories = get_the_category();
$separator = ' ';
$output_cats = '';
if($categories){
foreach($categories as $category) {
$output_cats .= ''.$category->cat_name.''.$separator;
}
}
$output .= '<li class="yj-trainingcamp-item">
<a href="' . get_permalink() . '" title="' . get_the_title() . '" class="trainingcamp-atom-wrap" target="_blank">
<div class="cover-img-zone">
<div class="el-image cover-img"><img src="' .get_the_post_thumbnail_url($post->ID, 'full'). '" alt="" class="el-image__inner" style="object-fit: cover;"></div></div><div class="infos"><div class="camp-info"><div class="camp-name"><span class="camp-num">第10期</span>' . get_the_title() . '</div>
<div class="nums"><div class="sale-count">' .get_the_excerpt(). ' ' . trim($output_cats, $separator) . ' </div>
</div>
</div>
<div class="teacher-info">
<div class="teacher-img-zone">
<div class="el-image teacher-img">' . get_avatar( get_the_author_meta('user_email') , 32 ) . '
</div>
</div>
<div class="teacher-name">作者: ' .get_the_author(). ' | ' .get_the_modified_time('M j, Y'). '</div>
</div>
</div>
</a>
</li>';
}
$output .= '</ul>';
wp_reset_postdata();
}
return $output;
}
add_shortcode( 'myprefix_custom_grid', 'myprefix_custom_grid_shortcode' );
Here's the issue showing multiple div
wanna display post's categories'name and categories'link ( foreach ) in each post but doesn't works...
Below is the part I doubt...
$categories = get_the_category();
$separator = ' ';
$output_cats = '';
if($categories){
foreach($categories as $category) {
$output_cats .= ''.$category->cat_name.''.$separator;
}
}
not really sure right now, because I cannot debug it and I am not able to read the text on the picture but as described in the wordpress the documentation, you can set the post id for the function:
get_the_category( int $id = false )
A small example from the page:
Get the Post Categories From Outside the Loop
Therefore, I would suggest, that you can add the post ID to get_the_category like this:
$categories = get_the_category(get_the_ID());
$separator = ' ';
$output_cats = '';
if($categories){
foreach($categories as $category) {
$output_cats .= ''.$category->cat_name.''.$separator;
}
}
Otherwise, I guess, the foreach loop adds all categories (name and links) to each post because you are interating over all published categories.

Wordpress shortcode shows as plain text in one view, works in other

I have this complex loop:
<?php
$args = array(
'cat' => 54,
'order' => 'ASC',
'posts_per_page' => -1
);
$query = new WP_Query($args);
$q = array();
while ( $query->have_posts() ) {
$query->the_post();
$a = '<h2>' . get_the_title() .'</h2>'
. get_the_post_thumbnail() .
'<p>' . get_the_content("...plačiau") . '</p>';
$categories = get_the_category();
foreach ( $categories as $key=>$category ) {
$b = '<h1 class="thetitle">' . $category->name . '<span>Išskleisti <i class="fa fa-arrow-circle-down"></i></span></h1>';
}
$q[$b][] = $a; // Create an array with the category names and post titles
}
/* Restore original Post Data */
wp_reset_postdata();
foreach ($q as $key=>$values) {
echo $key;
echo '<div class="straipsniai">';
foreach ($values as $value){
if (count($values) == 1) {
echo '<div class="vienas">' . $value . '</div>';
} else if (count($values) == 2) {
echo '<div class="du">' . $value . '</div>';
} else if (count($values) == 3) {
echo '<div class="trys">' . $value . '</div>';
} else {
echo '<div>' . $value . '</div>';
}
}
echo '</div>';
}
?>
Which worked for me, gave me this nice list/accordion:
http://bruzienesklinika.lt/web/gydytojai/
Now, each person in the category has some articles as posts and I want a list of their articles under their description. (basic Title + exerpt + read more link)
I've tried to do this by using "List category posts" plugin which allows me to use [catlist id=24] shortcode, but the problem is that browser prints it as plain text, source shows [catlist id=24](You can open the most bottom "GYDYTOJA REUMATOLOGĖ" tab to see that). The shortcode does work inside page, which is rendered by single.php, but it does not show when rendered in the loop I gave you in the beginning of the question.
SO, the question is, how do I make the shortcode work in the initial list, where all the categories are listed with posts inside the accordion.
Now it is not the problem of this certain plugin because no shortcodes work in that accordion list.
Or maybe you have an idea how to do this the other way?

wordpress : how to add commas between meta terms on single custom post type

extendeing may last question about how to change the display of meta on single custom post type, with a great thanks to TimRDD for his helpful answer, now i have another question.
the working generating code
<?php
//get all taxonomies and terms for this post (uses post's post_type)
foreach ( (array) get_object_taxonomies($post->post_type) as $taxonomy ) {
$object_terms = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'all'));
if ($object_terms) {
echo '- '.$taxonomy;
foreach ($object_terms as $term) {
echo '<a href="' . esc_attr(get_term_link($term, $taxonomy)) . '" title="' . sprintf( __( "View all posts in %s" ), $term->name ) . '" ' . '>' . $term->name.'</a> ';
}
}
}
}
?>
displays the terms in a single row but without commas between them such as :
(- Proceeding2015 - keywordsbusinessconsumerresearch).
I need your help please to put (:) after every set of terms and commas between terms to display them such as :
(- proceeding : 2015 - keywords : business, consumer, research).
You're code is ok, you just need to modify the output a bit. Try this code:
//get all taxonomies and terms for this post (uses post's post_type)
foreach ((array) get_object_taxonomies($post->post_type) as $taxonomy) {
$object_terms = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'all'));
if ($object_terms) {
echo ': (- ' . $taxonomy . ': ';// I modify the output a bit.
$res = '';
foreach ($object_terms as $term) {
$res .= '<a href="' . esc_attr(get_term_link($term, $taxonomy)) . '" title="' . sprintf(__("View all posts in %s"), $term->name) . '" ' . '>' . $term->name . '</a>, ';
}
echo rtrim($res,' ,').')';// I remove the last trailing comma and space and add a ')'
}
}
Hope it works.
I've not tested this code, but I have linted it. Based on your description, this should do it.
<?php
//get all taxonomies and terms for this post (uses post's post_type)
I moved this out of the fornext.
$taxonomies = get_object_taxonomies($post->post_type);
foreach ( $taxonomies as $taxonomy ) {
I moved this into an if statement. If the assignment fails (nothing is returned) it should fail the if and skip all of this.
if ($object_terms = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'all'))) {
$holding = array();
foreach ($object_terms as $term) {
Instead of outputting it immediately, I am building an array.
$holding[] = '<a href="' . esc_attr(get_term_link($term, $taxonomy)) . '" title="' . sprintf( __( "View all posts in %s" ), $term->name ) . '" ' . '>' . $term->name.'</a> ';
} // foreach ($object_terms as $term)
Here is where we do that output. I'm using the explode() function. This will output each element of the array and put a ', ' after all of them except for the last one.
echo '- '.$taxonomy . ': ' .explode(', ',$holding) . ' ';
} // if ($object_terms)
} // foreach ( $taxonomies as $taxonomy )
?>
I do hope I got it right.
Cheers!
=C=

Highlight menu item depending on current page

I'm trying to highlight a menu item depending if it's on the current page. The code below is currently highlighting every menu item because it's within the foreach loop. How can I highlight the taxonomy term if it's on a certain page id and ONLY that term (not every one)?
<?php $args = array( 'taxonomy' => 'blog' );
$terms = get_terms('blog', $args);
$count = count($terms); $i=0;
if ($count > 0) {
$cape_list = '<p class="my_term-archive">';
echo $postid;
foreach ($terms as $term) {
$i++;
$absolute = get_bloginfo('url');
$postid = get_the_ID();
if($postid == "561") {
$term_list .= '<a class="menu-active" style="padding-left:30px;width:88%!IMPORTANT;" href="' . $absolute . '/blog/' . $term->slug . '" title="' . sprintf(__('View all post filed under %s', 'my_localization_domain'), $term->name) . '">' . $term->name . '</a>';
} else {
$term_list .= '<a style="padding-left:30px;width:88%!IMPORTANT;" href="' . $absolute . '/blog/' . $term->slug . '" title="' . sprintf(__('View all post filed under %s', 'my_localization_domain'), $term->name) . '">' . $term->name . '</a>';
} } ?>
<?php echo $term_list; } ?>
You will have to query the taxonomy terms belonging to the current page and compare their id-s in the foreach loop.
The get_the_ID() function returns the id of the current post, not the current taxonomy.
Here is a link to a wordpress related question which shows how you can query current taxonomy terms:
https://wordpress.stackexchange.com/questions/20431/how-to-get-taxonomy-term-of-the-current-page-and-populate-queries-in-the-templat

get_category_link() is returning nothing

I am using the get_categories() function to manually create myself a nav menu. I have a custom taxonomy I'm using called Category and I'm trying to return the link for it for my tags in the menu using the get_category_link() function.
foreach ($categories as $category) {
if ($category->parent == 0) { //Check to see it is a parent
$output .= '<li>';
$output .= '' . $category->name . ''; //display parent taxonomy category
}
}
But it always returns <a href="">. I can echo out the $category->cat_ID successfully so I know it is passing the ID into the function but I don't know why it's returning blank.
Am I missing something? Is it because these are custom taxonomies? They have slugs.
You need something like this for custom taxonomies:
$tax = 'cars';
$cats = get_terms( $tax, '' );
if ($cats) {
foreach($cats as $cat) {
$output .= "<li>";
$output .= '<a href="' . esc_attr(get_term_link($cat, $tax)) . '" title="' . sprintf( __( "View all posts in %s" ), $cat->name ) . '" ' . '>' . $cat->name.'</a>';
$output .= "</li>";
}
}
Although you can easily add to the top of the script to get an array of all taxonomies to feed in if you wanted.

Categories