You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Optimizely多站点如何为每个站点配置独立Wastebasket/Trash bin?

在Optimizely CMS中为每个站点创建独立回收站的实现方案

默认Optimizely CMS的回收站是全局共享的,要实现站点级独立回收站,需通过自定义容器、重写删除逻辑和权限隔离三步完成:

1. 为每个站点创建专属回收站容器

先给每个站点的根节点下添加专属的回收站容器节点,用于存储该站点删除的内容:

  • 定义自定义容器类型,继承自PageData:
[ContentType(DisplayName = "站点回收站容器", GUID = "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]
public class SiteTrashContainer : PageData { }
  • 在站点初始化时自动创建该容器(通过IInitializableModule实现):
public class SiteTrashInitializer : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {
        var contentRepo = context.Locate.Advanced.GetInstance<IContentRepository>();
        var siteDefinitions = context.Locate.Advanced.GetInstance<ISiteDefinitionRepository>().List();
        
        foreach (var site in siteDefinitions)
        {
            if (site.RootPage != null)
            {
                var existingTrash = contentRepo.GetChildren<SiteTrashContainer>(site.RootPage)
                                              .FirstOrDefault();
                if (existingTrash == null)
                {
                    var newTrash = contentRepo.GetDefault<SiteTrashContainer>(site.RootPage);
                    newTrash.Name = "站点回收站";
                    contentRepo.Save(newTrash, SaveAction.Publish, AccessLevel.NoAccess);
                }
            }
        }
    }

    public void Uninitialize(InitializationEngine context) { }
}

2. 重写内容删除逻辑

替换默认的全局回收站逻辑,将删除的内容移动到对应站点的专属容器:

  • 实现IContentEvents拦截删除事件:
public class SiteSpecificTrashHandler : IContentEvents
{
    private readonly IContentRepository _contentRepo;
    private readonly ISiteDefinitionRepository _siteRepo;

    public SiteSpecificTrashHandler(IContentRepository contentRepo, ISiteDefinitionRepository siteRepo)
    {
        _contentRepo = contentRepo;
        _siteRepo = siteRepo;
    }

    public void DeletedContent(object sender, ContentEventArgs e)
    {
        // 获取被删除内容所属的站点根节点
        var site = _siteRepo.List().FirstOrDefault(s => s.Contains(e.ContentLink));
        if (site?.RootPage == null) return;

        // 找到对应站点的专属回收站
        var siteTrash = _contentRepo.GetChildren<SiteTrashContainer>(site.RootPage)
                                    .FirstOrDefault();
        if (siteTrash == null) return;

        // 将内容移动到站点回收站,取消默认全局回收站操作
        var movedContent = _contentRepo.Move(e.ContentLink, siteTrash.ContentLink);
        _contentRepo.Save(movedContent, SaveAction.Save, AccessLevel.NoAccess);
        e.CancelAction = true;
    }

    // 空实现其他IContentEvents接口方法
    public void CreatedContent(object sender, ContentEventArgs e) { }
    public void SavedContent(object sender, ContentEventArgs e) { }
    public void DeletingContent(object sender, ContentEventArgs e) { }
    public void MovingContent(object sender, ContentEventArgs e) { }
    public void MovedContent(object sender, ContentEventArgs e) { }
    // 其余接口方法省略
}
  • 在初始化模块中注册事件处理器:
// 在SiteTrashInitializer的Initialize方法中添加
var contentEvents = context.Locate.Advanced.GetInstance<IContentEvents>();
var trashHandler = new SiteSpecificTrashHandler(contentRepo, siteRepo);
contentEvents.DeletedContent += trashHandler.DeletedContent;

3. 配置权限隔离

通过Optimizely权限系统限制编辑器只能访问自身站点的回收站:

  • 进入CMS Admin后台,打开Permissions页面
  • 找到目标站点的编辑器用户组:
    • 定位到该站点根节点下的站点回收站容器,授予Create、Edit、Delete、Publish权限
    • 找到全局回收站(Root节点下的Trash),移除该用户组的所有访问权限
  • 重复上述步骤为每个站点的编辑器组配置对应权限

可选:自定义回收站UI入口

如果需要让编辑器更直观地访问站点回收站,可以自定义CMS导航菜单:

  • 扩展Optimizely的UI,在站点导航中添加"站点回收站"选项,直接指向当前站点的专属容器节点

注意事项

  • 确保所有删除操作(包括批量删除、API删除)都走自定义逻辑
  • 可批量迁移现有全局回收站中的内容到对应站点的专属回收站
  • 测试时验证跨站点编辑器无法访问其他站点的回收站内容

内容的提问来源于stack exchange,提问作者OJs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:44:56