소스 정보
- 저장소
- diegosouzapw/awesome-omni-skill
- 최근 소스 활동
- 2026년 2월 28일 04:30
- 감지된 SKILL.md 언어
- 영어
- 스타
- 50
- 포크
- 19
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/diegosouzapw/awesome-omni-skill --skill umbraco-development명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Token-efficient tracking for AI orchestration. CLI-first for status updates (~50 tokens), agent fallback for complex ops (~1KB). Use when: updating task status, querying blockers, creating progress files, validating phases.
AshAi extension guidelines for integrating AI capabilities with Ash Framework. Use when implementing vectorization/embeddings, exposing Ash actions as LLM tools, creating prompt-backed actions, or setting up MCP servers. Covers semantic search, LangChain integration, and structured outputs.
This skill should be used when solving hard questions, complex architectural problems, or debugging issues that benefit from GPT-5 Pro or GPT-5.1 thinking models with large file context. Use when standard Claude analysis needs deeper reasoning or extended context windows.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | umbraco-development |
| description | Apply when working with Umbraco CMS, Composers, services, or content APIs |
| globs | ["**/Composers/**/*.cs","**/Controllers/**/*.cs","**/App_Plugins/**/*","**/Views/**/*.cshtml","**/appsettings.json","**/*.scss","**/*.css","**/scripts/**/*.js","**/*.tsx","**/*.jsx"] |
This plugin includes the following additional skills for comprehensive development context:
| Skill | Purpose |
|---|---|
frontend-razor | Razor view syntax, layouts, partials, tag helpers |
frontend-classic | CSS/SASS organization, JavaScript/jQuery patterns (traditional sites) |
frontend-modern | React, Vue, TypeScript patterns (headless/decoupled sites) |
backend-csharp | C#/.NET DI patterns, service architecture, async/await |
fullstack-classic | jQuery AJAX integration, form handling (traditional) |
fullstack-modern | REST/GraphQL APIs, Content Delivery API integration (headless) |
These skills are automatically included when you install the Umbraco Analyzer plugin.
src/
├── Web/ # Main Umbraco web project
│ ├── App_Plugins/ # Backoffice extensions
│ ├── Composers/ # DI and configuration
│ ├── Controllers/ # Surface and API controllers
│ ├── Views/ # Razor templates
│ └── Program.cs
├── Core/ # Business logic (optional)
│ ├── Services/
│ ├── Models/
│ └── Interfaces/
└── Infrastructure/ # Data access (optional)
├── Repositories/
└── ExternalServices/
Composers are the entry point for dependency injection and configuration.
using Umbraco.Cms.Core.Composing;
public class ServicesComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
// Register services
builder.Services.AddScoped<IProductService, ProductService>();
builder.Services.AddScoped<ISearchService, SearchService>();
// Register notification handlers
builder.AddNotificationHandler<ContentPublishedNotification, ContentPublishedHandler>();
builder.AddNotificationAsyncHandler<ContentSavingNotification, ContentSavingHandler>();
}
}
public class ConfiguredServicesComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
// Register with configuration
builder.Services.Configure<EmailOptions>(
builder.Config.GetSection("Email"));
builder.Services.AddScoped<IEmailService, EmailService>();
}
}
// Run after another Composer
[ComposeAfter(typeof(ServicesComposer))]
public class DependentComposer : IComposer
{
public void Compose(IUmbracoBuilder builder) { }
}
// Run before another Composer
[ComposeBefore(typeof(OtherComposer))]
public class EarlyComposer : IComposer
{
public void Compose(IUmbracoBuilder builder) { }
}
public class ContentPublishedHandler : INotificationHandler<ContentPublishedNotification>
{
private readonly ILogger<ContentPublishedHandler> _logger;
public ContentPublishedHandler(ILogger<ContentPublishedHandler> logger)
{
_logger = logger;
}
public void Handle(ContentPublishedNotification notification)
{
foreach (var content in notification.PublishedEntities)
{
_logger.LogInformation("Content published: {Name}", content.Name);
}
}
}
public class ContentSavingHandler : INotificationAsyncHandler<ContentSavingNotification>
{
private readonly IExternalService _externalService;
public ContentSavingHandler(IExternalService externalService)
{
_externalService = externalService;
}
public async Task HandleAsync(ContentSavingNotification notification, CancellationToken ct)
{
foreach (var content in notification.SavedEntities)
{
await _externalService.SyncContentAsync(content.Key, ct);
}
}
}
public class ContentService
{
private readonly IPublishedContentQuery _contentQuery;
public ContentService(IPublishedContentQuery contentQuery)
{
_contentQuery = contentQuery;
}
public IPublishedContent? GetContentByKey(Guid key)
{
return _contentQuery.Content(key);
}
public IPublishedContent? GetContentByRoute(string route)
{
return _contentQuery.ContentSingleAtXPath($"//{route}");
}
public IEnumerable<IPublishedContent> GetChildren(IPublishedContent parent)
{
return parent.Children.Where(x => x.IsVisible());
}
}
public class SingletonService
{
private readonly IUmbracoContextFactory _contextFactory;
public SingletonService(IUmbracoContextFactory contextFactory)
{
_contextFactory = contextFactory;
}
public IPublishedContent? GetContent(Guid key)
{
using var cref = _contextFactory.EnsureUmbracoContext();
return cref.UmbracoContext?.Content?.GetById(key);
}
}
public class ContactFormController : SurfaceController
{
private readonly IContactService _contactService;
private readonly ILogger<ContactFormController> _logger;
public ContactFormController(
IUmbracoContextAccessor umbracoContextAccessor,
IUmbracoDatabaseFactory databaseFactory,
ServiceContext services,
AppCaches appCaches,
IProfilingLogger profilingLogger,
IPublishedUrlProvider publishedUrlProvider,
IContactService contactService,
ILogger<ContactFormController> logger)
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
{
_contactService = contactService;
_logger = logger;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Submit(ContactFormModel model, CancellationToken ct)
{
if (!ModelState.IsValid)
{
return CurrentUmbracoPage();
}
try
{
await _contactService.ProcessContactAsync(model, ct);
TempData["ContactSuccess"] = true;
return RedirectToCurrentUmbracoPage();
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to process contact form");
ModelState.AddModelError("", "An error occurred. Please try again.");
return CurrentUmbracoPage();
}
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SubmitAjax(ContactFormModel model, CancellationToken ct)
{
if (!ModelState.IsValid)
{
return Json(new
{
success = false,
errors = ModelState.SelectMany(x => x.Value.Errors.Select(e => e.ErrorMessage))
});
}
await _contactService.ProcessContactAsync(model, ct);
return Json(new { success = true, message = "Thank you for your message!" });
}
[Route("api/products")]
public class ProductsApiController : UmbracoApiController
{
private readonly IProductService _productService;
public ProductsApiController(IProductService productService)
{
_productService = productService;
}
[HttpGet]
public async Task<IActionResult> GetAll(CancellationToken ct)
{
var products = await _productService.GetAllAsync(ct);
return Ok(products);
}
[HttpGet("{id:guid}")]
public async Task<IActionResult> GetById(Guid id, CancellationToken ct)
{
var product = await _productService.GetByIdAsync(id, ct);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
public class SearchService
{
private readonly IExamineManager _examineManager;
public SearchService(IExamineManager examineManager)
{
_examineManager = examineManager;
}
public IEnumerable<ISearchResult> Search(string term)
{
if (!_examineManager.TryGetIndex("ExternalIndex", out var index))
{
return Enumerable.Empty<ISearchResult>();
}
var searcher = index.Searcher;
var query = searcher.CreateQuery("content")
.NativeQuery($"+__NodeTypeAlias:blogPost +bodyText:{term}*");
return query.Execute();
}
}
public ISearchResults SearchProducts(string term, string category, int page, int pageSize)
{
if (!_examineManager.TryGetIndex("ExternalIndex", out var index))
{
return EmptySearchResults.Instance;
}
var query = index.Searcher.CreateQuery("content")
.NodeTypeAlias("product");
if (!string.IsNullOrEmpty(term))
{
query = query.And().ManagedQuery(term);
}
if (!string.IsNullOrEmpty(category))
{
query = query.And().Field("category", category);
}
var results = query.Execute(new QueryOptions(
skip: (page - 1) * pageSize,
take: pageSize
));
return results;
}
public class CachedContentService
{
private readonly AppCaches _appCaches;
private readonly IContentService _contentService;
public CachedContentService(AppCaches appCaches, IContentService contentService)
{
_appCaches = appCaches;
_contentService = contentService;
}
public object GetCachedData(string key)
{
return _appCaches.RuntimeCache.GetCacheItem(
key,
() => _contentService.GetData(),
TimeSpan.FromMinutes(5)
);
}
public void ClearCache(string key)
{
_appCaches.RuntimeCache.ClearByKey(key);
}
}
{
"Umbraco": {
"CMS": {
"Content": {
"AllowEditInvariantFromNonDefault": true
},
"Global": {
"UseHttps": true
},
"ModelsBuilder": {
"ModelsMode": "SourceCodeAuto"
}
}
},
"MyApp": {
"Email": {
"SmtpHost": "smtp.example.com",
"SmtpPort": 587,
"FromAddress": "noreply@example.com"
}
}
}
public class EmailOptions
{
public string SmtpHost { get; set; } = string.Empty;
public int SmtpPort { get; set; } = 587;
public string FromAddress { get; set; } = string.Empty;
}
// In Composer
builder.Services.Configure<EmailOptions>(
builder.Config.GetSection("MyApp:Email"));
// In Service
public class EmailService
{
private readonly EmailOptions _options;
public EmailService(IOptions<EmailOptions> options)
{
_options = options.Value;
}
}
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.BlogPost>
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels
@{
Layout = "Master.cshtml";
}
<article>
<h1>@Model.Title</h1>
<p class="meta">
Published: @Model.PublishDate.ToString("MMMM dd, yyyy")
by @Model.Author?.Name
</p>
<div class="content">
@Html.Raw(Model.BodyText)
</div>
</article>
@* Views/Partials/_Navigation.cshtml *@
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@{
var root = Model.Root();
var items = root.Children.Where(x => x.IsVisible());
}
<nav>
<ul>
@foreach (var item in items)
{
<li class="@(item.IsAncestorOrSelf(Model) ? "active" : "")">
<a href="@item.Url()">@item.Name</a>
</li>
}
</ul>
</nav>
@using (Html.BeginUmbracoForm<ContactFormController>(nameof(ContactFormController.Submit)))
{
@Html.AntiForgeryToken()
<div class="form-group">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Message"></label>
<textarea asp-for="Message" class="form-control"></textarea>
<span asp-validation-for="Message" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Send</button>
}