Are Containable Parts and Widgets exclusive of each other? - orchardcms

I'm struggling with a decision to choose between creating a custom type as a Content Type with the Containable Part, or to create them as a Widget. I know that an existing Content Part can be used to create a new Widget, but this leaves me with having to create each instance from within the Widget Management section of the dashboard (I think). I'm not able to select a content item that already exists and have it act as a widget.
What I would really like is to have the ability to select a single, existing, Content Item and display it as a Widget. The widget could then expose a link that would take the user to the page-level display of that item. This would also allow me to have a list of these content types on a page where I also had html elements (html widgets) sprinkled in and amoungst them.
Alternatively, I could create my Content Type and attach the Containable Part. This would allow me to create the ad-hoc list (not a Projection) of content items I want. I would, however, have to create another Content Type to hold the HTML want to have appearing between the primary types.
Are my assumptions correct?: Must one create a new instance of a widget when they add it to a zone? Or can they select one from a list of existing content types?
Are Containable Parts and Widgets exclusive of each other?

Create a widget type with a content item picker field.

Thanks, Bertrand for the suggestion to create a widget type with a content item picker field. Here is my implementation:
public UpdateFrom1() {
ContentDefinitionManager.AlterTypeDefinition("BioPickerWidget", cfg => cfg
.WithPart("BioPickerWidget")
.WithPart("WidgetPart")
.WithPart("CommonPart")
.WithSetting("Stereotype", "Widget"));
ContentDefinitionManager.AlterPartDefinition("BioPickerWidget", cfg => cfg
.WithField("BioPicker", fb => fb
.OfType("ContentPickerField")
.WithSetting("ContentPickerFieldSettings.Hint", "Add Bio Content Items here.")
.WithSetting("ContentPickerFieldSettings.Required", "True")
.WithSetting("ContentPickerFieldSettings.Multiple", "True")
.WithSetting("ContentPickerFieldSettings.ShowContentTab", "True")
.WithSetting("ContentPickerFieldSettings.ShowSearchTab", "True")
.WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", "BioPart")
.WithDisplayName("Bio Content Picker"))
.WithSetting("ContentPartSettings.Attachable", "True")
);
return 2;
}
This allows me to add 1 or more of my Bio Content Types to a widget. Seems to be working nicely. All I have to do now is figure out the view customization.

Related

Access content field from views in Orchard CMS 1.10.1

I would like to display certain first level menuitem in bold.
This setting should be done by a checkbox when the user create / edit a menu item. (I have a workaround using the Model.Href, but it is not nice).
So I created a boolean field in Content definition / Menuitem URL (I don't know the name of the corresponding content definition in English Orchard).
How to access a custom field (Content Field) from a view?
(There already is a view which is used to customize the menu)
The examples I found use custom shapes, where the fields are accessed as built in fields (e.g. Model.ContentItem.FieldName ). But this is a different case.
With the help of "Piedone", the solution:
Model.Content.ContentItem.MenuItem.FieldTechnicalName.Value
Explanation
Examining the Model object in Visual Studio, the Model is a dynamic shape that have eg. Href property and a Content.
Content is a MenuPart, that is a content part that have a ContentItem property with the content item itself. Technically only content parts have Fields. When you (seemingly) add a field to a type it will be a part corresponding the type's name, that is MenuItem in this case (It's confusing that the display name of 'MenuItem' content type is Custom Link...)
The field's technical name is as you name it. When you add to a type, the Value will be a property of the BooleanField class. (By the way, it is nullable, so if you dont't save after adding the field, it will be null else the value you set).

Alternate shape for EditorTemplate of Field is not being recognized

I need an alternate for the EditorTemplate of an Enumerator Field that's used when the Field has a particular name (PublishingMethod).
Based on the docs, I created a view with the pattern [ShapeType__FieldName] in the same folder as the original shape:
This is not working and still uses the original. I've thought of changing the Editor method in the Driver, but I think that defeats the purpose of alternates, which is that Orchard automatically detects the correct shape as I understand from the docs:
The Orchard framework automatically creates many alternates that you can use in your application. However, you can create templates for these alternate shapes.
Note: I can't use the Shape Tracing module, it never worked even with a clean Orchard install.
The editors in Orchard work different to how Display works. I guess it is so you get a MVC-style experience. Basically, the actual shape returned is of type EditorTemplate, which then binds your model and prefix then renders a partial view with the template name you gave it. What this means is alternates wont work as expected, or as the docs state. The alternates for your field name are actually added to the EditorTemplate shape. So what you can do is add a view called EditorTemplate-PublishingMethod.cshtml with contents like:
#{
var m = (Orchard.Fields.Fields.EnumerationField)Model.Model;
}
#Html.Partial("PublishingMethodEditor", m, new ViewDataDictionary {
TemplateInfo = new TemplateInfo { HtmlFieldPrefix = Model.Prefix }
})
Then add another view called PublishingMethodEditor.cshtml with the overrides you want for your editor. All these views should go in the root of your Views folder.
Another approach would be to implement the IShapeTableProvider interface and adjust the TemplateName property on a certain condition but, meh, that requires code...
Edit 1
If you have that field name on other content types that you don't want to override you can use the override EditorTemplate-ContentTypeName-PublishingMethod.cshtml

Creating a navigation menu item in Orchard

I have written an Orchard Module and would like an item to appear in a Navigation list when the module is Enabled. Ideally, I would like to be able to remove the item when the Module is disabled.
Where should I hook into to for when the module is enabled and disabled?
How do I programmatically add a menu item to an already existing Navigation?
You can implement the IMenuProvider interface for this. An example implementation might look something like this:
namespace Orchard.Bar {
public class SuperMenuProvider : IMenuProvider {
private readonly IOrchardServices _orchardServices;
public SuperMenuProvider(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void GetMenu(IContent menu, NavigationBuilder builder) {
string position = "10";
builder.Add(T("Foo"), position, item => item.Url("http://foo.com").AddClass("someClass"));
builder.Add(T("Bar"), position + ".1", item => item.Action("Index", "Foo", new { area = "Orchard.Bar" }));
if (_orchardServices.Authorizer.Authorize(Orchard.Security.StandardPermissions.AccessAdminPanel)) {
builder.Add(T("Secure FooBar"), position + ".2", item => item.Action("Index", "Secure", new { area = "Orchard.Bar" }));
}
}
}
}
This will appear on all menus on the front end. You may want to put in the name of the menu you are targeting if you know for sure that is what it is called (default in Orchard is "Main Menu", people don't generally change it to be honest). This could be a little brittle, so you may want it customizable, either with a site setting or you could create a part that you attach to the menu content type that lets the admin specify whether to show your menu items on the said menu.
An alternative approach would be to hook into the modules enable event using IFeatureEventHandler and using the content manager to create menu items with urls and adding them to a specified Menu. I don't really recommend this approach; you lose control of the menu items (e.g. to update a url), they can be removed from the menu accidentally, you have to know the name of the Menu you are adding them to, you are more limited (cant do permissions checks etc.).
I assume you are talking about showing up on the front end. If you talking about the admin menu then check out pretty much any module for a file generally called AdminMenu.cs, plenty of examples :)
The question doesn't specify what the module does so I guess we're to assume that it creates a content type. In that case you have (at least) two options:
In the Content Type's Content Definition go to Add Parts and add the Menu part. This will allow you to add a content item to a menu from the item's content editor.
From the Navigation menu choose the appropriate Menu and select add a Content Menu Item. Note that the content type must be set as "listable" in Content Definition in order for the items to be listed as a choice.
Disabling the module should remove the item from the navigation in either case.

Widget to show Data

I created a Deposit module. My main goal with this module is to save some data on the DB.
I already made my custom type (Deposit) with my custom part (DepositPart) and it worked like I expected.
This DepositPart save the name, currency, liquidity, month, and url on the database.
But now I want to make a simple widget with 3 combobox and a button.
On those combobox I have some static text where the user can choose from. When the user hit the button I want to make a query and return a list with some Deposits and show only the name and the liquidity.
What is the best way to achieved this?
The best is creating your own controller.
For the part you have you can easily present as a widget adding some lines to migrations.
example:
(you can find more at this link: http://docs.orchardproject.net/Documentation/Writing-a-widget )
public int UpdateFrom1()
{
// Create a new widget content type with our map
ContentDefinitionManager.AlterTypeDefinition("MapWidget", cfg => cfg
.WithPart("MapPart")
.WithPart("WidgetPart")
.WithPart("CommonPart")
.WithSetting("Stereotype", "Widget"));
return 2;
}
Note that you simple add WidgetPart and add stereotype "Widget" to a new Content Type that also has yourpart (in this example MapPart).
For the result you may use a controller.
Having more information about your part I can help you more.

displaying a list on screen with orchard

Using orchard cms 1.6 I have a table in my db 'cars'. I want to display the column 'CarName' from the table, as a list on screen with all the records from the table.
carname1
carname2
carname3
When the user clicks on their link it will bring them to that page.
I know how to do this from the view e.g.
#T("Cars")
but I would like to try and create a content type which shows this list.
Content type seems to be all UI related. Im not sure how to take a table and display a column as a list on screen through the content type...any idea on how to do this?
then I can choose to show the content type as a form and the user can view it from the main menu.
thanks
It looks like you want to create a content type called Car, possibly with a CarPart and a record class CarPartRecord (perhaps refactor your Car class to CarPartRecord to follow Orchard's naming conventions). Make sure CarPartRecord derives from ContentPartRecord.
To render a list of Cars, you could use a Projection that renders a list of cars. A Projection renders content based on a Query, which you configure using the dashboard.
Alternatively, you could create a controller that leverages IContentManager to query all Car content items, and returns a view to render them in a table.
For each Car content item, use Html.ItemDisplayLink to render a link to its details page.

Resources