mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Merge pull request #6030 from OrchardCMS/feature/widget-elements
Widgets in Layouts
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+86
-86
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ namespace Orchard.AuditTrail.Services {
|
||||
var originalContent = currentElement.Value;
|
||||
var currentContent = reader.ReadElementContentAsString();
|
||||
|
||||
stack.Pop();
|
||||
readNext = false;
|
||||
yield return
|
||||
new DiffNode {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
-46
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
+14
-5
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Orchard.DynamicForms.Elements;
|
||||
using Orchard.DynamicForms.Services;
|
||||
using Orchard.DynamicForms.Services.Models;
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Services;
|
||||
|
||||
namespace Orchard.DynamicForms.Handlers {
|
||||
@@ -46,11 +48,18 @@ namespace Orchard.DynamicForms.Handlers {
|
||||
}
|
||||
|
||||
void IElementEventHandler.CreatingDisplay(ElementCreatingDisplayShapeContext context) { }
|
||||
void IElementEventHandler.Displayed(ElementDisplayedContext context) {}
|
||||
void IElementEventHandler.Displayed(ElementDisplayedContext context) { }
|
||||
void IFormElementEventHandler.GetElementValue(FormElement element, ReadElementValuesContext context) { }
|
||||
void IElementEventHandler.Creating(ElementCreatingContext context) {}
|
||||
void IElementEventHandler.Created(ElementCreatedContext context) {}
|
||||
void IElementEventHandler.BuildEditor(ElementEditorContext context) {}
|
||||
void IElementEventHandler.UpdateEditor(ElementEditorContext context) {}
|
||||
void IElementEventHandler.Creating(ElementCreatingContext context) { }
|
||||
void IElementEventHandler.Created(ElementCreatedContext context) { }
|
||||
void IElementEventHandler.BuildEditor(ElementEditorContext context) { }
|
||||
void IElementEventHandler.UpdateEditor(ElementEditorContext context) { }
|
||||
void IElementEventHandler.Removing(ElementRemovingContext context) { }
|
||||
void IElementEventHandler.LayoutSaving(ElementSavingContext context) { }
|
||||
void IElementEventHandler.Exporting(ExportElementContext context) { }
|
||||
void IElementEventHandler.Exported(ExportElementContext context) { }
|
||||
void IElementEventHandler.Importing(ImportElementContext context) { }
|
||||
void IElementEventHandler.Imported(ImportElementContext context) { }
|
||||
void IElementEventHandler.ImportCompleted(ImportElementContext context) { }
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@
|
||||
"inputs": [
|
||||
"Assets/JavaScript/Models/Helpers.js",
|
||||
"Assets/JavaScript/Models/Editor.js",
|
||||
"Assets/JavaScript/Models/RecycleBin.js",
|
||||
"Assets/JavaScript/Models/Element.js",
|
||||
"Assets/JavaScript/Models/Container.js",
|
||||
"Assets/JavaScript/Models/Canvas.js",
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
var index = _(this.children).indexOf(child);
|
||||
if (index >= 0) {
|
||||
this.children.splice(index, 1);
|
||||
this.editor.recycleBin.add(child);
|
||||
if (child.getIsActive())
|
||||
this.editor.activeElement = null;
|
||||
if (child.getIsFocused()) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
this.dropTargetElement = null;
|
||||
this.isDragging = false;
|
||||
this.isResizing = false;
|
||||
this.recycleBin = new LayoutEditor.RecycleBin();
|
||||
|
||||
this.resetToolboxElements = function () {
|
||||
this.toolboxElements = [
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
var LayoutEditor;
|
||||
(function (LayoutEditor) {
|
||||
|
||||
LayoutEditor.RecycleBin = function () {
|
||||
this.elements = [];
|
||||
|
||||
this.add = function(element) {
|
||||
this.elements.push(element);
|
||||
};
|
||||
|
||||
this.toObject = function () {
|
||||
var result = {
|
||||
type: "RecycleBin",
|
||||
children: []
|
||||
};
|
||||
|
||||
for (var i = 0; i < this.elements.length; i++) {
|
||||
var element = this.elements[i];
|
||||
var dto = element.toObject();
|
||||
result.children.push(dto);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
})(LayoutEditor || (LayoutEditor = {}));
|
||||
@@ -5,6 +5,7 @@ using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Layouts.Elements;
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
@@ -112,12 +113,12 @@ namespace Orchard.Layouts.Drivers {
|
||||
updater.TryUpdateModel(viewModel, Prefix, null, new[] { "Part", "Templates" });
|
||||
var describeContext = new DescribeElementsContext { Content = part };
|
||||
var elementInstances = _mapper.ToLayoutModel(viewModel.LayoutEditor.Data, describeContext).ToArray();
|
||||
var removedElementInstances = _serializer.Deserialize(viewModel.LayoutEditor.Trash, describeContext).ToArray();
|
||||
var recycleBin = (RecycleBin)_mapper.ToLayoutModel(viewModel.LayoutEditor.RecycleBin, describeContext).SingleOrDefault();
|
||||
var context = new LayoutSavingContext {
|
||||
Content = part,
|
||||
Updater = updater,
|
||||
Elements = elementInstances,
|
||||
RemovedElements = removedElementInstances
|
||||
RemovedElements = recycleBin != null ? recycleBin.Elements : Enumerable.Empty<Element>()
|
||||
};
|
||||
|
||||
_elementManager.Saving(context);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Helpers;
|
||||
|
||||
namespace Orchard.Layouts.Elements {
|
||||
public class PlaceableContentItem : Element {
|
||||
public override string Category {
|
||||
get { return "Content Items"; }
|
||||
}
|
||||
|
||||
public override bool IsSystemElement {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool HasEditor {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public int? ContentItemId {
|
||||
get { return this.Retrieve(x => x.ContentItemId); }
|
||||
set { this.Store(x => x.ContentItemId, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
|
||||
namespace Orchard.Layouts.Elements {
|
||||
public class RecycleBin : Container {
|
||||
public override string Category { get { return null; } }
|
||||
public override bool IsSystemElement { get { return true; } }
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,14 @@ using Orchard.Layouts.Models;
|
||||
|
||||
namespace Orchard.Layouts.Framework.Drivers {
|
||||
public class ExportElementContext {
|
||||
public ExportElementContext() {
|
||||
ExportableData = new ElementDataDictionary();
|
||||
public ExportElementContext(Element element, ILayoutAspect layout, ElementDataDictionary exportableData) {
|
||||
Element = element;
|
||||
Layout = layout;
|
||||
ExportableData = exportableData;
|
||||
}
|
||||
|
||||
public ILayoutAspect Layout { get; set; }
|
||||
public Element Element { get; set; }
|
||||
public ElementDataDictionary ExportableData { get; set; }
|
||||
public ILayoutAspect Layout { get; private set; }
|
||||
public Element Element { get; private set; }
|
||||
public ElementDataDictionary ExportableData { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,16 @@ using Orchard.Layouts.Models;
|
||||
|
||||
namespace Orchard.Layouts.Framework.Drivers {
|
||||
public class ImportElementContext {
|
||||
public ImportElementContext() {
|
||||
ExportableData = new ElementDataDictionary();
|
||||
public ImportElementContext(Element element, ILayoutAspect layout, ElementDataDictionary exportableData, IContentImportSession session) {
|
||||
Element = element;
|
||||
Layout = layout;
|
||||
ExportableData = exportableData;
|
||||
Session = session;
|
||||
}
|
||||
|
||||
public ILayoutAspect Layout { get; set; }
|
||||
public Element Element { get; set; }
|
||||
public ElementDataDictionary ExportableData { get; set; }
|
||||
public IContentImportSession Session { get; set; }
|
||||
public ILayoutAspect Layout { get; private set; }
|
||||
public Element Element { get; private set; }
|
||||
public ElementDataDictionary ExportableData { get; private set; }
|
||||
public IContentImportSession Session { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,16 @@ namespace Orchard.Layouts.Framework.Elements {
|
||||
Category = category;
|
||||
GetDrivers = Enumerable.Empty<IElementDriver>;
|
||||
CreatingDisplay = context => { };
|
||||
Displaying = context => {};
|
||||
Displaying = context => { };
|
||||
Editor = context => { };
|
||||
UpdateEditor = context => { };
|
||||
LayoutSaving = context => { };
|
||||
Removing = context => { };
|
||||
Exporting = context => { };
|
||||
Exported = context => { };
|
||||
Importing = context => { };
|
||||
Imported = context => { };
|
||||
ImportCompleted = context => { };
|
||||
StateBag = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
@@ -33,6 +40,13 @@ namespace Orchard.Layouts.Framework.Elements {
|
||||
public Action<ElementDisplayedContext> Displayed { get; set; }
|
||||
public Action<ElementEditorContext> Editor { get; set; }
|
||||
public Action<ElementEditorContext> UpdateEditor { get; set; }
|
||||
public Action<ElementSavingContext> LayoutSaving { get; set; }
|
||||
public Action<ElementRemovingContext> Removing { get; set; }
|
||||
public Action<ExportElementContext> Exporting { get; set; }
|
||||
public Action<ExportElementContext> Exported { get; set; }
|
||||
public Action<ImportElementContext> Importing { get; set; }
|
||||
public Action<ImportElementContext> Imported { get; set; }
|
||||
public Action<ImportElementContext> ImportCompleted { get; set; }
|
||||
public bool IsSystemElement { get; set; }
|
||||
public bool EnableEditorDialog { get; set; }
|
||||
public IDictionary<string, object> StateBag { get; set; }
|
||||
|
||||
+17
-8
@@ -1,11 +1,20 @@
|
||||
namespace Orchard.Layouts.Framework.Elements {
|
||||
public class ElementRemovingContext : LayoutSavingContext {
|
||||
public ElementRemovingContext(LayoutSavingContext stub) {
|
||||
Content = stub.Content;
|
||||
RemovedElements = stub.RemovedElements;
|
||||
Updater = stub.Updater;
|
||||
Elements = stub.Elements;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Layouts.Framework.Elements {
|
||||
public class ElementRemovingContext {
|
||||
public ElementRemovingContext(Element element, IEnumerable<Element> elements, IEnumerable<Element> removedElements, IContent content) {
|
||||
Element = element;
|
||||
Elements = elements;
|
||||
RemovedElements = removedElements;
|
||||
Content = content;
|
||||
}
|
||||
public Element Element { get; set; }
|
||||
|
||||
public IContent Content { get; private set; }
|
||||
// All the other elements on the canvas.
|
||||
public IEnumerable<Element> Elements { get; set; }
|
||||
// All the other removed elements from the canvas (including the current element).
|
||||
public IEnumerable<Element> RemovedElements { get; set; }
|
||||
public Element Element { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Orchard.Layouts.Framework.Elements {
|
||||
public class ElementSavingContext : LayoutSavingContext {
|
||||
public ElementSavingContext(LayoutSavingContext stub) {
|
||||
public ElementSavingContext(Element element, LayoutSavingContext stub) {
|
||||
Element = element;
|
||||
Content = stub.Content;
|
||||
Updater = stub.Updater;
|
||||
Elements = stub.Elements;
|
||||
}
|
||||
public Element Element { get; set; }
|
||||
public Element Element { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Services;
|
||||
|
||||
namespace Orchard.Layouts.Handlers {
|
||||
@@ -17,6 +18,34 @@ namespace Orchard.Layouts.Handlers {
|
||||
BuildEditorInternal(context, driver => driver.UpdateEditor(context));
|
||||
}
|
||||
|
||||
public override void LayoutSaving(ElementSavingContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.LayoutSaving(context));
|
||||
}
|
||||
|
||||
public override void Removing(ElementRemovingContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.Removing(context));
|
||||
}
|
||||
|
||||
public override void Exporting(ExportElementContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.Exporting(context));
|
||||
}
|
||||
|
||||
public override void Exported(ExportElementContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.Exported(context));
|
||||
}
|
||||
|
||||
public override void Importing(ImportElementContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.Importing(context));
|
||||
}
|
||||
|
||||
public override void Imported(ImportElementContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.Imported(context));
|
||||
}
|
||||
|
||||
public override void ImportCompleted(ImportElementContext context) {
|
||||
InvokeDrivers(context.Element, driver => driver.ImportCompleted(context));
|
||||
}
|
||||
|
||||
private void BuildEditorInternal(ElementEditorContext context, Func<IElementDriver, EditorResult> action) {
|
||||
var descriptor = context.Element.Descriptor;
|
||||
var drivers = _elementManager.GetDrivers(descriptor);
|
||||
@@ -36,5 +65,10 @@ namespace Orchard.Layouts.Handlers {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeDrivers(Element element, Action<IElementDriver> action) {
|
||||
var drivers = _elementManager.GetDrivers(element.Descriptor);
|
||||
drivers.Invoke(action, Logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Alias;
|
||||
using Orchard.Autoroute.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Data;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Models;
|
||||
using Orchard.Layouts.Services;
|
||||
using Orchard.Utility.Extensions;
|
||||
@@ -17,13 +20,15 @@ namespace Orchard.Layouts.Handlers {
|
||||
private readonly IShapeDisplay _shapeDisplay;
|
||||
private readonly ILayoutSerializer _serializer;
|
||||
private readonly IAliasService _aliasService;
|
||||
private readonly IElementManager _elementManager;
|
||||
|
||||
public LayoutPartHandler(
|
||||
IRepository<LayoutPartRecord> repository,
|
||||
ILayoutManager layoutManager,
|
||||
IContentManager contentManager,
|
||||
IContentPartDisplay contentPartDisplay,
|
||||
IShapeDisplay shapeDisplay,
|
||||
IRepository<LayoutPartRecord> repository,
|
||||
ILayoutManager layoutManager,
|
||||
IElementManager elementManager,
|
||||
IContentManager contentManager,
|
||||
IContentPartDisplay contentPartDisplay,
|
||||
IShapeDisplay shapeDisplay,
|
||||
ILayoutSerializer serializer,
|
||||
IAliasService aliasService) {
|
||||
|
||||
@@ -33,10 +38,12 @@ namespace Orchard.Layouts.Handlers {
|
||||
_shapeDisplay = shapeDisplay;
|
||||
_serializer = serializer;
|
||||
_aliasService = aliasService;
|
||||
_elementManager = elementManager;
|
||||
|
||||
Filters.Add(StorageFilter.For(repository));
|
||||
OnPublished<LayoutPart>(UpdateTemplateClients);
|
||||
OnIndexing<LayoutPart>(IndexLayout);
|
||||
OnRemoved<LayoutPart>(RemoveElements);
|
||||
}
|
||||
|
||||
private void IndexLayout(IndexContentContext context, LayoutPart part) {
|
||||
@@ -87,6 +94,16 @@ namespace Orchard.Layouts.Handlers {
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveElements(RemoveContentContext context, LayoutPart part) {
|
||||
var elements = _layoutManager.LoadElements(part).ToList();
|
||||
var savingContext = new LayoutSavingContext {
|
||||
Content = part,
|
||||
Elements = new List<Element>(),
|
||||
RemovedElements = elements
|
||||
};
|
||||
_elementManager.Removing(savingContext);
|
||||
}
|
||||
|
||||
private bool IsHomePage(IContent content) {
|
||||
var homepage = _aliasService.Get(String.Empty);
|
||||
var displayRouteValues = _contentManager.GetItemMetadata(content).DisplayRouteValues;
|
||||
|
||||
@@ -5,5 +5,9 @@ namespace Orchard.Layouts.Helpers {
|
||||
public static ContentPartDefinitionBuilder Placeable(this ContentPartDefinitionBuilder builder, bool placeable = true) {
|
||||
return builder.WithSetting("ContentPartLayoutSettings.Placeable", placeable.ToString());
|
||||
}
|
||||
|
||||
public static ContentTypeDefinitionBuilder Placeable(this ContentTypeDefinitionBuilder builder, bool placeable = true) {
|
||||
return builder.WithSetting("ContentTypeLayoutSettings.Placeable", placeable.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.FieldStorage.InfosetStorage;
|
||||
|
||||
namespace Orchard.Layouts.Helpers {
|
||||
public static class PlaceableContentExtensions {
|
||||
public static bool IsPlaceableContent(this IContent content) {
|
||||
return content.As<InfosetPart>().Retrieve<bool>("PlacedAsElement");
|
||||
}
|
||||
|
||||
public static void IsPlaceableContent(this IContent content, bool value) {
|
||||
content.As<InfosetPart>().Store("PlacedAsElement", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -79,15 +79,13 @@
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\JavaScript\Models\RecycleBin.js" />
|
||||
<Content Include="Default.html" />
|
||||
<Content Include="Assets.json" />
|
||||
<Content Include="Images\azure.png" />
|
||||
<Content Include="Images\illustration.jpg" />
|
||||
<Content Include="Images\logo.svg" />
|
||||
<Content Include="Placement.info" />
|
||||
<Content Include="Scripts\contentpart-layouts-settings.js" />
|
||||
<Content Include="Scripts\DemoConfig.js" />
|
||||
<Content Include="Scripts\DemoData.js" />
|
||||
<Content Include="Scripts\element-browser.js" />
|
||||
<Content Include="Scripts\AutoFocus.js" />
|
||||
<Content Include="Scripts\Elements\Image.js" />
|
||||
@@ -292,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>
|
||||
@@ -313,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" />
|
||||
@@ -338,6 +336,7 @@
|
||||
<Compile Include="Elements\Shape.cs" />
|
||||
<Compile Include="Elements\Break.cs" />
|
||||
<Compile Include="Elements\UIElement.cs" />
|
||||
<Compile Include="Elements\PlaceableContentItem.cs" />
|
||||
<Compile Include="Filters\TokensFilter.cs" />
|
||||
<Compile Include="Framework\Display\ElementDisplayedContext.cs" />
|
||||
<Compile Include="Framework\Display\ElementDisplayingContext.cs" />
|
||||
@@ -360,6 +359,7 @@
|
||||
<Compile Include="Framework\Elements\IElement.cs" />
|
||||
<Compile Include="Handlers\ElementDriversCoordinator.cs" />
|
||||
<Compile Include="Handlers\ElementRuleCoordinator.cs" />
|
||||
<Compile Include="Helpers\PlaceableContentExtensions.cs" />
|
||||
<Compile Include="Helpers\DictionaryExtensions.cs" />
|
||||
<Compile Include="Helpers\EditorResultExtensions.cs" />
|
||||
<Compile Include="Helpers\ElementDisplayContextHelper.cs" />
|
||||
@@ -368,6 +368,9 @@
|
||||
<Compile Include="Helpers\JsonHelper.cs" />
|
||||
<Compile Include="Helpers\StringHelper.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Providers\PlaceableContentElementHarvester.cs" />
|
||||
<Compile Include="Elements\RecycleBin.cs" />
|
||||
<Compile Include="ViewModels\PlaceableContentItemViewModel.cs" />
|
||||
<Compile Include="Recipes\Builders\CustomElementsStep.cs" />
|
||||
<Compile Include="Recipes\Executors\CustomElementsStep.cs" />
|
||||
<Compile Include="Providers\BlueprintElementHarvester.cs" />
|
||||
@@ -393,6 +396,8 @@
|
||||
<Compile Include="Services\LayoutModelMapper.cs" />
|
||||
<Compile Include="Services\ElementSerializer.cs" />
|
||||
<Compile Include="Services\ObjectStore.cs" />
|
||||
<Compile Include="Settings\ContentTypeLayoutSettingsHooks.cs" />
|
||||
<Compile Include="Settings\ContentTypeLayoutSettings.cs" />
|
||||
<Compile Include="Signals.cs" />
|
||||
<Compile Include="Tokens\ElementTokens.cs" />
|
||||
<Compile Include="ViewModels\BreadcrumbsEditorViewModel.cs" />
|
||||
@@ -429,9 +434,9 @@
|
||||
<Compile Include="Services\ContentFieldDisplay.cs" />
|
||||
<Compile Include="Services\IContentFieldDisplay.cs" />
|
||||
<Compile Include="Settings\ContentPartLayoutSettings.cs" />
|
||||
<Compile Include="Settings\LayoutSettingsHooks.cs" />
|
||||
<Compile Include="Settings\LayoutTypePartSettingsHooks.cs" />
|
||||
<Compile Include="Settings\LayoutTypePartSettings.cs" />
|
||||
<Compile Include="Settings\ContentPartSettingsHooks.cs" />
|
||||
<Compile Include="Settings\ContentPartLayoutSettingsHooks.cs" />
|
||||
<Compile Include="ViewModels\BlueprintsIndexViewModel.cs" />
|
||||
<Compile Include="ViewModels\ContentItemEditorViewModel.cs" />
|
||||
<Compile Include="ViewModels\EditElementBlueprintViewModel.cs" />
|
||||
@@ -591,6 +596,18 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Assets\CSS\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Elements\PlaceableContentItem.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Elements\PlaceableContentItem.Design.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\DefinitionTemplates\ContentTypeLayoutSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Elements.PlaceableContentItem.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
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.Layouts.Elements;
|
||||
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.Layouts.Settings;
|
||||
using Orchard.Layouts.ViewModels;
|
||||
using ContentItem = Orchard.ContentManagement.ContentItem;
|
||||
|
||||
namespace Orchard.Layouts.Providers {
|
||||
public class PlaceableContentElementHarvester : Component, IElementHarvester {
|
||||
private readonly Work<IContentManager> _contentManager;
|
||||
|
||||
public PlaceableContentElementHarvester(Work<IContentManager> contentManager) {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public IEnumerable<ElementDescriptor> HarvestElements(HarvestElementsContext context) {
|
||||
var contentTypeDefinitions = GetPlaceableContentTypeDefinitions();
|
||||
|
||||
return contentTypeDefinitions.Select(contentTypeDefinition => {
|
||||
var settings = contentTypeDefinition.Settings;
|
||||
var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName;
|
||||
return new ElementDescriptor(typeof (PlaceableContentItem), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category: "Content Items") {
|
||||
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 = (PlaceableContentItem)context.Element;
|
||||
var contentItemId = element.ContentItemId;
|
||||
var versionOptions = context.DisplayType == "Design" ? VersionOptions.Latest : VersionOptions.Published;
|
||||
var contentItem = contentItemId != null
|
||||
? _contentManager.Value.Get(contentItemId.Value, versionOptions)
|
||||
: _contentManager.Value.New(contentTypeName);
|
||||
|
||||
var contentShape = contentItem != null ? _contentManager.Value.BuildDisplay(contentItem) : default(dynamic);
|
||||
context.ElementShape.ContentItem = contentItem;
|
||||
context.ElementShape.ContentShape = contentShape;
|
||||
}
|
||||
|
||||
private void Editor(ElementEditorContext context) {
|
||||
UpdateEditor(context);
|
||||
}
|
||||
|
||||
private void UpdateEditor(ElementEditorContext context) {
|
||||
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
|
||||
var element = (PlaceableContentItem) context.Element;
|
||||
var elementViewModel = new PlaceableContentItemViewModel {
|
||||
ContentItemId = element.ContentItemId
|
||||
};
|
||||
|
||||
if (context.Updater != null) {
|
||||
context.Updater.TryUpdateModel(elementViewModel, context.Prefix, null, null);
|
||||
}
|
||||
|
||||
var contentItemId = elementViewModel.ContentItemId;
|
||||
var contentItem = contentItemId != null
|
||||
? _contentManager.Value.Get(contentItemId.Value, VersionOptions.Latest)
|
||||
: _contentManager.Value.New(contentTypeName);
|
||||
|
||||
dynamic contentEditorShape;
|
||||
|
||||
if (context.Updater != null) {
|
||||
if (contentItem.Id == 0) {
|
||||
_contentManager.Value.Create(contentItem, VersionOptions.Draft);
|
||||
}
|
||||
else {
|
||||
var isDraftable = contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable;
|
||||
var versionOptions = isDraftable ? VersionOptions.DraftRequired : VersionOptions.Latest;
|
||||
contentItem = _contentManager.Value.Get(contentItem.Id, versionOptions);
|
||||
}
|
||||
|
||||
element.ContentItemId = contentItem.Id;
|
||||
|
||||
// If the placed content item has the CommonPart attached, set its Container property to the Content (if any).
|
||||
// This helps preventing widget types from appearing as orphans.
|
||||
var commonPart = contentItem.As<ICommonPart>();
|
||||
if (commonPart != null)
|
||||
commonPart.Container = context.Content;
|
||||
|
||||
contentItem.IsPlaceableContent(true);
|
||||
contentEditorShape = _contentManager.Value.UpdateEditor(contentItem, context.Updater);
|
||||
|
||||
_contentManager.Value.Publish(contentItem);
|
||||
}
|
||||
else {
|
||||
contentEditorShape = _contentManager.Value.BuildEditor(contentItem);
|
||||
}
|
||||
|
||||
var elementEditorShape = context.ShapeFactory.EditorTemplate(TemplateName: "Elements.PlaceableContentItem", 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 = (PlaceableContentItem) context.Element;
|
||||
var contentItemId = element.ContentItemId;
|
||||
|
||||
// Only remove the content item 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 placeableElements =
|
||||
from e in context.Elements.Flatten()
|
||||
let p = e as PlaceableContentItem
|
||||
where p != null && p.ContentItemId == contentItemId
|
||||
select p;
|
||||
|
||||
if (placeableElements.Any())
|
||||
return;
|
||||
|
||||
var contentItem = contentItemId != null ? _contentManager.Value.Get(contentItemId.Value, VersionOptions.Latest) : default(ContentItem);
|
||||
|
||||
if(contentItem != null)
|
||||
_contentManager.Value.Remove(contentItem);
|
||||
}
|
||||
|
||||
private void ExportElement(ExportElementContext context) {
|
||||
var element = (PlaceableContentItem)context.Element;
|
||||
var contentItemId = element.ContentItemId;
|
||||
var contentItem = contentItemId != null ? _contentManager.Value.Get(contentItemId.Value, VersionOptions.Latest) : default(ContentItem);
|
||||
var contentItemIdentity = contentItem != null ? _contentManager.Value.GetItemMetadata(contentItem).Identity.ToString() : default(string);
|
||||
|
||||
if (contentItemIdentity != null)
|
||||
context.ExportableData["ContentItemId"] = contentItemIdentity;
|
||||
}
|
||||
|
||||
private void ImportElement(ImportElementContext context) {
|
||||
var contentItemIdentity = context.ExportableData.Get("ContentItemId");
|
||||
|
||||
if (String.IsNullOrWhiteSpace(contentItemIdentity))
|
||||
return;
|
||||
|
||||
var contentItem = context.Session.GetItemFromSession(contentItemIdentity);
|
||||
var element = (PlaceableContentItem)context.Element;
|
||||
|
||||
element.ContentItemId = contentItem != null ? contentItem.Id : default(int?);
|
||||
}
|
||||
|
||||
private IEnumerable<ContentTypeDefinition> GetPlaceableContentTypeDefinitions() {
|
||||
// Select all types that have either "Placeable" set to true.
|
||||
var contentTypeDefinitionsQuery =
|
||||
from contentTypeDefinition in _contentManager.Value.GetContentTypeDefinitions()
|
||||
where contentTypeDefinition.Settings.GetModel<ContentTypeLayoutSettings>().Placeable
|
||||
select contentTypeDefinition;
|
||||
|
||||
return contentTypeDefinitionsQuery.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
var demoConfig = {
|
||||
"createContentUrl": "/Modules/Orchard.Layouts/Controller/Create/{contentTypeId}",
|
||||
"editContentUrl": "/Modules/Orchard.Layouts/Controller/Edit/{contentTypeId}",
|
||||
"categories": [
|
||||
{
|
||||
"name": "Content",
|
||||
"contentTypes": [
|
||||
{ "label": "Content Item", "id": "Orchard.Layouts.Elements.ContentItem" },
|
||||
{ "label": "Html", "id": "Orchard.Layouts.Elements.Html" },
|
||||
{ "label": "Paragraph", "id": "Orchard.Layouts.Elements.Paragraph" },
|
||||
{ "label": "Text", "id": "Orchard.Layouts.Elements.Text" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Media",
|
||||
"contentTypes": [
|
||||
{ "label": "Image", "id": "Orchard.Layouts.Elements.Image" },
|
||||
{ "label": "Media Item", "id": "Orchard.Layouts.Elements.MediaItem" },
|
||||
{ "label": "Vector Image", "id": "Orchard.Layouts.Elements.VectorImage" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Parts",
|
||||
"contentTypes": [
|
||||
{ "label": "CommonPart", "id": "CommonPart" },
|
||||
{ "label": "TitlePart", "id": "TitlePart" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Forms",
|
||||
"contentTypes": [
|
||||
{ "label": "Button", "id": "Orchard.DynamicForms.Elements.Button" },
|
||||
{ "label": "Check Box", "id": "Orchard.DynamicForms.Elements.CheckBox" },
|
||||
{ "label": "Email Field", "id": "Orchard.DynamicForms.Elements.EmailField" },
|
||||
{ "label": "Enumeration", "id": "Orchard.DynamicForms.Elements.Enumeration" },
|
||||
{ "label": "Form", "id": "Orchard.DynamicForms.Elements.Form" },
|
||||
{ "label": "Hidden Field", "id": "Orchard.DynamicForms.Elements.HiddenField" },
|
||||
{ "label": "Ip Address Field", "id": "Orchard.DynamicForms.Elements.IpAddressField" },
|
||||
{ "label": "Label", "id": "Orchard.DynamicForms.Elements.Label" },
|
||||
{ "label": "Password Field", "id": "Orchard.DynamicForms.Elements.PasswordField" },
|
||||
{ "label": "Radio Button", "id": "Orchard.DynamicForms.Elements.RadioButton" },
|
||||
{ "label": "Text Area", "id": "Orchard.DynamicForms.Elements.TextArea" },
|
||||
{ "label": "Text Field", "id": "Orchard.DynamicForms.Elements.TextField" },
|
||||
{ "label": "User Name Field", "id": "Orchard.DynamicForms.Elements.UserNameField" },
|
||||
{ "label": "Validation Message", "id": "Orchard.DynamicForms.Elements.ValidationMessage" },
|
||||
{ "label": "Validation Summary", "id": "Orchard.DynamicForms.Elements.ValidationSummary" }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -1,261 +0,0 @@
|
||||
var demoData = {
|
||||
"type": "Canvas",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Grid",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Row",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "Image",
|
||||
"html": "<img class='img-responsive' src='/OrchardLocal/Modules/Orchard.Layouts/Images/illustration.jpg' />"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 8,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<h2>Who are we?</h2>"
|
||||
},
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "Vector Image",
|
||||
"html": "<img class='img-responsive' src='/OrchardLocal/Modules/Orchard.Layouts/Images/logo.svg' style='width: 400px;' />"
|
||||
},
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<p>IDeliverable is a company of like-minded individuals with a true passion for .NET based software development and cloud computing.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Row",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 12,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<h2>What do we do?</h2><p>We provide software development, consulting and training within our three areas of focus.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Row",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<h3>.NET software development</h3><p>Microsoft .NET is at the core of everything we do. We have worked with .NET since its inception back in 2000 and are exceptionally proficient in all aspects of the platform, including its languages, frameworks, services and tools. Whether it’s the latest ASP.NET technologies with HTML5, CSS3 and modern JavaScript frameworks, Windows Phone and Windows Store apps with XAML, or more enterprise oriented Windows Forms or WPF rich client apps with WCF based service back ends, we’ve done it all for years and feel right at home.</p>"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<h3>Microsoft Azure</h3><p>We are true believers in cloud computing, and as far as hosting goes, we believe there’s no better home for .NET based applications than Microsoft Azure. And so we have worked hard in the past few years to become experts in every nook and cranny of this platform. Our expertise includes architecting and designing applications for Microsoft Azure, adapting and migrating existing applications to Microsoft Azure, automating Microsoft Azure deployment and building hybrid solutions involving both on-premises components and Microsoft Azure.</p>"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<h3>Orchard CMS</h3>"
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Row",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"children": [
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<p>When it comes to web site development, the Orchard CMS is our framework of choice.</p>"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<p>We have worked with Orchard for almost three years and have built a wide array of web sites, large and small, using it. We have two developers who participate actively in the development of Orchard and who have commit rights in the official Orchard source code repository.</p>"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Column",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"width": 4,
|
||||
"offset": 0,
|
||||
"children": [
|
||||
{
|
||||
"type": "Content",
|
||||
"data": null,
|
||||
"htmlId": null,
|
||||
"htmlClass": null,
|
||||
"htmlStyle": null,
|
||||
"contentType": "HTML",
|
||||
"html": "<p>One of them is even on the Orchard steering committee, so it’s fair to say we have our ears to the ground when it comes to what’s happening in the Orchard community.</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
this.element = element;
|
||||
this.element.data("layout-designer-host", this);
|
||||
this.editor = window.layoutEditor;
|
||||
this.isFormSubmitting = false;
|
||||
this.settings = {
|
||||
antiForgeryToken: self.element.data("anti-forgery-token"),
|
||||
editorDialogTitleFormat: self.element.data("editor-dialog-title-format"),
|
||||
@@ -62,6 +61,11 @@
|
||||
return JSON.stringify(layoutData, null, "\t");
|
||||
};
|
||||
|
||||
var serializeRecycleBin = function () {
|
||||
var recycleBinData = self.editor.recycleBin.toObject();
|
||||
return JSON.stringify(recycleBinData, null, "\t");
|
||||
};
|
||||
|
||||
var applyTemplate = function (templateId) {
|
||||
var layoutData = serializeCanvas();
|
||||
|
||||
@@ -79,21 +83,23 @@
|
||||
});
|
||||
};
|
||||
|
||||
var monitorForm = function() {
|
||||
var layoutDesigner = self.element;
|
||||
var form = layoutDesigner.closest("form");
|
||||
|
||||
var monitorForm = function () {
|
||||
var form = $(".zone-content form:first");
|
||||
|
||||
form.on("submit", function (e) {
|
||||
self.isFormSubmitting = true;
|
||||
form.attr("isSubmitting", true);
|
||||
serializeLayout();
|
||||
});
|
||||
};
|
||||
|
||||
var serializeLayout = function () {
|
||||
var layoutDataField = self.element.find(".layout-data-field");
|
||||
var recycleBinDataField = self.element.find(".recycle-bin-data-field");
|
||||
var layoutDataDataJson = serializeCanvas();
|
||||
var recycleBinDataJson = serializeRecycleBin();
|
||||
|
||||
layoutDataField.val(layoutDataDataJson);
|
||||
recycleBinDataField.val(recycleBinDataJson);
|
||||
};
|
||||
|
||||
this.element.on("change", ".template-picker select", function (e) {
|
||||
@@ -103,7 +109,10 @@
|
||||
});
|
||||
|
||||
$(window).on("beforeunload", function () {
|
||||
if (!self.isFormSubmitting && self.editor.isDirty())
|
||||
|
||||
var form = $(".zone-content form:first");
|
||||
var isFormSubmitting = form.attr("isSubmitting");
|
||||
if (!isFormSubmitting && self.editor.isDirty())
|
||||
return "You have unsaved changes.";
|
||||
|
||||
return undefined;
|
||||
@@ -118,7 +127,7 @@
|
||||
window.Orchard.Layouts.LayoutEditorHost = window.Orchard.Layouts.LayoutEditorHost || {};
|
||||
|
||||
$(function () {
|
||||
var host = new LayoutDesignerHost($(".layout-designer"));
|
||||
window.layoutDesignerHost = new LayoutDesignerHost($(".layout-designer"));
|
||||
$(".layout-designer").each(function (e) {
|
||||
var designer = $(this);
|
||||
var dialog = designer.find(".layout-editor-help-dialog");
|
||||
|
||||
@@ -58,6 +58,7 @@ var LayoutEditor;
|
||||
this.dropTargetElement = null;
|
||||
this.isDragging = false;
|
||||
this.isResizing = false;
|
||||
this.recycleBin = new LayoutEditor.RecycleBin();
|
||||
|
||||
this.resetToolboxElements = function () {
|
||||
this.toolboxElements = [
|
||||
@@ -78,6 +79,34 @@ var LayoutEditor;
|
||||
|
||||
})(LayoutEditor || (LayoutEditor = {}));
|
||||
|
||||
var LayoutEditor;
|
||||
(function (LayoutEditor) {
|
||||
|
||||
LayoutEditor.RecycleBin = function () {
|
||||
this.elements = [];
|
||||
|
||||
this.add = function(element) {
|
||||
this.elements.push(element);
|
||||
};
|
||||
|
||||
this.toObject = function () {
|
||||
var result = {
|
||||
type: "RecycleBin",
|
||||
children: []
|
||||
};
|
||||
|
||||
for (var i = 0; i < this.elements.length; i++) {
|
||||
var element = this.elements[i];
|
||||
var dto = element.toObject();
|
||||
result.children.push(dto);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
})(LayoutEditor || (LayoutEditor = {}));
|
||||
|
||||
var LayoutEditor;
|
||||
(function (LayoutEditor) {
|
||||
|
||||
@@ -154,9 +183,9 @@ var LayoutEditor;
|
||||
|
||||
this.setIsFocused = function () {
|
||||
if (!this.editor)
|
||||
return;
|
||||
return;
|
||||
if (!this.children && this.isTemplated)
|
||||
return;
|
||||
return;
|
||||
if (this.editor.isDragging || this.editor.isResizing)
|
||||
return;
|
||||
|
||||
@@ -208,7 +237,7 @@ var LayoutEditor;
|
||||
this.delete = function () {
|
||||
if (!this.canDelete())
|
||||
return;
|
||||
this.parent.deleteChild(this);
|
||||
this.parent.deleteChild(this);
|
||||
};
|
||||
|
||||
this.canMoveUp = function () {
|
||||
@@ -220,7 +249,7 @@ var LayoutEditor;
|
||||
this.moveUp = function () {
|
||||
if (!this.canMoveUp())
|
||||
return;
|
||||
this.parent.moveChildUp(this);
|
||||
this.parent.moveChildUp(this);
|
||||
};
|
||||
|
||||
this.canMoveDown = function () {
|
||||
@@ -232,7 +261,7 @@ var LayoutEditor;
|
||||
this.moveDown = function () {
|
||||
if (!this.canMoveDown())
|
||||
return;
|
||||
this.parent.moveChildDown(this);
|
||||
this.parent.moveChildDown(this);
|
||||
};
|
||||
|
||||
this.elementToObject = function () {
|
||||
@@ -262,8 +291,8 @@ var LayoutEditor;
|
||||
|
||||
this.cut = function (clipboardData) {
|
||||
if (this.canDelete()) {
|
||||
this.copy(clipboardData);
|
||||
this.delete();
|
||||
this.copy(clipboardData);
|
||||
this.delete();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -322,6 +351,7 @@ var LayoutEditor;
|
||||
var index = _(this.children).indexOf(child);
|
||||
if (index >= 0) {
|
||||
this.children.splice(index, 1);
|
||||
this.editor.recycleBin.add(child);
|
||||
if (child.getIsActive())
|
||||
this.editor.activeElement = null;
|
||||
if (child.getIsFocused()) {
|
||||
@@ -431,7 +461,7 @@ var LayoutEditor;
|
||||
result.children = this.childrenToObject();
|
||||
return result;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
LayoutEditor.Canvas.from = function (value) {
|
||||
var result = new LayoutEditor.Canvas(
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
(function ($) {
|
||||
var placeable = $("input[name=\"ContentPartLayoutSettings.Placeable\"]");
|
||||
|
||||
$(placeable).on("change", function (e) {
|
||||
syncEnableEditorInput();
|
||||
});
|
||||
|
||||
$(function () {
|
||||
syncEnableEditorInput();
|
||||
});
|
||||
|
||||
var syncEnableEditorInput = function () {
|
||||
var enableEditorDialog = $("input[name=\"ContentPartLayoutSettings.EnableEditorDialog\"]");
|
||||
var isPlaceable = placeable.is(":checked");
|
||||
|
||||
enableEditorDialog.prop("disabled", !isPlaceable);
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -76,8 +76,6 @@
|
||||
|
||||
$(document).off("keyup", onKeyUp);
|
||||
closedDialogs.push(self);
|
||||
|
||||
|
||||
};
|
||||
|
||||
this.load = function (url, data, method) {
|
||||
@@ -135,8 +133,8 @@
|
||||
if (self.frame == null)
|
||||
return;
|
||||
|
||||
self.frame.element.height($(window).height() * .75);
|
||||
self.frame.element.width($(window).width() * .75);
|
||||
self.frame.element.height($(window).height() * .80);
|
||||
self.frame.element.width($(window).width() * .87);
|
||||
};
|
||||
|
||||
var resizeView = function () {
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Orchard.Layouts.Services {
|
||||
element.HtmlClass = (string)node["htmlClass"];
|
||||
element.HtmlStyle = (string)node["htmlStyle"];
|
||||
element.IsTemplated = (bool)(node["isTemplated"] ?? false);
|
||||
element.Rule = (string) node["rule"];
|
||||
element.Rule = (string)node["rule"];
|
||||
}
|
||||
|
||||
protected bool? ReadBoolean(JToken node) {
|
||||
@@ -113,7 +113,7 @@ namespace Orchard.Layouts.Services {
|
||||
element.HtmlClass = (string)node["htmlClass"];
|
||||
element.HtmlStyle = (string)node["htmlStyle"];
|
||||
element.IsTemplated = (bool)(node["isTemplated"] ?? false);
|
||||
element.Rule = (string) node["rule"];
|
||||
element.Rule = (string)node["rule"];
|
||||
|
||||
return element;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ namespace Orchard.Layouts.Services {
|
||||
node["htmlStyle"] = element.HtmlStyle;
|
||||
node["rule"] = element.Rule;
|
||||
node["isTemplated"] = element.IsTemplated;
|
||||
node["hasEditor"] = element.HasEditor;
|
||||
node["hasEditor"] = element.Descriptor.EnableEditorDialog;
|
||||
node["contentType"] = element.Descriptor.TypeName;
|
||||
node["contentTypeLabel"] = element.Descriptor.DisplayText.Text;
|
||||
node["contentTypeClass"] = element.DisplayText.Text.HtmlClassify();
|
||||
@@ -161,4 +161,19 @@ namespace Orchard.Layouts.Services {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
public class RecycleBinModelMap : ILayoutModelMap {
|
||||
public int Priority { get { return 0; } }
|
||||
public string LayoutElementType { get { return "RecycleBin"; } }
|
||||
public bool CanMap(Element element) {
|
||||
return element.Type == "RecycleBin";
|
||||
}
|
||||
|
||||
public Element ToElement(IElementManager elementManager, DescribeElementsContext describeContext, JToken node) {
|
||||
return new RecycleBin();
|
||||
}
|
||||
|
||||
public void FromElement(Element element, DescribeElementsContext describeContext, JToken node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
|
||||
namespace Orchard.Layouts.Services {
|
||||
public abstract class ElementEventHandlerBase : Component, IElementEventHandler {
|
||||
public virtual void Creating(ElementCreatingContext context) { }
|
||||
public virtual void Created(ElementCreatedContext context) { }
|
||||
public virtual void CreatingDisplay(ElementCreatingDisplayShapeContext context) {}
|
||||
public virtual void CreatingDisplay(ElementCreatingDisplayShapeContext context) { }
|
||||
public virtual void Displaying(ElementDisplayingContext context) { }
|
||||
public virtual void Displayed(ElementDisplayedContext context) { }
|
||||
public virtual void BuildEditor(ElementEditorContext context) { }
|
||||
public virtual void UpdateEditor(ElementEditorContext context) { }
|
||||
public virtual void LayoutSaving(ElementSavingContext context) { }
|
||||
public virtual void Removing(ElementRemovingContext context) { }
|
||||
public virtual void Exporting(ExportElementContext context) { }
|
||||
public virtual void Exported(ExportElementContext context) { }
|
||||
public virtual void Importing(ImportElementContext context) { }
|
||||
public virtual void Imported(ImportElementContext context) { }
|
||||
public virtual void ImportCompleted(ImportElementContext context) { }
|
||||
}
|
||||
}
|
||||
@@ -55,21 +55,21 @@ namespace Orchard.Layouts.Services {
|
||||
|
||||
public IEnumerable<CategoryDescriptor> GetCategories(DescribeElementsContext context) {
|
||||
var contentType = context.Content != null ? context.Content.ContentItem.ContentType : default(string);
|
||||
return _cacheManager.Get(String.Format("ElementCategories-{0}-{1}", contentType ?? "AnyType", context.CacheVaryParam), true, acquireContext => {
|
||||
var elements = DescribeElements(context);
|
||||
return _cacheManager.Get(String.Format("ElementCategories-{0}-{1}", contentType ?? "AnyType", context.CacheVaryParam), acquireContext => {
|
||||
var elementDescriptors = DescribeElements(context);
|
||||
var categoryDictionary = GetCategories();
|
||||
var categoryDescriptorDictionary = new Dictionary<string, CategoryDescriptor>();
|
||||
|
||||
foreach (var element in elements) {
|
||||
var category = categoryDictionary.ContainsKey(element.Category)
|
||||
? categoryDictionary[element.Category]
|
||||
: new Category(element.Category, T(element.Category), position: int.MaxValue);
|
||||
foreach (var elementDescriptor in elementDescriptors) {
|
||||
var category = categoryDictionary.ContainsKey(elementDescriptor.Category)
|
||||
? categoryDictionary[elementDescriptor.Category]
|
||||
: new Category(elementDescriptor.Category, T(elementDescriptor.Category), position: int.MaxValue);
|
||||
|
||||
var descriptor = categoryDescriptorDictionary.ContainsKey(element.Category)
|
||||
? categoryDescriptorDictionary[element.Category]
|
||||
: categoryDescriptorDictionary[element.Category] = new CategoryDescriptor(category.Name, category.DisplayName, category.Description, category.Position);
|
||||
var descriptor = categoryDescriptorDictionary.ContainsKey(elementDescriptor.Category)
|
||||
? categoryDescriptorDictionary[elementDescriptor.Category]
|
||||
: categoryDescriptorDictionary[elementDescriptor.Category] = new CategoryDescriptor(category.Name, category.DisplayName, category.Description, category.Position);
|
||||
|
||||
descriptor.Elements.Add(element);
|
||||
descriptor.Elements.Add(elementDescriptor);
|
||||
}
|
||||
|
||||
acquireContext.Monitor(_signals.When(Signals.ElementDescriptors));
|
||||
@@ -141,76 +141,68 @@ namespace Orchard.Layouts.Services {
|
||||
|
||||
public void Saving(LayoutSavingContext context) {
|
||||
var elements = context.Elements.Flatten();
|
||||
InvokeDriver(elements, (driver, element) => driver.LayoutSaving(new ElementSavingContext(context) {
|
||||
Element = element
|
||||
}));
|
||||
|
||||
foreach (var element in elements) {
|
||||
var savingContext = new ElementSavingContext(element, context);
|
||||
_elementEventHandler.LayoutSaving(savingContext);
|
||||
element.Descriptor.LayoutSaving(savingContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void Removing(LayoutSavingContext context) {
|
||||
var elementInstances = context.RemovedElements.Flatten();
|
||||
InvokeDriver(elementInstances, (driver, elementInstance) => driver.Removing(new ElementRemovingContext(context) {
|
||||
Element = elementInstance
|
||||
}));
|
||||
var elements = context.RemovedElements.Flatten().ToList();
|
||||
|
||||
foreach (var element in elements) {
|
||||
var removingContext = new ElementRemovingContext(element, context.Elements, context.RemovedElements, context.Content);
|
||||
_elementEventHandler.Removing(removingContext);
|
||||
element.Descriptor.Removing(removingContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void Exporting(IEnumerable<Element> elements, ExportLayoutContext context) {
|
||||
InvokeDriver(elements, (driver, element) => {
|
||||
var exportElementContext = new ExportElementContext {
|
||||
Layout = context.Layout,
|
||||
Element = element,
|
||||
ExportableData = element.ExportableData
|
||||
};
|
||||
driver.Exporting(exportElementContext);
|
||||
element.ExportableData = new ElementDataDictionary(exportElementContext.ExportableData);
|
||||
});
|
||||
foreach (var element in elements) {
|
||||
var exportingContext = new ExportElementContext(element, context.Layout, element.ExportableData ?? new ElementDataDictionary());
|
||||
_elementEventHandler.Exporting(exportingContext);
|
||||
element.Descriptor.Exporting(exportingContext);
|
||||
|
||||
// Update potentially modified ExportableData.
|
||||
element.ExportableData = new ElementDataDictionary(exportingContext.ExportableData);
|
||||
}
|
||||
}
|
||||
|
||||
public void Exported(IEnumerable<Element> elements, ExportLayoutContext context) {
|
||||
InvokeDriver(elements, (driver, element) => {
|
||||
var exportElementContext = new ExportElementContext {
|
||||
Layout = context.Layout,
|
||||
Element = element,
|
||||
ExportableData = element.ExportableData
|
||||
};
|
||||
driver.Exported(exportElementContext);
|
||||
element.ExportableData = new ElementDataDictionary(exportElementContext.ExportableData);
|
||||
});
|
||||
foreach (var element in elements) {
|
||||
var exportingContext = new ExportElementContext(element, context.Layout, element.ExportableData ?? new ElementDataDictionary());
|
||||
_elementEventHandler.Exported(exportingContext);
|
||||
element.Descriptor.Exported(exportingContext);
|
||||
|
||||
// Update potentially modified ExportableData.
|
||||
element.ExportableData = new ElementDataDictionary(exportingContext.ExportableData);
|
||||
}
|
||||
}
|
||||
|
||||
public void Importing(IEnumerable<Element> elements, ImportLayoutContext context) {
|
||||
InvokeDriver(elements, (driver, element) => {
|
||||
var importElementContext = new ImportElementContext {
|
||||
Layout = context.Layout,
|
||||
Element = element,
|
||||
ExportableData = element.ExportableData,
|
||||
Session = context.Session
|
||||
};
|
||||
driver.Importing(importElementContext);
|
||||
});
|
||||
foreach (var element in elements) {
|
||||
var importingContext = new ImportElementContext(element, context.Layout, element.ExportableData ?? new ElementDataDictionary(), context.Session);
|
||||
_elementEventHandler.Importing(importingContext);
|
||||
element.Descriptor.Importing(importingContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void Imported(IEnumerable<Element> elements, ImportLayoutContext context) {
|
||||
InvokeDriver(elements, (driver, element) => {
|
||||
var importElementContext = new ImportElementContext {
|
||||
Layout = context.Layout,
|
||||
Element = element,
|
||||
ExportableData = element.ExportableData,
|
||||
Session = context.Session
|
||||
};
|
||||
driver.Imported(importElementContext);
|
||||
});
|
||||
foreach (var element in elements) {
|
||||
var importingContext = new ImportElementContext(element, context.Layout, element.ExportableData ?? new ElementDataDictionary(), context.Session);
|
||||
_elementEventHandler.Imported(importingContext);
|
||||
element.Descriptor.Imported(importingContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void ImportCompleted(IEnumerable<Element> elements, ImportLayoutContext context) {
|
||||
InvokeDriver(elements, (driver, element) => {
|
||||
var importElementContext = new ImportElementContext {
|
||||
Layout = context.Layout,
|
||||
Element = element,
|
||||
ExportableData = element.ExportableData,
|
||||
Session = context.Session
|
||||
};
|
||||
driver.ImportCompleted(importElementContext);
|
||||
});
|
||||
foreach (var element in elements) {
|
||||
var importingContext = new ImportElementContext(element, context.Layout, element.ExportableData ?? new ElementDataDictionary(), context.Session);
|
||||
_elementEventHandler.ImportCompleted(importingContext);
|
||||
element.Descriptor.ImportCompleted(importingContext);
|
||||
}
|
||||
}
|
||||
|
||||
private IDictionary<string, Category> GetCategories() {
|
||||
@@ -225,15 +217,6 @@ namespace Orchard.Layouts.Services {
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private void InvokeDriver(IEnumerable<Element> elements, Action<IElementDriver, Element> driverAction) {
|
||||
foreach (var element in elements) {
|
||||
var drivers = GetDrivers(element.Descriptor);
|
||||
foreach (var driver in drivers) {
|
||||
driverAction(driver, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsElementType(IElementDriver elementDriver, Type elementType) {
|
||||
var driverType = elementDriver.GetType();
|
||||
var driverElementType = driverType.BaseType.GenericTypeArguments[0];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Orchard.Events;
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
|
||||
namespace Orchard.Layouts.Services {
|
||||
public interface IElementEventHandler : IEventHandler {
|
||||
@@ -11,5 +12,12 @@ namespace Orchard.Layouts.Services {
|
||||
void Displayed(ElementDisplayedContext context);
|
||||
void BuildEditor(ElementEditorContext context);
|
||||
void UpdateEditor(ElementEditorContext context);
|
||||
void LayoutSaving(ElementSavingContext context);
|
||||
void Removing(ElementRemovingContext context);
|
||||
void Exporting(ExportElementContext context);
|
||||
void Exported(ExportElementContext context);
|
||||
void Importing(ImportElementContext context);
|
||||
void Imported(ImportElementContext context);
|
||||
void ImportCompleted(ImportElementContext context);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ namespace Orchard.Layouts.Services {
|
||||
icon = descriptor.ToolboxIcon,
|
||||
hasEditor = descriptor.EnableEditorDialog,
|
||||
|
||||
// If the element has no editor then the toolbox will add the element straight to to designer when being dragged & dropped,
|
||||
// If the element has no editor then the toolbox will add the element straight to the designer when being dragged & dropped,
|
||||
// so we'll want to present the user with a prerendered element.
|
||||
html = descriptor.EnableEditorDialog ? "" : RenderElement(element, new DescribeElementsContext { Content = content })
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Orchard.Layouts.Settings {
|
||||
public class ContentPartLayoutSettings {
|
||||
/// <summary>
|
||||
/// This setting is used to configure a part to be placeable on a layout.
|
||||
/// This setting is used to configure a content part to be placeable on a layout.
|
||||
/// </summary>
|
||||
public bool Placeable { get; set; }
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Layouts.Helpers;
|
||||
|
||||
namespace Orchard.Layouts.Settings {
|
||||
public class ContentPartSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
public class ContentPartLayoutSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
|
||||
public override IEnumerable<TemplateViewModel> PartEditor(ContentPartDefinition definition) {
|
||||
var model = definition.Settings.GetModel<ContentPartLayoutSettings>();
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Orchard.Layouts.Settings {
|
||||
public class ContentTypeLayoutSettings {
|
||||
/// <summary>
|
||||
/// This setting is used to configure a content type to be placeable on a layout.
|
||||
/// </summary>
|
||||
public bool Placeable { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Layouts.Helpers;
|
||||
|
||||
namespace Orchard.Layouts.Settings {
|
||||
public class ContentTypeLayoutSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
public override IEnumerable<TemplateViewModel> TypeEditor(ContentTypeDefinition definition) {
|
||||
var model = definition.Settings.GetModel<ContentTypeLayoutSettings>();
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
var model = new ContentTypeLayoutSettings();
|
||||
updateModel.TryUpdateModel(model, "ContentTypeLayoutSettings", null, null);
|
||||
builder.Placeable(model.Placeable);
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -8,11 +8,11 @@ using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Layouts.Services;
|
||||
|
||||
namespace Orchard.Layouts.Settings {
|
||||
public class LayoutSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
public class LayoutTypePartSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
private readonly ILayoutSerializer _serializer;
|
||||
private readonly ILayoutManager _layoutManager;
|
||||
|
||||
public LayoutSettingsHooks(ILayoutSerializer serializer, ILayoutManager layoutManager) {
|
||||
public LayoutTypePartSettingsHooks(ILayoutSerializer serializer, ILayoutManager layoutManager) {
|
||||
_serializer = serializer;
|
||||
_layoutManager = layoutManager;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -75,7 +75,8 @@ header, footer, aside, nav, article { display: block; }
|
||||
}
|
||||
|
||||
.zone-content .edit-widget .primary .widget-props,
|
||||
.zone-content .edit-widget .secondary {
|
||||
.zone-content .edit-widget .secondary,
|
||||
.zone-content .edit-item .edit-item-secondary {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Orchard.Layouts.ViewModels {
|
||||
public IContent Content { get; set; }
|
||||
public string Data { get; set; }
|
||||
public string ConfigurationData { get; set; }
|
||||
public string Trash { get; set; }
|
||||
public string RecycleBin { get; set; }
|
||||
public int? TemplateId { get; set; }
|
||||
public string SessionKey { get; set; }
|
||||
public IList<LayoutPart> Templates { get; set; }
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Orchard.Layouts.ViewModels {
|
||||
public class PlaceableContentItemViewModel {
|
||||
public int? ContentItemId { get; set; }
|
||||
}
|
||||
}
|
||||
-4
@@ -1,8 +1,4 @@
|
||||
@model Orchard.Layouts.Settings.ContentPartLayoutSettings
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Include("contentpart-layouts-settings.js");
|
||||
}
|
||||
<fieldset>
|
||||
@Html.CheckBoxFor(m => m.Placeable)
|
||||
<label for="@Html.FieldIdFor(m => m.Placeable)" class="forcheckbox">@T("Placeable")</label>
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@model Orchard.Layouts.Settings.ContentTypeLayoutSettings
|
||||
<fieldset>
|
||||
@Html.CheckBoxFor(m => m.Placeable)
|
||||
<label for="@Html.FieldIdFor(m => m.Placeable)" class="forcheckbox">@T("Placeable")</label>
|
||||
<span class="hint">@T("Check to allow this type to be placeable on a layout.")</span>
|
||||
</fieldset>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
@model Orchard.Layouts.ViewModels.PlaceableContentItemViewModel
|
||||
@Html.HiddenFor(m => m.ContentItemId)
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
@Html.HiddenFor(m => m.SessionKey)
|
||||
@Html.HiddenFor(m => m.Data, new { @class = "layout-data-field" })
|
||||
@Html.HiddenFor(m => m.RecycleBin, new { @class = "recycle-bin-data-field" })
|
||||
<div class="layout-editor-toolbar">
|
||||
<ol class="layout-editor-toolbar-group">
|
||||
<li>
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
@using Orchard.ContentManagement
|
||||
@{
|
||||
var contentItem = (ContentItem)Model.ContentItem;
|
||||
}
|
||||
<div class="layout-placeholder">
|
||||
@if (contentItem != null) {
|
||||
@String.Format("{0} - {1}", Html.ItemDisplayText(contentItem), contentItem.TypeDefinition.DisplayName)
|
||||
}
|
||||
else {
|
||||
@T("Content Item Not Found");
|
||||
}
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
@using Orchard.Layouts.Helpers
|
||||
@{
|
||||
var tagBuilder = TagBuilderExtensions.CreateElementTagBuilder(Model);
|
||||
}
|
||||
@tagBuilder.StartElement
|
||||
@if (Model.ContentShape != null) {
|
||||
@Display(Model.ContentShape)
|
||||
}
|
||||
@tagBuilder.EndElement
|
||||
@@ -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));
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Layouts.Helpers;
|
||||
using Orchard.Widgets.Models;
|
||||
|
||||
namespace Orchard.Widgets.Handlers {
|
||||
[OrchardFeature("Orchard.Widgets.Elements")]
|
||||
public class WidgetElementsHandler : ContentHandler {
|
||||
private readonly IOrchardServices _orchardServices;
|
||||
|
||||
public WidgetElementsHandler(IOrchardServices orchardServices) {
|
||||
_orchardServices = orchardServices;
|
||||
OnUpdated<WidgetPart>(PostProcessPlacedWidget);
|
||||
}
|
||||
|
||||
private void PostProcessPlacedWidget(UpdateContentContext context, WidgetPart part) {
|
||||
if (!part.IsPlaceableContent())
|
||||
return;
|
||||
|
||||
// This is a widget placed on a layout, so clear out the zone propertiey
|
||||
// to prevent the widget from appearing on the Widgets screen and on the front-end.
|
||||
part.Zone = null;
|
||||
|
||||
// To prevent the widget from being recognized as being orphaned, set its container.
|
||||
// If the current container is a LayerPart, override that as well.
|
||||
var commonPart = part.As<ICommonPart>();
|
||||
if (commonPart != null && (commonPart.Container == null || commonPart.Container.Is<LayerPart>())) {
|
||||
commonPart.Container = _orchardServices.WorkContext.CurrentSite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using Orchard.ContentManagement.Aspects;
|
||||
|
||||
namespace Orchard.Widgets.Models {
|
||||
public class WidgetPart : ContentPart<WidgetPartRecord>, ITitleAspect {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The widget's title.
|
||||
/// </summary>
|
||||
@@ -25,7 +25,7 @@ namespace Orchard.Widgets.Models {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the Title should be rendered on the front-end
|
||||
/// Whether or not the Title should be rendered on the front-end.
|
||||
/// </summary>
|
||||
public bool RenderTitle {
|
||||
get { return Retrieve(x => x.RenderTitle); }
|
||||
@@ -36,8 +36,7 @@ namespace Orchard.Widgets.Models {
|
||||
/// The widget's position within the zone.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Position
|
||||
{
|
||||
public string Position {
|
||||
get { return Retrieve(x => x.Position); }
|
||||
set { Store(x => x.Position, value); }
|
||||
}
|
||||
@@ -61,8 +60,11 @@ namespace Orchard.Widgets.Models {
|
||||
/// <summary>
|
||||
/// The layerPart identifier.
|
||||
/// </summary>
|
||||
public int LayerId {
|
||||
get { return this.As<ICommonPart>().Container.As<LayerPart>().Id; }
|
||||
public int? LayerId {
|
||||
get {
|
||||
var layerPart = LayerPart;
|
||||
return layerPart != null ? layerPart.Id : default(int?);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,9 @@
|
||||
(function ($) {
|
||||
// Hide the Layer, Zone, and Position fieldsets and set a value for the required fields.
|
||||
$(function() {
|
||||
var fieldsets = $("#element-properties .edit-widget fieldset").slice(0, 3);
|
||||
fieldsets.hide();
|
||||
|
||||
$("input[name='WidgetPart.Position']").val("0");
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -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; }
|
||||
|
||||
+53
-52
@@ -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)
|
||||
+3
-3
@@ -17,18 +17,18 @@
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Html.LabelFor(widget => widget.Title, T("Title"))
|
||||
@Html.TextBoxFor(widget => widget.Title, new { @class = "text medium" })
|
||||
@Html.TextBoxFor(widget => widget.Title, new { @class = "text large" })
|
||||
<span class="hint">@T("The title of the Widget.")</span>
|
||||
@Html.EditorFor(widget => widget.RenderTitle)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.RenderTitle)">@T("Check to render the title on the front-end, uncheck to hide")</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Html.LabelFor(widget => widget.Name, T("Name"))
|
||||
@Html.TextBoxFor(widget => widget.Name, new { @class = "text" })
|
||||
@Html.TextBoxFor(widget => widget.Name, new { @class = "text large" })
|
||||
<span class="hint">@T("The technical name of the Widget, used for css class and alternates.")</span>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Html.LabelFor(widget => widget.CssClasses, T("Css classes"))
|
||||
@Html.TextBoxFor(widget => widget.CssClasses, new { @class = "text medium" })
|
||||
@Html.TextBoxFor(widget => widget.CssClasses, new { @class = "text large" })
|
||||
<span class="hint">@T("Add custom css classes for the widget separated by spaces.")</span>
|
||||
</fieldset>
|
||||
|
||||
@@ -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
|
||||
@@ -7,7 +7,7 @@
|
||||
}
|
||||
@if (widgets.Count() > 0) {
|
||||
<div id="widgets-orphans" class="widgets-container widgets-listed message-Warning">
|
||||
<h3>@T("Widgets with problems.")</h3>
|
||||
<h3>@T("Widgets with problems")</h3>
|
||||
<p>@T("These widgets aren't going to appear anywhere because they're missing the CommonPart from their content type. To fix these widgets, if you still want to keep them around, start by fixing their <a href=\"{0}\">Content Types</a>.", Url.Action("Index", "Admin", new { area = "Orchard.ContentTypes" }))</p>
|
||||
<ul>
|
||||
@foreach (WidgetPart widget in widgets) {
|
||||
|
||||
@@ -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