1
votes

update: I'm using Sitecore version 7.0

I'm using Glass.Mapper.Sc with success so far. I've got a number of models being succesfully mapped. I've now just tried my first Query mapping and cannot get it to work.

I have the following two models

[SitecoreType(TemplateName = "Testimonial")]
public class Testimonial : ContentItem
{
    [SitecoreField(FieldType = SitecoreFieldType.MultiLineText)]
    public virtual string Summary { get; set; }

    [SitecoreField(FieldType = SitecoreFieldType.RichText)]
    public virtual string Testimony { get; set; }

    [SitecoreField]
    public virtual string Testifier { get; set; }

    [SitecoreField(FieldType = SitecoreFieldType.GeneralLink)]
    public virtual Link TestifierUrl { get; set; }

    [SitecoreField]
    public virtual string Company { get; set; }

}

and

[SitecoreType(TemplateName = "Testimonials")]
public class Testimonials : ContentFeatureItem
{
    public Testimonials()
    {
        TestimonialList = new List<Testimonial>();
    }

    [SitecoreQuery("/sitecore/content//*[@@templatename='Testimonial']", IsRelative = true)]
    public virtual IEnumerable<Testimonial> TestimonialList { get; set; }
}

According to the tutorial I should expect that TestimonialList be populated with a list of Testimonial items. However, the list is always empty.

I have checked that the path is valid by both using the XPath builder in the Developer Tools of sitecore and through the following usage of the Sitecore API.

var query = new Query("/sitecore/content//*[@@templateName='Testimonial']");
var returnVal = query.Execute();

Where returnVal is populated with the expected items. I've also tried ./*[@@templateName='Testimonial'] as the query on the mapping attribute.

I've successfully manually retrieved a specific Testimonial instance to check that it's not some weird mapping issue.

This issue aside, everything appears to be working correctly with Glass.Mapping.Sc and my models. So far I've followed the tutorials on glass.lu, and I've installed Glass.Mapping.Sc via NuGet.

I've had a look through the source on github but can't see anything that may be causing my problem. Has anyone else had this problem or successfully used query populated parameters with glass?

UPDATE (Following Michael's reply):
I added the following property to the Testimonials class

[SitecoreQuery("./*")]
public virtual IEnumerable<AbstractModel> Children { get; set; }

This returned a populated IEnumerable of AbstractModel's that were the 6 Testimonial items that are direct children of the Testimonials item.

I also tried

[SitecoreQuery("//*")]
public virtual IEnumerable<AbstractModel> Children { get; set; }

and got the same result. I don't understand that one, becuase I'd expect to get many more items than just the 6 testimonials.

I deleted the TestimonialList property and added a new property, Children, and this property works perfectly

[SitecoreQuery("./*[@@templatename='Testimonial']", IsRelative = true)]        
public virtual IEnumerable<Testimonial> Children { get; set; }      

I then used resharper to rename the property to TestimonialList, and then ZYX, then Blerg. All three times it didn't work (didn't populate), but if I rename back to Children, everything is ok. Strange.

More Update I have found why the query seemed to be working when the property is named "Children". It doesn't work, which is way I was getting unexpected results. "Children" is a common property that is populated on all Child items. Because all my child items are Testimonials, this can be correctly populated.

So if I change my property to just the following it is still correctly populated

public virtual IEnumerable<Testimonial> Children { get; set; } 

Seen in Glass.Mapper.Sc.Integration.DataMappers.SitecoreChildrenMapperFixture.MapToProperty_ItemHasThreeChildren_ThreeObjectsAreCreated.

2

2 Answers

5
votes

Your query isn't a relative query so you need to update the attribute to this:

[SitecoreQuery("/sitecore/content//*[@@templatename='Testimonial']")]
public virtual IEnumerable<Testimonial> TestimonialList { get; set; }

Removing the IsRelative means that Glass will query from the root of the solution. By default the IsRelative flag is false.

IsRelative is used to indicate that the query is relative to the current item being loaded by Glass. For example if I have a News landing page and I wanted to get only children of the news page which had a feature flag I might do this:

[SitecoreQuery("./*[@featured='1']", IsRelative=true)]
public virtual IEnumerable<News> FeaturedNews { get; set; }

I hope this explains the use of the IsRelative flag, if it doesn't let me know and I will write up a blog post for the Glass site.

0
votes

I have found my problem (after spending a few hours searching through the Glass Mapper source - at least I learned some stuff about Glass Mapper :)). I renamed my assembly a while back and I hadn't changed the name being passed into {{SitecoreAttributeConfigurationLoader}}.

Once I changed that name I still couldn't get it to work so I deleted the old dll from my bin folder, restarted the PC and danced around the desk a few times chanting work! work! work! over and over (ok that last bit was made up).

After that, everything works ok.