First, I've searched Google, SO, and magento SE to no avail. I've seen many results, but none that seemed to work.

I've got a "custom" product listing on the front-end, which uses the below code:

$magentoProduct = Mage::getModel('catalog/product');
$_helper = $this->helper('catalog/output');

$collection = $magentoProduct->getCollection()
            ->addAttributeToFilter('status', 1)
// This doesn't have any effect
//          ->setOrder('position', 'ASC');

$collectionIds = $collection->getAllIds();
foreach ($collectionIds as $prodId):
    $magentoProduct = $magentoProduct->load($prodId);
    $cats = $magentoProduct->getCategoryIds();
    // ... do stuff ...

I want the sort order to respond to the Product Position (as set in the "Catalog"=>"Manage Categories" interface).

I've tried a variety of things, to no avail.

Any insights? (I'm also open to a better / different approach to this, so feel free to suggest best practices).


First, you should know that the position is saved in the relation table catalog_category_product, so without filtering by category you will not have this data. In theory you could join the relation table without actually filtering by category, but which row will you use? Usually products belong to multiple categories.

Your product collection is independent of any category, so it will contain products from different categories. Does it really makes sense to sort these products by position within an arbitrary category? You decide. But I would recommend adding a product attribute. If you call it "position" and add it as static attribute, i.e. as field to the main table1, you can use the code as it is. But to avoid conflicts with the position inside a category, I would choose a different code. Also, if you don't add it as static field, but as normal EAV attribute, you have to use addAttributeToSort('position') instead of setOrder('position').

A general recommendation: Instead of addAttributeToSelect('*') load only the attributes that you need. In product listing, the following is usually sufficient:


With this code, you should configure your new position attribute as "Used in product listing: Yes", so that it will be included in addAttributeToSelect() automatically.

1) Usually, you don't do that but if you use these custom collections a lot with many products, you should consider it, alongside with a MySQL index on the column, to improve the sorting performance.

  • Thank you. This looks great. Question: I don't see anything dealing with the sort in your sample code - what am I missing? Aug 27 '15 at 21:11
  • This: If you call it "position" you can use the code as it is. - I was referring to ->setOrder('position', 'ASC'); - replace position with the code of the new attribute of course Aug 27 '15 at 21:13
  • OK. Got it. Is there a built-in product sort order that would be useful to use (other than the category related product position)? Or is adding an attribute the "best" way to go? Aug 27 '15 at 21:15
  • Oh, actually it has to be addAttributeToSort('position');, not setOrder('position'), because it will be a EAV attribute, not a column in the main table. See: magento.stackexchange.com/questions/62043/… Aug 27 '15 at 21:19
  • No, there is nothing like a built in sort order for arbitrary product collections. For your requirements, a custom attribute seems to be the best way. Aug 27 '15 at 21:20
$category = Mage::getModel('catalog/category')->load('category-id');
$collection = $category->getProductCollection()
 ->addAttributeToSort('position', 'ASC');

use above code to sort by category position.otherwise it won't work as said by fschmengler

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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