In Sitecore SXA already exist a Reference rendering variant which lets you display fields from a referenced item.
For the reference rendering variant If you want to display a field from a referenced item, you can define this field in the “Pass through field” field.

To display fields from referrers items we need to create a custom Referrer Rendering Variant.
First thing we need to create a template for Referrers Rendering Variant which should inherit from “_Rendering Variants Base” and “_Variant Paging”

We need to create the model for this template.
public class VariantReferrers : BaseVariantField { public int? MaxNumberOfResults { get; set; } public int? NumberOfResultsToSkip { get; set; } public IEnumerable<BaseVariantField> Items { get; set; } public string RefferItemTemplateName { get; set; } }
To create the VariatReferrers model we need to create it inside a class which inherits from ParseVariantFieldProcessor and to render it we need to create a class which interits from RenderRenderingVariantFieldProcessor
public class ParseReferrers : ParseVariantFieldProcessor { public override ID SupportedTemplateId => Templates.VariantReferrers.ID; public override void TranslateField(ParseVariantFieldArgs args) { var obj = new VariantReferrers { ItemName = args.VariantItem.Name, RefferItemTemplateName = args.VariantItem[Templates.VariantReferrers.Fields.TemplatesAllowed] }; IList<BaseVariantField> items; if (args.VariantItem.Children.Count <= 0) { IList<BaseVariantField> list = new List<BaseVariantField>(); items = list; } else { items = ServiceLocator.ServiceProvider.GetService<IVariantFieldParser>() .ParseVariantFields(args.VariantItem, args.VariantRootItem, false); } obj.Items = items; args.TranslatedField = obj; if (int.TryParse(args.VariantItem[Sitecore.XA.Foundation.RenderingVariants.Templates._VariantPaging.Fields.MaxNumberOfResults], out var result)) (args.TranslatedField as VariantReferrers).MaxNumberOfResults = result; if (int.TryParse(args.VariantItem[Sitecore.XA.Foundation.RenderingVariants.Templates._VariantPaging.Fields.NumberOfResultsToSkip], out var result2)) (args.TranslatedField as VariantReferrers).NumberOfResultsToSkip = result2; } }
SupportedTemplateId propery represents the ID of the template created above.
Inside TranslatedField method we set the RefferItemTemplateName property with the value from rendering variant.

On RenderReferrers class , inside method RenderField is the logic to get the referrers of current item and we filter refferes item by templatename.
public class RenderReferrers : RenderVariantFieldProcessor { public override Type SupportedType => typeof(VariantReferrers); public override RendererMode RendererMode => RendererMode.Html; public override void RenderField(RenderVariantFieldArgs args) { VariantReferrers variantReferrers = args.VariantField as VariantReferrers; if (string.IsNullOrWhiteSpace(variantReferrers?.RefferItemTemplateName) || !variantReferrers.Items.Any()) { return; } List<Item> targetItems = GetReffererItems(args, variantReferrers); if (!targetItems.Any()) { return; } Control control = new PlaceHolder(); foreach (Item item in targetItems) { foreach (BaseVariantField referencedItem in variantReferrers.Items) { RenderVariantFieldArgs renderVariantFieldArgs = new RenderVariantFieldArgs { VariantField = referencedItem, Item = item, HtmlHelper = args.HtmlHelper, IsControlEditable = args.IsControlEditable, IsFromComposite = args.IsFromComposite, RendererMode = args.RendererMode, Model = args.Model }; base.PipelineManager.Run("renderVariantField", renderVariantFieldArgs); if (renderVariantFieldArgs.ResultControl != null) { control.Controls.Add(renderVariantFieldArgs.ResultControl); } } } args.ResultControl = control; args.Result = RenderControl(args.ResultControl); } protected List<Item> GetReffererItems( RenderVariantFieldArgs args, VariantReferrers variantReferrers) { var currentItem = args.Item; var links= Globals.LinkDatabase.GetReferrers(currentItem); var originalSource = links.Select(i => i.GetSourceItem()).Where(i => i != null&& i.TemplateName.Equals(variantReferrers.RefferItemTemplateName)); if (variantReferrers.NumberOfResultsToSkip.HasValue) originalSource = originalSource.Skip<Item>(variantReferrers.NumberOfResultsToSkip.Value); int? maxNumberOfResults = variantReferrers.MaxNumberOfResults; if (maxNumberOfResults.HasValue) { IEnumerable<Item> source2 = originalSource; maxNumberOfResults = variantReferrers.MaxNumberOfResults; int count = maxNumberOfResults.Value; originalSource = source2.Take<Item>(count); } return originalSource.ToList<Item>(); } }
We need to register these 2 processors in a config file:
<?xml version="1.0"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore> <pipelines> <parseVariantFields> <processor type="XA.Reference.Foundation.RenderingVariants.Pipelines.ParseVariantFields.ParseReferrers, XA.Reference.Foundation.RenderingVariants" /> </parseVariantFields> <renderVariantField> <processor type="XA.Reference.Foundation.RenderingVariants.Pipelines.ParseVariantFields.RenderReferrers, XA.Reference.Foundation.RenderingVariants" /> </renderVariantField> </pipelines> </sitecore> </configuration>