Display MediaLibraryPickerField when editting a part - orchardcms

I'm missing something here and can't for the life of me figure out what.
I've added a MediaLibraryPickerField to a part I created:
ContentDefinitionManager.AlterPartDefinition(typeof (FloorPlanPart).Name, cfg => cfg
.WithField("Photo", f => f
.OfType("MediaLibraryPickerField")
.WithDisplayName("Photo")
.WithSetting("MediaLibraryPickerFieldSettings.Required", "true")));
I can verify that this field has been added correctly to my part. This part belongs to a custom type:
ContentDefinitionManager.AlterTypeDefinition("FloorPlan", cfg => cfg
.WithPart(typeof(FloorPlanPart).Name)
.Creatable()
.Draftable(false));
I have my driver setup to return the following on an edit:
protected override DriverResult Editor(FloorPlanPart part, dynamic shapeHelper)
{
return ContentShape("Parts_FloorPlan_Edit",
() => shapeHelper.EditorTemplate(
TemplateName: "Parts/FloorPlan",
Model: part,
Prefix: Prefix));
}
my edit view looks like the following:
#using System.Web.Mvc.Html
#model Models.FloorPlanPart
<fieldset>
<legend>Floor Plan Fields</legend>
<div class="editor-label">#Html.LabelFor(x => x.FloorPlanName)</div>
<div class="editor-field">
#Html.EditorFor(x => x.FloorPlanName)
#Html.ValidationMessageFor(x => x.FloorPlanName)
</div>
</fieldset>
Some where along the line the Media picker is supposed to show up but never does when creating a new Floor Plan. All I get is just the fields in my part (FloorPlanName). How do I get the media picker to show? If I add the Media picker as a field on my content type it does show but shouldn't I be able to do it this way as well?

Rookie mistake, I thought I was using the latest version of Orchard 1.7.2 but was using 1.6.2.

Related

How to use DataAnnotations Display attribute for multiple radio button lables

It's handy to use a Display attribute for model properties in MVC:
Model:
[Display(Name="Your Name:")]
public string Name { get; set; }
View:
#Html.LabelFor(m => m.Name)
#Html.EditorFor(m => m.Name)
But ... is it possible to use the Display attribute for naming the individual choices for radio buttons? The following is what I use now, but the 'Label for...' tag is a little inconsistent with the rest of the view. Anyone?
<div class="radio-inline">
#Html.RadioButtonFor(m => m.OpenToPublic, true, new { id = "isOpenToPublic" })
<label for="isOpenToPublic">Open to the Public</label>
</div>
<div class="radio-inline">
#Html.RadioButtonFor(m => m.OpenToPublic, false, new { id = "isInviteesOnly" })
<label for="isInviteesOnly">Invitees Only</label>
</div>
I like the code above, since using the Label tag results in being able to click on the label text to select the radio button, and the styling of the text is correct. I just wonder if there's a way to do this with data annotations on the model's property for the radio button.
Thanks,
Brian

Orchard MediaPickerField to MediaLibraryPickerField

I am currently trying to update a site from Orchard 1.6 to 1.8.
Ran into some issues at the Media -> Media Library step.
We have this in our Migrations.cs
SchemaBuilder.CreateTable(typeof(CarouselRecord).Name, table => table
.ContentPartRecord()
.Column<string>("Interval", column => column.WithDefault(""))
.Column<string>("MinHeight", column => column.WithDefault(""))
);
ContentDefinitionManager.AlterPartDefinition(
typeof(CarouselPart).Name, cfg => cfg
.WithField("CarouselImage1", fieldBuilder => fieldBuilder.OfType("MediaPickerField").WithDisplayName("Img1"))
.WithField("CarouselImage2", fieldBuilder => fieldBuilder.OfType("MediaPickerField").WithDisplayName("Img2"))
.WithField("CarouselImage3", fieldBuilder => fieldBuilder.OfType("MediaPickerField").WithDisplayName("Img3"))
.WithField("CarouselImage4", fieldBuilder => fieldBuilder.OfType("MediaPickerField").WithDisplayName("Img4"))
.Attachable()
);
ContentDefinitionManager.AlterTypeDefinition("CarouselWidget", cfg => cfg
.WithPart(typeof(CarouselPart).Name)
.WithPart("WidgetPart")
.WithPart(typeof(CommonPart).Name)
.WithSetting("Stereotype", "Widget")
);
After disabling the Media module and Enabling the Media Library Module (and migrating the Media Files and Media picker fields), this stopped working completelty, crashing at this line in the .cshtml:
<div class="item"><img src="#(Href(Model.ContentPart.CarouselImage2.Url))" alt="" /></div>
First i tried updating the template to use MediaLibraryPickerFields instead, but no luck.
Turns out, when i go to admin -> widgets -> edit widget, the media fields for the widget is gone.
Did i do something wrong in the updating process, or do i have to write new updates in Migrations.cs to remove the MediaPickerFields and add MediaLibraryPickerFields instead?
3 Months and no answer, thought i would close this.
What i ended up doing was removing the MediaPickerFields
ContentDefinitionManager.AlterPartDefinition(
typeof(CarouselPart).Name, cfg => cfg
.RemoveField("CarouselImage1")
.RemoveField("CarouselImage2")
.RemoveField("CarouselImage3")
.RemoveField("CarouselImage4")
.Attachable()
);
and then adding a MediaLibraryPickerField instead
ContentDefinitionManager.AlterPartDefinition(
typeof(CarouselPart).Name, cfg => cfg
.WithField("CarouselImages", fieldBuilder => fieldBuilder.OfType("MediaLibraryPickerField").WithDisplayName("Images").WithSetting("MediaLibraryPickerFieldSettings.Multiple", "true"))
.Attachable()
);
Not optimal due to the loss of data, but it was not a big issue in this case.

Craeting Custom Widget in Orchard 1.7

I am new to Orchard. So please forgive me if there is anything looking silly!
I want to create a custom widget for my Orchard website to encourage visitors to sign up for my Newsletter service. I have seen there is an option of using HTML widget but I want to create a new widget type like "Newsletter" which I shall use conditionally at AsideFirst block.
Is this possible to do? I only want to grab visitor's Name and Email address, and the form submission will be done using an action controller.
Do I have to create this widget through by-hand coding in VS? In fact I want to this way, not through the Orchard admin console.
Seeking for help. Any suggestion please?
Edit:
I have managed to create the widget following Sipke Schoorstra's suggestion. The area where I want to display the widget is now showing along with the the title I set from admin at the time of adding it to a zone. But the content (form elements) I created in the view is not displaying.
The View: (Views/NewsLetterSignupPart/NewsletterSignup.cshtml)
#model Emfluence.Intrust.Models.NewsLetterSignupPart
#{
ViewBag.Title = "Newsletter Signup";
}
#using (Html.BeginForm("NewsletterSignup", "NewsLetter", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="row-fluid">
<div class="span6">
<label>Name</label>
<input type="text" name="txtNewsletterUserName" required maxlength="50" style="width: 95%" />
<label>Email</label>
<input name="txtNewsletterUserEmail" type="email" required maxlength="85" style="width: 95%" />
<button class="btn pull-right">Submit</button>
</div>
</div>
}
Migration.cs
public int UpdateFrom15()
{
ContentDefinitionManager.AlterTypeDefinition(
"NewsletterWidget", cfg => cfg
.WithPart("NewsLetterSignupPart")
.WithPart("CommonPart")
.WithPart("WidgetPart")
.WithSetting("Stereotype", "Widget")
);
return 16;
}
NewsLetterSignupPart.cs
public class NewsLetterSignupPart : ContentPart<NewsletterSignupRecord>
{
[Required]
public string Name
{
get { return Record.Name; }
set { Record.Name = value; }
}
[Required]
public string Email
{
get { return Record.Email; }
set { Record.Email = value; }
}
}
And NewsletterSignupRecord.cs
public class NewsletterSignupRecord : ContentPartRecord
{
public virtual string Name { get; set; }
public virtual string Email { get; set; }
}
Where I am doing wrong?
The Custom Forms module is great if you don't want or need to code something yourself. In case you do want to handle form submissions yourself without using Custom Forms, this is what you could do:
Create a custom module
Create a migrations class that defines a new widget content type (see the docs for details on how to do this. Note: you don't need to create a custom part. You don't even need to create a migrations file to create a content type - you could do it using a recipe file. The nice thing about a migration though is that it will execute automatically when your module's feature is enabled).
Create a view specific for content items of your widget type (e.g. Widget-Newsletter.cshtml).
Inside of this view, write markup that includes a form element and input elements. Have this form post back to your controller.
Create your controller.
In the /admin interface, click Modules, on the Features` tab search for Custom Forms and click Enable. This will add a new Forms admin link on the left.
Next, create a custom content type (under Content Definition) called Newsletter, and add two fields (of type Text Field) called Name and E-mail.
Finally, click Forms and add a new Custom Form. Give it a title: this will be the default URL to access e.g. "Newsletter Form" will have a URL of /newsletter-form by Orchard defaults. Under Content Type select your newly created content type, Newsletter, from the dropdown. Customize anything else you want on this page, and click Publish Now
If you want to make this a widget, edit the content type and add the Widget Part. Create a layer with the rules you need and you can add the "Newsletter" widget to any zone you need on that layer.

Orchard cms Extending Menu Item part

What's the best way to extent the Menu part in orchard ?
I want to use the normal menu part for most content types.
But I also want a Custom MainNavigationMenuPart. that has all the things the menu part has but adds a media picker field and a text field to it. - These items that will display on menu rollover.
Option 1
I think this is the best way to go ...
I've looked at writing a custom Menu part - but it seem like a lot of functionality for how the menu part currently work is there, I'm not sure how best to tap into this in a DRY way.
I can add a MenuPartItem to my customPart, so main menu part model would look like this
public class MainMenuPart : ContentPart<MainMenuRecord>
{
public MenuPart MenuPart { get; set; }
public string ShortDescription
{
get { return Record.ShortDescription; }
set { Record.ShortDescription = value; }
}
}
But ...
how do I render this on in the editor view for the part ?
I want to use the exiting MenuPartItemEditor.
how do I save this information in the record for the part?
Option 2
I've looked also at adding fields to the menu part (via cms).
My menu part now looks like this on the back end
Here I have customise the admin view for the menu depending on the content type.
Buy creating a Parts.Navigation.Menu.Edit.cshtml in Views/EditorTemplates, in my custom them I have access to the menu part, but I can seem to control the display of the fileds I have added to the part. (menu image, highlight, and short description)
Here is the custom Parts.Navigation.Menu.Edit.cshtml (original found in Orchard.Core/Navigation/Views/EditorTemplates/Parts.Navigation.Menu.Edit.cshtml)
#model Orchard.Core.Navigation.ViewModels.MenuPartViewModel
#using Orchard.ContentManagement
#using Orchard.Core.Navigation.Models;
#if (!Model.ContentItem.TypeDefinition.Settings.ContainsKey("Stereotype") || Model.ContentItem.TypeDefinition.Settings["Stereotype"] != "MenuItem")
{
if (Model.ContentItem.ContentType == "StandardIndexPage" ||
Model.ContentItem.ContentType == "AlternateIndexPage" ||
Model.ContentItem.ContentType == "MapIndexPage")
{
var sd = ((dynamic)Model.ContentItem).MenuPart.ShortDescription;
#sd
<fieldset>
#Html.HiddenFor(m => m.OnMenu, true)
#Html.HiddenFor(m => m.CurrentMenuId, Model.CurrentMenuId)
<div>
<label for="MenuText">#T("Menu text (will appear on main menu)")</label>
#Html.TextBoxFor(m => m.MenuText, new { #class = "text-box single-line" })
<span class="hint">#T("The text that should appear in the menu.")</span>
</div>
</fieldset>
}
else
{
<fieldset>
#Html.EditorFor(m => m.OnMenu)
<label for="#Html.FieldIdFor(m => m.OnMenu)" class="forcheckbox">#T("Show on menu")</label>
<div data-controllerid="#Html.FieldIdFor(m => m.OnMenu)" class="">
<select id="#Html.FieldIdFor(m => m.CurrentMenuId)" name="#Html.FieldNameFor(m => m.CurrentMenuId)">
#foreach (ContentItem menu in Model.Menus)
{
#Html.SelectOption(Model.CurrentMenuId, menu.Id, Html.ItemDisplayText(menu).ToString())
}
</select>
<span class="hint">#T("Select which menu you want the content item to be displayed on.")</span>
<label for="MenuText">#T("Menu text")</label>
#Html.TextBoxFor(m => m.MenuText, new { #class = "text-box single-line" })
<span class="hint">#T("The text that should appear in the menu.")</span>
</div>
</fieldset>
}
}
else
{
<fieldset>
<label for="MenuText">#T("Menu text")</label>
#Html.TextBoxFor(m => m.MenuText, new { #class = "textMedium", autofocus = "autofocus" })
<span class="hint">#T("The text that should appear in the menu.")</span>
#Html.HiddenFor(m => m.OnMenu, true)
#Html.HiddenFor(m => m.CurrentMenuId, Request["menuId"])
</fieldset>
}
I've also tried to control the display of fields using the placement.info in the theme
<Match ContentType="StandardIndexPage">
<Place Fields_Boolean_Edit-Highlight="-"/>
</Match>
with no success.

Orchard CMS work with MediaPickerField defined in Migrations.cs

MediaPickerFields still elude me.
I've defined a new Part in Migrations.cs and added a Boolean column and a MediaPickerField to the part as follows:
SchemaBuilder.CreateTable("ImageContentPartRecord", table =>
table.ContentPartRecord()
.Column("DisplayImage", DbType.Boolean));
ContentDefinitionManager.AlterPartDefinition("ImageContentPart", builder =>
builder
.Attachable()
.WithField("ImageField", fld =>
fld.OfType("MediaPickerField")
.WithDisplayName("Image")));
Assuming I have ImageContentPart and ImageContentPartRecord classes, how can I retrieve the data from my MediaPickerField (url, dimensions, alt text, class, etc) in my Driver and in my Part Templates (Edit / Display)?
i.e. - Parts.ImageContent.cshtml (I want to accomplish something like this):
<div>
<img src="#Model.ImageField.Url" alt="#Model.ImageField.Alt" />
</div>
Any ideas?
Here is the solution:
In my Display Driver method, I make sure to pass my ImageContentPart(part) when building the ContentShape:
return ContentShape("Parts_ImageContent", () =>
shapeHelper.Parts_ImageContent(
Content: part));
Then in my Template View, I leverage the dynamic nature of Orchard's architecture to consume my MediaPickerField. To do this, you access the .ContentItem property on your part, then leaning on dynamics, chain the part name (.ImageContentPart) and then the field name (.ImageContent) to access the field.
#{
// Attempting to access MediaPickerField named 'ImageContent'
var image = Model.Content.ContentItem.ImageContentPart.ImageContent;
// Leaning on Orchard dynamics to access properties of the field
var url = image.Url;
}
<img src="#url" alt="#T(image.AlternateText)" />
Here is an exhaustive list of MediaPickerField properties from \\Orchard.Fields\Views\Fields\MediaPicker.cshtml:
#*
Alternate Text: #Model.ContentField.AlternateText
Class: #Model.ContentField.Class
Style: #Model.ContentField.Style
Alignment: #Model.ContentField.Alignment
Width: #Model.ContentField.Width
Height: #Model.ContentField.Height
Url: #Model.ContentField.Url
You can also display an image using this example, and add the attributes you need:
<img src="#Href(Model.ContentField.Url)" />
*#
Hopefully, if you stumble upon a similar problem, this will help out!

Resources