0

更新: 根据伯特兰的建议和我自己的发现,我已经彻底改变了原来的问题。现在它在其文本中提供了一个不完整的解决方案,而不是我自己对果园的盲目曲折和评论,这是完全错误的!

我需要在悬停/选择时使用图像而不是文本、一个标准和另一个标准来显示菜单。该站点的要求规定最终用户应该能够管理菜单项图像。标准导航模块现在提供了一个 HTML 菜单项,这不是最终用户想要的。客户想要一个非常简单、直观的界面来配置站点许多菜单,并且所有菜单都是基于图像的。

根据 Bertrand 的建议,在意识到内容菜单项是内容类型之后,我在管理界面中创建了一个新的内容部件(不是通过代码,我只想在最终需要时为部件和内容类型编写代码.. . 我真的很想看看我可以通过使用管理界面和模板/CSSing 与 Orchard 一起走多远)。

因此,我创建了一个菜单图像部件,其中添加了两个内容选择器字段:图像和悬停图像。然后我将此部分添加到管理内容项管理界面的内容菜单项中。

由于我没有为它编写驱动程序,因此传递给菜单项模板的模型没有像@Model.Href 这样易于访问的属性...到目前为止,我已经用以下代码覆盖了 MenuItemLink-ContentMenuItem.cshtml :

@using Orchard.Core.Common.Models
@using Orchard.ContentManagement
@{
    var contentManager = WorkContext.Resolve<IContentManager>();
    var itemId = Model.Content.ContentItem.ContentMenuItemPart.Id;
    ContentItem contentItem = contentManager.Get(itemId);
    ContentField temp = null;
    var menuImagePart = contentItem.Parts.FirstOrDefault(p => p.PartDefinition.Name == "MenuImagePart");
    if (menuImagePart != null)
    {
        temp = menuImagePart.Fields.First();
    }
}

<span>@temp</span>
<a href="@Model.Href">@Model.Text</a>

这会在链接中生成预期的菜单标题,在它之前有一个跨度和以下文本:

Orchard.Fields.Fields.MediaPickerField 

所以上面所有代码(获取当前内容管理器和表示ContentMenuItemPart的ContentItem的id,然后使用内容管理器获取ContentItem本身,然后linqing over它的Parts找到MenuImagePart(我不能使用Get来获取它因为它需要一个类型并且 MenuImagePart 不是一个类型,所以它是在管理界面中创建的),然后最终获得第一个字段用于调试目的(这应该是我创建的 MenuImagePart 的 Image 字段......)。 .. 以上所有代码实际上让我进入了我的 Meny Image Part 上的媒体选择器字段...

What I'm not being able to do, and what makes me certainly a lot obtuse and stupid, is to find a way to read the MediaPickerField URL property! I've tried casting it to MediaPickerField, but I can't access its namespace from inside my template code above. I don't even know which reference to add to my theme to be able to add the following directive to it:

@using Orchard.Fields.Fields

4

1 回答 1

2

I've finally succeeded in this task (thanks to Bertrand's direction).

UPDATE: And thanks again to Bertrand I've polished the solution which was running in circles, querying content items from the content manager when they were already available on the Model... now I'm leveraging the dynamic nature of content item, etc. And I'm finally satisfied with this solution.

It was necessary to create a new Content Part called Menu Image, then add this to the Content Type named Content Item Menu, and finally overriding the Content Item Menu template. This last part was the really tricky one. If it was not for Bertrand's directions the code bellow would have been smelly and daunting. The template ended up as follow:

@using Orchard.Utility.Extensions;
@using System.Dynamic
@{

/* Getting the menu content item
***************************************************************/

var menu = Model.Content.ContentItem;

/* Creating a unique CSS class name based on the menu item
***************************************************************/

// !!! for some reason the following code throws: 'string' does not contain a definition for 'HtmlClassify'
//string test = menu.ContentType.HtmlClassify();
string cssPrefix = Orchard.Utility.Extensions.StringExtensions.HtmlClassify(menu.ContentType);
var uniqueCSSClassName = cssPrefix + '-' + Model.Menu.MenuName;

/* Adds the normal and hovered styles to the html if any
***************************************************************/

if (menu.MenuImagePart != null)
{

    if (!string.IsNullOrWhiteSpace(menu.MenuImagePart.Image.Url))
    {
    using(Script.Head()){
    <style>
        .@uniqueCSSClassName {
            background-image: url('@Href(menu.MenuImagePart.Image.Url)');
            width: @{@menu.MenuImagePart.Image.Width}px;
            height: @{@menu.MenuImagePart.Image.Height}px;
            display: block;
        }
    </style>
    }
    }
    if (!string.IsNullOrWhiteSpace(menu.MenuImagePart.HoverImage.Url))
    {
    using(Script.Head()){
    <style>
        .@uniqueCSSClassName:hover {
            background-image: url('@Href(menu.MenuImagePart.HoverImage.Url)');
            width: @{@menu.MenuImagePart.HoverImage.Width}px;
            height: @{@menu.MenuImagePart.HoverImage.Height}px;
        }
    </style>    
    }
    }
}
}    
<a class="@uniqueCSSClassName" href="@Model.Href">@Model.Text</a>

The only thing that I didn't understand is why I can't use HtmlClassify as an extension method with menu.ContentItem.HtmlClassify() and have to resort to calling the method as a standard static method (see the line with the comment `// !!! for some reason the following code throws´...)

Thanks again Bertrand!

于 2012-09-17T08:31:33.033 回答