内容类型 (OrchardCore.ContentTypes
)¶
视图组件¶
SelectContentTypes
¶
渲染一个编辑器以选择内容类型列表。
它可以选择性地过滤特定原型的内容类型。
编辑器将选择作为模型上的 string[]
返回。
参数¶
参数 | 类型 | 描述 |
---|---|---|
selectedContentTypes |
string[] |
渲染编辑器时应标记为选定的内容类型列表。 |
htmlName |
string |
将结果绑定到的模型属性的名称。 |
stereotype (可选) |
string |
用于过滤可选择的内容类型列表的原型名称。 |
示例¶
@await Component.InvokeAsync("SelectContentTypes", new { selectedContentTypes = Model.ContainedContentTypes, htmlName = Html.NameFor(m => m.ContainedContentTypes) })
迁移¶
迁移类可用于更改内容类型定义,例如添加新的 类型,或配置其 部分 和 字段。
IContentDefinitionManager
¶
此服务提供了一种修改内容类型定义的方法。从迁移类中,我们可以注入此接口的实例。
public class Migrations : DataMigration
{
IContentDefinitionManager _contentDefinitionManager;
public Migrations(IContentDefinitionManager contentDefinitionManager)
{
_contentDefinitionManager = contentDefinitionManager;
}
public int Create()
{
// 此代码将在启用功能时运行
return 1;
}
}
创建新的内容类型¶
以下示例创建名为 Product
的新内容类型。
_contentDefinitionManager.AlterTypeDefinition("Product");
更改内容类型的元数据¶
要更改内容类型的特定属性,可以使用参数进行配置:
_contentDefinitionManager.AlterTypeDefinition("Product", type => type
// 此类型的内容项可以有草稿
.Draftable()
// 此类型的内容项版本已保存
.Versionable()
// 此内容类型出现在新菜单部分中
.Creatable()
// 可以将权限专门应用于此类型的实例
.Securable()
);
将内容部分添加到类型¶
以下示例将 TitlePart
内容部分添加到 Product
类型。
_contentDefinitionManager.AlterTypeDefinition("Product", type => type
.WithPart("TitlePart")
);
每个部分也可以在类型的上下文中进行配置。例如,AutoroutePart
需要一个 Liquid 模板作为其模式以生成自定义路由。它在此部分的自定义设置中定义。
_contentDefinitionManager.AlterTypeDefinition("Product", type => type
.WithPart("AutoroutePart", part => part
// 在其他部分中设置位置
.WithPosition("2")
// 设置 AutoroutePart 上的所有设置
.WithSettings(new AutoroutePartSettings { Pattern = "{{ ContentItem | display_text | slugify }}" })
)
);
有关每种类型可以使用的所有设置的列表,请参阅它们各自的文档页面。
将内容字段添加到部分¶
字段不能直接附加到内容类型。要将字段添加到内容类型,请创建与类型名称相同的部分,并将字段添加到此部分中。
_contentDefinitionManager.AlterTypeDefinition("Product", type => type
.WithPart("Product")
);
_contentDefinitionManager.AlterPartDefinition("Product", part => part
.WithField("Image", field => field
.OfType("MediaField")
.WithDisplayName("主图像")
)
.WithField("Price", field => field
.OfType("NumericField")
.WithDisplayName("价格")
)
);
将字段添加到部分时,字段还可以具有自定义设置,例如定义编辑器的行为方式或验证规则。有关可能设置的列表,请参阅它们各自的文档页面。
从 CSharp 使用内容部分和字段¶
可以从上述类型定义中获取 Content Parts 和 Fields 的强类型版本。
警告
这些类型可能会在 CMS 中进行修改。在代码中使用它们时,确保在开发周期之外不会修改这些类型非常重要。
首先,创建与类型定义匹配的部分:
public class Product : ContentPart
{
public MediaField Image { get; set; }
public NumericField Price { get; set; }
}
然后,使用依赖项注入注册 ContentPart:
using OrchardCore.ContentManagement;
...
public class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddContentPart<Product>();
}
}
最后,以下是在控制器中将 Content Item 作为 Content Part 使用的示例。
public class ProductController : Controller
{
private readonly IOrchardHelper _orchardHelper;
private readonly IContentManager _contentManager;
public ProductController(IOrchardHelper orchardHelper, IContentManager contentManager)
{
_orchardHelper = orchardHelper;
_contentManager = contentManager;
}
[HttpGet("/api/product/{productId}")]
public async Task<ObjectResult> GetProductAsync(string productId)
{
var product = _orchardHelper.GetContentItemByIdAsync(productId);
if (product == null)
{
return NotFoundObjectResult();
}
var productPart = product.As<Product>();
// 如果这些字段中的任何一个为 null,则会引发异常
// 对于不需要的任何字段,应使用 null-conditional 运算符 (?)
return new ObjectResult(new {
Image = productPart.Image.Paths.FirstOrDefault(),
Price = productPart.Price.Value,
});
}
[HttpPost("/api/product/{productId}/price/{price}")]
public async Task<ContentValidateResult> UpdateProductPriceAsync(string productId, int price)
{
//此调用仅获取已发布的内容项,这使得更新后的发布变得多余
var product = _orchardHelper.GetContentItemByIdAsync(productId);
if (product == null)
{
return NotFoundObjectResult();
}
var productPart = product.As<Product>();
productPart.Price.Value = price;
product.Apply(productPart) //将修改后的部分应用于内容项
await _contentManager.UpdateAsync(product); //更新将触发处理程序,这些处理程序可能会更改内容项。
//验证将取消更改,如果产品无效。它在更新后触发,因为处理程序可能会更改对象。
return await _contentManager.ValidateAsync(product);
}
}
该文档由ChatGPT 4 翻译
Last update:
March 22, 2023