5

My item template has a field for a General Link and is representing by the following class:

[SitecoreType]
public class MenuLink
{
    [SitecoreField(FieldName = "Link")]
    public virtual Link Link { get; set; }
}

Now my link field contains external and internal links (links pointing to other items). Is it possible to configure Glass Mapper that the Url Property of the Link contains the absolute url (like AlwaysIncludeServerUrl=true)? And also that is used the site resolving (SiteResolving=true)?

Basically I would like to give the Link property an UrlOptions configuration.

I'm using Sitecore 7.1 with Glass.Mapper.Sc 3.1.2.18.

Marek Musielak
  • 26,832
  • 8
  • 72
  • 80
Kevin Brechbühl
  • 4,717
  • 3
  • 24
  • 47

3 Answers3

7

Kevin

Please download release 3.1.6 I have added the UrlOptions property to the SitecoreFieldAttribute class. You should be able for force the server path like so:

[SitecoreField(UrlOptions=SitecoreInfoUrlOptions.AlwaysIncludeServerUrl)]
public virtual Link MyLink{get;set;}

You can also added other options by piping the flags:

[SitecoreField(UrlOptions=SitecoreInfoUrlOptions.AlwaysIncludeServerUrl|SitecoreInfoUrlOptions.LanguageEmbeddingNever)]
public virtual Link MyLink{get;set;}
Michael Edwards
  • 6,308
  • 6
  • 44
  • 75
4

Have you tried replacing SitecoreField attribute with:

[Glass.Mapper.Sc.Configuration.Attributes.SitecoreInfo(Type=Glass.Mapper.Sc.Configuration.SitecoreInfoType.Url,UrlOptions= Glass.Mapper.Sc.Configuration.SitecoreInfoUrlOptions.AlwaysIncludeServerUrl)]

I have not tried this yet, but worth trying.

Update : This method is not working correctly, please refer to Michael solution.

Community
  • 1
  • 1
Ahmed Okour
  • 2,392
  • 1
  • 16
  • 31
  • This does not work for me. If I add the attribute to my "Link" property, I get the exception "Failed to map property Link on DomainModel.MenuLink" -> "Unable to cast object of type 'System.String' to type 'Glass.Mapper.Sc.Fields.Link'.". So this attribute only returns the Url and not the complete Link Property with the Url as absolute link? When I add a new string Property and add the attribute, I get the raw values of the link field instead of the desired url. And does this attribute only work with with 1 UrlOptions parameter? How to achieve this if I also would like to add "SiteResolving"? – Kevin Brechbühl Jan 20 '14 at 09:37
  • Nice one, I didn't know about this. – Ruud van Falier Jan 20 '14 at 10:03
  • 3
    Sorry kevin I thought Amhed had used the Field handler but I realise now that the SitecoreField attribute doesn't have the UrlOptions attribute. i will add this and get a release out ASAP. – Michael Edwards Jan 20 '14 at 10:54
4

Add this extension method to your solution:

using Sitecore;
using Sitecore.Links;
using Glass.Mapper.Sc.Fields;

public static class LinkExtensions
{
    public static string GetLinkUrl(this Link link, ISitecoreContext sitecoreContext = null)
    {
        if (link != null)
        {
            if (link.Type == LinkType.External || link.Type == LinkType.Media)
            {
                return link.Url;
            }
            else if (link.Type == LinkType.Internal)
            {
                var target = (sitecoreContext ?? new SitecoreContext()).Database.GetItem(new ID(link.TargetId));

                var urlOptions = Sitecore.Links.UrlOptions.DefaultOptions;
                urlOptions.AlwaysIncludeServerUrl = true;
                urlOptions.SiteResolving = true;

                return LinkManager.GetItemUrl(target, urlOptions);
            }
        }

        return string.Empty;
    }
}

Then, assuming you have this model:

[SitecoreType]
public class MenuLink
{
    [SitecoreField(FieldName = "Link")]
    public virtual Link Link { get; set; }
}

You can get the URL like this:

model.Link.GetLinkUrl();
Ruud van Falier
  • 8,765
  • 5
  • 30
  • 59
  • I like this idea, but what I don't like is the dependency to the "Context.Database", what makes the code harder to test. Glass uses an instance of "SitecoreContext" to resolve the context. Do you see a solution to use the same context as Glass uses to map the Item instead of using another context? – Kevin Brechbühl Jan 20 '14 at 09:43
  • Hehe, I was afraid you would ask that ;) You can simply pass in the ISitecoreContext as an optional parameter. In your Unit Tests you would use the parameter, in your regular code you would just leave it blank so it created a SitecoreContext itself. You should look into the solution that Ahmed gave. That seems to be the correct way of doing it and I didn't know that. – Ruud van Falier Jan 20 '14 at 10:02
  • Jep, that would be an easy way. Will try this. Thanks for the hint, but the solution from Ahmed doesn't actually work (see my comment). So if this won't work, this would be a nice alternative :) – Kevin Brechbühl Jan 20 '14 at 10:39