Take the 2-minute tour ×
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It's 100% free, no registration required.

Is there any way to set an attribute option's position per product?

To clarify with a simple scenario, we sell blue shirts and pink shirts. For products in a women's category, we want the pink shirts first in the list, for men, we want blue.

Thanks!

share|improve this question
    
Can you reiterate the question? The question sounds like you want to reorder product attributes (like in the "additional info" section of the product view page), but the example sounds like you want to sort products under a category. –  Sam Jun 3 '13 at 20:37
    
Sure. For example, for this product link. The order of the colors is set by the attribute option's position. I'm looking for a way to set the order of the colors per product instead. –  Wilson Sheldon Jun 3 '13 at 21:00
    
+1 good question! –  kalenjordan Jun 3 '13 at 21:14
add comment

2 Answers

How about:

1) sort them using usort and define a custom function to take into consideration your variables (gender, color)

2) Create a new module where you can define the order based on the gender:

  • base attribute value (in your case gender)
  • attribute value (color: gray, blue, pink)
  • sort order

and implement this logic in the part that pulls the list of possible attribute values.

Note: Souldn't your products be configurable based on gender and color, not just color?

share|improve this answer
add comment

Ok, solved this for us. Here's what I did.

First I created a textarea attribute (code: attribute_order_override) for configurable products to allow the content editors to enter a JSON snippet like this:

{
    "color": [
        "Athletic Grey", 
        "Athletic Blue"
    ]
}

Then in app/design/frontend/.../default/template/catalog/product/view/type/options/configurable.phtml. I created an "order reference array":

$orderReferenceArray = array();
$attributeOrderOverride = $_product->getResource()->getAttribute('attribute_order_override')->getFrontend()->getValue($_product);
if ($attributeOrderOverrideArray = Mage::helper('core')->jsonDecode($attributeOrderOverride, true)) {
    foreach($attributeOrderOverrideArray as $k => $v) {
        if (is_array($v) && count($v) > 1) {
            $attribute = Mage::getSingleton('eav/config')->getAttribute('catalog_product', $k);
            $orderReferenceArray[$attribute->getAttributeId()] = array();
            $options = $attribute->getSource()->getAllOptions(false);
            foreach($v as $k2 => $v2) {
                foreach($options as $option) {
                    if ($option['label'] === trim($v2)) {
                    $orderReferenceArray[$attribute->getAttributeId()][$option['value']] = $option['label'];
                    }
                }
            }
        }
    }
}

Then, in our case, we in our catalog helper, $this->helper('catalog'), we parse the JSON configuration from Magento with PHP to build our attribute structure. So before we build out the HTML, I check if there's an overriding "order reference" for these attribute options, and, if so, swap the options around. Otherwise, they'll use the position set in the Attribute in the admin area:

    $configData = Mage::helper('core')->jsonDecode($jsonConfig, true);

    if (count($orderReferenceArray) > 0) {
        foreach($configData['attributes'] as $k => $v) {
            if (count($v['options']) > 1 && isset($orderReferenceArray[$k])) {
                $tmpOptions = array();
                foreach ($v['options'] as $v2) {
                    $tmpOptions[$v2['id']] = $v2;
                }
                $configData['attributes'][$k]['options'] = $this->sortArrayByArray($tmpOptions, array_keys($orderReferenceArray[$k]));
            }
        }
    }

And the sortArrayByArray method is:

public function sortArrayByArray($array,$orderArray) {
    $ordered = array();
    foreach($orderArray as $key) {
        if(array_key_exists($key,$array)) {
            $ordered[$key] = $array[$key];
            unset($array[$key]);
        }
    }
    return $ordered + $array;
}
share|improve this answer
    
+1 Nice solution! –  drj201 Sep 21 '13 at 9:55
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.