How to convert existing Data Object to variant?

I’m wondering if there’s a way from the admin interface for an end-user to convert an already created item to a variant?

Technically, the only thing that differences a variant from a regular child-item, is a column in the database (table object, column o_type). Via API you can change the type freely $objcet->setType(AbstractObject::OBJECT_TYPE_VARIANT). There is no way using the Pimcore UI to do that though, but you can create an extension that does that for you, as I did in a project:

Sounds good. I’m surprised that’s not just a standard feature, especially since the implementation would be so simple. I’ll have products being added from many channels, and most won’t come with a predetermined parent.

I was able to get that added. Curious, is there a way to have it refresh the object on success so all the children display the proper icon?

this is my JS


zeroridge.tree.variant_convert_context_menu = Class.create(pimcore.plugin.admin, {
    getClassName: function() {
        return "zeroridge.tree.variant_convert_context_menu";

    initialize: function() {;

    prepareObjectTreeContextMenu: function (tree, treeClass, menuItem) {
        if (!'className')) {

        if ( !== coreshop.class_map.coreshop.product) {

            { xtype: 'menuseparator' },
                text: 'Convert childs to Variants',
                iconCls: "pimcore_icon_variant",
                handler: function() {
                        url: '/admin/zeroridge/convert-childs-to-variants',
                        params: {
                        success: function (response) {
                            treeClass.reloadNode(tree, menuItem);

new zeroridge.tree.variant_convert_context_menu();

this is my controller:


namespace AppBundle\Controller\Admin;

use AppBundle\Model\ProductInterface;
use AppBundle\Model\ProductPackageTypeInterface;
use CoreShop\Bundle\WarehouseBundle\Notes;
use Pimcore\Model\Asset;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\DataObject\ZeroRidgeProduct;
use Pimcore\Model\DataObject\ZeroRidgeProductPackageType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class AdminController extends \Pimcore\Bundle\AdminBundle\Controller\AdminController
    public function convertChildsToVariantsAction(Request $request)
        $id = $request->get('id');
        $object = Concrete::getById($id);

        if (!$object instanceof ProductInterface) {
            throw new NotFoundHttpException();

        $children = $object->getChildren([Concrete::OBJECT_TYPE_OBJECT], true);

         * @var Concrete $child
        foreach ($children as $child) {

        return $this->json(['success' => true]);

with that, the tree reloads as well

Thank you for going above and beyond. I imagine that will help others out as well.