sitecore-classic

This plugin includes the following additional skills for comprehensive development context:

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "sitecore-classic" with this command: npx skills add twofoldtech-dakota/claude-marketplace/twofoldtech-dakota-claude-marketplace-sitecore-classic

Bundled Skills

This plugin includes the following additional skills for comprehensive development context:

Skill Purpose

frontend-classic

CSS/SASS organization, JavaScript/jQuery patterns, BEM naming

frontend-razor

Razor view syntax, layouts, partials, tag helpers

backend-csharp

C#/.NET DI patterns, service architecture, async/await

fullstack-classic

jQuery AJAX integration, form handling, anti-forgery tokens

These skills are automatically included when you install the Sitecore Classic Analyzer plugin.

Sitecore 10.x Development Patterns

Helix Architecture

Layer Responsibilities

Foundation Layer

  • Cross-cutting concerns shared across features

  • Examples: Logging, Serialization, DI registration, Indexing, ORM

  • No business logic, only technical infrastructure

  • Can reference other Foundation modules

Feature Layer

  • Business capabilities and features

  • Examples: Navigation, Search, Forms, Checkout, Articles

  • Each feature is independent and self-contained

  • Can reference Foundation modules only

  • NEVER reference other Feature modules

Project Layer

  • Tenant/site-specific implementations

  • Examples: Website, Corporate, MobileApp

  • Assembles features for specific sites

  • Can reference Feature and Foundation modules

Dependency Rule

Project → Feature → Foundation

Features must NEVER reference other Features. If shared logic is needed, extract to Foundation.

Folder Structure

src/ ├── Foundation/ │ └── {Module}/ │ ├── code/ │ │ ├── DependencyInjection/ │ │ ├── Services/ │ │ └── Foundation.{Module}.csproj │ └── serialization/ │ └── {Module}.module.json ├── Feature/ │ └── {Module}/ │ ├── code/ │ │ ├── Controllers/ │ │ ├── Models/ │ │ ├── Services/ │ │ ├── Repositories/ │ │ └── Feature.{Module}.csproj │ └── serialization/ │ ├── Templates/ │ ├── Renderings/ │ └── {Module}.module.json └── Project/ └── {Site}/ ├── code/ │ ├── Layouts/ │ └── Project.{Site}.csproj └── serialization/ ├── Content/ └── {Site}.module.json

Dependency Injection

Service Registration

using Microsoft.Extensions.DependencyInjection; using Sitecore.DependencyInjection;

public class RegisterDependencies : IServicesConfigurator { public void Configure(IServiceCollection services) { // Transient: New instance each time services.AddTransient<ISearchService, SearchService>();

    // Scoped: One instance per HTTP request
    services.AddScoped&#x3C;INavigationService, NavigationService>();

    // Singleton: One instance for application lifetime
    services.AddSingleton&#x3C;ICacheService, CacheService>();
}

}

Config Registration

<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <services> <configurator type="Foundation.DI.RegisterDependencies, Foundation.DI" /> </services> </sitecore> </configuration>

Constructor Injection

public class NavigationController : Controller { private readonly INavigationService _navigationService; private readonly ILogger<NavigationController> _logger;

public NavigationController(
    INavigationService navigationService,
    ILogger&#x3C;NavigationController> logger)
{
    _navigationService = navigationService;
    _logger = logger;
}

public ActionResult Index()
{
    var datasource = RenderingContext.Current.Rendering.Item;
    if (datasource == null)
    {
        _logger.LogWarning("Navigation datasource is null");
        return new EmptyResult();
    }

    var model = _navigationService.GetNavigation(datasource);
    return View(model);
}

}

Content Access Patterns

Use Content Search (Recommended)

public class SearchRepository : ISearchRepository { private readonly ISearchIndex _index;

public SearchRepository(ISearchIndexResolver indexResolver)
{
    _index = indexResolver.GetIndex("sitecore_web_index");
}

public IEnumerable&#x3C;ArticleSearchResult> GetArticles(
    ID templateId,
    string language,
    int maxResults = 100)
{
    using (var context = _index.CreateSearchContext())
    {
        return context.GetQueryable&#x3C;ArticleSearchResult>()
            .Where(x => x.TemplateId == templateId)
            .Where(x => x.Language == language)
            .OrderByDescending(x => x.Created)
            .Take(maxResults)
            .ToList();
    }
}

}

Avoid Sitecore.Query (Slow)

// BAD - Tree traversal, O(n) where n = tree size var items = item.Axes.SelectItems(".//*[@@templateid='{GUID}']");

// BAD - Even "fast:" queries traverse the tree var items = Database.SelectItems("fast:/sitecore/content//*");

// GOOD - Use Content Search instead var items = searchContext.GetQueryable<SearchResultItem>() .Where(x => x.TemplateId == templateId) .ToList();

Avoid GetDescendants (Memory Heavy)

// BAD - Loads entire subtree into memory var allItems = rootItem.GetDescendants().ToList();

// GOOD - Use Content Search with path filter var items = searchContext.GetQueryable<SearchResultItem>() .Where(x => x.Paths.Contains(rootItem.ID)) .Take(1000) .ToList();

Caching

HTML Cache (Rendering Level)

Configure in rendering item or config:

<r> <d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}"> <r uid="{RENDERING-UID}" s:caching="1" s:varybydata="1" s:varybydevice="0" s:varybylogin="0" s:varybyuser="0" s:varybyquerystirng="0" s:timeout="01:00:00" /> </d> </r>

Custom Cache

public class NavigationCache : CustomCache { public NavigationCache(string name, long maxSize) : base(name, maxSize) { }

public NavigationModel Get(string cacheKey)
{
    return GetObject&#x3C;NavigationModel>(cacheKey);
}

public void Set(string cacheKey, NavigationModel model, TimeSpan duration)
{
    SetObject(cacheKey, model, duration);
}

}

Register cache:

public class RegisterCaches : IServicesConfigurator { public void Configure(IServiceCollection services) { services.AddSingleton<NavigationCache>(provider => new NavigationCache("NavigationCache", StringUtil.ParseSizeString("50MB"))); } }

Configuration Patching

Basic Patch

<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <settings> <setting name="MySetting" value="MyValue" /> </settings> </sitecore> </configuration>

Environment-Specific Settings

<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:env="http://www.sitecore.net/xmlconfig/env/"> <sitecore> <settings> <!-- Only in Production --> <setting name="Analytics.Enabled" env:require="Production"> <patch:attribute name="value">true</patch:attribute> </setting>

  &#x3C;!-- Only in Development -->
  &#x3C;setting name="Analytics.Enabled" env:require="Development">
    &#x3C;patch:attribute name="value">false&#x3C;/patch:attribute>
  &#x3C;/setting>
&#x3C;/settings>

</sitecore> </configuration>

Role-Specific Settings

<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore> <settings> <!-- Only on Content Management servers --> <setting name="Preview.Enabled" role:require="ContentManagement"> <patch:attribute name="value">true</patch:attribute> </setting>

  &#x3C;!-- Only on Content Delivery servers -->
  &#x3C;setting name="Preview.Enabled" role:require="ContentDelivery">
    &#x3C;patch:attribute name="value">false&#x3C;/patch:attribute>
  &#x3C;/setting>
&#x3C;/settings>

</sitecore> </configuration>

Pipeline Processors

Custom Processor

public class EnrichContextProcessor : HttpRequestProcessor { public override void Process(HttpRequestArgs args) { // Early exit for efficiency if (Context.Item == null) return; if (Context.Site == null) return; if (Context.PageMode.IsExperienceEditor) return;

    // Processor logic here
    EnrichContext();
}

private void EnrichContext()
{
    // Custom enrichment logic
}

}

Config Registration

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <pipelines> <httpRequestBegin> <processor type="Feature.Context.EnrichContextProcessor, Feature.Context" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']" /> </httpRequestBegin> </pipelines> </sitecore> </configuration>

Solr Index Configuration

Custom Index

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <contentSearch> <configuration> <indexes> <index id="custom_articles_index"> <configuration ref="contentSearch/indexConfigurations/defaultSolrIndexConfiguration"> <documentOptions> <fields hint="raw:AddComputedIndexField"> <field fieldName="article_author" returnType="string"> Feature.Articles.ComputedFields.ArticleAuthor, Feature.Articles </field> <field fieldName="article_category" returnType="stringCollection"> Feature.Articles.ComputedFields.ArticleCategories, Feature.Articles </field> </fields> </documentOptions> </configuration> </index> </indexes> </configuration> </contentSearch> </sitecore> </configuration>

Computed Field

public class ArticleAuthor : IComputedIndexField { public string FieldName { get; set; } public string ReturnType { get; set; }

public object ComputeFieldValue(IIndexable indexable)
{
    var item = (indexable as SitecoreIndexableItem)?.Item;
    if (item == null) return null;

    var authorItem = item.GetReferenceField("Author")?.TargetItem;
    return authorItem?["Name"];
}

}

Sitecore Content Serialization (SCS)

module.json Structure

{ "namespace": "Feature.Navigation", "items": { "includes": [ { "name": "templates", "path": "/sitecore/templates/Feature/Navigation", "allowedPushOperations": "CreateUpdateAndDelete" }, { "name": "renderings", "path": "/sitecore/layout/Renderings/Feature/Navigation", "allowedPushOperations": "CreateUpdateAndDelete" }, { "name": "settings", "path": "/sitecore/system/Settings/Feature/Navigation", "allowedPushOperations": "CreateUpdateAndDelete" } ] } }

CLI Commands

Pull items from Sitecore to disk

dotnet sitecore ser pull

Push items from disk to Sitecore

dotnet sitecore ser push

Validate serialization

dotnet sitecore ser validate

Glass Mapper Patterns

Model Definition

[SitecoreType(TemplateId = "{GUID}", AutoMap = true)] public class ArticlePage { [SitecoreId] public virtual Guid Id { get; set; }

[SitecoreField("Title")]
public virtual string Title { get; set; }

[SitecoreField("Content")]
public virtual string Content { get; set; }

[SitecoreField("Author")]
public virtual Author Author { get; set; }

[SitecoreChildren]
public virtual IEnumerable&#x3C;RelatedArticle> RelatedArticles { get; set; }

}

Service Usage

public class ArticleService : IArticleService { private readonly ISitecoreService _sitecoreService;

public ArticleService(ISitecoreService sitecoreService)
{
    _sitecoreService = sitecoreService;
}

public ArticlePage GetArticle(Guid id)
{
    return _sitecoreService.GetItem&#x3C;ArticlePage>(id);
}

}

Avoid N+1 Queries

// BAD - N+1 queries with lazy loading foreach (var article in articles) { var author = article.Author; // Lazy load for each article }

// GOOD - Eager load or use Content Search var articleIds = articles.Select(a => a.Id).ToList(); var authors = searchContext.GetQueryable<AuthorSearchResult>() .Where(x => articleIds.Contains(x.ArticleId)) .ToList();

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

optimizely-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

umbraco-development

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-razor

No summary provided by upstream source.

Repository SourceNeeds Review
General

optimizely-content-cloud

No summary provided by upstream source.

Repository SourceNeeds Review