Umbraco 7多节点树选择器属性转节点及自定义数据类型实现
嘿,我来帮你搞定这个自定义数据类型的问题——结合Umbraco节点层级(My Product Holder → Product Category → Product)和Merchello的GUID属性,其实分几步就能实现,我给你拆解清楚:
1. 先确认关联基础:Umbraco与Merchello节点的绑定
首先得确保你的Umbraco Product节点和Merchello产品之间有明确的关联。最直接的方式是给Product文档类型加一个属性,比如叫merchelloProductKey,类型选Guid或者Textstring,用来存储对应Merchello产品的唯一Key(GUID)。如果还没加这一步,先去后台把这个属性加上,后续所有逻辑都依赖这个绑定。
2. 改造你已有的自定义选择器
你已经做了能加载Umbraco节点ID的选择器,现在要给它加个“转化”逻辑,把选中的Product节点ID对应到Merchello的GUID:
2.1 后端逻辑调整(C#)
假设你的选择器是基于Umbraco的PropertyEditor做的,在处理选中节点的代码里,加这么几步:
- 根据选中的节点ID,拿到对应的
IPublishedContent实例 - 从实例里读取
merchelloProductKey属性的值(就是你存的Merchello GUID) - 把这个GUID作为最终存储的值,或者同时保留节点ID和GUID(看你后续需求)
给你个代码片段参考:
// 拿到选中的Umbraco节点列表 var selectedNodes = UmbracoContext.Current.Content.GetByIds(selectedNodeIds); var merchelloProductKeys = new List<Guid>(); foreach (var node in selectedNodes) { // 读取Merchello产品Key,记得替换成你实际的属性别名 if (node.HasValue("merchelloProductKey") && Guid.TryParse(node.GetPropertyValue<string>("merchelloProductKey"), out var productKey)) { merchelloProductKeys.Add(productKey); } } // 可以选择只存GUID字符串列表,方便后续直接用 return merchelloProductKeys.Select(k => k.ToString()).ToList();
2.2 前端界面优化(可选)
如果你的选择器有前端界面(比如基于Angular的Umbraco编辑器),可以在用户选中节点后,异步请求后端拿到对应的Merchello GUID,在界面上展示出来,让用户清楚知道选的节点关联了哪个Merchello产品。简化的前端逻辑大概是这样:
// 节点选中事件触发 function onNodeSelected(node) { // 调用自定义API获取Merchello GUID $http.get('/umbraco/api/MerchelloHelper/GetProductKey?nodeId=' + node.id) .then(function(response) { // 把GUID挂到节点对象上,方便展示 node.merchelloKey = response.data; // 更新选中列表的显示内容 }); }
3. 打包成自定义数据类型
把改造好的选择器包装成Umbraco能直接用的数据类型:
- 进Umbraco后台 → Settings → Data Types → 点Create
- 选择你改造后的自定义Property Editor作为编辑器
- 配置参数:和原来的MNTP一样,设置根节点为My Product Holder,限制只能选择Product Nodes
- 保存这个数据类型,之后就能在文档类型里用它了
4. 在代码/模板中访问Merchello节点属性
当你在视图或业务代码里使用这个数据类型的属性时,直接拿存储的GUID,然后通过Merchello的服务获取对应的产品属性就行:
比如在Umbraco视图里的示例:
@using Merchello.Core.Services @{ // 获取存储的Merchello GUID列表,替换成你的数据类型别名 var merchelloKeys = Model.Value<IEnumerable<string>>("customMerchelloProductPicker")?.Select(Guid.Parse); var productService = ApplicationContext.Current.Services.ProductService; if (merchelloKeys != null) { foreach (var key in merchelloKeys) { var merchelloProduct = productService.GetByKey(key); if (merchelloProduct != null) { // 这里就能访问Merchello产品的各种属性了 <div> <h4>@merchelloProduct.Name</h4> <p>价格:@merchelloProduct.Price | SKU:@merchelloProduct.Sku</p> </div> } } } }
5. 进阶选项:直接做Merchello产品选择器
如果你的需求不需要依赖Umbraco的节点层级,也可以直接做一个完全自定义的Property Editor,直接调用Merchello的API加载产品列表,让用户直接选Merchello产品。不过这种方式需要更多的前后端开发,适合不需要Umbraco节点关联的场景。
内容的提问来源于stack exchange,提问作者Tommy

