when you hit edit in orchard for a menu it takes you to the widget. I am trying to figure out how to make the edit link go to the specific navigation that the menu widget holds.
You can alter default Display/Edit/Remove links for any content item by using OnGetContentItemMetadata method inside a content handler.
In your specific example, making edit link for a widget to point to the underlying menu editor would look like:
public class MyHandler : ContentHandler
{
public MyHandler()
{
OnGetContentItemMetadata<MenuWidgetPart>((ctx, part) =>
{
ctx.Metadata.EditorRouteValues = new RouteValueDictionary
{
{ "Area", "Navigation" },
{ "Controller", "Admin" },
{ "Action", "Index" },
{ "menuId", part.MenuContentItemId }
};
});
}
}
Related
I use Orchard CMS 1.10.1. I have created a content type, now I want to have a section menu in admin page to have specific links for this content type. I want it include New link and content item list for this content type.
How can i achieve this? preferably with no editing in the code.
You can't do this without code, at the same time you will need a small code chunk to achieve this, like the following code:
public class AdminMenu : INavigationProvider {
public Localizer T { get; set; }
public string MenuName {
get { return "admin"; }
}
public void GetNavigation(NavigationBuilder builder) {
builder
.Add(T("Your Content Type Display Name"), "1", menu => menu
.Action("List", "Admin", new { area = "Contents", id = "YourContentTypeName" }));
}
}
I have created my navigation menus in Orchard using a mix of Content Item and Custom Link Elements (parts of the website are outside the scope of the CMS). Now there are a couple of links that I need to open in a new window/tab, basically the target="_blank" behaviour.
SInce the original Custom Link does not have any parameters I tried to create an extended version of it. In the admin backend I went to "Content definition" looked up Custom Link and tried to create a copy of it, then add a target field that I could check for and use in my theme's Menu.cshtml file.
However I can't even get the basic carbon copy of the Custom Link item working. It has the same stereotype, same Parts, same Forms (none) as the original Custom Link, and it does appear in the list of items on the admin -> navigation window. However the item does not have a field for the URL/link. It only has the field for Menu Text, nothing else.
So my question is 2-tiered:
How can I get a carbon copy of the Custom Link item type working in my Orchard backend navigation?
When I have my copy of the Custom Link working and add a text field named target, how can I access its value in the Menu.cshtml view?
(I tried simply adding a URL field to my copy, that would then show up in the navigation editor, however the navigation itself would ignore it in the output and create a link to the content item id instead).
Any help is greatly appreciated!
Edit: Here are some screenshots to better illustrate the problem, maybe they can help pin down the problem.
Seems like you've done everything right. Please double check if MenuItemPart is there. This part is responsible for holding the URL information and displaying an editor for it. Not sure if this part is attachable though - if it's not, then make it so in the Content Definition\Parts pane.
Instead of hardwiring things inside Menu.cshtml, you should create a file named MenuItemLink-[YourTypeName].cshtml. This shape file will be used to display your custom menu items. Then you can access any fields via Model.Content object, eg. Model.Content.YourTypeName.FieldWithTargetName.Value.
You need to use the MenuItemPart because it has a few important functions integrated into Orchard.Core.
This works fine:
AdvancedMenuItemPartRecord:
public class AdvancedMenuItemPartRecord : ContentPartRecord
{
public virtual string Target { get; set; }
public virtual string Classes { get; set; }
}
AdvancedMenuItemPart:
public class AdvancedMenuItemPart : ContentPart<AdvancedMenuItemPartRecord>
{
public string Target
{
get { return Retrieve(x => x.Target); }
set { Store(x => x.Target, value); }
}
public string Classes
{
get { return Retrieve(x => x.Classes); }
set { Store(x => x.Classes, value); }
}
}
AdvancedMenuItemPartDriver:
public class AdvancedMenuItemPartDriver : ContentPartDriver<AdvancedMenuItemPart>
{
protected override string Prefix
{
get { return "AdvancedMenuItem"; }
}
protected override DriverResult Editor(AdvancedMenuItemPart part, dynamic shapeHelper)
{
return ContentShape("Parts_AdvancedMenuItem_Edit", () => shapeHelper.EditorTemplate(TemplateName: "Parts/AdvancedMenuItem", Model: part, Prefix: Prefix));
}
protected override DriverResult Editor(AdvancedMenuItemPart part, IUpdateModel updater, dynamic shapeHelper)
{
updater.TryUpdateModel(part, Prefix, null, null);
return Editor(part, shapeHelper);
}
}
AdvancedMenuItemPartHandler (ActivatingFilter add MenuItemPart to your AdvancedMenuItem dynamicaly):
public class AdvancedMenuItemPartHandler : ContentHandler
{
public AdvancedMenuItemPartHandler(IRepository<AdvancedMenuItemPartRecord> repository)
{
Filters.Add(StorageFilter.For(repository));
Filters.Add(new ActivatingFilter<MenuItemPart>("AdvancedMenuItem"));
}
}
Placement.info:
<Place Parts_AdvancedMenuItem_Edit="Content:11"/>
Migrations:
public int UpdateFrom2()
{
SchemaBuilder.CreateTable("AdvancedMenuItemPartRecord",
table => table
.ContentPartRecord()
.Column<string>("Target")
.Column<string>("Classes")
);
ContentDefinitionManager.AlterPartDefinition("AdvancedMenuItemPart", part => part
.WithDescription(""));
ContentDefinitionManager.AlterTypeDefinition("AdvancedMenuItem", cfg => cfg
.WithPart("AdvancedMenuItemPart")
.WithPart("MenuPart")
.WithPart("CommonPart")
.WithIdentity()
.DisplayedAs("Custom Link Advanced")
.WithSetting("Description", "Custom Link with target and classes fields")
.WithSetting("Stereotype", "MenuItem")
// We don't want our menu items to be draftable
.Draftable(false)
// We don't want the user to be able to create new ActionLink items outside of the context of a menu
.Creatable(false)
);
return 3;
}
MenuItemLink-AdvancedMenuItem.cshtml:
#{
var advancedPart = Model.Content.AdvancedMenuItemPart;
var tag = new TagBuilder("a");
tag.InnerHtml = WebUtility.HtmlDecode(Model.Text.Text);
tag.MergeAttribute("href", Model.Href);
if (!string.IsNullOrWhiteSpace(advancedPart.Target)) {
tag.MergeAttribute("target", advancedPart.Target);
}
if (!string.IsNullOrWhiteSpace(advancedPart.Classes))
{
tag.AddCssClass(advancedPart.Classes);
}
}
#Html.Raw(tag.ToString(TagRenderMode.Normal))
I have a View with 2 textbox and a button that call an action on a ViewModel to show another View; that what will show in it depends on values of 2 texbox.
For that reason before to call my ViewModel i want to check textbox values and if its are empty show a Dialog. Now to call my ViewModel i have add a binding like this:
this.AddBindings(new Dictionary<object, string>()
{
{ btnSearch, "TouchUpInside GoParameterizedCommand" },
});
as Swiss Binding. Now if i want to use same event to check if my textbox are valorized and don't call GoParameterizedCommand, how could i do?
You could bind all your controls to ViewModel properties like:
this.AddBindings(new Dictionary<object, string>()
{
{ btnSearch, "TouchUpInside GoCommand" },
{ text1, "Text MyText" },
{ switch1, "On MyOption" },
// ...
};
Then inside the GoCommand handler you could put whatever logic you need:
public ICommand GoCommand
{
get
{
return new MvxCommand(() => {
if (MyOption)
{
ShowViewModel<OptionViewModel>();
}
else
{
ShowViewModel<DetailViewModel>(new { text = MyText });
}
});
}
}
For showing a dialog - eg an error dialog - then this might be best done using a messenger - sending an error message from the viewmodel. There are a few questions on here about error handling - eg http://slodge.blogspot.co.uk/2012/05/one-pattern-for-error-handling-in.html - plenty of other options are available for giving the user a hint about what to do - eg you could bind the background colour of the text field to an IsMyTextValid property.
Using Orchard cms 1.5.1 I have created a module which contains controller that fetches list from a web service.
I want to add a menu item in main menu when this module is enabled. For that i have created
MainMenu as follows:
public class MainMenu:INavigationProvider
{
public Localizer T { get; set; }
public String MenuName
{
get { return "main"; }
}
public void GetNavigation(NavigationBuilder builder)
{
builder.Add(menu => menu.Add(T("Fetched List"), "4", item => item.Action("Index", "FetchedList")));
}
}
When my module is enabled, navigation won't show that menu item. Am i doing something wrong?
From Orchard 1.5.0 onwards, INavigationProvider isn't used to build menus on the front end (it is still used to build the admin menu for the Dashboard though). You need to implement either IMenuProvider or INavigationFilter. See this post on David Hayden's blog for some pointers. You can also find good examples in both Orchard.Projections, and Orchard.CulturePicker.
Hi i m added the File menu item creating the views, my code look like
final Class viewClass : new Class[] { Dashboard.class,
Editor.class, Ticket.class, MockupView.class }) {
navigator.addView(viewClass.getSimpleName(), viewClass);
menu.addItem(viewClass.getSimpleName(), new MenuBar.Command() {
public void menuSelected(MenuItem selectedItem) {
navigator.navigateTo(viewClass);
}
});
but how to add sub menu item inside this menu, any one can help me if you provide me example it will be great full for me
menu.addItem returns a reference to the new menu item, which you can then use to add child items:
MenuBar.MenuItem item = menu.addItem("Parent", null);
item.addItem("Child", null);
Everything you need to know is on this Vaadin documentation page