Placement of Dynamic Shapes

Topics: Customizing Orchard
May 22, 2015 at 9:22 PM
Is it possible to specify placement of a dynamic shape within a zone? I've tried using a file in TheAdmin, but that doesn't work. I've built a separate users area in the admin area that allows a "MinorAdmin" to manage users that aren't administrators. I had to create a new dynamic shape (editortemplate) for the roles because I needed to remove the administrator role from the list of available roles to assign to a user. This worked but when I tried using the new password editor the placement is messed up because the two dynamic shapes for the roles and the user show above the password editor which is at the bottom. I would like the password editor to be below the user edit but above roles. Nothing I've tried so far seems to work except changing the Edit.cshtml view to display the individual templates or shapes instead of the whole shape.
@{ Layout.Title = T("Edit User").ToString(); }

@using (Html.BeginFormAntiForgeryPost()) { 
    // Model is a Shape, calling Display() so that it is rendered using the most specific template for its Shape type
This seems like a rather poor approach to solving the problem. Thank you for any help.
May 25, 2015 at 12:20 PM
Can you show how you created that "dynamic shape"? I'm a little confused on what exactly you've done.
May 28, 2015 at 7:42 PM
Edited May 28, 2015 at 7:44 PM
I ended up figuring out a better way of doing what I wanted and it fixed my placement issue. I was trying to create an area for managing users that hid administrators and the administrator role. My original method for doing so was to remove the UserRoles editor that gets added to the model through the use of the following statement: "var model = Services.ContentManager.BuildEditor(user);" and then I would add a custom UserRoles editor that had the administrator role removed. This worked fine in Orchard 1.8 but in 1.9 it would place the UserRoles editor in between the User editor (username and email) and the Password editor which looked bad. Here is an example of my original code for creating a new user:
 public ActionResult Create()
            if (!Services.Authorizer.Authorize(Permissions.ManageBankUsers, T("Not authorized to manage users")))
                return new HttpUnauthorizedResult();

            var user = Services.ContentManager.New<IUser>("User");
            //Editor for user
            var editor = Shape.EditorTemplate(TemplateName: "Parts/User.Create", Model: new UserCreateViewModel(), Prefix: null);
            editor.Metadata.Position = "2";

            //Editor for user roles
            //Create a collection of the current system roles using the UserRoleEntry ViewModel (removing admin accounts)
            var roles = _roleService.GetRoles().Where(x => !x.Name.Contains("Administrator")).Select(x => new UserRoleEntry 
                RoleId = x.Id,
                Name = x.Name,
                Granted = user.ContentItem.Get<UserRolesPart>().Roles.Contains(x.Name)

            //Set up the ViewModel to be passed to the user roles editor
            var rolesModel = new UserRolesViewModel
                User = user,
                UserRoles = user.ContentItem.Get<UserRolesPart>(),
                Roles = roles.ToList(),

            //Create the editor for the user roles
            var roleEditor = Shape.EditorTemplate(TemplateName: "Parts/User.Roles", Model: rolesModel, Prefix: null);
            //Build the model to be passed to the view
            var model = Services.ContentManager.BuildEditor(user);


            //This all has to do with permissions to assign roles - if the user doesn't have permissions to do so then the roles editor won't already exist in the model
            //Make sure model.Content.Items has more than 1 element (1 or less means the roles editor wasn't already created; 2 or more means it was so we need to remove it)
            if (model.Content.Items.Count > 1)
                //Remove the current editor for the user roles from the model
                //Add the new editor for user roles to the model
            return View(model);
I found that I could instead go into the model and remove the UserRoleEntry for the administrator role directly instead of having to go through all the hassle of removing the UserRoles editor and building a custom one like I was originally doing. This simplified my code greatly and fixed the problem with the UserRoles editor being in between the User editor and Password editor.

Note: My original question was how to specify placement of the editors stored in the model being built. I tried to use various methods and variables in the metadata such as "editor.Metadata.Position = 1;" but none of those worked.