Skill for creating Orchard Core recipes. Covers recipe structure, content type definitions, content items, feature enablement, and recipe steps.
Recipes are JSON documents that configure a tenant through ordered steps. Use a recipe for repeatable setup, environment provisioning, deployment imports, or migration updates. Steps are processed in order and their names are case-insensitive at handler dispatch, but use the registered casing below and in the schemas.
Recipes/<name>.recipe.json in a module or theme. The extension's manifest makes that extension discoverable; there is no separate recipe manifest file.RecipeHarvester iterates enabled extensions and reads each extension's Recipes folder. The application recipe harvester also contributes application-level recipes.issetuprecipe to true only for recipes intended to appear during tenant setup.Recipes step. A data migration may execute a recipe in its module/theme Migrations folder through IRecipeMigrator.IRecipeExecutor.ExecuteAsync(executionId, recipeDescriptor, environment, cancellationToken). A RecipeDescriptor carries the recipe metadata, base path, file provider, and recipe file.Use .recipe.json, not arbitrary .json, for discovered extension recipes. Recipes can contain JSON comments, but generated automation should emit strict JSON unless comments are intentionally needed.
[js: uuid()], [file:text('...')], [env:NAME], and [appsettings:Section:Key] rather than inventing stable IDs or embedding secrets.{ "steps": [ ... ] } root wrapper when composing a recipe.ContentItemId, ContentItemVersionId, and timestamps rather than manually invented IDs.references/recipe-schemas/recipe.schema.json for the root document.references/recipe-schemas/index.json and locate the schema for every planned step.ContentDefinition, combine its schema with orchardcore-content-fields and orchardcore-content-parts guidance, then validate the final JSON again.references/recipe-schemas/recipe.schema.json — full recipe document schema.references/recipe-schemas/index.json — step-name to schema mapping.references/recipe-schemas/*.schema.json — per-step contracts.references/recipe-schemas/README.md — schema usage guidance.{
"name": "MyModule.Baseline",
"displayName": "My Module Baseline",
"description": "Creates the baseline configuration.",
"author": "My Team",
"website": "https://example.invalid",
"version": "1.0.0",
"issetuprecipe": false,
"categories": [ "Configuration" ],
"tags": [ "baseline" ],
"variables": {
"now": "[js: new Date().toISOString()]"
},
"steps": []
}
The schema references remain the authority for each payload. These examples show the release/3.0 handler names and common casing.
{
"steps": [
{
"name": "Feature",
"enable": [
"OrchardCore.ContentTypes",
"OrchardCore.Title"
],
"disable": []
},
{
"name": "Settings",
"SiteName": "Example",
"TimeZoneId": "UTC"
},
{
"name": "ContentDefinition",
"ContentTypes": [
{
"Name": "Article",
"DisplayName": "Article",
"Settings": {
"ContentTypeSettings": {
"Creatable": true,
"Listable": true,
"Draftable": true,
"Versionable": true
}
},
"ContentTypePartDefinitionRecords": [
{
"PartName": "TitlePart",
"Name": "TitlePart",
"Settings": {}
}
]
}
],
"ContentParts": []
}
]
}
{
"variables": {
"now": "[js: new Date().toISOString()]"
},
"steps": [
{
"name": "Content",
"data": [
{
"ContentItemId": "[js: uuid()]",
"ContentItemVersionId": "[js: uuid()]",
"ContentType": "Article",
"DisplayText": "Welcome",
"Latest": true,
"Published": true,
"CreatedUtc": "[js: variables('now')]",
"ModifiedUtc": "[js: variables('now')]",
"PublishedUtc": "[js: variables('now')]",
"TitlePart": {
"Title": "Welcome"
}
}
]
},
{
"name": "Recipes",
"Values": [
{
"executionid": "MyModule.Extras",
"name": "MyModule.Extras"
}
]
}
]
}
Recipes runs a harvested recipe by its root name; executionid distinguishes that execution from other runs.
Use the matching schema before emitting any of these: Themes, Layers, Queries, Media, MediaProfile, Roles, Users, Templates, AdminTemplates, AdminMenu, Placement, WorkflowType, deployment, LuceneIndex, LuceneIndexRebuild, LuceneIndexReset, ElasticsearchIndex, ElasticsearchIndexRebuild, ElasticsearchIndexReset, CreateOrUpdateIndexProfile, RebuildIndex, ResetIndex, Translations, Sitemaps, FeatureProfiles, CustomSettings, CustomUserSettings, and provider-specific authentication settings.
WorkflowType imports serialized workflow definitions. Create workflows in the admin editor, export them through the workflow deployment step, and use that exported data payload instead of hand-authoring activity IDs and transitions.
{
"steps": [
{
"name": "WorkflowType",
"data": [
{
"WorkflowTypeId": "[js: uuid()]",
"Name": "Example workflow",
"IsEnabled": true,
"Activities": [],
"Transitions": []
}
]
}
]
}
The lowercase deployment step creates deployment plans. Its Type values must match enabled deployment step factories.
{
"steps": [
{
"name": "deployment",
"Plans": [
{
"Name": "Configuration",
"Steps": [
{
"Type": "AllFeaturesDeploymentStep",
"Step": {
"Id": "[js: uuid()]",
"Name": "AllFeatures"
}
}
]
}
]
}
]
}
Implement IRecipeStepHandler when a handler must inspect several names. For one named step, derive from NamedRecipeStepHandler; it compares context.Name case-insensitively and invokes HandleAsync only when the name matches. Release/3.0 does not use a [RecipeStep] attribute for handler discovery: registration is explicit.
RecipeExecutionContext provides ExecutionId, Name, Step as a JsonObject, RecipeDescriptor, nested recipes, and an Errors collection. Add a user-actionable error to context.Errors when input cannot be applied; do not silently ignore malformed required data.
using System.Text.Json.Nodes;
using OrchardCore.Recipes.Models;
using OrchardCore.Recipes.Services;
using OrchardCore.Settings;
namespace MyModule.Recipes;
public sealed class MySettingsStep : NamedRecipeStepHandler
{
private readonly ISiteService _siteService;
public MySettingsStep(ISiteService siteService)
: base("MySettings")
{
_siteService = siteService;
}
protected override async Task HandleAsync(RecipeExecutionContext context)
{
var enabled = context.Step["Enabled"]?.GetValue<bool>();
if (enabled is null)
{
context.Errors.Add("MySettings requires an Enabled value.");
return;
}
var site = await _siteService.LoadSiteSettingsAsync();
site ??= new SiteSettings();
site.Properties["MyModuleSettings"] = new JsonObject
{
["Enabled"] = enabled.Value,
};
await _siteService.UpdateSiteSettingsAsync(site);
}
}
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Modules;
using OrchardCore.Recipes;
namespace MyModule;
public sealed class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddRecipeExecutionStep<MySettingsStep>();
}
}
The exact API is AddRecipeExecutionStep<TImplementation>(); it registers the handler as a scoped IRecipeStepHandler. Add the feature that contains this startup before the custom step in a consuming recipe.
npx skills add CrestApps/orchardcore-recipes下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer