For the code:
strMenuText.Append(RenderLink(mainlinkitem,
x => x.NavigationItem.Url.StringToLink(),
isEditable: true,
contents: mainlinkitem.NavigationTitle));
Here mainlinkitem
is Navigation object for interface created for data template.
I am using interfaces in this case and castle windsor creates dynamic proxy objects for this.
Things work ok until I try to use Page editor mode and below error shows up from glass mapper api.
Expression doesn't evaluate to a member x.NavigationItem.Url.StringToLink() at Glass.Mapper.Sc.GlassHtml.MakeEditable[T](Expression
1 field, Expression
1 standardOutput, T model, String parameters, Context context, Database database, TextWriter writer)
Note: StringToLink is extension method for converting external url in string
form to Glass mapper Glass.Mapper.Sc.Fields.Link
type.
public static Link StringToLink(this string urlvalue)
{
Link itemLink = new Link();
itemLink.Url = urlvalue;
return itemLink;
}
UPDATE
Code for menu user control:
public partial class MenuControl : GlassUserControl<INavigationFolder>
{
protected override void GetModel()
{
base.GetModel();
SiteLevelSettings siteSettings = SitecoreContext.GetItem<SiteLevelSettings>(Guid.Parse("Some GUID"));
Model = siteSettings.HeaderMenuFolder;
}
protected void Page_Load()
{
if (!Page.IsPostBack)
{
LoadMenu();
}
}
private void LoadMenu()
{
StringBuilder strMenuText = new StringBuilder();
foreach (INavigationLink mainlinkitem in Model.ChildLinks)
{
if (CanRead(mainlinkitem))
{
strMenuText.Append("<td class='menu-item'>");
if (mainlinkitem.ChildLinks != null && mainlinkitem.ChildLinks.Count() > 0)
{
strMenuText.Append("<ul>");
foreach (INavigationLink linkitem in mainlinkitem.ChildLinks)
{
if (CanRead(linkitem))
{
strMenuText.Append("<li>");
if (linkitem.NavigationItem != null)
{
strMenuText.Append(RenderLink(linkitem, x => x.NavigationItem.Url.StringToLink(), isEditable: false, contents: linkitem.NavigationTitle));
}
else if (linkitem.NavigationGeneralLink != null)
{
strMenuText.Append(RenderLink(linkitem, x => x.NavigationGeneralLink, isEditable: false, contents: linkitem.NavigationTitle));
}
strMenuText.Append("</li>");
}
}
strMenuText.Append("</ul>");
}
strMenuText.Append("<div class='nav-divider'>");
if (mainlinkitem.NavigationItem != null)
{
strMenuText.Append(RenderLink(mainlinkitem, x => x.NavigationItem.Url.StringToLink(), isEditable: false, contents: mainlinkitem.NavigationTitle));
}
else if (mainlinkitem.NavigationGeneralLink != null)
{
strMenuText.Append(RenderLink(mainlinkitem, x => x.NavigationGeneralLink, isEditable: true, contents: mainlinkitem.NavigationTitle));
}
strMenuText.Append("</div></td>");
}
}
ltrMenu.Text = strMenuText.ToString();
}
private bool CanRead(IItem mainlinkitem)
{
var ItemId = mainlinkitem.TemplateId;
var ItemIDObj = new Sitecore.Data.ID(ItemId);
var contentdatabase = Sitecore.Context.Database;
var item = contentdatabase.GetItem(ItemIDObj);
return item.Access.CanRead();
}
}
Navigation Folder interface for glass mapper:
[SitecoreType(TemplateId = "{Some GUID}")]
public interface INavigationFolder : IItem
{
[SitecoreChildren(IsLazy = false)]
IEnumerable<INavigationLink> ChildLinks { get; set; }
}
Navigation Link interface for glass mapper:
[SitecoreType(TemplateId = "{Some GUID}")]
public interface INavigationLink : IItem
{
[SitecoreField(FieldId = "{Some GUID}")]
string NavigationTitle { get; set; }
[SitecoreField(FieldId = "{Some GUID}")]
IItem NavigationItem { get; set; }
[SitecoreField(FieldId = "{Some GUID}")]
Link NavigationGeneralLink { get; set; }
[SitecoreField(FieldId = "{Some GUID}")]
string ShortDescription { get; set; }
[SitecoreChildren(IsLazy = false)]
IEnumerable<INavigationLink> ChildLinks { get; set; }
}
Note: This will code will generate menu similar to sitecore site
UPDATE
Url property in interface IItem
is defined as follows:
[SitecoreType(TemplateId = "{Some GUID}")]
public interface IItem
{
[SitecoreId()]
Guid ID { get; }
[SitecoreInfo(Type = SitecoreInfoType.Language)]
Language Language { get; }
[SitecoreInfo(Type = SitecoreInfoType.Version)]
int Version { get; }
[SitecoreInfo(Type = SitecoreInfoType.Url)]
string Url { get; }
[SitecoreInfo(Type = SitecoreInfoType.TemplateId)]
Guid TemplateId { get; }
[SitecoreInfo(Type = SitecoreInfoType.Key)]
string Key { get; }
}
RenderLink
method is from glass mapper library my usercontrol is inheriting fromGlassUserControl<T>
class whereT
is my model representing data template – Harsh Baid