Sitecore Experience Accelerator (SXA): Creating a Site - Part 3.2 Custom Modules - Social Feed

Configuration

To create a custom module from scratch the first step is very similar to what we did in Part 3.1 (Add Module)

Once the module has been added the next step is to manually create the different items that were created automatically in the previous blog post. i.e.

  • Templates
  • Branches
  • Renderings
  • Settings

Templates

The first item we need to add is the data templates. Go to Templates/Features/ITWORX/Social Feed

Create a template that has the base /sitecore/templates/System/Templates/Template and has the base template Folder and name it Social Feed Folder

Next create a template for the Social Feeds that inherits from Standard Template. The template should contain the access tokens for the different social media channels, a title for the social feed

Create a Rendering Parameters folder and add configurations for each social media whether it should be visible or not

Renderings

Next go to renderings/features/ITWORX/social feed and insert a controller rendering. We will discuss how to write the controller later in this article but for now add the fully qualified name of the controller class that you will create (ITWORX.SXA.Feature.SocialFeed.Controllers.SocialfeedsController,ITWORX.SXA.Feature.SocialFeed)

  • Add Controller Action as Index
  • Configure the Rendering Parameters to the rendering parameters you created, i.e. Templates/Feature/ITWORX/Social Feed/Rendering Parameters/Social Feed
  • Add Data Source as query:$site/*[@@name='Data']/*[@@templatename='Social Feed Folder']|query:$sharedSites/*[@@name='Data']/*[@@templatename='Social Feed Folder']. This states that the data source will reside inside Data/Social Feed Folder
  • Choose Data Source Template to be /sitecore/templates/Feature/ITWORX/Social Feed/Social Feed (The template we created)
  • Add a Rendering css class "social-media-container"
  • Add a Renderings View Path "~/Views/Components/FeaturedSocialFeeds.cshtml" (we will create it later)

Branches

Add the Available Renderings and Rendering Variant branches

System / Settings

Add the branches to the site setup

Development

Let's now start preparing the back end code.

  1. Create an MVC empty project
  2. Add the Sitecore References. My recommendation is use the Sitecore Nuget and add the following: Sitecore.Kernel, Sitecore.Mvc
  3. I usually recommend to create a project structure similar to the below

So lets go through the above folder structure explaining what each item is.

App_Config

Within the App_Config we add a Feature / Include folder and add a config file to register our component. The config file will add a configurator pointing to the IoC Register class

<configuration xmlns:patch="https://www.sitecore.net/xmlconfig/">
  <sitecore>
    <services>
      <configurator type="ITWORX.SXA.Feature.SocialFeed.Pipeline.IoC.RegisterSocialFeedsServices,ITWORX.SXA.Feature.SocialFeed" />
    </services>
  </sitecore>
</configuration>

Pipeline

I usually add a folder called IoC (Inversion of Control) within the Pipeline folder what it has is a registration for the social feed item and social feed list repositories

using Microsoft.Extensions.DependencyInjection;
using Sitecore.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace ITWORX.SXA.Feature.SocialFeed.Pipeline.IoC
{
    public class RegisterSocialFeedsServices : IServicesConfigurator
    {
        public void Configure(IServiceCollection serviceCollection)
        {


            serviceCollection.AddTransient<ISocialFeedItemRepository, SocialFeedItemRepository>();
            serviceCollection.AddTransient<ISocialFeedListRepository, SocialFeedListRepository>();

        }
    }
}

Note that this will do a build error until the models are added, but what this ultimately does is adds to the service collection the implementation of the Social Feed Repositories

Models

The models as with any MVC project contain the Models, in our scenario we have a list model and an item model

List Model

 public class SocialFeedListModel : VariantListsRenderingModel
    {
        public List<SocialFeedItemModel> SocialFeedListItems { getset; }
        public List<SocialFeedItemModel> TwitterFeedListItems { getset; }
        public List<SocialFeedItemModel> InstagramFeedListItems { getset; }
        public List<SocialFeedItemModel> FacebookFeedListItems { get; set; }
        public List<SocialFeedItemModel> YoutubeListItems { get; set; }
        public List<SocialFeedItemModel> LinkedInListItems { get; set; }
        public string TwitterRedirectURLTitle { getset; }
        public string TwitterAuth { getset; }
        public string TwitterScreenName { getset; }
        public string InstagramAccessToken { getset; }
        public string TwitterRedirectURL { getset; }
        public string Title { getset; }
        public string InstagramRedirectURL { getset; }
        public string InstagramRedirectURLTitle { getset; }
        public string FacebookRedirectURL { get; internal set; }
        public string FacebookRedirectURLTitle { get; internal set; }
        public string YouTubeRedirectURL { get; internal set; }
        public string YoutubeRedirectURLTitle { get; internal set; }
        public string LinkedInRedirectURL { get; internal set; }
        public string LinkedInRedirectURLTitle { get; internal set; }
    }

Item Model

 public class SocialFeedItemModel : VariantsRenderingModel
    {
        public string Text { getset; }
        public string ScreenName { getset; }
        public string CreatedAt { getset; }
        public string URL { get; internal set; }
        public string Type { get; internal set; }
        public string redirectURL { get; set; }
    }

As you can see they inherit from VariantListsRenderingModel and VariantsRenderingModel respectively

Controllers

The social feeds controller is quite simple, since the repository does all the heave lifting. IT inherits from PaginableController and overrides the GetModel function. The GetModel then instantiates the List Repository and invokes its GetModel

 public class SocialfeedsController : PaginableController
    {
        protected ISocialFeedItemRepository SocialFeedItemRepository
        { get; set; }
        protected ISocialFeedListRepository SocialFeedListRepository
        { get; set; }


        public SocialfeedsController()
        {


        }


        public SocialfeedsController(ISocialFeedListRepository Repository)
        {
            SocialFeedListRepository = Repository;


        }
        protected override object GetModel()
        {
            //string test = null;


            //test.ToLower();
            SocialFeedListRepository = new SocialFeedListRepository();
            return SocialFeedListRepository.GetModel();
        }
    }

Repositories

The repositories has two interfaces and two classes for item and list

ISocialFeedItemRepository

The ISocialFeedItemRepository is quite basic since all it does is inherit from IVariantsRepository

 public interface ISocialFeedItemRepository : IVariantsRepository
    {
    }

ISocialFeedListRepository

The ISocialFeedListRepository again doesn't have any functions but inherits from quite a few items

public interface ISocialFeedListRepository : IModelRepository, IControllerRepository, IAbstractRepository<IRenderingModelBase>
    {
    }

SocialFeedItemRepository

The social feed item repository inherits from VariantsRepository and ISocialFeedItemRepository, and overrides the GetMode by creating an instance of the model and invoking the FillBaseProperties of the model. What this does is fills the inherited fields of the Model

 public class SocialFeedItemRepository : VariantsRepository, ISocialFeedItemRepository
    {
        public SocialFeedItemRepository()
        { }


        public override IRenderingModelBase GetModel()
        {
            SocialFeedItemModel model = new SocialFeedItemModel();
            FillBaseProperties(model);
            return model;
        }
    }

SocialFeedListRepository

The SocialFeedListRepository is where most of the code is written.

 public class SocialFeedListRepository : ListRepository, ISocialFeedListRepository, IModelRepository, IControllerRepository, IAbstractRepository<IRenderingModelBase>
    {
       
        private IEnumerable<SocialFeedItemModel> _socialFeedListItems;
       

        public IEnumerable<SocialFeedItemModel> SocialFeedListItems
        {
            get
            {
                
                List<SocialFeedItemModel> socialFeeds = new List<SocialFeedItemModel>();
                
               //Removed code to fill in the Social Feed, this is just a request through the REST Endpoint 
                return _socialFeedListItems;
            }
        }
     

        public override IRenderingModelBase GetModel()
        {
//instanitate the social feed list model
            SocialFeedListModel model = new SocialFeedListModel();
            model.Title = GetFieldValue("Title");
            model.TwitterAuth = GetFieldValue("TwitterAuth");
            model.TwitterScreenName = GetFieldValue("TwitterScreenName");
            model.InstagramAccessToken = GetFieldValue("InstagramAccessToken");
            model.TwitterRedirectURL = GetFieldValue("TwitterRedirectURL");
            model.TwitterRedirectURLTitle = GetFieldValue("TwitterRedirectURLTitle");
            model.InstagramRedirectURL = GetFieldValue("InstagramRedirectURL");
            model.InstagramRedirectURLTitle = GetFieldValue("InstagramRedirectURLTitle");


            model.FacebookRedirectURL = GetFieldValue("FacebookRedirectURL");
            model.FacebookRedirectURLTitle = GetFieldValue("FacebookRedirectURLTitle");
            model.YouTubeRedirectURL = GetFieldValue("YouTubeRedirectURL");
            model.YoutubeRedirectURLTitle = GetFieldValue("YoutubeRedirectURLTitle");
            model.LinkedInRedirectURL = GetFieldValue("LinkedInRedirectURL");
            model.LinkedInRedirectURLTitle = GetFieldValue("LinkedInRedirectURLTitle");


            this.FillBaseProperties((object)model);
//Get the different social feeds
            model.SocialFeedListItems = this.SocialFeedListItems.ToList();
            model.TwitterFeedListItems = this.TwitterFeedListItems.ToList();
            model.InstagramFeedListItems = this.InstagramFeedListItems.ToList();
            model.FacebookFeedListItems = this.FacebookFeedListItems.ToList();
            model.YoutubeListItems = this.YoutubeFeedListItems.ToList();
            model.LinkedInListItems = this.LinkedInListItems.ToList();


            return (IRenderingModelBase)model;


        }

//Do a null check before returning the field value

        private string GetFieldValue(string fieldName)
        {
            if(Rendering!=null && Rendering.DataSourceItem!=null && Rendering.DataSourceItem.Fields[fieldName]!=null && Rendering.DataSourceItem.Fields[fieldName].Value!=null)
            {
                return Rendering.DataSourceItem.Fields[fieldName].Value;
            }
            return "";
        }
    }

Views

Finally we will create a view, the view will loop through the different list items and loop through the rendering variant for them.

要查看或添加评论,请登录

Mo Cherif的更多文章

社区洞察

其他会员也浏览了