I've written two functions to show custom fields on the shop pages below each product, which can be viewed here. The ones specifically are Light Bulb Type and Coverage Area. However, these only apply to certain products. Right now, I am typing in N/A when they don't apply, but I would like to write a conditional statement to hide the entire section if the field is left empty.
Unfortunately, every time I do so, the code breaks the site because it is incorrectly written.
These are the functions I've written to show the custom fields.
add_action('woocommerce_shop_loop_item_title','show_coverage');
function show_coverage() {
echo '<span class="extra-info-head">Coverage Area:</span> ';
$coverage = get_post_meta( $post->ID );
$custom_fields = get_post_custom();
$coverage = $custom_fields['wpcf-coverage-area'];
foreach ( $coverage as $key => $value ) {
echo $value . '<br/>';
}}
add_action('woocommerce_shop_loop_item_title','show_bulbs');
function show_bulbs() {
echo '<span class="extra-info-head">Light Bulbs:</span> ';
$custom_fields = get_post_custom();
$bulbs = $custom_fields['wpcf-light-bulbs'];
foreach ( $bulbs as $key => $value ) {
echo $value;
}}
Apologies if these are poorly written and much appreciation to any suggestions and help!
*UPDATE: This was solved with a combination of the answer below and back-end options on WordPress's custom field posts.
Unfortunately, every time I do so, the code breaks the site because it is incorrectly written.
Your site is erroring out because you have an "undeclared variable."
In the callback function show_coverage(), you are using an undefined variable $post. The function doesn't know about this variable, because you haven't brought it into the function' scope.
While you could include the global $post, it's better to use the API function instead of the global variable.
$coverage = get_post_meta( get_the_ID(), 'wpcf-coverage-area' );
Let's go one step further. What if the custom metadata doesn't exist in the database? Then $coverage is not going to have anything in it. Let's protect for that by checking and then bailing out if nothing is returned.
function show_coverage() {
$coverage = get_post_meta( get_the_ID(), 'wpcf-coverage-area' );
if ( ! $coverage ) {
return;
}
echo '<span class="extra-info-head">Coverage Area:</span>';
foreach ( $coverage as $key => $value ) {
echo $value . '<br/>';
}
}
Now, let's do the same treatment to the other callback function:
function show_bulbs() {
$bulbs = get_post_meta( get_the_ID(), 'wpcf-light-bulbs' );
if ( ! $bulbs ) {
return;
}
echo '<span class="extra-info-head">Light Bulbs:</span> ';
foreach ( $bulbs as $key => $value ) {
echo $value;
}
}
Now the above functions will fetch the custom field (which is metadata). If it does not exist, you bail out. Otherwise, you start building the HTML markup and rendering it out to the browser.
Related
I would like to use an ACF field to inject Schema merkup to a few specific pages on my WordPress website. Some of them are custom taxonomies or custom post types.
After a two hour research on the topic, I am still stuck.
I have created a text area field called schema_code and entered the desired Schema markup for some of my sub pages.
I currently use this code in my functions.php which does not do anything:
function acf_header_script() {
$schema = get_field('schema_code');
echo '<script type=application/ld+json>' . json_encode($schema_code) . '</script>';
}
add_action ( 'wp_head', 'acf_header_script' );
What am I missing here? Thanks a lot!
The second parameter of the ACF get_field() is required in this case, since you're not in the loop. It is either the post->ID or it's the taxonomy ID where it's {taxonomy_name}_{taxonomy_id} https://www.advancedcustomfields.com/resources/get_field/
Since you want to do this on pages and archives, etc... You need to first determine if it's a single page or an archive, etc.
function acf_header_script() {
// is it a single post?
if ( ! is_single() ) {
// no? get the queried object.
$object = get_queried_object();
if ( is_a( $object, 'WP_POST' ) ) {
$param = $object->ID;
} else {
$param = $object->taxonomy . '_' . $object->term_id;
}
} else {
// yes it's a single.
global $post;
$param = $post->ID;
}
$schema = get_field( 'schema_code', $param );
// if $schema is not empty.
if ( $schema ) {
echo '<script type=application/ld+json>' . json_encode( $schema ) . '</script>';
}
}
add_action( 'wp_head', 'acf_header_script' );
I'm having trouble disabling a function in the Woocommerce Force Sells extension. The function adds some text under the buy button on the frontend product page, that I would like to remove.
I think I have found the function in question in the woocommerce-force-sells.php file:
/**
* Displays information of what linked products that will get added when current
* product is added to cart.
*/
public function show_force_sell_products() {
global $post;
$product_ids = $this->get_force_sell_ids( $post->ID, array( 'normal', 'synced' ) );
$titles = array();
// Make sure the products still exist and don't display duplicates.
foreach( array_values( array_unique( $product_ids ) ) as $key => $product_id ) {
$product = wc_get_product( $product_id );
if ( $product && $product->exists() && 'trash' !== $product->get_status() ) {
$titles[] = version_compare( WC_VERSION, '3.0', '>=' ) ? $product->get_title() : get_the_title( $product_id );
}
}
if ( ! empty( $titles ) ) {
echo '<div class="clear"></div>';
echo '<div class="wc-force-sells">';
echo '<p>' . __( 'This will also add the following products to your cart:', 'woocommerce-force-sells' ) . '</p>';
echo '<ul>';
foreach ( $titles as $title ) {
echo '<li>' . $title . '</li>';
}
echo '</ul></div>';
}
}
I have looked at https://codex.wordpress.org/Function_Reference/remove_action but I can't really figure out how to employ that in the code above.
Thanks a lot in advance!
The easy way to do this is by hiding the content from the page. Look for the class and add
display:none ;
to that class in css.
or
you can edit it in woocommerce template files. it is hard to find from which page it is coming from (look in all possible pages in templates ). once you find it remember to copy that template to child theme.(create a folder in child theme named as woocommerce---add folder path if there is some in actual location). or else you will loose all the edits when woocommerce is updated.
easy way is just hiding it from css
You cannot remove a function, you can only prevent it from being executed. That is not the same as removing an action though. However, if you want to remove text from a button, you are probably better off changing the template file that adds the button to the page.
Here is some more information about changing the template: https://docs.woocommerce.com/document/template-structure/
Site I’m working on is a radio show. I have a bunch of custom fields, courtesy of Advanced Custom Fields, for links to musicians’ websites, social profiles, etc.. For the last few years, we’ve used a Genesis child theme to display them, and the code I adapted worked great. The radio show’s host/producer now wants to move to a non-Genesis theme, and I’m having some trouble making it work.
Here’s an example from the site we’re migrating FROM, which includes the functioning code. (The Artist Links box, floated to the right of the main copy.)
Here’s the same post at the new site, where the code doesn’t yet display. (It will display in the same place.) FWIW, the theme is GrandBlog.
Here’s the code:
<?php
add_action ('if_artist_links');
function if_artist_links() {
// These are the custom field keys defined in the dashboard:
$metas_links = array(
'website',
'album',
'tour',
'twitter',
'facebook',
'bandcamp',
'soundcloud',
'youtube',
'instagram',
'linkedin',
'myspace',
'image',
);
// If _any_ ACF field is filled in, it's a go.
$has_meta = false; // init
foreach ($metas_links as $test ) {
if ( get_field($test) ) {
$has_meta = true;
continue; // Just need one meta field filled to create the div.
}
}
if ( $has_meta ) {
echo '<div class="custom-data artist-links">';
echo '<h2 class="artistname">' ?> <?php the_field('name') ?></h2>
<center><strong> <?php the_field('tribe') ?></strong></center> <?php
foreach ( $metas_links as $meta_links ) {
$$meta_links = get_field($meta_links);
if ( $$meta_links ) {
$f_object = get_field_object($meta_links);
$label = $f_object['label'];
echo '<div class="' . $meta_links . '">' .
'<span class="label">' . $label . '</span>' .
'</div>';
}
}
echo '</div><!-- /.custom-data -->';
}
}
?>`
Where there’s an ACF value, a link is created. Where there’s no ACF value, there’s no link. Just one link is required to make the box appear.
As far as I can tell, I’m not telling the code to run, or run in the right way. If you can help me do that, I’ll sing your praises through the weekend.
If possible, I’d really like to wrap this up in a WP plugin, for simplicity and ease of maintenance, and to put minimal code in single.php.
Thanks so much for your help!
You need to use WordPress the_content hook. Replace this in your theme's 'functions.php'.
function single_add_to_content( $content ) {
if( is_single() ) {
// These are the custom field keys defined in the dashboard:
$metas_links = array(
'website',
'album',
'tour',
'twitter',
'facebook',
'bandcamp',
'soundcloud',
'youtube',
'instagram',
'linkedin',
'myspace',
'image',
);
// If _any_ ACF field is filled in, it's a go.
$has_meta = false; // init
foreach ($metas_links as $test ) {
if ( get_field($test) ) {
$has_meta = true;
continue; // Just need one meta field filled to create the div.
}
}
if ( $has_meta ) {
$content.= '<div class="custom-data artist-links">';
$content.= '<h2 class="artistname">'.get_field('name').'</h2>
<center><strong>'.get_field('tribe').'</strong></center>';
foreach ( $metas_links as $meta_links ) {
$$meta_links = get_field($meta_links);
if ( $$meta_links ) {
$f_object = get_field_object($meta_links);
$label = $f_object['label'];
$content.= '<div class="' . $meta_links . '">' .
'<span class="label">' . $label . '</span>' .
'</div>';
}
}
$content.= '</div><!-- /.custom-data -->';
}
}
return $content;
}
add_filter( 'the_content', 'single_add_to_content' );
Or you can copy 'single.php' to your child theme and add this code directly without function.
I have a div with inputs within it in my document, and I would like to be able to save more than just each input's value in a function, run during the save_post hook. for testing, it looks like this at the moment:
$sanitized_data = array();
foreach ( $resources as $index=>$resource ) {
$resource = esc_url( strip_tags( $resource ) );
if ( ! empty( $resource ) ) {
$sanitized_data[$index] = $resource;
}
}
$myDocument->update_post_meta(
$post_id,
'Meta_key',
$sanitized_data
);
I'm not sure how to retrieve any other information, and I suspect when the save_post action is run the document no longer exists, only the meta data, or at least that's the way it seems.
I created this function to try and see what was going on:
$elements = $this->getElementsByTagName('input_wrapper');
foreach($elements as $index=>$child) {
var_dump( $child );
}
die();
Unfortunately, this comes up with nothing but a blank screen. Can anyone help me?
I'm working on something on wordpress + woocommerce.
I've inputed some 'filter' attributes value for some products.
So if the value of the attribute for this product includes a "Wood Grains" value, i want to echo an Woodgrains.jpg on the front end.
Therefore if the value = Texture, i want to echo Texture.jpg icon.
the code below is what i've mustered so far, but this only echoes out all the values tagged to a product, i can't figure out what to change to get the 'if' statement in it.
$terms = get_the_terms( $product->id, 'pa_filter');
foreach ( $terms as $term ) {
echo $term->name;
}
here's a screenshot of what the code above does on the front end:
http://edleuro.com/new/wp-content/themes/mystile/img/1.png
If this returns an array of terms for the said product:
$terms = get_the_terms( $product->id, 'pa_filter');
You can check if the returned result array has what you are looking for by doing this:
if (in_array("Wood Grains", $terms))
{
// has it
}
else
{
// doesn't have it
}
Update
Based in your reply to my answer, I have came up with the following:
Create a helper function like this:
function termExists($myTerm, $terms)
{
if (is_array($terms)) {
foreach ($terms as $id => $data) {
if ($data->name == $myTerm)
return true;
}
}
return false;
}
Then you use it like this:
if (termExists('Wood Grains', get_the_terms($product->id, 'pa_filter')))
{
// term exists
}
else
{
// does not exists
}
i found a better way to resolve my problem. i had this in my content-product.php woocommerce template.
<?php
$terms = get_the_terms( $product->id, 'pa_filter');
foreach($terms as $term){
if($term->name == 'Wood Grains'){
echo '<img src="icon_woodgrains.gif">';
}
}
?>
do take note that the term name is case sensitive.
foreach prints Warning: invalid argument supplied for foreach()…
This works for me "on a purely":
if ( is_product() && has_term( 'Wood Grains', 'pa_filter' )) {
echo '<img src="Texture.jpg">';
}