Woocommerce get parent slug / name on single-product.php - woocommerce

I know that people have asked before on here regarding woocommerce and getting the parent category. I've done quite a bit of research through Stack Overflow, and seen quite a lot of answers that don't fit the simplicity of what I'm trying to achieve.
Basically I have my single-product.php page, and we have a site that requires different headers / footer and design based on what category a product belongs in.
To achieve this we just need to access the name of the parent category so we can dictate what header / footer it should load.
I did find this on wordpress.stackexchange, but it's too complex for my needs, so I tried stripping some of the code out and placing directly in the single-product.php page like this:
global $post;
$descendant = get_the_terms( $post->ID, 'product_cat' );
$descendant = array_reverse($descendant);
$descendant = $descendant[0];
$descendant_id = $descendant->term_id;
$ancestors = array_reverse(get_ancestors($descendant_id, 'product_cat'));
$ac = count($ancestors);
$c = 1;
$origin_ancestor_term = get_term_by("id", $ancestors[0], "product_cat");
$origin_ancestor_term->name;
$headername = $origin_ancestor_term->name;
if ($headername == 'Events') {
$productparentcat = 'events';
} else {
$productparentcat = 'adventures';
}
get_header($productparentcat);
Strangely this did seem to work on my local version until I updated the version of wordpress and then it broke. I also get the following errors now:
Notice: Undefined offset: 0 (for $c = 1;)
Notice: Trying to get property of non-object (for the $origin_ancestor_term->name;)
Does anyone know an easy way to just retrieve the parent category name on the single-product template? I've looked a lot of standard wordpress functions to achieve this, but they don't work with woocommerce templates, I guess because they use a custom taxonomy...
Thank you!

After further researching the problem, I realised the answer was ridiculously simple and that the main issue was I was looking for a solution in the wrong place.
I'd become fixated with the idea of finding the products' category parent ID / name, but in fact all the products on the site were included under both child and parent categories.
So for example, a product called "Fiesta Special Edition" was under both "Fiesta" and "Ford", so if I had tried to search for a parent for the category "Fiesta" using the product ID it didn't work, since it was looking for a parent for "Ford" as well and that was the top most level category.
This was what caused my Error regarding "Notice: Undefined offset: 0 (for $c = 1;)".
In the end I used this:
if ( has_term('Ford', 'product_cat', null) ) {
get_header('ford');
} else {
get_header('other-makes');
}
$carclass = '';
if(has_term('Ford', 'product_cat', $post)) {
$carclass = 'ford';
} else {
$carclass = 'other-cars';
}
That allowed me to style the page and pull in the right header depending on if a specific category was ticked.

Related

Filter by Attribute not filtering on shop page

I’ve developed a new theme for a website, but i seem to have a problem related to widget Filter By Attribute.
When i use the filter, that comes with the gutenberg block editor for widgets, the filter attribute widget doesn’t filter anything. (i guess it uses ajax to filter, but its not filtering anything)
When i use the add_filter('use_widgets_block_editor', '__return_false'); to remove the gutenberg and use a new filter by attribute (which is a different widget, than the one that comes with Gutenberg), the widget works, because it filters the query by passing some params on the url, but has a problem. It shows variations that are out of stock, which is something that have been fixed with the new widget, using the product lookup tables, and it's exactly what i'm trying to achieve here.
I strongly believe this is related to the AJAX call it uses to filter the shop page, so i guess i'm missing an ID or Class, to the product wrapper or something.
Does anyone also had this problem?
If you want to see the page in question, is this one https://www.hiima-store.com/bch/shop/
When you go into Filters, you can see both widgets there. (there are two for sizes. the first one uses query params and the second one, is the one that is not filtering).
I did a custom script regarding that.
It might help someone with the same problem.
It will hide the product if the variation is out of stock.
add_action('woocommerce_before_shop_loop_item_title', 'out_of_stock_variations_loop');
function out_of_stock_variations_loop()
{
global $product;
if (isset($_GET["filter_size"])) { // check if the attribute is in the url
if ($product->product_type == 'variable') {
$available = $product->get_available_variations();
if ($available) foreach ($available as $instockvar) {
if (isset($instockvar['attributes']['attribute_pa_' . __('size', 'hiima')])) {
var_dump('entrei');
if (($instockvar['attributes']['attribute_pa_.' . __('size', 'hiima')] == $_GET['filter_size']) && (!$instockvar['max_qty'] > 0)) {
global $product;
$id = $product->get_id();
echo "<style>.post-$id{display: none}</style>";
}
}
}
}
if (!$product->is_in_stock()) {
global $product;
$id = $product->get_id();
echo "<style>.post-$id{display: none}</style>";
}
}
}

Wordpress : Create breadcrumb style link using get_post_type_archive_link

I am trying to create a breadcrumb style link back to the archive/feed page for each of my custom post types, for a magazine style website, preferably without having to make a separate template for each post type as there are a few. (I'm also hoping to be able to use the same breadcrumb style link on my main feed in a featured posts kind of way. EG above each H1 of each featured post, so that if somebody clicked fashion instead of the H1 it would take them through to that archive page, as another way of browsing the site as opposed to having to use the top level menu nav.)
Using the following:
$postType = get_post_type_object(get_post_type());
if ($postType) { echo ''; echo esc_html($postType->labels->name); echo ''; }
the_title('', '');
Stackoverflow has stripped the HTML parts from the above code, not sure what I'm doing wrong there
It is correctly pulling and displaying the name of the post type, eg 'Fashion', however the link returned is for the current post, not the feed page.
has_archive and hierarchical are both set to true when creating post type and I've updated permalinks. Anybody have a solution?
So I had a related problem while back and because I despise plugins I decided to make my own breadcrumb.
Instead of going full on php, I went the js road. The breadcrumb is automatically generated based on the user current url. Which is way more efficient than building it the other way around.
Container to add to your theme, wherever:
<ol id="bread"></ol>
Script to enqueue:
var pathname = location.pathname;
if (((bread = []), pathname.endsWith("/"))) var crumbs = pathname.split("/").slice(1, -1);
else crumbs = pathname.split("/").slice(1);
for (crumb = 0; crumb < crumbs.length; crumb++) {
var url = location.href.split(crumbs[crumb])[0];
if (crumbs[crumb].length > 35) var short = crumbs[crumb].replace(/-/g, " ").substring(0, 35) + "[...]";
else short = crumbs[crumb].replace(/-/g, " ");
bread.push('<li style="display:inline;padding:0 5px;">' + short + "</li>");
}
(document.getElementById("bread").innerHTML = bread.join(">")),
(document.getElementById("bread").lastChild.style.pointerEvents = "none"),
(document.getElementById("bread").lastChild.firstElementChild.style.textDecoration = "none"),
(document.getElementById("bread").lastChild.firstElementChild.style.color = "inherit");
The breadcrumb is unstyled beside display:inline;padding:0 5px; which display the list inline and can be easily modified.
You could probably also achieve the same behaviour in php.
The way I achieved with PHP was
$postType = get_post_type_object(get_post_type());
if($postType) {
esc_html($postType->labels->link); echo esc_html($postType->labels->name);
}
I created an extra label within custom post types replicating the slug in order to spit out the URL correctly. I'm not sure why, but when I tried to echo the slug this way I got a critical error.
When originally searching for the answer I found quite a few posts about this, so while I'm not sure its the perfect solution to this problem, I hope this is helpful for anybody else looking.

How to hide a content on WordPress after receiving a certain number of views

How can I hide content in a post or page after it has received a certain amount of views I have set using a shortcode in WordPress?
Let's say I make a post. I enclose some content in the shortcode. I set the content to be shown for just 500 views. Then once the post reaches 500 views, the content should disappear from the post or page.
I have tried so many other plugins but couldn't find any solutions to this. wp-limit-post-views plugin also didn't solve my problem. I need help on this.
You could try something like that:
function hide_contents_function($atts, $content) {
$attributes = shortcode_atts(
array(
'count' => 500
),
$atts
);
// Get the max counts for the current post from the DB.
// You could use either an options if the counter is global, or the post meta.
// For this example I am using options, but it's up to you the implementation
$total_count = get_option('total_count', 0);
// Alternative way using post meta to get the counter per page/post
$total_count = get_post_meta(get_the_ID(), 'post_view_count', true);
if ( ! $total_count ) {
$total_count = 0;
}
// If the count loaded from the DB is bigger than the count
// property value then return nothing.
if ( $total_count > (int)$attributes['count'] ) {
return '';
}
return do_shortcode($content);
}
add_shortcode('hide_contents', 'hide_contents_function');
The above code, will register a short code that accepts an attribute allowing you to control how many views you want to have before you hide the contents.
In this example I used a single value from options table, but you are free to use any method you like to count the total views of a single post.
To use this short code you can do something like that:
[hide_contents count="345"]I will be hidden after 345 views.[/hide_contents]
Note that if you have installed any cache system, your content will not be hidden if the page is cached! That's not a problem of the short code, but the problem will occur because of the cache.
Finally, remember to update the counter of the views on each post refresh :)

Wordpress - Portfolio - Changing Title Length?

I've Googled my fingers off but just can't find the solution! I'm using a Wordpress Child Theme (on top of Cherry) and simply want to change the length of the Title used and displayed in the Portfolio. It is the default portfolio, not a plug in.
Unfortunately I'm not allowed to provide links due to confidentiality! Any help appreciated.
Neil.
EDIT - Well I'm not a developer so apologies for my clear lack of detail. I don't know which part of functions.php controls this post. I can see it loads theme-portfoliometa.php which has what looks like some likely code but I can't read it well enough to know what's what.
I can manage CSS/HTML but not php. I can provide a link via PM if anyone has the patience to help.
So far, I inserted a php script I found on another post into my-functions.php (child theme) but that changed the excerpt length of the news (posts). I've tried looking for '35' in all php files also which is the current limit.
$the_title = esc_attr ( the_title_attribute ( 'echo=0' ) );
$max_length = 50;
$title_length = strlen ( $the_title );
if ( $title_length > $max_length ) {
$title_excerpt = substr ( $the_title, 0, $max_length ) . '...';
} else {
$title_excerpt = $the_title;
}
This will truncate the title to 50 characters if it is larger and append ...
If the title is <= 50 characters it will just display as normal.

Why isn't $vars['node'] available in preprocess_page for some content types?

I am currently using drupal 6 for a site I'm working on. I have a MYTHEME_preprocess_page() function that adds a few variables to the page.tpl.php template from the taxonomy and from a cck field. It was working correctly for a bit, and then the $vars['node'] is empty, but only for 2 content types. The 'node' variable is available to the preprocess_page function in other content types.
I thought it was a problem with using the following code, but when I remove all of this, the 'node' variable is still empty.
function mytheme_preprocess_node(&$vars, $hook) {
$function = 'mytheme_preprocess_node'.'_'. $vars['node']->type;
if (function_exists($function)) {
$function(&$vars);
}
}
Does anyone know of any gotchas or bugs that might be removing the 'node' variable? I can't seem to figure out where I'm going wrong. I'm at a loss.
Here is my complete mytheme_preprocess_page() function.
function mytheme_preprocess_page(&$vars, $hook) {
if ($hook == 'node' || $hook == 'page') {
if (is_object($vars['node'])) {
// grab the header image if it exists to make it avaialble to the content header
$vars['header_image'] = _mytheme_get_header_image($vars);
// get the taxonomy term to put in the content header
if (count($vars['node']->taxonomy) > 0) {
$vars['tax_term'] = "<div class=\"terms\">" . _mytheme_get_first_taxonomy_term($vars['node']->taxonomy) . "</div>";
}
// add the teacher's credentials to the content header
if ($vars['node']->field_credentials[0]['view'] != '') {
$vars['teacher_credentials'] = '<span class="teacher-creds">' . $vars['node']->field_credentials[0]['view'] . '</span>';
}
}
}
}
After going through and disabling modules one-by-one, I determined that the problem is related to the module, node_breadcrumb. A similar issue was filed here: http://drupal.org/node/616100#comment-2199374
In the 3rd comment, you'll see a link to another issue with a resolution
For others that run into this, I had the same issue as a result of using the jQuery UI module. Disabling and re-enabling fixed it, and I could not track down the specific issue, but it appeared to be related to $static variables in some path check functions.
To others that stumble their way into here, I suggest you pull some of the more obvious modules right out of the module folder on your dev setup, see if things change, and then put them back in there until you figure it out.
Another option is to search for instances of _preprocess_page(, $variables['node'] and $vars['node'] to see if some contributed code is unwittingly unsetting a node when it shouldn't be.

Resources