Does anyone have any sample code for themeing a product-enabled node with phptemplate? I am interested in moving the "add to cart" link to a more prominent position on the page. For example, this is what I would like:

NODE TITLE HERE
<div>price info and "add to cart" link</div>
<div>Node body content, etc...</div>

FYI, my settings are such that the "add to cart" link still shows up in the links section of the node.

I know a little bit about phptemplate theme-level overrides, but I can't get this one to work properly. Here is what I currently have in my template.php file (recycled from the theme_node_product() and product_link() functions in product.module:

/**
 * Theme function to render product node.
 */
function phptemplate_node_product($node, $teaser = 0, $page = 0) {
  $product_type_theme = false;
  $f = 'theme_product_'. $node->ptype . '_view';
  if (function_exists($f)) {
    $product_type_theme = true;
    $node = theme('product_'. $node->ptype. '_view', $node, $teaser, $page);
  }

  if (!$product_type_theme) {

  if ($type == 'node' && $node->ptype) {
    /* Determine whether or not the 'add to cart' link needs to be displayed. */
    $item = cart_get_items();
    if ($node->hide_cart_link == 0) {

      /* Right here we need to check if a given product type is in stock */
      if (module_invoke($node->ptype, 'productapi', $node, 'in_stock')) {
        // Is it already in our cart?
        if ($item[$node->nid]->qty) {
          $add = t('This item is in <a href="/%cart_view">your shopping cart</a>.', array('%cart_view' => url('cart/view')));
        }
        else {
          $add = l(t('add to cart'), "cart/add/$node->nid", array('class' => 'cart_link', 'title' => t('Add this item to your shopping cart.')));
        }
      }
      else {
        $add = t('sold out');
      }
    }

}

    $price_string = '<div class="price">';
    $price_string .= '<strong>'. t('Price') .'</strong>: '. payment_format(product_adjust_price($node));
    $price_string .= $add;
    $price_string .= '</div>';
    if ($node->is_recurring) {
      $price_string .= '<div class="recurring-details">'. product_recurring_nice_string($node) . '<div>';
    }
    $node->teaser = $price_string . $node->teaser;
    $node->body = $price_string . $node->body;
  }

  return $node;
}

On nodes that I have created through node/add/product, the price shows up, but not the "add to cart" text. On nodes that were originally created as "book" type nodes, and then later augmented with product information, nothing shows up. What am I missing here?

Thanks in advance,

Bjorn A

Comments

conann’s picture

How did you get on with this I am interested in doing similar

Conánn

bjornarneson’s picture

using a variation of the code above, I managed to get product nodes themed differently. However, it only worked with nodes that were created as products, not "product-enabled" after creation. Making progress on this hasn't been a high priority for me. Sorry I can't help more.

--
Bjorn | choirgeek.com

conann’s picture

I ended up not using the product page as I need product catagories, instead I created a static page with each product type looking the way I wanted linking to each types taxonomy. Combined with taxonomy_theme.module I was able to get the whole site working the way I wanted it too, with an ounce of sweat.
Conánn

bomarmonk’s picture

I think what I'm trying to do might be even simpler-- I just want the images for a product to look a certain way (left aligned) with the text for the product wrapping around the image or in a column to the right.

Maybe I should create a flexinode for my products and a seperate node.tpl.php file to theme the products, but it seems like this should be easier...without the need for flexinode?

Any ideas or stories about how this has been achieved? Thanks in advanced!

forreststevens’s picture

Not to dredge up an old topic but I needed to do the same thing, basically add a separate bit of text after the price and organize it a bit differently. The trick here is to realize that theme_node_product isn't actually spitting back output, but rather modifying the node->teaser and node->body and returning the node object.

To do this you can't use the _phptemplate_callback() function. Rather just create a function in template.php that looks like this...

function phptemplate_node_product(&$node, $teaser = 0, $page = 0) {
  $product_type_theme = false;
  $f = 'theme_product_'. $node->ptype . '_view';
  if (function_exists($f)) {
    $product_type_theme = true;
    $node = theme('product_'. $node->ptype. '_view', $node, $teaser, $page);
  }

// ... rest of theme_node_product() function plus customizations ...
}

And make your customizations to the phptemplate_node_product() within template.php rather than in a node_product.tpl.php file. Anyway, hope this helps out other people who might be searching for the same thing in the future.