不同的观点与Orchard Multi-Tenancy交替出现

时间:2013-09-24 11:06:28

标签: orchardcms multi-tenant

我有一个Orchard CMS安装,启用了多租户模块,并设置了2个租户。两个租户都使用相同的主题。

我想要的是能够创建视图交替来定位每个租户,例如:

~/Themes/MyTheme/Views/Content.Tenant1.cshtml会针对租户1和 ~/Themes/MyTheme/Views/Content.Tenant2.cshtml将以租户2为目标。

我意识到我可以用2个不同(但非常相似)的主题来做,但这感觉就像不必要的重复。

2 个答案:

答案 0 :(得分:1)

答案当然是从ShapeDisplayEvents继承并绑定到context.ShapeMetadata.OnDisplaying事件:

public class MultiTenancyAlternatesFactory : ShapeDisplayEvents
{
    private readonly ShellSettings _shellSettings;

    public MultiTenancyAlternatesFactory(ShellSettings shellSettings)
    {
        _shellSettings = shellSettings;
    }

    public override void Displaying(ShapeDisplayingContext context)
    {
        context.ShapeMetadata.OnDisplaying(displayingContext =>
        {
            var tenant = _shellSettings.Name;

            // look for ContentItem property
            ContentItem contentItem = displayingContext.Shape.ContentItem;

            // if not, check for ContentPart 
            if (contentItem == null)
            {
                ContentPart contentPart = displayingContext.Shape.ContentPart;
                if (contentPart != null)
                {
                    contentItem = contentPart.ContentItem;
                }
            }

            var shapeName = displayingContext.ShapeMetadata.Type;

            if (contentItem != null)
            {
                var contentTypeName = contentItem.ContentType;

                displayingContext.ShapeMetadata.Alternates.Add(shapeName + "__" + contentTypeName + "__tenant__" + tenant);
            }

            displayingContext.ShapeMetadata.Alternates.Add(shapeName + "__tenant__" + tenant);

        });
    }
}

答案 1 :(得分:1)

我尝试在上面实现您的代码,但它仅适用于形状。

我希望有一个Index-tennant- [TenantName] .cshtml的视图来覆盖Index.cshtml

要做到这一点,我必须覆盖RazorViewEngineProvider,然后添加额外的路径供ViewEngine查找。我使用了[OrchardSuppressDependency ...],因为我不想对实际的Orchard CMS代码进行更改,因为这样会使任何未来的升级变得更加痛苦。

我希望这可以帮助那些在果园中提出多租户相同问题的人。

[UsedImplicitly]
[OrchardSuppressDependency("Orchard.Mvc.ViewEngines.Razor.RazorViewEngineProvider")]
public class RazorViewEngineProvider : Orchard.Mvc.ViewEngines.Razor.RazorViewEngineProvider, IViewEngineProvider, IShapeTemplateViewEngine
{
    private readonly string _tenant;
    public RazorViewEngineProvider(ShellSettings shellSettings)
    {
        _tenant = shellSettings.Name;
    }

    public new IViewEngine CreateThemeViewEngine(CreateThemeViewEngineParams parameters)
    {
        var viewEngine = base.CreateThemeViewEngine(parameters);
        if (!string.IsNullOrWhiteSpace(_tenant))
        {
            var razorView = viewEngine as RazorViewEngine;
            if (razorView != null)
            {
                razorView.PartialViewLocationFormats = addTenant(razorView.PartialViewLocationFormats);
                razorView.AreaPartialViewLocationFormats = addTenant(razorView.AreaPartialViewLocationFormats);
            }
        }

        return viewEngine;
    }

    public new IViewEngine CreateModulesViewEngine(CreateModulesViewEngineParams parameters)
    {
        var viewEngine = base.CreateModulesViewEngine(parameters);
        if (!string.IsNullOrWhiteSpace(_tenant))
        {
            var razorView = viewEngine as RazorViewEngine;
            if (razorView != null)
            {
                razorView.ViewLocationFormats = addTenant(razorView.ViewLocationFormats);
                razorView.PartialViewLocationFormats = addTenant(razorView.PartialViewLocationFormats);
                razorView.AreaViewLocationFormats = addTenant(razorView.AreaViewLocationFormats);
                razorView.AreaPartialViewLocationFormats = addTenant(razorView.AreaPartialViewLocationFormats);
            }
        }

        return viewEngine;

    }

    private string[] addTenant(string[] views)
    {
        var tenantedView = new List<string>();
        foreach (var view in views)
        {
            if (view.EndsWith(".cshtml",StringComparison.OrdinalIgnoreCase))
                tenantedView.Add(string.Format ("{0}-tenant-{1}.cshtml", view.Substring(0,view.Length - 7) ,_tenant));
            tenantedView.Add(view);
        }
        return tenantedView.ToArray();
    }
}