I want to add a product's size attribute to the product information shown by the Woocommerce [product] shortcode.
Is there a way to do this? I don't think it is a standard parameter to the shortcode so am assuming the code will need amending?
You could either unregister and re-register your own version of the shortcode OR the [product] shortcode displays content via
<?php wc_get_template_part( 'content', 'product' ); ?>
Therefore you can customize the the content-product.php template in your own theme via template overrides or via hooks/filters. (The content-product.php template is mostly just a few action hooks so it looks a little sparse if you aren't familiar with hooks.)
I would probably go the hooks route. Assuming your attribute is called "pa_size" (WooCommerce always prefaces the attribute with "pa_" so it know that the taxonomy is a "product attribute") I would add the following to my theme's functions.php
function kia_add_size_attr(){
global $product;
$attribute_name = "pa_size";
$results = wc_get_product_terms( $product->id, $attribute_name, array('fields' => 'names') );
if ( $results ) {
echo '<label>' . wc_attribute_label($attribute_name) . ': </label>' . implode( ', ', $results );
}
}
add_action('woocommerce_after_shop_loop_item_title', 'kia_add_size_attr' );
Do keep in mind that this will add the attribute to every "loop" product with a size attribute. If you only want to apply it to the shortcode, then you probably need to write your own shortcode.
Related
I'm trying to show an Advanced Custom Fields repeater in custom order in a Timber/Twig based WordPress theme. Is it possible to install the array-extension (http://twig-extensions.readthedocs.io/en/latest/array.html) to achieve this or how can it be done? I'm completely lost at the moment and would appreciate any ideas on how to solve it.
I wouldn't use a twig extension.
Why not something like this:
$rows = get_field( 'repeater_field' );
if( $rows ) {
shuffle( $rows );
foreach( $rows as $row ) {
// your code
}
}
In your php file (index.php, page.php etc.)
// Create context
$context = Timber::get_context();
// Get Field
$repeat = get_field('my_repeater_field');
// Shuffle it
shuffle($repeat);
// Add it to context
$context['repeat'] = $repeat;
And then call it in your twig file as your normally would
Using Timber, you can also do this with the Twig sort filter:
{% for item in items|sort(rand) %}
https://twig.symfony.com/doc/2.x/filters/sort.html
I want to override the item listing template file core/themes/classy/templates/dataset/item-list.html.twig for listing the fields field_slider_images as well as field_blog_tags respectively of their's multiple values of the field.
I have selected "Unordered List" in the view.
Please do check the attached image.
I have created following files :
item-list--field-blog-tags.html.twig
item-list--field-slider-images.html.twig
But, this is not rendered for the listing of the fields.
When I have created item-list.html.twig then only it will access.
However, both fields have different data to style and I am not able to get the current field name which is loading it's data in item-list.html.twig.
Had a brief look at this and it doesn't seem that 'item-list' to have suggestions, which is quite unfortunate.
In this situation there are two options:
Create your own suggestion which would accomplish exactly what you need.
You'll have to do something like this:
/
/*add new variable to theme with suggestion name*/
function hook_theme_registry_alter(&$theme_registry) {
$theme_registry['item_list']['variables']['suggestion'] = '';
}
//send a value to newly added variable to use it build the suggestion
function hook_ENTITY_TYPE_view(array &$build, $entity, $display, $view_mode) {
//add condition here if field exists or whatever, do the same for other field
$build['field_slider_images']['#suggestion'] = 'field_slider_images';
}
//use newly added variable to build suggestion
function hook_theme_suggestions_THEME_HOOK(array $variables) {//THEME_HOOK=item_list
$suggestions = array();
if(isset($variables['suggestion'])){
$suggestions[] = 'item_list__' . $variables['suggestion'];
}
return $suggestions;
}
Now you should be able to use item-list--field-slider-images.html.twig
Second option is to do what others in core did: use a new theme
function hook_ENTITY_TYPE_view(array &$build, $entity, $display, $view_mode) {
//add condition here if field exists or whatever, do the same for other field
$build['field_slider_images']['#theme'] = array(
'item_list',
'item_list__field_slider_images',
);
}
In Woocommerce you can add global product attributes and terms. So for instance:
Size (attribute)
small (term)
medium (term)
large (term)
This is product independent. You can then select from the pre defined attributes on a product.
I need to get all of the terms in an attribute with php. So select the attribute required, eg size, and then return an array including [small,medium,large].
Seems simple enough but I can't find any help on doing this.
Slightly confusing, especially when looking through the WooCommerce Docs since there is absolutely no mention of getting a list of the terms/attributes.
The Attributes are saved as a custom taxonomy, and the terms are taxonomy terms. That means you can use native Wordpress functions: Wordpress get_terms() Function Reference
By clicking on an attribute in WooCommerce, you can look in the URL and you can see they are all prepended with 'pa_'
This is likely what you need:
$terms = get_terms("pa_size");
foreach ( $terms as $term ) {
echo "<option>" . $term->name . "</option>";
}
I wanted to be able to get all the different attributes from the backend that were set, and get them in an array for me to work with, I took some code from the class-wc-admin-attributes.php file and modified it for my needs:
<?php
$attribute_taxonomies = wc_get_attribute_taxonomies();
$taxonomy_terms = array();
if ($attribute_taxonomies) :
foreach ($attribute_taxonomies as $tax) :
if (taxonomy_exists(wc_attribute_taxonomy_name($tax->attribute_name))) :
$taxonomy_terms[$tax->attribute_name] = get_terms(wc_attribute_taxonomy_name($tax->attribute_name), 'orderby=name&hide_empty=0');
endif;
endforeach;
endif;
var_dump($taxonomy_terms);
exit;
This will loop through all the attribute taxonomies, retrieve the terms for each, leaving you with an array of term objects to work with for each taxonomy.
Since 4.5.0, taxonomies should be passed via the ‘taxonomy’ argument in the $args array:
$terms = get_terms( array(
'taxonomy' => 'pa_taxonyname',
'hide_empty' => false,
) );
For example, if the taxonomy slug is 'date', so the taxonomy will be 'pa_date'.
You can also mouse over the attribute name and see the taxonomy name at the bottom of the browser.
I hope it helps!
I use this:
echo '<h1>variations</h1>';
mario( $product->get_available_variations());
echo '<h1>Atributos</h1>';
mario($product->get_attributes());
echo '<h1>Poste Terms</h1>';
mario(wp_get_post_terms( $post->ID, 'pa_color'));
function mario($texto){
echo '<pre>';var_dump($texto);echo '</pre>';
};
Really with: "wp_get_post_terms( $post->ID, 'pa_color')" i search only one term, but the idea is to loop for the key ['name'] that return that function.
Get all attributes with attribute terms in woocommerce.
$attributes = wc_get_attribute_taxonomies();
foreach ($attributes as $attribute) {
$attribute->attribute_terms = get_terms(array(
'taxonomy' => 'pa_'.$attribute->attribute_name,
'hide_empty' => false,
));
}
Using the admin panel on Orchard CMS I've created the following:
A content type called CalendarEvent, it contains several fields including the EventDate;
A query that has 2 filters, one by the content type (= CalendarEvent) and another one based on the date of the event. The Display Mode on the Layout is set to Properties;
A projection to display the query when a menu item is clicked.
The problem is that based on the EventDate we only display upcoming events, not the ones in the past. If for some reason there are no events to be displayed, all the user gets is an empty page with no information whatsoever.
My question is, how can I modify my query or projection in order to display something like: "There are no current events scheduled"?
I know the Properties on the Query's Layout allow me to specify a "No Result", but this implies that a record is present and that the actual property is empty. However, in my example, no record is present.
Thank you all in advance.
Rafael
By the way, I am using the latest Orchard version 1.6.
What I have done is to create a shape and use it as a view in my query. The shape will then have an if statement to check if the query return gives any results.
Example:
#using Orchard.ContentManagement
#using Orchard.Utility.Extensions
#{
var dealsTerms = ((IEnumerable<ContentItem>)Model.ContentItems).ToList();
}
#if (dealsTerms.Any() )
{
<div>
#foreach (var dealTerm in dealsTerms)
{
var contentManager = dealTerm.ContentManager;
<div>
#Display(contentManager.BuildDisplay(dealTerm, "Summary"))
</div>
}
</div>
}
else
{
<p>No deals found</p>
}
I used this article as reference:
http://www.ideliverable.com/blog/ways-to-render-lists-of-things
Good luck
If your projections are Layouts elements, you can create a Projection.cshtml file in your theme's Views/Elements folder with the following:
#{
var list = Model.List;
var pager = Model.Pager;
if (list != null)
{
#Display(list)
if (list.Items.Count == 0)
{
<div>There are currently no items.</div>
}
}
if (pager != null)
{
#Display(pager)
}
}
This is a copy of the default template with the if (list.Items.Count == 0) section added. Edit as needed.
i have a page tweety which contains a single form where a user enters a word in a textbox and in on pressing search the tweets corresponding to that word are displayed.
I want to use hook_nodeapi to add these tweets but i want those things only on a specific url not all the page(or any node type).
I ll use hook_menu to make that page and display the form for the search. What should i do after that. I knw the twiiter api to fetch the tweets so that is not a issue.
I think what you're attempting to do is have the tweets load on a predetermined page by passing the posted information to the page, is that correct?
There's a couple ways I think you could accomplish this - easiest, and not requiring any complex ahah scripting would be to take the word they enter and generate a path which you could then use to make the page in question.
Make a menu Item:
function mymodule_menu() {
$items = array();
$items['mymodule/tweets/%'] = array(
'title' => t('Tweets about' . check_plain(array(2))),
'page callback' => 'mymodule_tweet_display',
'page arguments' => array(2) // This is the 3rd argument in the path, the %
);
}
In your form, you'll need to send the user to this path so add to your hook_submit function:
$tweet_topic = $form_state['values']['your-field-name-here'];
drupal_goto('mymodule/tweets/' . $tweet_topic);
Now add your page module, this is where you can use the twitter api:
function mymodule_tweet_display($tweet_topic) {
$tweet_topic = check_plain($tweet_topic);
// Use this variable in your Twitter API call
// ...
// Make sure you assign your display content to the page by returning a variable
return $page;
}