So I'm trying to achieve the following.
My code so far..
add_filter('wpseo_title', 'vehicle_listing_title');
function vehicle_listing_title( $title )
{
if ( get_post_type() == 'vehicles' )
{
$location = get_the_terms($post->ID, 'vehicle_location');
$model = get_the_terms($post->ID, 'vehicle_model');
$title = $model . 'used cars for sale in' . $location .'on'. get_bloginfo('name');
}
return $title;
}
This code results in $location & $model being an object containing the following term_id =>,name=>,slug=>,term_group=>,etc so I want to get the name part of it.
How do I do that?
What do I have to add to the code to still return the modified $title even when there aren't any posts assigned to the queried taxonomies?
Change your code to this:
add_filter('wpseo_title', 'vehicle_listing_title');
function vehicle_listing_title( $title )
{
if ( get_post_type() == 'vehicles' )
{
$location = get_the_terms($post->ID, 'vehicle_location');
$model = get_the_terms($post->ID, 'vehicle_model');
$title = '';
if($model && $model[0]) $title .= $model[0]->name . ' used';
else $title .= 'Used';
$title .= ' cars for sale';
if($location && $location[0]) $title .= ' in ' . $location[0]->name;
$title .= ' on ' . get_bloginfo('name');
return $title;
}
return $title;
}
Basically, you need to construct your title using IF's to check if the terms array could be obtained for the model and the location. Also, wp_terms() returns an array of term arrays, hence why you also need to obtain the first element of the result using a [0] index, and then chaining the ['name'] index to get the name of the term.
Related
I have constructed the below function to work in conjunction with a button displayed on the edit product page. It is designed to generate some description text based on the title and SKU of the product. The code works perfectly for 'simple' products, but I am struggling to get it to work for 'variable' products too.
What exactly do I need to do to get it to work correctly for both simple and variable products?
The current behaviour is:
When triggered on a simple product, it adds the new description or updates the old one to the new one.
When triggered on a variable product, it updates the main description, but deletes all variations which were previously set up on the product.
add_action('woocommerce_process_product_meta', 'update_and_save_utapd');
function update_and_save_utapd() {
if(isset($_POST['button_new_update_description'])){
$product_id = wc_get_product(get_the_ID());
$wcProduct = new WC_Product($product_id);
$get_title = $wcProduct->get_name();
$get_mpn = $wcProduct->get_meta('sp_wc_barcode_field');
$get_description = $wcProduct->get_description();
$output = '';
if(!empty($get_title)){
$output .= "<p>The " . $get_title;
}if(!empty($get_mpn)){
$output .= " (MPN: " . $get_mpn . ").";
}if(!empty($get_description)){
$wcProduct->set_description($output);
$wcProduct->save();
return "<div>SUCCESS: YOU HAVE UPDATED YOUR DESCRIPTION.</div>";
}elseif(empty($get_description)){
$wcProduct->set_description($output);
$wcProduct->save();
return "<div>SUCCESS: YOU HAVE GENERATED A NEW DESCRIPTION.</div>";
}
}
}
First when using action hooks in backend that save product data, you can't return a string (a text) as you are trying to do and anyway, it will never be displayed
Now since WooCommerce 3 you can use woocommerce_admin_process_product_object much better hook that include the WC_Product Object as function argument and there is no need to use save() method at the end of your code as once this hook is triggered the save() method is auto applied.
So we can simplify your code:
add_action('woocommerce_admin_process_product_object', 'update_and_save_utapd');
function update_and_save_utapd( $product ) {
if( isset($_POST['button_new_update_description']) ){
$name = $product->get_name();
$barcode = $product->get_meta('sp_wc_barcode_field');
$output = '';
if ( ! empty($name) ) {
$output .= "<p>The " . $name;
}
if ( ! empty($barcode) ) {
$output .= " (MPN: " . $barcode . ").";
}
$product->set_description( $output );
}
}
Code goes in functions.php file of the active child theme (or active theme). It should better work now, without throwing errors.
With the woocommerce_process_product_meta hook you already have the product id and the product object available. Here you will find more information.
To verify that the button has been clicked you must also check its value, in addition to the isset() function.
Replace value_button with the value of the element's value
attribute
add_action('woocommerce_process_product_meta', 'update_and_save_utapd', 10, 2 );
function update_and_save_utapd( $product_id, $product ) {
// replace "value_button" with the value of the element's "value" attribute
if ( isset( $_POST['button_new_update_description'] ) && $_POST['button_new_update_description'] == 'value_button' ) {
if ( $product->is_type('simple') || $product->is_type('variable') ) {
$title = $product->get_name();
$mpn = $product->get_meta('sp_wc_barcode_field');
$description = $product->get_description();
$output = '';
if ( ! empty($title) ) {
$output .= "<p>The " . $title;
}
if ( ! empty($mpn) ) {
$output .= " (MPN: " . $mpn . ").";
}
if ( ! empty($get_description) ) {
$product->set_description($output);
$product->save();
return "<div>SUCCESS: YOU HAVE UPDATED YOUR DESCRIPTION.</div>";
} else {
$product->set_description($output);
$product->save();
return "<div>SUCCESS: YOU HAVE GENERATED A NEW DESCRIPTION.</div>";
}
}
}
}
I would like to make a shortcode, that can be placed on category pages, for example on the sidebar.
It should display the category's best selling products.
The only solution that I find is if I specify the category, with slug or id, like below:
[best_selling_products category=”KITCHEN-ACCESSORIES” columns="1" per_page="5"]
How can I transform the shortcode to something like this?
[best_selling_products category=”CURRENT-CATEGORY” columns="1" per_page="5"]
Add this to your functions.php
function custom_best_selling_products( $attr = array() ){
$string = '[best_selling_products ';
$string .= ' category="' . get_query_var( 'term' ) . '" ';
if( $attr ){
foreach ( $attr as $key => $value ) {
$string .= ' ' . $key . '="' . $value . '" ';
}
}
$string .= ']';
return do_shortcode( $string );
}
add_shortcode( 'custom_best_selling_products', 'custom_best_selling_products' );
This will create a custom shortcode and you can use it like this: [custom_best_selling_products columns="1" per_page="5"]
This shortcode will automatically get the category
Add the follows code snippet in your active theme's functions.php to get best selling products from current $term or category page -
function modify_woocommerce_shortcode_products_query( $query_args, $attributes, $type ) {
if( $type != 'best_selling_products' ) return $query_args;
$term = get_queried_object();
if( $term ) {
if( !isset($query_args['category'] ) ){
$query_args['category'] = $term->slug;
}
}
return $query_args;
}
add_filter( 'woocommerce_shortcode_products_query', 'modify_woocommerce_shortcode_products_query', 99, 3 );
Add just use woocommerce default shortcode [best_selling_products columns="1" per_page="5"] to get the data.
I have a page called used-cars and I'm trying filter its title and display it as an H1 header. I have rewrite the permalink structure to pass double terms e.g example.com/used-cars/term1/term2 and it works like a charm
So at this point. I'm trying to filter the page title to match the URLs, but I just can't get it to work with this code
`add_filter( 'wp_title', 'new_listing_title', 10, 1 );
function new_listing_title($title)
{
if ( is_page('used-cars') && $id = get_queried_object_id() )
{
$locations = get_query_var('area');
$location = get_term_by('slug', $locations, 'area');
$models = get_query_var('serie');
$model = get_term_by('slug', $models, 'serie');
$title = '';
if($model && $model) $title .= $model->name . ' Used';
else $title .= 'Used';
$title .= ' Cars For Sale';
if($location && $location) $title .= ' In ' . $location->name;
return $title;
}
return $title;
}`
However when I use this. it works
global $wp_query;
echo 'Car : ' . $wp_query->query_vars['serie'];
echo '<br />';
echo 'Area : ' . $wp_query->query_vars['area'];
So how can I Incorporate these two solutions to filter the title of this page's title?
For anybody in search for this solution. This is how I finally resolved this problem.
I hooked into wpseo_title instead of wp_title which has been discontinued since Wordpress 4.4
Hope this helps.
I have created a custom column with a custom plugin.
I dont know if I can use the following to populate this column with a value from an xml.
//POPULATE COLUMN
add_action('manage_posts_custom_column', 'wnetpp_populate_custom_columns3', 10, 2);
function wnetpp_populate_custom_columns3( $column, $post_id ) {
if ($column == 'test_column3') {
$current_product = wc_get_product( $post_id );
$product_sku = $current_product->get_sku();
read_parse_xml($product_sku)
} }
and with a function like the following:
function read_parse_xml($product_sku)
{
$url = 'https://example.com/ProductsUpdates4.xml';
$xml = file_get_contents($url);
$xml = simplexml_load_string($xml);
foreach($xml as $x) {
$sku = $x->sku;
$bfsku = $x->bf_sku;
$suppliersku = $x->supplier_sku;
$price = $x->price;
$availability = $x->availability;
if($sku==$product_sku)
{
echo '<div id="_supprice-' . $post_id . '">' . $price . '</div>';
}
}
}
But nothing is working.
I get a blank page for products.
How I am supposed to check if xml has been accessed.
First I forgot to put a semicolumn ; after read_parse_xml($product_sku)
For each column I created a different read_parse_xml($product_sku) function called read_parse_xml1 2 3 etc.
and I used number_format to format my string to Number like
if($sku==$product_sku)
{
echo '<div id="_supprice-' . $post_id . '">' . number_format( (float)$price,2) . € . '</div>';
}
Even though I dont know if there is another proper way with less code to do it, it worked for me
I'm using this code to show only the first category of a post on my page template but I need to find a way to exclude some specific categories from it
$category = get_the_category(); echo $category[0]->cat_name;?
Example:
Let's say that I have a post on tree categories: "admin cat" and "admin cat2" and "item cat". If I use this function, the output will be:
This post is under "admin cat"!
and I need it to be:
This post is under "item cat"!
Is it possible to add an array of cats that will be omitted on the output to my code or should I be using other method?
Try this one: https://wordpress.org/support/topic/exclude-categories-from-the_category/
<?php the_excluded_category(array(1,328,338,339)); ?>
function the_excluded_category($excludedcats = array()){
$count = 0;
$categories = get_the_category();
foreach($categories as $category) {
$count++;
if ( !in_array($category->cat_ID, $excludedcats) ) {
echo '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "Cortos de %s" ), $category->name ) . '" ' . '>' . $category->name.'</a>';
if( $count != count($categories) ){
echo ", ";
}
}
}
}
Simply loop through your category array and match each item against an array of excluded categories. This will return the first non-matching category.
function getCategory() {
$categories = array('admin cat','admin cat2', 'item cat', 'some other cat', 'dog');
$excluded_categories = array('admin cat','admin cat2');
foreach($categories as $category) {
if (!in_array($category,$excluded_categories)) {
return $category;
}
}
return false;
}
echo getCategory();
// outputs 'item cat'
?>