0

I have a custom node template based on a custom content type and I want to display products with their "Add to Cart" buttons from this custom node template.

In the content type (actually a field collection), I added the Product reference. In the template (node--{content type}.tpl.php) I do this type of thing:

$wrapper = entity_metadata_wrapper('node', $node); // Since it's a field collection, I loop these: foreach ($wrapper->field_content_group as $group) { //Now each "$group" has the fields I want to display //I permit N products (not just 1), so I can get product information, //like price for example, like this: if($group->field_featured_product) { $product_references = $group->field_featured_product->value(); foreach($product_references as $product_reference) { $product = commerce_product_load(intval($product_reference->product_id)); $price = entity_metadata_wrapper('commerce_product', $product)->commerce_price->value(); print $price_display = commerce_currency_format($price['amount'], $price['currency_code'], $product); } } } 

I don't need to alter the display, I'm happy with that. I'd like to just call something that prints the product, price, etc., along with the "Add to Cart" button. I'm thinking I call commerce_product_load and then some method(s) that gives me the completed form. Is there such a thing that I can call?

NOTE: Yes, I know about separation of concerns and that code is best placed outside of the template file.

2
  • I've got to ask - if you know it's good practice to separate logic and display, why would you ignore it? This logic should be moved out of the template file and into a preprocess function for all sorts of reasons, not just best practice. Caching for one. Commented Oct 22, 2013 at 13:43
  • Work in Process Commented Oct 22, 2013 at 18:04

2 Answers 2

0

Since views seem to be the easiest way to display product offerings, the way I solved this was to create views for the products. The views are configured as blocks. Then I use:

$block = module_invoke('views', 'block_view', $block_name); print render($block['content']); 

to display the block.

I used content type fields to specify the block names I want to display within certain areas so it isn't hard-coded. It isn't terribly elegant, but sometimes programming is that way since there isn't an infinite amount of time to solve problems!

0

There is an alternate way of doing this, as shown by duckzland on drupal.org:

Note: You may need to alter the product retrieval code slightly to match the way your node is set up. Using var_dump($content) should help you determine the structure.

Load your product through the node template, without calling commerce_product_load():

<?php $view['product'] = NULL; // retrieve raw product from field containing your product's info if(isset($content['product:field_featured_product']) { $view['product'] = $content['product:field_featured_product']; } // do stuff to output the product here // add to the cart here // build the line items for shopping cart $order_id = 0; // optional $line_item = commerce_line_item_new($view['product']->type, $order_id); $line_item->data['context']['product_ids'] = array($view['product']->product_id); $line_item->quantity = 1; // need to create config for quantity $qty = 1; $form_id = commerce_cart_add_to_cart_form_id(array($view['product']->product_id), $qty); $addtocart_form = drupal_get_form($form_id, $line_item); // we alter the submit form to use our special theme function // need to move this to configuration $addtocart_form['submit']['#theme'][] = 'vtcommerce_button_small'; $variables['cart'] = render($addtocart_form); 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.