SubPointSolutions / spmeta2

SharePoint artifact provision for .NET platform. Supports SharePoint Online, SharePoint 2019, 2016 and 2013 via CSOM/SSOM.
http://subpointsolutions.com/spmeta2
133 stars 56 forks source link

Enhance ListDefinition - add EnableListRatings property #1027

Closed digital88 closed 7 years ago

digital88 commented 7 years ago

Hello. It would be great if SPMeta2 could enable ratings in lists during provisioning. Right now, I do it like this:

public static void EnableListRatings(ClientContext ctx, string listTitle)
{
  bool enabled = false;
  var web = ctx.Site.OpenWeb(string.Empty);
  var list = web.Lists.GetByTitle(listTitle);
  ctx.Load(list, ls=>ls.RootFolder, ls=>ls.RootFolder.Properties, ls=>ls.Fields.Include(f=>f.InternalName));
  ctx.ExecuteQuery();
  foreach (var fld in list.Fields)
  {
    if (fld.InternalName.Equals("RatingCount"))
    {
      enabled = true;
      break;
    }
  }
  if (!enabled)
  {
    // this is built in SP fields
    var avgRating = web.Fields.GetById(new Guid("5a14d1ab-1513-48c7-97b3-657a5ba6c742"));
    var rateCount = web.Fields.GetById(new Guid("b1996002-9167-45e5-a4df-b2c41c6723c7"));
    var ratedBy = web.Fields.GetById(new Guid("4D64B067-08C3-43DC-A87B-8B8E01673313"));
    var rating = web.Fields.GetById(new Guid("434F51FB-FFD2-4A0E-A03B-CA3131AC67BA"));
    var likesCount = web.Fields.GetById(new Guid("6E4D832B-F610-41a8-B3E0-239608EFDA41"));
    var likedBy = web.Fields.GetById(new Guid("2CDCD5EB-846D-4f4d-9AAF-73E8E73C7312"));
    var flds = new Field[]
    {
      avgRating,rateCount,ratedBy
      rating,likesCount,likedBy
    }

    foreach (var fld in flds)
    {
      ctx.Load(fld);
    }
    ctx.ExecuteQuery();

    foreach (var fld in flds)
    {
      list.Fields.Add(fld);
    }
    list.Update();
    ctx.ExecuteQuery();

    list.RootFolder.Properties["Ratings_VotingExperience"] = "Ratings"; // could be either "Ratings" or "Likes"
    list.RootFolder.Update();
    ctx.ExecuteQuery();
  }
}
SubPointSupport commented 7 years ago

@digital88, thank you for reporting this one.

It's a great idea and we had a few similar suggestions reported early. We'd be happy to implement this feature. However, it doesn't seem to be related to a particular SharePoint API. SPMeta2 maps and provides POCOs for most of the SharePoint objects without a particular opinion but in this case, we would be providing some kind of custom logic with a particular opinion on how it should work.

Simply saying, this does look like a component or some kind of extension for SPMeta2 library rather than definition. Having this one as some kind of plugin or component for SPMeta2 would be a better fit, we guess.

Next, you can still implement this one with SPMeta2. You need to add list, and then add all fields, and then add property bag value to the root folder. Natively, it would be a quite verbose syntax with .AddList(), .AddFieldLink() and AddProperty() but you can wrap it up into a custom syntax to simplify the usage:

You might end up with something as this where .AddListWithRatings() method is your custom syntax. Internaly, it would get the list definition, add it to the model, and then add all the required fields and property bags.

var webModel = SPMeta2Model.NewWebModel(web => {

    web.AddListWithRatings(you-list-definition);

});

That way you still stay on SPMeta2, your model is serializable, you still can deploy with CSOM/SSOM.

What do you think?

digital88 commented 7 years ago

Yes, I think I will just rewrite it in a couple of SPMeta AddXXX() methods.

SubPointSupport commented 7 years ago

Sweet, thank you. We probably need to blog about it. How is the rest? No major blockers?