2012-09-16 47 views
0

更新:我已經根據伯特朗的建議和我自己的發現大幅改變了原來的問題。現在它在文本中提供了一個不完整的解決方案,而不是我自己對Orchard的盲目歪曲和評論,完全是錯誤的!如何擴展果園導航模塊添加圖像到菜單項

我需要顯示一個菜單,使用圖像而不是文本,一個標準,另一個用於懸停/選擇。對網站的要求規定最終用戶應該能夠管理菜單項圖像。標準導航模塊現在提供HTML菜單項,這不是最終用戶想要的。客戶需要一個非常簡單直觀的界面來配置網站上的許多菜單,所有菜單都是基於圖像的。

根據Bertrand的建議,在實現內容菜單項是內容類型之後,我在管理界面中創建了一個新的內容部件(不是通過代碼,我只想爲部件和內容類型編寫代碼最終需要......我真的很想看看我能夠通過使用管理界面和模板/ CSS來與Orchard走多遠)。

所以,我創建了一個Menu Image Part,其中添加了兩個Content Picker字段:Image和Hover Image。然後我將這部分添加到管理內容項管理界面中的內容菜單項。

因爲我沒有爲它寫驅動程序,所以傳遞給菜單項模板的Model沒有像@ Model.Href這樣的易訪問的屬性...我已經用MenuItemLink-ContentMenuItem.cshtml覆蓋了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 

因此,所有上面的代碼(獲取當前內容管理器和表示ContentMenuItemPa的ContentItem的id rt,然後使用內容管理器獲取ContentItem本身,然後通過它的Parts找到MenuImagePart(我不能使用Get來獲取它,因爲它需要一個類型,而MenuImagePart不是一個類型,它是在管理中創建的接口),然後最後得到第一個字段用於調試目的(這應該是我創建的MenuImagePart的圖像字段...)...以上所有代碼實際上讓我到我的Meny圖像部件上的媒體選擇器字段...

我不能做的事情,是什麼讓我當然很愚蠢和愚蠢,是找到一種方法來閱讀MediaPickerField的URL屬性!我已經嘗試將其轉換爲MediaPickerField,但是我無法從上面的模板代碼中訪問它的名稱空間。我甚至不知道要加入哪個參考我的主題,能夠將以下指令添加到它:

@using Orchard.Fields.Fields

+1

從HTML菜單項開始。 David Hayden在擴展導航方面也有一個很好的帖子:http://www.davidhayden.me/blog/dynamically-injecting-menu-items-in-orchard-cms –

+0

Bertrand,這就是我已經嘗試的! Html菜單做我想做的事情,它爲菜單「添加」一個新的「字段」,但我正在考慮另一種方法,可能會更容易,而且仍然很優雅。我可以創建一個MenuImagePart並將其添加到我想在菜單中顯示的任何內容。因此,任何內容都可以指定在菜單項顯示時使用哪些圖像,而不實際更改MenuItemPart上的任何內容。我將不得不能夠讓ContentMenuItem得到它指向的ContentItem,以便我可以從中讀取MenuImagePart。它可行嗎? – Loudenvier

+1

只需添加一個媒體選擇器字段,並覆蓋主題中的模板,以顯示其內容。 –

回答

2

我終於成功地將這個任務(感謝伯特蘭的方向)。

UPDATE:再次並感謝貝特朗我擦亮這是手忙腳亂的解決方案,從內容管理器查詢內容項目時,他們的模型已經可以......現在我借力內容項目的動態性質等。我終於滿意這個解決方案。

有必要創建一個名爲Menu Image的新內容部件,然後將其添加到名爲Content Item Menu的Content Type中,最後覆蓋Content Item Menu模板。這最後一部分是非常棘手的。如果不是伯特蘭的指示,那麼這個代碼會變得很臭和令人生畏。模板結束如下:

@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> 
     [email protected] { 
      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> 
     [email protected]: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> 

,我不知道的唯一的事情是爲什麼我不能使用HtmlClassify與menu.ContentItem.HtmlClassify()擴展方法,並不得不訴諸調用該方法作爲標準靜態方法(請參閱「// !!!由於某些原因,下面的代碼會拋出'......'行)

再次感謝Bertrand!

+1

是的,您在這裏錯過了一些東西:D首先,沒有充分的理由說明,爲什麼您需要通過向內容項目查詢內容管理器來獲取內容項目。 )其次,你可以在ContentItem中使用動態支持來簡化你的代碼:'var menuImagePart = Model.ContentItem.MenuImagePart;'第三,你也可以通過動態支持訪問字段:'menuImagePart .FieldName.Url' –

+0

@BertrandLeRoy,無視我以前的,珍貴的,有點愚蠢的評論。我只是盲目地複製你的代碼!內容項目可以在'Model.Content.ContentItem'處訪問,現在所有的代碼都可以使用最小代碼。我會更新答案以反映您的指導方針。這是一個好主人,在圈內跑步幫助我挖掘果園的一些內部運作! – Loudenvier

+0

HtmlClassify是一種擴展方法。您需要包含相關的名稱空間才能使用它。 –