mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Layouts, Widgets and Conditions.
- Moved Rules engine code to new Orchard.Conditions module. - Refactored Layouts and Widgets to use Conditions. - Moved Widgets element harvester to the Widgets module as a separate feature.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Scripting;
|
||||
using Orchard.Tests.Stubs;
|
||||
|
||||
namespace Orchard.Tests.Modules.Conditions {
|
||||
[TestFixture]
|
||||
public class ConditionEvaluationTests {
|
||||
private IContainer _container;
|
||||
private IConditionManager _conditionManager;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<ScriptExpressionEvaluator>().As<IScriptExpressionEvaluator>();
|
||||
builder.RegisterType<AlwaysTrueCondition>().As<IConditionProvider>();
|
||||
builder.RegisterType<ConditionManager>().As<IConditionManager>();
|
||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
||||
|
||||
_container = builder.Build();
|
||||
_conditionManager = _container.Resolve<IConditionManager>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProviderGetsCalledForExpression() {
|
||||
var result = _conditionManager.Matches("hello");
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RubyExpressionIsEvaluated() {
|
||||
var result = _conditionManager.Matches("not hello");
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ArgumentsArePassedCorrectly() {
|
||||
var result = _conditionManager.Matches("add(2, 3) == 5");
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
}
|
||||
|
||||
public class AlwaysTrueCondition : IConditionProvider {
|
||||
public void Evaluate(ConditionEvaluationContext evaluationContext) {
|
||||
if (evaluationContext.FunctionName == "add") {
|
||||
evaluationContext.Result = Convert.ToInt32(evaluationContext.Arguments[0]) + Convert.ToInt32(evaluationContext.Arguments[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
evaluationContext.Result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,87 +1,87 @@
|
||||
using System;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Widgets.RuleEngine;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Tests.Modules.Widgets.RuleEngine {
|
||||
[TestFixture]
|
||||
public class UrlRuleProviderTest {
|
||||
private IContainer _container;
|
||||
private IRuleProvider _urlRuleProvider;
|
||||
private StubHttpContextAccessor _stubContextAccessor;
|
||||
private ShellSettings _shellSettings;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
_shellSettings = new ShellSettings { RequestUrlPrefix = String.Empty };
|
||||
builder.RegisterType<UrlRuleProvider>().As<IRuleProvider>();
|
||||
builder.RegisterInstance(_shellSettings);
|
||||
_stubContextAccessor = new StubHttpContextAccessor();
|
||||
builder.RegisterInstance(_stubContextAccessor).As<IHttpContextAccessor>();
|
||||
_container = builder.Build();
|
||||
_urlRuleProvider = _container.Resolve<IRuleProvider>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForHomePageMatchesHomePagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/"));
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForAboutPageMatchesAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/about"));
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/about" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForBlogWithEndingWildcardMatchesBlogPostPageInSaidBlog() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/my-blog/my-blog-post"));
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/my-blog/*" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForHomePageDoesNotMatchAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/about"));
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForAboutPageMatchesDifferentCasedAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/About"));
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/about" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForAboutPageWithEndingSlashMatchesAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/About/"));
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/about" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForHomePageMatchesHomePagePathWithUrlPrefix() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/site1"));
|
||||
_shellSettings.RequestUrlPrefix = "site1";
|
||||
var context = new RuleContext { FunctionName = "url", Arguments = new[] { "~/" } };
|
||||
_urlRuleProvider.Process(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Widgets.RuleEngine;
|
||||
|
||||
namespace Orchard.Tests.Modules.Conditions.Providers {
|
||||
[TestFixture]
|
||||
public class UrlRuleConditionTest {
|
||||
private IContainer _container;
|
||||
private IConditionProvider _urlCondition;
|
||||
private StubHttpContextAccessor _stubContextAccessor;
|
||||
private ShellSettings _shellSettings;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
_shellSettings = new ShellSettings { RequestUrlPrefix = String.Empty };
|
||||
builder.RegisterType<UrlCondition>().As<IConditionProvider>();
|
||||
builder.RegisterInstance(_shellSettings);
|
||||
_stubContextAccessor = new StubHttpContextAccessor();
|
||||
builder.RegisterInstance(_stubContextAccessor).As<IHttpContextAccessor>();
|
||||
_container = builder.Build();
|
||||
_urlCondition = _container.Resolve<IConditionProvider>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForHomePageMatchesHomePagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/"));
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForAboutPageMatchesAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/about"));
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/about" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForBlogWithEndingWildcardMatchesBlogPostPageInSaidBlog() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/my-blog/my-blog-post"));
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/my-blog/*" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForHomePageDoesNotMatchAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/about"));
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForAboutPageMatchesDifferentCasedAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/About"));
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/about" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForAboutPageWithEndingSlashMatchesAboutPagePath() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/About/"));
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/about" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UrlForHomePageMatchesHomePagePathWithUrlPrefix() {
|
||||
_stubContextAccessor.Set(new StubHttpContext("~/site1"));
|
||||
_shellSettings.RequestUrlPrefix = "site1";
|
||||
var context = new ConditionEvaluationContext { FunctionName = "url", Arguments = new[] { "~/" } };
|
||||
_urlCondition.Evaluate(context);
|
||||
Assert.That(context.Result, Is.True);
|
||||
}
|
||||
}
|
||||
}
|
@@ -190,9 +190,9 @@
|
||||
<Compile Include="Users\Services\MembershipServiceTests.cs" />
|
||||
<Compile Include="Warmup\WebDownloaderTests.cs" />
|
||||
<Compile Include="Warmup\WarmupUpdaterTests.cs" />
|
||||
<Compile Include="Widgets\RuleEngine\UrlRuleProviderTest.cs" />
|
||||
<Compile Include="Conditions\Providers\UrlRuleConditionTest.cs" />
|
||||
<Compile Include="Widgets\Services\WidgetsServiceTest.cs" />
|
||||
<Compile Include="Widgets\WidgetsTests.cs" />
|
||||
<Compile Include="Conditions\ConditionEvaluationTests.cs" />
|
||||
<Compile Include="Workflows\Activities\WebRequestActivityTests.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\LiveWriterControllerTests.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\HomeControllerTests.cs" />
|
||||
@@ -225,6 +225,10 @@
|
||||
<Project>{14C049FD-B35B-415A-A824-87F26B26E7FD}</Project>
|
||||
<Name>Orchard.Comments</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Web\Modules\Orchard.Conditions\Orchard.Conditions.csproj">
|
||||
<Project>{98251eae-a41b-47b2-aa91-e28b8482da70}</Project>
|
||||
<Name>Orchard.Conditions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Web\Modules\Orchard.DesignerTools\Orchard.DesignerTools.csproj">
|
||||
<Project>{4A4595EF-6C37-4F99-96ED-4AE0B9E438D3}</Project>
|
||||
<Name>Orchard.DesignerTools</Name>
|
||||
|
@@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Scripting;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Widgets.RuleEngine;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Tests.Modules.Widgets {
|
||||
[TestFixture]
|
||||
public class WidgetsTests {
|
||||
private IContainer _container;
|
||||
private IRuleManager _ruleManager;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<ScriptExpressionEvaluator>().As<IScriptExpressionEvaluator>();
|
||||
builder.RegisterType<AlwaysTrueRuleProvider>().As<IRuleProvider>();
|
||||
builder.RegisterType<RuleManager>().As<IRuleManager>();
|
||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
||||
|
||||
_container = builder.Build();
|
||||
_ruleManager = _container.Resolve<IRuleManager>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProviderGetsCalledForExpression() {
|
||||
bool result = _ruleManager.Matches("hello");
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RubyExpressionIsEvaluated() {
|
||||
bool result = _ruleManager.Matches("not hello");
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ArgumentsArePassedCorrectly() {
|
||||
bool result = _ruleManager.Matches("add(2, 3) == 5");
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
}
|
||||
|
||||
public class AlwaysTrueRuleProvider : IRuleProvider {
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (ruleContext.FunctionName == "add") {
|
||||
ruleContext.Result = Convert.ToInt32(ruleContext.Arguments[0]) + Convert.ToInt32(ruleContext.Arguments[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
ruleContext.Result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
src/Orchard.Web/Modules/Orchard.Conditions/Module.txt
Normal file
13
src/Orchard.Web/Modules/Orchard.Conditions/Module.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Name: Conditions
|
||||
AntiForgery: enabled
|
||||
Author: The Orchard Team
|
||||
Website: http://orchardproject.net
|
||||
Version: 1.0
|
||||
OrchardVersion: 1.9
|
||||
Description: Provides a rules API that evaluate to true or false.
|
||||
Features:
|
||||
Orchard.Conditions:
|
||||
Name: Conditions
|
||||
Description: Provides a rules API that evaluate to true or false.
|
||||
Category: Scripting
|
||||
Dependencies: Orchard.Scripting
|
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{98251EAE-A41B-47B2-AA91-E28B8482DA70}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Orchard.Conditions</RootNamespace>
|
||||
<AssemblyName>Orchard.Conditions</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||
<MvcBuildViews>false</MvcBuildViews>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>false</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>..\..\..\OrchardBasicCorrectness.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
<Reference Include="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Web.Abstractions" />
|
||||
<Reference Include="System.Web.Routing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Web.config" />
|
||||
<Content Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="Module.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
|
||||
<Name>Orchard.Framework</Name>
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
|
||||
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
|
||||
<Name>Orchard.Core</Name>
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Scripting\Orchard.Scripting.csproj">
|
||||
<Project>{99002b65-86f7-415e-bf4a-381aa8ab9ccc}</Project>
|
||||
<Name>Orchard.Scripting</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Providers\AuthenticatedCondition.cs" />
|
||||
<Compile Include="Providers\BuiltinCondition.cs" />
|
||||
<Compile Include="Services\ConditionManager.cs" />
|
||||
<Compile Include="Providers\UrlCondition.cs" />
|
||||
<Compile Include="Services\IConditionManager.cs" />
|
||||
<Compile Include="Services\IConditionProvider.cs" />
|
||||
<Compile Include="Services\ConditionEvaluationContext.cs" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target> -->
|
||||
<Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler">
|
||||
<PropertyGroup>
|
||||
<AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir>
|
||||
</PropertyGroup>
|
||||
<!-- If this is an area child project, uncomment the following line:
|
||||
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
|
||||
-->
|
||||
<!-- If this is an area parent project, uncomment the following lines:
|
||||
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
|
||||
<CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />
|
||||
-->
|
||||
</Target>
|
||||
<Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">
|
||||
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
|
||||
</Target>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>45979</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>
|
||||
</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>True</UseCustomServer>
|
||||
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
@@ -0,0 +1,37 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Orchard.Conditions")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyProduct("Orchard")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("1c288740-10c0-4fa9-a051-501d259e4fc0")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Security;
|
||||
|
||||
namespace Orchard.Conditions.Providers {
|
||||
public class AuthenticatedCondition : IConditionProvider {
|
||||
private readonly IAuthenticationService _authenticationService;
|
||||
|
||||
public AuthenticatedCondition(IAuthenticationService authenticationService) {
|
||||
_authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
public void Evaluate(ConditionEvaluationContext evaluationContext) {
|
||||
if (!String.Equals(evaluationContext.FunctionName, "authenticated", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_authenticationService.GetAuthenticatedUser() != null) {
|
||||
evaluationContext.Result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
evaluationContext.Result = false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using Orchard.Conditions.Services;
|
||||
|
||||
namespace Orchard.Conditions.Providers {
|
||||
public class BuiltinCondition : IConditionProvider {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
|
||||
public BuiltinCondition(IWorkContextAccessor workContextAccessor) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
}
|
||||
|
||||
public void Evaluate(ConditionEvaluationContext evaluationContext) {
|
||||
if (string.Equals(evaluationContext.FunctionName, "WorkContext", StringComparison.OrdinalIgnoreCase)) {
|
||||
evaluationContext.Result = _workContextAccessor.GetContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,47 +1,47 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Widgets.RuleEngine {
|
||||
public class UrlRuleProvider : IRuleProvider {
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
|
||||
public UrlRuleProvider(IHttpContextAccessor httpContextAccessor, ShellSettings shellSettings) {
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_shellSettings = shellSettings;
|
||||
}
|
||||
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "url", StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
var context = _httpContextAccessor.Current();
|
||||
var url = Convert.ToString(ruleContext.Arguments[0]);
|
||||
if (url.StartsWith("~/")) {
|
||||
url = url.Substring(2);
|
||||
var appPath = context.Request.ApplicationPath;
|
||||
if (appPath == "/")
|
||||
appPath = "";
|
||||
|
||||
if(!String.IsNullOrEmpty(_shellSettings.RequestUrlPrefix))
|
||||
appPath = String.Concat(appPath, "/", _shellSettings.RequestUrlPrefix);
|
||||
|
||||
url = String.Concat(appPath, "/", url);
|
||||
}
|
||||
|
||||
if (!url.Contains("?"))
|
||||
url = url.TrimEnd('/');
|
||||
|
||||
var requestPath = context.Request.Path;
|
||||
if (!requestPath.Contains("?"))
|
||||
requestPath = requestPath.TrimEnd('/');
|
||||
|
||||
ruleContext.Result = url.EndsWith("*")
|
||||
? requestPath.StartsWith(url.TrimEnd('*'), StringComparison.OrdinalIgnoreCase)
|
||||
: string.Equals(requestPath, url, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Web;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Mvc;
|
||||
|
||||
namespace Orchard.Widgets.RuleEngine {
|
||||
public class UrlCondition : IConditionProvider {
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
|
||||
public UrlCondition(IHttpContextAccessor httpContextAccessor, ShellSettings shellSettings) {
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_shellSettings = shellSettings;
|
||||
}
|
||||
|
||||
public void Evaluate(ConditionEvaluationContext evaluationContext) {
|
||||
if (!String.Equals(evaluationContext.FunctionName, "url", StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
var context = _httpContextAccessor.Current();
|
||||
var url = Convert.ToString(evaluationContext.Arguments[0]);
|
||||
if (url.StartsWith("~/")) {
|
||||
url = url.Substring(2);
|
||||
var appPath = context.Request.ApplicationPath;
|
||||
if (appPath == "/")
|
||||
appPath = "";
|
||||
|
||||
if(!String.IsNullOrEmpty(_shellSettings.RequestUrlPrefix))
|
||||
appPath = String.Concat(appPath, "/", _shellSettings.RequestUrlPrefix);
|
||||
|
||||
url = String.Concat(appPath, "/", url);
|
||||
}
|
||||
|
||||
if (!url.Contains("?"))
|
||||
url = url.TrimEnd('/');
|
||||
|
||||
var requestPath = context.Request.Path;
|
||||
if (!requestPath.Contains("?"))
|
||||
requestPath = requestPath.TrimEnd('/');
|
||||
|
||||
evaluationContext.Result = url.EndsWith("*")
|
||||
? requestPath.StartsWith(url.TrimEnd('*'), StringComparison.OrdinalIgnoreCase)
|
||||
: string.Equals(requestPath, url, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
namespace Orchard.Conditions.Services {
|
||||
public class ConditionEvaluationContext {
|
||||
public string FunctionName { get; set; }
|
||||
public object[] Arguments { get; set; }
|
||||
public object Result { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Scripting;
|
||||
|
||||
namespace Orchard.Conditions.Services {
|
||||
public class ConditionManager : IConditionManager {
|
||||
private readonly IConditionProvider _conditions;
|
||||
private readonly IEnumerable<IScriptExpressionEvaluator> _evaluators;
|
||||
|
||||
public ConditionManager(IConditionProvider conditions, IEnumerable<IScriptExpressionEvaluator> evaluators) {
|
||||
_conditions = conditions;
|
||||
_evaluators = evaluators;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public bool Matches(string expression) {
|
||||
var evaluator = _evaluators.FirstOrDefault();
|
||||
if (evaluator == null) {
|
||||
throw new OrchardException(T("There are currently no scripting engines enabled"));
|
||||
}
|
||||
|
||||
var result = evaluator.Evaluate(expression, new List<IGlobalMethodProvider> { new GlobalMethodProvider(this) });
|
||||
if (!(result is bool)) {
|
||||
throw new OrchardException(T("Expression is not a boolean value"));
|
||||
}
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
private class GlobalMethodProvider : IGlobalMethodProvider {
|
||||
private readonly ConditionManager _conditionManager;
|
||||
|
||||
public GlobalMethodProvider(ConditionManager conditionManager) {
|
||||
_conditionManager = conditionManager;
|
||||
}
|
||||
|
||||
public void Process(GlobalMethodContext context) {
|
||||
var ruleContext = new ConditionEvaluationContext {
|
||||
FunctionName = context.FunctionName,
|
||||
Arguments = context.Arguments.ToArray(),
|
||||
Result = context.Result
|
||||
};
|
||||
|
||||
_conditionManager._conditions.Evaluate(ruleContext);
|
||||
|
||||
context.Result = ruleContext.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
namespace Orchard.Conditions.Services {
|
||||
public interface IConditionManager : IDependency {
|
||||
bool Matches(string expression);
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
using Orchard.Events;
|
||||
|
||||
namespace Orchard.Conditions.Services {
|
||||
public interface IConditionProvider : IEventHandler {
|
||||
void Evaluate(ConditionEvaluationContext evaluationContext);
|
||||
}
|
||||
}
|
43
src/Orchard.Web/Modules/Orchard.Conditions/Web.config
Normal file
43
src/Orchard.Web/Modules/Orchard.Conditions/Web.config
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<remove name="host" />
|
||||
<remove name="pages" />
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="System.Web.WebPages" />
|
||||
<add namespace="System.Linq"/>
|
||||
<add namespace="System.Collections.Generic"/>
|
||||
<add namespace="Orchard.Mvc.Html"/>
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<system.web>
|
||||
<compilation targetFramework="4.5.1">
|
||||
<assemblies>
|
||||
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<add assembly="Orchard.Framework,Culture=neutral, PublicKeyToken=null"/>
|
||||
<add assembly="Orchard.Core,Culture=neutral, PublicKeyToken=null"/>
|
||||
</assemblies>
|
||||
</compilation>
|
||||
</system.web>
|
||||
|
||||
</configuration>
|
@@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Services;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Layouts.Handlers {
|
||||
public class ElementRuleCoordinator : ElementEventHandlerBase {
|
||||
private readonly IRuleManager _ruleManager;
|
||||
private readonly IConditionManager _conditionManager;
|
||||
private readonly Dictionary<string, bool> _evaluations = new Dictionary<string, bool>();
|
||||
|
||||
public ElementRuleCoordinator(IRuleManager ruleManager) {
|
||||
_ruleManager = ruleManager;
|
||||
public ElementRuleCoordinator(IConditionManager conditionManager) {
|
||||
_conditionManager = conditionManager;
|
||||
}
|
||||
|
||||
public override void CreatingDisplay(ElementCreatingDisplayShapeContext context) {
|
||||
@@ -27,7 +27,7 @@ namespace Orchard.Layouts.Handlers {
|
||||
if (_evaluations.ContainsKey(rule))
|
||||
return _evaluations[rule];
|
||||
|
||||
var result = _ruleManager.Matches(rule);
|
||||
var result = _conditionManager.Matches(rule);
|
||||
_evaluations[rule] = result;
|
||||
return result;
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ Features:
|
||||
Orchard.Layouts:
|
||||
Name: Layouts
|
||||
Description: Provides tools to create layouts.
|
||||
Dependencies: Common, Orchard.jQuery, Orchard.Forms, Orchard.Tokens, Orchard.MediaLibrary, Orchard.Widgets
|
||||
Dependencies: Common, Orchard.jQuery, Orchard.Forms, Orchard.Tokens, Orchard.MediaLibrary, Orchard.Conditions
|
||||
Category: Layout
|
||||
Orchard.Layouts.Snippets:
|
||||
Name: Layout Snippets
|
||||
|
@@ -86,7 +86,6 @@
|
||||
<Content Include="Images\illustration.jpg" />
|
||||
<Content Include="Images\logo.svg" />
|
||||
<Content Include="Placement.info" />
|
||||
<Content Include="Scripts\placeable-widget-editor.js" />
|
||||
<Content Include="Scripts\element-browser.js" />
|
||||
<Content Include="Scripts\AutoFocus.js" />
|
||||
<Content Include="Scripts\Elements\Image.js" />
|
||||
@@ -291,6 +290,10 @@
|
||||
<Project>{66fccd76-2761-47e3-8d11-b45d0001ddaa}</Project>
|
||||
<Name>Orchard.Autoroute</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Conditions\Orchard.Conditions.csproj">
|
||||
<Project>{98251eae-a41b-47b2-aa91-e28b8482da70}</Project>
|
||||
<Name>Orchard.Conditions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Forms\Orchard.Forms.csproj">
|
||||
<Project>{642a49d7-8752-4177-80d6-bfbbcfad3de0}</Project>
|
||||
<Name>Orchard.Forms</Name>
|
||||
@@ -312,10 +315,6 @@
|
||||
<Project>{6f759635-13d7-4e94-bcc9-80445d63f117}</Project>
|
||||
<Name>Orchard.Tokens</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Widgets\Orchard.Widgets.csproj">
|
||||
<Project>{194d3ccc-1153-474d-8176-fde8d7d0d0bd}</Project>
|
||||
<Name>Orchard.Widgets</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
@@ -360,7 +359,6 @@
|
||||
<Compile Include="Framework\Elements\IElement.cs" />
|
||||
<Compile Include="Handlers\ElementDriversCoordinator.cs" />
|
||||
<Compile Include="Handlers\ElementRuleCoordinator.cs" />
|
||||
<Compile Include="Handlers\WidgetPartHandler.cs" />
|
||||
<Compile Include="Helpers\PlaceableContentExtensions.cs" />
|
||||
<Compile Include="Helpers\DictionaryExtensions.cs" />
|
||||
<Compile Include="Helpers\EditorResultExtensions.cs" />
|
||||
@@ -607,12 +605,6 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\DefinitionTemplates\ContentTypeLayoutSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\PlacedContentElementEditor.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\PlacedContentElementEditor-Widget.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Elements.PlaceableContentItem.cshtml" />
|
||||
</ItemGroup>
|
||||
|
@@ -30,9 +30,7 @@ namespace Orchard.Layouts.Providers {
|
||||
return contentTypeDefinitions.Select(contentTypeDefinition => {
|
||||
var settings = contentTypeDefinition.Settings;
|
||||
var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName;
|
||||
var stereotype = settings.ContainsKey("Stereotype") ? settings["Stereotype"] : default(string);
|
||||
var category = GetCategoryFromStereotype(stereotype);
|
||||
return new ElementDescriptor(typeof (PlaceableContentItem), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category) {
|
||||
return new ElementDescriptor(typeof (PlaceableContentItem), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category: "Content Items") {
|
||||
Displaying = Displaying,
|
||||
Editor = Editor,
|
||||
UpdateEditor = UpdateEditor,
|
||||
@@ -112,18 +110,11 @@ namespace Orchard.Layouts.Providers {
|
||||
}
|
||||
|
||||
var elementEditorShape = context.ShapeFactory.EditorTemplate(TemplateName: "Elements.PlaceableContentItem", Model: elementViewModel, Prefix: context.Prefix);
|
||||
var editorWrapper = context.ShapeFactory.PlacedContentElementEditor(ContentItem: contentItem);
|
||||
var stereotype = contentItem.TypeDefinition.Settings.ContainsKey("Stereotype") ? contentItem.TypeDefinition.Settings["Stereotype"] : default(string);
|
||||
|
||||
if(!String.IsNullOrWhiteSpace(stereotype))
|
||||
editorWrapper.Metadata.Alternates.Add(String.Format("PlacedContentElementEditor__{0}", stereotype));
|
||||
|
||||
editorWrapper.Metadata.Position = "Properties:0";
|
||||
|
||||
elementEditorShape.Metadata.Position = "Properties:0";
|
||||
contentEditorShape.Metadata.Position = "Properties:0";
|
||||
context.EditorResult.Add(elementEditorShape);
|
||||
context.EditorResult.Add(contentEditorShape);
|
||||
context.EditorResult.Add(editorWrapper);
|
||||
}
|
||||
|
||||
private void RemoveContentItem(ElementRemovingContext context) {
|
||||
@@ -171,23 +162,13 @@ namespace Orchard.Layouts.Providers {
|
||||
}
|
||||
|
||||
private IEnumerable<ContentTypeDefinition> GetPlaceableContentTypeDefinitions() {
|
||||
// Select all types that have either "Placeable" set ot true or the "Widget" stereotype.
|
||||
// Select all types that have either "Placeable" set to true.
|
||||
var contentTypeDefinitionsQuery =
|
||||
from contentTypeDefinition in _contentManager.Value.GetContentTypeDefinitions()
|
||||
let stereotype = contentTypeDefinition.Settings.ContainsKey("Stereotype") ? contentTypeDefinition.Settings["Stereotype"] : default(string)
|
||||
where contentTypeDefinition.Settings.GetModel<ContentTypeLayoutSettings>().Placeable || stereotype == "Widget"
|
||||
where contentTypeDefinition.Settings.GetModel<ContentTypeLayoutSettings>().Placeable
|
||||
select contentTypeDefinition;
|
||||
|
||||
return contentTypeDefinitionsQuery.ToList();
|
||||
}
|
||||
|
||||
private string GetCategoryFromStereotype(string stereotype) {
|
||||
switch (stereotype) {
|
||||
case "Widget":
|
||||
return "Widgets";
|
||||
default:
|
||||
return "Content Items";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Include("placeable-widget-editor.js");
|
||||
}
|
@@ -1 +0,0 @@
|
||||
<!-- Placeholder -->
|
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Widgets.Handlers;
|
||||
|
||||
namespace Orchard.Widgets.Conditions {
|
||||
public class ContentDisplayedRuleProvider : IConditionProvider {
|
||||
private readonly IDisplayedContentItemHandler _displayedContentItemHandler;
|
||||
|
||||
public ContentDisplayedRuleProvider(IDisplayedContentItemHandler displayedContentItemHandler) {
|
||||
_displayedContentItemHandler = displayedContentItemHandler;
|
||||
}
|
||||
|
||||
public void Evaluate(ConditionEvaluationContext evaluationContext) {
|
||||
if (!String.Equals(evaluationContext.FunctionName, "contenttype", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var contentType = Convert.ToString(evaluationContext.Arguments[0]);
|
||||
|
||||
evaluationContext.Result = _displayedContentItemHandler.IsDisplayed(contentType);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
@@ -11,14 +12,14 @@ using Orchard.Widgets.Services;
|
||||
namespace Orchard.Widgets.Drivers {
|
||||
|
||||
public class LayerPartDriver : ContentPartDriver<LayerPart> {
|
||||
private readonly IRuleManager _ruleManager;
|
||||
private readonly IConditionManager _conditionManager;
|
||||
private readonly IWidgetsService _widgetsService;
|
||||
|
||||
public LayerPartDriver(
|
||||
IRuleManager ruleManager,
|
||||
IConditionManager conditionManager,
|
||||
IWidgetsService widgetsService) {
|
||||
|
||||
_ruleManager = ruleManager;
|
||||
_conditionManager = conditionManager;
|
||||
_widgetsService = widgetsService;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
@@ -53,7 +54,7 @@ namespace Orchard.Widgets.Drivers {
|
||||
}
|
||||
|
||||
try {
|
||||
_ruleManager.Matches(layerPart.LayerRule);
|
||||
_conditionManager.Matches(layerPart.LayerRule);
|
||||
}
|
||||
catch (Exception e) {
|
||||
updater.AddModelError("Description", T("The rule is not valid: {0}", e.Message));
|
||||
|
@@ -1,15 +1,16 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Layouts.Helpers;
|
||||
using Orchard.Layouts.Models;
|
||||
using Orchard.Widgets.Models;
|
||||
|
||||
namespace Orchard.Layouts.Handlers {
|
||||
public class WidgetPartHandler : ContentHandler {
|
||||
namespace Orchard.Widgets.Handlers {
|
||||
[OrchardFeature("Orchard.Widgets.Elements")]
|
||||
public class WidgetElementsHandler : ContentHandler {
|
||||
private readonly IOrchardServices _orchardServices;
|
||||
|
||||
public WidgetPartHandler(IOrchardServices orchardServices) {
|
||||
public WidgetElementsHandler(IOrchardServices orchardServices) {
|
||||
_orchardServices = orchardServices;
|
||||
OnUpdated<WidgetPart>(PostProcessPlacedWidget);
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Helpers;
|
||||
|
||||
namespace Orchard.Widgets.Layouts.Elements {
|
||||
[OrchardFeature("Orchard.Widgets.Elements")]
|
||||
public class Widget : Element {
|
||||
public override string Category {
|
||||
get { return "Widgets"; }
|
||||
}
|
||||
|
||||
public override bool IsSystemElement {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool HasEditor {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public int? WidgetId {
|
||||
get { return this.Retrieve(x => x.WidgetId); }
|
||||
set { this.Store(x => x.WidgetId, value); }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,176 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Framework.Harvesters;
|
||||
using Orchard.Layouts.Helpers;
|
||||
using Orchard.Widgets.Layouts.Elements;
|
||||
using Orchard.Widgets.ViewModels;
|
||||
using ContentItem = Orchard.ContentManagement.ContentItem;
|
||||
|
||||
namespace Orchard.Widgets.Layouts.Providers {
|
||||
[OrchardFeature("Orchard.Widgets.Elements")]
|
||||
public class WidgetElementHarvester : Component, IElementHarvester {
|
||||
private readonly Work<IContentManager> _contentManager;
|
||||
|
||||
public WidgetElementHarvester(Work<IContentManager> contentManager) {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public IEnumerable<ElementDescriptor> HarvestElements(HarvestElementsContext context) {
|
||||
var contentTypeDefinitions = GetWidgetContentTypeDefinitions();
|
||||
|
||||
return contentTypeDefinitions.Select(contentTypeDefinition => {
|
||||
var settings = contentTypeDefinition.Settings;
|
||||
var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName;
|
||||
return new ElementDescriptor(typeof (Widget), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category: "Widgets") {
|
||||
Displaying = Displaying,
|
||||
Editor = Editor,
|
||||
UpdateEditor = UpdateEditor,
|
||||
ToolboxIcon = "\uf1b2",
|
||||
EnableEditorDialog = true,
|
||||
Removing = RemoveContentItem,
|
||||
Exporting = ExportElement,
|
||||
Importing = ImportElement,
|
||||
StateBag = new Dictionary<string, object> {
|
||||
{ "ContentTypeName", contentTypeDefinition.Name }
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void Displaying(ElementDisplayingContext context) {
|
||||
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
|
||||
var element = (Widget)context.Element;
|
||||
var widgetId = element.WidgetId;
|
||||
var versionOptions = context.DisplayType == "Design" ? VersionOptions.Latest : VersionOptions.Published;
|
||||
var widget = widgetId != null
|
||||
? _contentManager.Value.Get(widgetId.Value, versionOptions)
|
||||
: _contentManager.Value.New(contentTypeName);
|
||||
|
||||
var widgetShape = widget != null ? _contentManager.Value.BuildDisplay(widget) : default(dynamic);
|
||||
context.ElementShape.Widget = widget;
|
||||
context.ElementShape.WidgetShape = widgetShape;
|
||||
}
|
||||
|
||||
private void Editor(ElementEditorContext context) {
|
||||
UpdateEditor(context);
|
||||
}
|
||||
|
||||
private void UpdateEditor(ElementEditorContext context) {
|
||||
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
|
||||
var element = (Widget) context.Element;
|
||||
var elementViewModel = new WidgetElementViewModel {
|
||||
WidgetId = element.WidgetId
|
||||
};
|
||||
|
||||
if (context.Updater != null) {
|
||||
context.Updater.TryUpdateModel(elementViewModel, context.Prefix, null, null);
|
||||
}
|
||||
|
||||
var widgetId = elementViewModel.WidgetId;
|
||||
var widget = widgetId != null
|
||||
? _contentManager.Value.Get(widgetId.Value, VersionOptions.Latest)
|
||||
: _contentManager.Value.New(contentTypeName);
|
||||
|
||||
dynamic contentEditorShape;
|
||||
|
||||
if (context.Updater != null) {
|
||||
if (widget.Id == 0) {
|
||||
_contentManager.Value.Create(widget, VersionOptions.Draft);
|
||||
}
|
||||
else {
|
||||
var isDraftable = widget.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable;
|
||||
var versionOptions = isDraftable ? VersionOptions.DraftRequired : VersionOptions.Latest;
|
||||
widget = _contentManager.Value.Get(widget.Id, versionOptions);
|
||||
}
|
||||
|
||||
element.WidgetId = widget.Id;
|
||||
|
||||
// If the widget has the CommonPart attached, set its Container property to the Content (if any).
|
||||
// This helps preventing widgets from appearing as orphans.
|
||||
var commonPart = widget.As<ICommonPart>();
|
||||
if (commonPart != null)
|
||||
commonPart.Container = context.Content;
|
||||
|
||||
widget.IsPlaceableContent(true);
|
||||
contentEditorShape = _contentManager.Value.UpdateEditor(widget, context.Updater);
|
||||
|
||||
_contentManager.Value.Publish(widget);
|
||||
}
|
||||
else {
|
||||
contentEditorShape = _contentManager.Value.BuildEditor(widget);
|
||||
}
|
||||
|
||||
var elementEditorShape = context.ShapeFactory.EditorTemplate(TemplateName: "Elements.Widget", Model: elementViewModel, Prefix: context.Prefix);
|
||||
|
||||
elementEditorShape.Metadata.Position = "Properties:0";
|
||||
contentEditorShape.Metadata.Position = "Properties:0";
|
||||
context.EditorResult.Add(elementEditorShape);
|
||||
context.EditorResult.Add(contentEditorShape);
|
||||
}
|
||||
|
||||
private void RemoveContentItem(ElementRemovingContext context) {
|
||||
var element = (Widget) context.Element;
|
||||
var widgetId = element.WidgetId;
|
||||
|
||||
// Only remove the widget if no other elements are referencing this one.
|
||||
// This can happen if the user cut an element and then pasted it back.
|
||||
// That will delete the initial element and create a copy.
|
||||
var widgetElements =
|
||||
from e in context.Elements.Flatten()
|
||||
let p = e as Widget
|
||||
where p != null && p.WidgetId == widgetId
|
||||
select p;
|
||||
|
||||
if (widgetElements.Any())
|
||||
return;
|
||||
|
||||
var contentItem = widgetId != null ? _contentManager.Value.Get(widgetId.Value, VersionOptions.Latest) : default(ContentItem);
|
||||
|
||||
if(contentItem != null)
|
||||
_contentManager.Value.Remove(contentItem);
|
||||
}
|
||||
|
||||
private void ExportElement(ExportElementContext context) {
|
||||
var element = (Widget)context.Element;
|
||||
var widgetId = element.WidgetId;
|
||||
var widget = widgetId != null ? _contentManager.Value.Get(widgetId.Value, VersionOptions.Latest) : default(ContentItem);
|
||||
var widgetIdentity = widget != null ? _contentManager.Value.GetItemMetadata(widget).Identity.ToString() : default(string);
|
||||
|
||||
if (widgetIdentity != null)
|
||||
context.ExportableData["WidgetId"] = widgetIdentity;
|
||||
}
|
||||
|
||||
private void ImportElement(ImportElementContext context) {
|
||||
var widgetIdentity = context.ExportableData.Get("WidgetId");
|
||||
|
||||
if (String.IsNullOrWhiteSpace(widgetIdentity))
|
||||
return;
|
||||
|
||||
var widget = context.Session.GetItemFromSession(widgetIdentity);
|
||||
var element = (Widget)context.Element;
|
||||
|
||||
element.WidgetId = widget != null ? widget.Id : default(int?);
|
||||
}
|
||||
|
||||
private IEnumerable<ContentTypeDefinition> GetWidgetContentTypeDefinitions() {
|
||||
// Select all types that have either "the "Widget" stereotype.
|
||||
var contentTypeDefinitionsQuery =
|
||||
from contentTypeDefinition in _contentManager.Value.GetContentTypeDefinitions()
|
||||
let stereotype = contentTypeDefinition.Settings.ContainsKey("Stereotype") ? contentTypeDefinition.Settings["Stereotype"] : default(string)
|
||||
where stereotype == "Widget"
|
||||
select contentTypeDefinition;
|
||||
|
||||
return contentTypeDefinitionsQuery.ToList();
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ OrchardVersion: 1.9
|
||||
Description: An implementation of widgets for Orchard.
|
||||
FeatureDescription: An implementation of widgets.
|
||||
Category: Widget
|
||||
Dependencies: Orchard.Scripting, Orchard.Themes
|
||||
Dependencies: Orchard.Conditions, Orchard.Scripting, Orchard.Themes
|
||||
Features:
|
||||
Orchard.Widgets.PageLayerHinting:
|
||||
Name: Page Layer Hinting
|
||||
@@ -19,3 +19,8 @@ Features:
|
||||
Description: Add an Edit button on the front-end for authenticated users
|
||||
Category: Widget
|
||||
Dependencies: Orchard.Widgets
|
||||
Orchard.Widgets.Elements
|
||||
Name: Widget Elements
|
||||
Description: Enables widgets to be added as elements to layouts.
|
||||
Category: Layout
|
||||
Dependencies: Orchard.Layouts
|
@@ -26,6 +26,7 @@
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<TargetFrameworkProfile />
|
||||
<UseGlobalApplicationHostFile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -74,6 +75,9 @@
|
||||
<Compile Include="Handlers\DisplayedContentItemHandler.cs" />
|
||||
<Compile Include="Handlers\LayerHintHandler.cs" />
|
||||
<Compile Include="Drivers\WidgetPartDriver.cs" />
|
||||
<Compile Include="Handlers\WidgetElementsHandler.cs" />
|
||||
<Compile Include="Layouts\Elements\Widget.cs" />
|
||||
<Compile Include="Layouts\Providers\WidgetElementHarvester.cs" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Handlers\LayerPartHandler.cs" />
|
||||
<Compile Include="Handlers\WidgetPartHandler.cs" />
|
||||
@@ -85,11 +89,8 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Filters\WidgetFilter.cs" />
|
||||
<Compile Include="ResourceManifest.cs" />
|
||||
<Compile Include="RuleEngine\AuthenticatedRuleProvider.cs" />
|
||||
<Compile Include="RuleEngine\BuiltinRuleProvider.cs" />
|
||||
<Compile Include="RuleEngine\ContentDisplayedRuleProvider.cs" />
|
||||
<Compile Include="RuleEngine\RuleManager.cs" />
|
||||
<Compile Include="RuleEngine\UrlRuleProvider.cs" />
|
||||
<Compile Include="Conditions\ContentDisplayedRuleProvider.cs" />
|
||||
<Compile Include="Services\RuleManager.cs" />
|
||||
<Compile Include="Services\DefaultLayerEvaluationService.cs" />
|
||||
<Compile Include="Services\ILayerEvaluationService.cs" />
|
||||
<Compile Include="Services\IRuleManager.cs" />
|
||||
@@ -99,12 +100,14 @@
|
||||
<Compile Include="Services\RuleContext.cs" />
|
||||
<Compile Include="Services\WidgetsService.cs" />
|
||||
<Compile Include="Shapes.cs" />
|
||||
<Compile Include="ViewModels\WidgetElementViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\Admin\images\edit.png" />
|
||||
<Content Include="Content\Admin\images\moveup.gif" />
|
||||
<Content Include="Content\Admin\images\movedown.gif" />
|
||||
<Content Include="Module.txt" />
|
||||
<Content Include="Scripts\widget-element-editor.js" />
|
||||
<Content Include="Styles\images\all-zones-on.gif" />
|
||||
<Content Include="Styles\images\all-zones.gif" />
|
||||
<Content Include="Styles\images\arrows.png" />
|
||||
@@ -131,6 +134,14 @@
|
||||
<Name>Orchard.Framework</Name>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Conditions\Orchard.Conditions.csproj">
|
||||
<Project>{98251eae-a41b-47b2-aa91-e28b8482da70}</Project>
|
||||
<Name>Orchard.Conditions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Layouts\Orchard.Layouts.csproj">
|
||||
<Project>{6bd8b2fa-f2e3-4ac8-a4c3-2925a653889a}</Project>
|
||||
<Name>Orchard.Layouts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Scripting\Orchard.Scripting.csproj">
|
||||
<Project>{99002B65-86F7-415E-BF4A-381AA8AB9CCC}</Project>
|
||||
<Name>Orchard.Scripting</Name>
|
||||
@@ -192,6 +203,20 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\WidgetPlacement.Orphans.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Elements\Widget.Design.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Elements\Widget.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Elements.Widget.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Scripts\Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using Orchard.Security;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Widgets.RuleEngine {
|
||||
public class AuthenticatedRuleProvider : IRuleProvider {
|
||||
private readonly IAuthenticationService _authenticationService;
|
||||
|
||||
public AuthenticatedRuleProvider(IAuthenticationService authenticationService) {
|
||||
_authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "authenticated", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_authenticationService.GetAuthenticatedUser() != null) {
|
||||
ruleContext.Result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ruleContext.Result = false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Widgets.RuleEngine {
|
||||
public class BuiltinRuleProvider : IRuleProvider {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
|
||||
public BuiltinRuleProvider(IWorkContextAccessor workContextAccessor) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
}
|
||||
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (string.Equals(ruleContext.FunctionName, "WorkContext", StringComparison.OrdinalIgnoreCase)) {
|
||||
ruleContext.Result = _workContextAccessor.GetContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using Orchard.Widgets.Handlers;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Widgets.RuleEngine {
|
||||
public class ContentDisplayedRuleProvider : IRuleProvider {
|
||||
private readonly IDisplayedContentItemHandler _displayedContentItemHandler;
|
||||
|
||||
public ContentDisplayedRuleProvider(IDisplayedContentItemHandler displayedContentItemHandler) {
|
||||
_displayedContentItemHandler = displayedContentItemHandler;
|
||||
}
|
||||
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "contenttype", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var contentType = Convert.ToString(ruleContext.Arguments[0]);
|
||||
|
||||
ruleContext.Result = _displayedContentItemHandler.IsDisplayed(contentType);
|
||||
}
|
||||
}
|
||||
}
|
16
src/Orchard.Web/Modules/Orchard.Widgets/Scripts/Web.config
Normal file
16
src/Orchard.Web/Modules/Orchard.Widgets/Scripts/Web.config
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<staticContent>
|
||||
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
|
||||
</staticContent>
|
||||
|
||||
<handlers accessPolicy="Script,Read">
|
||||
<!--
|
||||
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||
-->
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Widgets.Models;
|
||||
@@ -8,13 +9,13 @@ using Orchard.ContentManagement.Utilities;
|
||||
|
||||
namespace Orchard.Widgets.Services{
|
||||
public class DefaultLayerEvaluationService : ILayerEvaluationService {
|
||||
private readonly IRuleManager _ruleManager;
|
||||
private readonly IConditionManager _conditionManager;
|
||||
private readonly IOrchardServices _orchardServices;
|
||||
|
||||
private readonly LazyField<int[]> _activeLayerIDs;
|
||||
|
||||
public DefaultLayerEvaluationService(IRuleManager ruleManager, IOrchardServices orchardServices) {
|
||||
_ruleManager = ruleManager;
|
||||
public DefaultLayerEvaluationService(IConditionManager conditionManager, IOrchardServices orchardServices) {
|
||||
_conditionManager = conditionManager;
|
||||
_orchardServices = orchardServices;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
@@ -38,7 +39,7 @@ namespace Orchard.Widgets.Services{
|
||||
}
|
||||
|
||||
private int[] PopulateActiveLayers() {
|
||||
// Once the Rule Engine is done:
|
||||
// Once the Condition Engine is done:
|
||||
// Get Layers and filter by zone and rule
|
||||
// NOTE: .ForType("Layer") is faster than .Query<LayerPart, LayerPartRecord>()
|
||||
var activeLayers = _orchardServices.ContentManager.Query<LayerPart>().WithQueryHints(new QueryHints().ExpandParts<LayerPart>()).ForType("Layer").List();
|
||||
@@ -47,7 +48,7 @@ namespace Orchard.Widgets.Services{
|
||||
foreach (var activeLayer in activeLayers) {
|
||||
// ignore the rule if it fails to execute
|
||||
try {
|
||||
if (_ruleManager.Matches(activeLayer.LayerRule)) {
|
||||
if (_conditionManager.Matches(activeLayer.LayerRule)) {
|
||||
activeLayerIds.Add(activeLayer.ContentItem.Id);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,7 @@
|
||||
namespace Orchard.Widgets.Services {
|
||||
using System;
|
||||
|
||||
namespace Orchard.Widgets.Services {
|
||||
[Obsolete("Use Orchard.Conditions.Services.IConditionManager instead.")]
|
||||
public interface IRuleManager : IDependency {
|
||||
bool Matches(string expression);
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using Orchard.Events;
|
||||
using System;
|
||||
using Orchard.Events;
|
||||
|
||||
namespace Orchard.Widgets.Services {
|
||||
[Obsolete("Use Orchard.Conditions.Services.IConditionProvider instead.")]
|
||||
public interface IRuleProvider : IEventHandler {
|
||||
void Process(RuleContext ruleContext);
|
||||
}
|
||||
|
@@ -1,4 +1,7 @@
|
||||
namespace Orchard.Widgets.Services {
|
||||
using System;
|
||||
|
||||
namespace Orchard.Widgets.Services {
|
||||
[Obsolete("Use Orchard.Conditions.Services.ConditionEvaluationContext instead.")]
|
||||
public class RuleContext {
|
||||
public string FunctionName { get; set; }
|
||||
public object[] Arguments { get; set; }
|
||||
|
@@ -1,53 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Scripting;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Widgets.RuleEngine {
|
||||
public class RuleManager : IRuleManager {
|
||||
private readonly IRuleProvider _ruleProviders;
|
||||
private readonly IEnumerable<IScriptExpressionEvaluator> _evaluators;
|
||||
|
||||
public RuleManager(IRuleProvider ruleProviders, IEnumerable<IScriptExpressionEvaluator> evaluators) {
|
||||
_ruleProviders = ruleProviders;
|
||||
_evaluators = evaluators;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public bool Matches(string expression) {
|
||||
var evaluator = _evaluators.FirstOrDefault();
|
||||
if (evaluator == null) {
|
||||
throw new OrchardException(T("There are currently no scripting engines enabled"));
|
||||
}
|
||||
|
||||
var result = evaluator.Evaluate(expression, new List<IGlobalMethodProvider> { new GlobalMethodProvider(this) });
|
||||
if (!(result is bool)) {
|
||||
throw new OrchardException(T("Expression is not a boolean value"));
|
||||
}
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
private class GlobalMethodProvider : IGlobalMethodProvider {
|
||||
private readonly RuleManager _ruleManager;
|
||||
|
||||
public GlobalMethodProvider(RuleManager ruleManager) {
|
||||
_ruleManager = ruleManager;
|
||||
}
|
||||
|
||||
public void Process(GlobalMethodContext context) {
|
||||
var ruleContext = new RuleContext {
|
||||
FunctionName = context.FunctionName,
|
||||
Arguments = context.Arguments.ToArray(),
|
||||
Result = context.Result
|
||||
};
|
||||
|
||||
_ruleManager._ruleProviders.Process(ruleContext);
|
||||
|
||||
context.Result = ruleContext.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Scripting;
|
||||
|
||||
namespace Orchard.Widgets.Services {
|
||||
[Obsolete("Use Orchard.Conditions.Services.ConditionManager instead.")]
|
||||
public class RuleManager : IRuleManager {
|
||||
private readonly IRuleProvider _ruleProviders;
|
||||
private readonly IEnumerable<IScriptExpressionEvaluator> _evaluators;
|
||||
|
||||
public RuleManager(IRuleProvider ruleProviders, IEnumerable<IScriptExpressionEvaluator> evaluators) {
|
||||
_ruleProviders = ruleProviders;
|
||||
_evaluators = evaluators;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public bool Matches(string expression) {
|
||||
var evaluator = _evaluators.FirstOrDefault();
|
||||
if (evaluator == null) {
|
||||
throw new OrchardException(T("There are currently no scripting engines enabled"));
|
||||
}
|
||||
|
||||
var result = evaluator.Evaluate(expression, new List<IGlobalMethodProvider> { new GlobalMethodProvider(this) });
|
||||
if (!(result is bool)) {
|
||||
throw new OrchardException(T("Expression is not a boolean value"));
|
||||
}
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
private class GlobalMethodProvider : IGlobalMethodProvider {
|
||||
private readonly RuleManager _ruleManager;
|
||||
|
||||
public GlobalMethodProvider(RuleManager ruleManager) {
|
||||
_ruleManager = ruleManager;
|
||||
}
|
||||
|
||||
public void Process(GlobalMethodContext context) {
|
||||
var ruleContext = new RuleContext {
|
||||
FunctionName = context.FunctionName,
|
||||
Arguments = context.Arguments.ToArray(),
|
||||
Result = context.Result
|
||||
};
|
||||
|
||||
_ruleManager._ruleProviders.Process(ruleContext);
|
||||
|
||||
context.Result = ruleContext.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
namespace Orchard.Widgets.ViewModels {
|
||||
public class WidgetElementViewModel {
|
||||
public int? WidgetId { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
@model Orchard.Widgets.ViewModels.WidgetElementViewModel
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Include("widget-element-editor.js");
|
||||
}
|
||||
@Html.HiddenFor(m => m.WidgetId)
|
@@ -0,0 +1,12 @@
|
||||
@using Orchard.ContentManagement
|
||||
@{
|
||||
var widget = (ContentItem)Model.Widget;
|
||||
}
|
||||
<div class="layout-placeholder">
|
||||
@if (widget != null) {
|
||||
@String.Format("{0} - {1}", Html.ItemDisplayText(widget), widget.TypeDefinition.DisplayName)
|
||||
}
|
||||
else {
|
||||
@T("Widget Not Found");
|
||||
}
|
||||
</div>
|
@@ -0,0 +1,9 @@
|
||||
@using Orchard.Layouts.Helpers
|
||||
@{
|
||||
var tagBuilder = TagBuilderExtensions.CreateElementTagBuilder(Model);
|
||||
}
|
||||
@tagBuilder.StartElement
|
||||
@if (Model.WidgetShape != null) {
|
||||
@Display(Model.WidgetShape)
|
||||
}
|
||||
@tagBuilder.EndElement
|
@@ -270,6 +270,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gulp", "Gulp", "{90EBEE36-B
|
||||
Package.json = Package.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Conditions", "Orchard.Web\Modules\Orchard.Conditions\Orchard.Conditions.csproj", "{98251EAE-A41B-47B2-AA91-E28B8482DA70}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeCoverage|Any CPU = CodeCoverage|Any CPU
|
||||
@@ -1082,6 +1084,13 @@ Global
|
||||
{BAC82DB9-F4C4-4DD1-ABDB-F70E6229E6B0}.FxCop|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAC82DB9-F4C4-4DD1-ABDB-F70E6229E6B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAC82DB9-F4C4-4DD1-ABDB-F70E6229E6B0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -1167,5 +1176,6 @@ Global
|
||||
{82190F52-2901-46D6-8A4C-34649959483F} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{BAC82DB9-F4C4-4DD1-ABDB-F70E6229E6B0} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{90EBEE36-B5CD-42A8-A21B-76270E2C5D24} = {DF3909B0-1DDD-4D8A-9919-56FC438E25E2}
|
||||
{98251EAE-A41B-47B2-AA91-E28B8482DA70} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Reference in New Issue
Block a user