mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
Binary file not shown.
BIN
lib/specflow/Gherkin.dll
Normal file
BIN
lib/specflow/Gherkin.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
lib/specflow/TechTalk.SpecFlow.Silverlight.dll
Normal file
BIN
lib/specflow/TechTalk.SpecFlow.Silverlight.dll
Normal file
Binary file not shown.
BIN
lib/specflow/TechTalk.SpecFlow.Utils.dll
Normal file
BIN
lib/specflow/TechTalk.SpecFlow.Utils.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,58 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Import Project="TechTalk.SpecFlow.tasks"/>
|
||||
|
||||
<!-- this setting is to workaround the bug in VS (does not detect changes during the pre-build event)
|
||||
see: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=423670&wa=wsignin1.0
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ShowTrace Condition="'$(ShowTrace)'==''">false</ShowTrace>
|
||||
|
||||
<OverwriteReadOnlyFiles Condition="'$(OverwriteReadOnlyFiles)'==''">false</OverwriteReadOnlyFiles>
|
||||
<ForceGeneration Condition="'$(ForceGeneration)'==''">false</ForceGeneration>
|
||||
<VerboseOutput Condition="'$(VerboseOutput)'==''">false</VerboseOutput>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(BuildServerMode)' == ''">
|
||||
<BuildServerMode Condition="'$(BuildingInsideVisualStudio)'=='true'">false</BuildServerMode>
|
||||
<BuildServerMode Condition="'$(BuildingInsideVisualStudio)'!='true'">true</BuildServerMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildDependsOn>
|
||||
UpdateFeatureFilesInProject;
|
||||
$(BuildDependsOn)
|
||||
</BuildDependsOn>
|
||||
<RebuildDependsOn>
|
||||
SwitchToForceGenerate;
|
||||
$(RebuildDependsOn)
|
||||
</RebuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="SwitchToForceGenerate">
|
||||
<PropertyGroup>
|
||||
<ForceGeneration>true</ForceGeneration>
|
||||
<OnlyUpdateIfChanged>true</OnlyUpdateIfChanged>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="UpdateFeatureFilesInProject">
|
||||
<GenerateAll
|
||||
ShowTrace="$(ShowTrace)"
|
||||
|
||||
BuildServerMode="$(BuildServerMode)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
|
||||
ProjectPath="$(MSBuildProjectFullPath)"
|
||||
ForceGeneration="$(ForceGeneration)"
|
||||
VerboseOutput="$(VerboseOutput)"
|
||||
/>
|
||||
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Import Project="TechTalk.SpecFlow.tasks"/>
|
||||
|
||||
<!-- this setting is to workaround the bug in VS (does not detect changes during the pre-build event)
|
||||
see: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=423670&wa=wsignin1.0
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ShowTrace Condition="'$(ShowTrace)'==''">false</ShowTrace>
|
||||
|
||||
<OverwriteReadOnlyFiles Condition="'$(OverwriteReadOnlyFiles)'==''">false</OverwriteReadOnlyFiles>
|
||||
<ForceGeneration Condition="'$(ForceGeneration)'==''">false</ForceGeneration>
|
||||
<VerboseOutput Condition="'$(VerboseOutput)'==''">false</VerboseOutput>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(BuildServerMode)' == ''">
|
||||
<BuildServerMode Condition="'$(BuildingInsideVisualStudio)'=='true'">false</BuildServerMode>
|
||||
<BuildServerMode Condition="'$(BuildingInsideVisualStudio)'!='true'">true</BuildServerMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildDependsOn>
|
||||
UpdateFeatureFilesInProject;
|
||||
$(BuildDependsOn)
|
||||
</BuildDependsOn>
|
||||
<RebuildDependsOn>
|
||||
SwitchToForceGenerate;
|
||||
$(RebuildDependsOn)
|
||||
</RebuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="SwitchToForceGenerate">
|
||||
<PropertyGroup>
|
||||
<ForceGeneration>true</ForceGeneration>
|
||||
<OnlyUpdateIfChanged>true</OnlyUpdateIfChanged>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="UpdateFeatureFilesInProject">
|
||||
<GenerateAll
|
||||
ShowTrace="$(ShowTrace)"
|
||||
|
||||
BuildServerMode="$(BuildServerMode)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
|
||||
ProjectPath="$(MSBuildProjectFullPath)"
|
||||
ForceGeneration="$(ForceGeneration)"
|
||||
VerboseOutput="$(VerboseOutput)"
|
||||
/>
|
||||
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SpecFlowTasksPath Condition="'$(SpecFlowTasksPath)'==''">specflow.exe</SpecFlowTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- handle absolute / targets-relative tasks path -->
|
||||
<__SpecFlowTasksFullPath>$(SpecFlowTasksPath)</__SpecFlowTasksFullPath>
|
||||
<!-- handle relative tasks path -->
|
||||
<__SpecFlowTasksFullPath Condition="Exists('$(MSBuildProjectDirectory)\$(SpecFlowTasksPath)')"
|
||||
>$(MSBuildProjectDirectory)\$(SpecFlowTasksPath)</__SpecFlowTasksFullPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask TaskName="TechTalk.SpecFlow.Tools.MsBuild.GenerateAll" AssemblyFile="$(__SpecFlowTasksFullPath)" />
|
||||
|
||||
</Project>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SpecFlowTasksPath Condition="'$(SpecFlowTasksPath)'==''">specflow.exe</SpecFlowTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- handle absolute / targets-relative tasks path -->
|
||||
<__SpecFlowTasksFullPath>$(SpecFlowTasksPath)</__SpecFlowTasksFullPath>
|
||||
<!-- handle relative tasks path -->
|
||||
<__SpecFlowTasksFullPath Condition="Exists('$(MSBuildProjectDirectory)\$(SpecFlowTasksPath)')"
|
||||
>$(MSBuildProjectDirectory)\$(SpecFlowTasksPath)</__SpecFlowTasksFullPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask TaskName="TechTalk.SpecFlow.Tools.MsBuild.GenerateAll" AssemblyFile="$(__SpecFlowTasksFullPath)" />
|
||||
|
||||
</Project>
|
||||
|
@@ -1,50 +1,175 @@
|
||||
|
||||
1.2.0 - 2009/11/25
|
||||
|
||||
New features:
|
||||
+ Generate #line pragmas to the output file (Issue 26)
|
||||
+ Allow transformation of feature files from command-line and MsBuild (Issue 3)
|
||||
+ Merge all command-line tool (generation, reports) to a single executable: specflow.exe
|
||||
+ Support for Dutch and Swedish language
|
||||
+ Support enumerations in step binding arguments (Issue 28)
|
||||
|
||||
Fixed issues:
|
||||
+ MsTest does not refresh tests automatically (Issue 25)
|
||||
+ Fixes in report localization
|
||||
+ Non-string parameters for bindings are not converted using the feature language (Issue 26)
|
||||
|
||||
1.1.0 - 2009/11/11
|
||||
|
||||
New features:
|
||||
+ Support for MsTest (Issue 4)
|
||||
+ Finalize configuration (Issue 13)
|
||||
+ Support German, French and Hungarian languages (Issue 5)
|
||||
+ Add strong-name for specflow assemblies (Issue 2)
|
||||
+ Allow scenario events to be instance methods (Issue 20)
|
||||
+ More descriptive name for the scenario outline example tests than XYZ_Variant1 (Issue 18)
|
||||
+ NUnit SpecFlow test execution report (Issue 23)
|
||||
+ Step definition usage report (Issue 24)
|
||||
|
||||
Fixed issues:
|
||||
+ Runtime: Remove direct dependency on nunit.framework.dll from the runtime (Issue 12)
|
||||
+ Runtime: Binding methods with more than 4 parameters cannot be used (Issue 21)
|
||||
+ Generator: Special language characters (e.g. accented letters) are removed when generating test method names (Issue 22)
|
||||
|
||||
1.0.2 - 2009/10/20
|
||||
|
||||
New features:
|
||||
+ Runtime: allow non-static bindings
|
||||
+ Runtime: support multiple step attributes on a single binding method
|
||||
|
||||
Fixed issues:
|
||||
+ VS: Error message is displayed when you add a SpecFlow project item to your project.
|
||||
+ Parser: mixed order of Given/When/Then is not supported
|
||||
+ Runtime: the original phrasing of the keywords (Given/And/But) is not preserved
|
||||
+ Generator: the generated test class has a "Fixture" suffix
|
||||
+ Parser: specifying any "given" should be optional
|
||||
|
||||
|
||||
1.0.1 - 2009/10/13
|
||||
|
||||
Initial publish on http://www.specflow.org
|
||||
|
||||
1.4.0 - 2010/10/07
|
||||
|
||||
Breaking changes:
|
||||
+ The generator has been improved to provide source code language. Because of this, SpecFlow test generated
|
||||
with this version will be incompatible with older runtimes.
|
||||
|
||||
New features:
|
||||
+ Scoped Step Definitions: you can scope step definitions (bindings) to tags, features and scenarios. Scope filter
|
||||
can be applied to a class or a method with the [StepScope] attribute.
|
||||
See examples in Tests/FeatureTests/ScopedSteps/ScopedSteps.feature and Tests/FeatureTests/ScopedSteps/ScopedStepsBindings.cs
|
||||
(Thanks to Jose Simas for the contribution.)
|
||||
+ Adding binding-culture to App.config. If set, this culture is used during execution of steps.
|
||||
+ VB-Step-Definition Skeleton Provider: For VB-projects, the suggested step skeletons are generated in VB.
|
||||
+ Merging strongly typed context accessors from Darren Cauthon's SpecFlowAssist
|
||||
+ Merging table/row extension methods from Darren Cauthon's SpecFlowAssist
|
||||
Add a using statement for the namespace TechTalk.SpecFlow.Assist to use the extension methods.
|
||||
See also Darren's youtube tutorial: http://bit.ly/aY4VOd
|
||||
+ Diagnostic tracing: VS2010 integration can display trace messages to the Output window
|
||||
if tracing is enabled. Tracing can be enabled by setting the environment variable SPECFLOW_TRACE
|
||||
to either "all" or to the comma separated list of individual SpecFlow traing categories (currently
|
||||
only the category "EditorParser" is supported).
|
||||
|
||||
Fixed issues:
|
||||
+ Better error reporting for wrong Gherkin files (multiple errors displayed, detect duplicate scenario names)
|
||||
+ Visual Studio 2010 editor slows down after editing a feature file for a longer time (Issue 9)
|
||||
|
||||
1.3.5.2 - 2010/08/11
|
||||
|
||||
Fixed issues:
|
||||
+ Sorry, we're ironing out our deploy strategy with the new Mono/MonoDevelop integration. We didn't
|
||||
change the version in the MonoDevelop Add-In XML file.
|
||||
|
||||
1.3.5.1 - 2010/08/11
|
||||
|
||||
New features:
|
||||
+ Support for hosting add-in on http://addins.monodevelop.com
|
||||
|
||||
1.3.5 - 2010/08/11
|
||||
|
||||
New features:
|
||||
+ Support for Mono (v2.6.7) & MonoDevelop (v2.4) by Dale Ragan
|
||||
|
||||
Fixed issues:
|
||||
+ Generating code randomly for the wrong testing engine
|
||||
+ Test class generation problem for Russian feature files
|
||||
+ Fix tag support for Silverlight
|
||||
|
||||
1.3.4 - 2010/07/28
|
||||
|
||||
Fixed issues:
|
||||
+ Installation fails if Visual Studio 2010 is not installed
|
||||
+ VS2010: Background section is not colored properly
|
||||
|
||||
1.3.3 - 2010/07/19
|
||||
|
||||
New features:
|
||||
+ Support for MsTest report generation
|
||||
usage: specflow mstestexecutionreport projectFile [/testResult:value] [/xsltFile:value] [/out:value]
|
||||
projectFile Visual Studio Project File containing specs
|
||||
[/testResult:value] Test Result file generated by MsTest. Defaults to TestResult.trx
|
||||
[/out:value] Generated Output File. Defaults to TestResult.html
|
||||
[/xsltFile:value] Xslt file to use, defaults to built-in stylesheet if not provided
|
||||
+ Visual Studio 2010 editor support:
|
||||
- syntax coloring with configurable colors ("Gherkin ...")
|
||||
- outlining for scenarios
|
||||
Uninstall the beta integration (TechTalk.SpecFlow.VsIntegration.GherkinFile.vsix) before installing
|
||||
SpecFlow 1.3.3.
|
||||
|
||||
Fixed issues:
|
||||
+ MbUnit execution fails for pending steps (Assert method not found: Inconclusive)
|
||||
|
||||
1.3.2 - 2010/06/29
|
||||
|
||||
New features:
|
||||
+ Support for MsTest for .NET 4.0 categories. Configure the test provider name to
|
||||
"MsTest.2010" in order to use the [TestCategory] attribute.
|
||||
+ Silverlight support (beta), see http://wiki.github.com/techtalk/SpecFlow/silverlight-support
|
||||
|
||||
Fixed issues:
|
||||
+ Report generation fails if no custom XSLT is provided
|
||||
|
||||
|
||||
1.3.1 - 2010/06/21
|
||||
|
||||
New features:
|
||||
+ Using standard Gherkin parser (http://github.com/aslakhellesoy/gherkin) v2.0.1
|
||||
+ Custom XSLT can be specified for generating reports.
|
||||
See examples in Tests/ReportingTests/CustomXsltTemplate.feature
|
||||
+ The test error can be accessed through ScenarioContext.Current.TestError
|
||||
(e.g. in an AfterScenario event).
|
||||
+ [StepTransformation] attribute has been renamed to [StepArgumentTransformation]
|
||||
because this name describe the intention better. Using the old attribute will
|
||||
generate a warning.
|
||||
+ Support for MbUnit
|
||||
|
||||
Fixed issues:
|
||||
+ NullReference exception when using BeforeTestRun event (Issue 41)
|
||||
|
||||
1.3.0 - 2010/05/05
|
||||
|
||||
New features:
|
||||
+ Using standard Gherkin parser (http://github.com/aslakhellesoy/gherkin) v1.0.24
|
||||
+ Context injection in step definitions. Step definitions can get a context injected with
|
||||
constructor injection. (Issue 30)
|
||||
See examples in Tests/FeatureTests/ContextInjection
|
||||
+ Using steps in other assemblies. This enables writing steps in VB. (Issue 19)
|
||||
See examples in Tests/FeatureTests/ExternalSteps
|
||||
+ Steps can be invoked from other steps using step text. See examples in
|
||||
Tests/FeatureTests/CallingStepsFromStepDefinitions
|
||||
+ Custom step parameter converters can be defined as a binding.
|
||||
See examples in Tests/FeatureTests/StepArgumentTransfomation
|
||||
+ SpecFlow feature files can be added also to VB.NET projects
|
||||
+ Support for xUnit
|
||||
+ Single installer for Visual Studio 2008 and 2010 (Issue 6, 10, 11)
|
||||
+ Place GeneratedCodeAttribute and 'Designer generated code' region on generated code to
|
||||
avoid having this code parsed by code analysis. (Issue 33)
|
||||
+ Configuration option to disable all output. (Issue 29)
|
||||
Use the following config to disable output:
|
||||
<trace listener="TechTalk.SpecFlow.Tracing.NullListener, TechTalk.SpecFlow" />
|
||||
|
||||
Fixed issues:
|
||||
+ SpecFlow Reporting doesn't work with Firefox (Issue 31)
|
||||
+ Binding methods are executed using the culture of the feature file.
|
||||
+ Several parsing issues are solved now (Issue 1, 8, 9, 37)
|
||||
|
||||
1.2.0 - 2009/11/25
|
||||
|
||||
New features:
|
||||
+ Generate #line pragmas to the output file (Issue 26)
|
||||
+ Allow transformation of feature files from command-line and MsBuild (Issue 3)
|
||||
+ Merge all command-line tool (generation, reports) to a single executable: specflow.exe
|
||||
+ Support for Dutch and Swedish language
|
||||
+ Support enumerations in step binding arguments (Issue 28)
|
||||
|
||||
Fixed issues:
|
||||
+ MsTest does not refresh tests automatically (Issue 25)
|
||||
+ Fixes in report localization
|
||||
+ Non-string parameters for bindings are not converted using the feature language (Issue 26)
|
||||
|
||||
1.1.0 - 2009/11/11
|
||||
|
||||
New features:
|
||||
+ Support for MsTest (Issue 4)
|
||||
+ Finalize configuration (Issue 13)
|
||||
+ Support German, French and Hungarian languages (Issue 5)
|
||||
+ Add strong-name for specflow assemblies (Issue 2)
|
||||
+ Allow scenario events to be instance methods (Issue 20)
|
||||
+ More descriptive name for the scenario outline example tests than XYZ_Variant1 (Issue 18)
|
||||
+ NUnit SpecFlow test execution report (Issue 23)
|
||||
+ Step definition usage report (Issue 24)
|
||||
|
||||
Fixed issues:
|
||||
+ Runtime: Remove direct dependency on nunit.framework.dll from the runtime (Issue 12)
|
||||
+ Runtime: Binding methods with more than 4 parameters cannot be used (Issue 21)
|
||||
+ Generator: Special language characters (e.g. accented letters) are removed when generating
|
||||
test method names (Issue 22)
|
||||
|
||||
1.0.2 - 2009/10/20
|
||||
|
||||
New features:
|
||||
+ Runtime: allow non-static bindings
|
||||
+ Runtime: support multiple step attributes on a single binding method
|
||||
|
||||
Fixed issues:
|
||||
+ VS: Error message is displayed when you add a SpecFlow project item to your project.
|
||||
+ Parser: mixed order of Given/When/Then is not supported
|
||||
+ Runtime: the original phrasing of the keywords (Given/And/But) is not preserved
|
||||
+ Generator: the generated test class has a "Fixture" suffix
|
||||
+ Parser: specifying any "given" should be optional
|
||||
|
||||
|
||||
1.0.1 - 2009/10/13
|
||||
|
||||
Initial publish on http://www.specflow.org
|
||||
|
||||
|
Binary file not shown.
@@ -85,6 +85,7 @@
|
||||
<Reference Include="System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\sqlce\System.Data.SqlServerCe.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Abstractions">
|
||||
|
@@ -6,7 +6,6 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.Records;
|
||||
@@ -110,14 +109,13 @@ namespace Orchard.Core.Tests.Routable.Services {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void VeryLongStringTruncatedTo1000Chars() {
|
||||
var veryVeryLongTitle = "this is a very long title...";
|
||||
for (var i = 0; i < 100; i++)
|
||||
veryVeryLongTitle += "aaaaaaaaaa";
|
||||
|
||||
var thing = CreateRoutePart(veryVeryLongTitle);
|
||||
var thing = CreateRoutePartFromScratch(veryVeryLongTitle);
|
||||
_routableService.FillSlugFromTitle(thing);
|
||||
|
||||
Assert.That(veryVeryLongTitle.Length, Is.AtLeast(1001));
|
||||
@@ -126,72 +124,111 @@ namespace Orchard.Core.Tests.Routable.Services {
|
||||
|
||||
[Test]
|
||||
public void NoExistingLikeSlugsGeneratesSameSlug() {
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePart("woohoo"), null);
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePartFromScratch("woohoo"), null);
|
||||
Assert.That(slug, Is.EqualTo("woohoo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExistingSingleLikeSlugThatsAConflictGeneratesADash2() {
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePart("woohoo"), new List<string> { "woohoo" });
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePartFromScratch("woohoo"), new List<string> { "woohoo" });
|
||||
Assert.That(slug, Is.EqualTo("woohoo-2"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExistingSingleLikeSlugThatsNotAConflictGeneratesSameSlug() {
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePart("woohoo"), new List<string> { "woohoo-2" });
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePartFromScratch("woohoo"), new List<string> { "woohoo-2" });
|
||||
Assert.That(slug, Is.EqualTo("woohoo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExistingLikeSlugsWithAConflictGeneratesADashVNext() {
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePart("woohoo"), new List<string> { "woohoo", "woohoo-2" });
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePartFromScratch("woohoo"), new List<string> { "woohoo", "woohoo-2" });
|
||||
Assert.That(slug, Is.EqualTo("woohoo-3"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExistingSlugsWithVersionGapsAndNoMatchGeneratesSameSlug() {
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePart("woohoo"), new List<string> { "woohoo-2", "woohoo-4", "woohoo-5" });
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePartFromScratch("woohoo"), new List<string> { "woohoo-2", "woohoo-4", "woohoo-5" });
|
||||
Assert.That(slug, Is.EqualTo("woohoo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExistingSlugsWithVersionGapsAndAMatchGeneratesADash2() {
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePart("woohoo-2"), new List<string> { "woohoo-2", "woohoo-4", "woohoo-5" });
|
||||
string slug = _routableService.GenerateUniqueSlug(CreateRoutePartFromScratch("woohoo-2"), new List<string> { "woohoo-2", "woohoo-4", "woohoo-5" });
|
||||
Assert.That(slug, Is.EqualTo("woohoo-2-2"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GeneratedSlugIsLowerCased() {
|
||||
var thing = CreateRoutePart("This Is Some Interesting Title");
|
||||
|
||||
public void SlugIsGeneratedLowerCased() {
|
||||
var thing = CreateRoutePartFromScratch("This Is Some Interesting Title");
|
||||
_routableService.FillSlugFromTitle(thing);
|
||||
|
||||
Assert.That(thing.Slug, Is.EqualTo("this-is-some-interesting-title"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SlugInConflictWithAnExistingItemsPathIsVersioned() {
|
||||
var thing1 = CreateRoutePart("bar", "bar", "foo");
|
||||
var thing2 = CreateRoutePart("fooslashbar", "foo/bar");
|
||||
|
||||
Assert.That(thing2.Slug, Is.EqualTo("foo/bar-2"));
|
||||
CreateRoutePartFromScratch("bar", "bar", "foo");
|
||||
var thing2 = CreateRoutePartFromScratch("fooslashbar", "foo/bar");
|
||||
Assert.That(thing2.Path, Is.EqualTo("foo/bar-2"));
|
||||
}
|
||||
|
||||
private RoutePart CreateRoutePart(string title, string slug = "", string containerPath = "") {
|
||||
[Test]
|
||||
public void GeneratedSlugInConflictInSameContaierPathIsVersioned() {
|
||||
var thing1 = CreateRoutePartFromScratch("Foo", "", "bar");
|
||||
var thing2 = CreateRoutePartWithExistingContainer("Foo", thing1.As<ICommonPart>().Container);
|
||||
Assert.That(thing2.Path, Is.EqualTo("bar/foo-2"));
|
||||
Assert.That(thing2.Slug, Is.EqualTo("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GivenSlugInConflictInSameContaierPathIsVersioned() {
|
||||
var thing1 = CreateRoutePartFromScratch("Hi", "foo", "bar");
|
||||
var thing2 = CreateRoutePartWithExistingContainer("There", thing1.As<ICommonPart>().Container, "foo");
|
||||
Assert.That(thing2.Path, Is.EqualTo("bar/foo-2"));
|
||||
Assert.That(thing2.Slug, Is.EqualTo("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GeneratedSlugInConflictInDifferentContaierPathIsNotVersioned() {
|
||||
var thing1 = CreateRoutePartFromScratch("Foo", "", "rab");
|
||||
var thing2 = CreateRoutePartFromScratch("Foo", "", "bar");
|
||||
Assert.That(thing1.Path, Is.EqualTo("rab/foo"));
|
||||
Assert.That(thing2.Path, Is.EqualTo("bar/foo"));
|
||||
Assert.That(thing1.Slug, Is.EqualTo("foo"));
|
||||
Assert.That(thing2.Slug, Is.EqualTo("foo"));
|
||||
}
|
||||
|
||||
private RoutePart CreateRoutePartWithExistingContainer(string title, IContent container, string slug = "") {
|
||||
var contentManager = _container.Resolve<IContentManager>();
|
||||
return contentManager.Create<Thing>("thing", t => {
|
||||
t.As<RoutePart>().Record = new RoutePartRecord();
|
||||
if (!string.IsNullOrWhiteSpace(slug))
|
||||
t.As<RoutePart>().Slug = slug;
|
||||
t.Title = title;
|
||||
if (!string.IsNullOrWhiteSpace(containerPath)) {
|
||||
t.As<ICommonPart>().Container = contentManager.Create<Thing>("thing", tt => {
|
||||
tt.As<RoutePart>().Path = containerPath;
|
||||
tt.As<RoutePart>().Slug = containerPath;
|
||||
});
|
||||
}
|
||||
})
|
||||
.As<RoutePart>();
|
||||
t.As<RoutePart>().Record = new RoutePartRecord();
|
||||
t.Title = title;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(slug))
|
||||
t.As<RoutePart>().Slug = slug;
|
||||
|
||||
if (container != null)
|
||||
t.As<ICommonPart>().Container = container;
|
||||
}).As<RoutePart>();
|
||||
}
|
||||
|
||||
private RoutePart CreateRoutePartFromScratch(string title, string slug = "", string containerPath = "") {
|
||||
var contentManager = _container.Resolve<IContentManager>();
|
||||
return contentManager.Create<Thing>("thing", t => {
|
||||
t.As<RoutePart>().Record = new RoutePartRecord();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(slug))
|
||||
t.As<RoutePart>().Slug = slug;
|
||||
|
||||
t.Title = title;
|
||||
if (!string.IsNullOrWhiteSpace(containerPath)) {
|
||||
t.As<ICommonPart>().Container = contentManager.Create<Thing>("thing", tt => {
|
||||
tt.As<RoutePart>().Path = containerPath;
|
||||
tt.As<RoutePart>().Slug = containerPath;
|
||||
tt.As<RoutePart>().Title = "Test Container";
|
||||
});
|
||||
}
|
||||
}).As<RoutePart>();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,6 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
@@ -16,7 +14,7 @@ namespace Orchard.Specs.Bindings {
|
||||
var webApp = Binding<WebAppHosting>();
|
||||
|
||||
webApp.GivenIHaveACleanSiteWith(TableData(
|
||||
new { extension = "module", names = "Orchard.Setup, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" },
|
||||
new { extension = "module", names = "Orchard.Setup, Orchard.Pages, Orchard.Blogs, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" },
|
||||
new { extension = "core", names = "Common, Dashboard, Feeds, HomePage, Messaging, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" },
|
||||
new { extension = "theme", names = "SafeMode, TheAdmin, TheThemeMachine" }));
|
||||
|
||||
@@ -34,9 +32,7 @@ namespace Orchard.Specs.Bindings {
|
||||
public void GivenIHaveInstalled(string name) {
|
||||
var webApp = Binding<WebAppHosting>();
|
||||
webApp.GivenIHaveModule(name);
|
||||
webApp.Host.Execute(() => {
|
||||
MvcApplication.ReloadExtensions();
|
||||
});
|
||||
webApp.Host.Execute(MvcApplication.ReloadExtensions);
|
||||
|
||||
GivenIHaveEnabled(name);
|
||||
}
|
||||
|
@@ -156,7 +156,7 @@ namespace Orchard.Specs.Bindings {
|
||||
[When(@"I fill in")]
|
||||
public void WhenIFillIn(Table table) {
|
||||
var inputs = _doc.DocumentNode
|
||||
.SelectNodes("//input") ?? Enumerable.Empty<HtmlNode>();
|
||||
.SelectNodes("(//input|//textarea)") ?? Enumerable.Empty<HtmlNode>();
|
||||
|
||||
foreach (var row in table.Rows) {
|
||||
var r = row;
|
||||
@@ -191,12 +191,15 @@ namespace Orchard.Specs.Bindings {
|
||||
var form = Form.LocateAround(submit);
|
||||
var urlPath = form.Start.GetAttributeValue("action", Details.UrlPath);
|
||||
var inputs = form.Children
|
||||
.SelectMany(elt => elt.DescendantsAndSelf("input"))
|
||||
.SelectMany(elt => elt.DescendantsAndSelf("input").Concat(elt.Descendants("textarea")))
|
||||
.Where(node => !((node.GetAttributeValue("type", "") == "radio" || node.GetAttributeValue("type", "") == "checkbox") && node.GetAttributeValue("checked", "") != "checked"))
|
||||
.GroupBy(elt => elt.GetAttributeValue("name", elt.GetAttributeValue("id", "")), elt => elt.GetAttributeValue("value", ""))
|
||||
.Where(g => !string.IsNullOrEmpty(g.Key))
|
||||
.ToDictionary(elt => elt.Key, elt => (IEnumerable<string>)elt);
|
||||
|
||||
if (submit.Attributes.Contains("name"))
|
||||
inputs.Add(submit.GetAttributeValue("name", ""), new[] {submit.GetAttributeValue("value", "yes")});
|
||||
|
||||
Details = Host.SendRequest(urlPath, inputs);
|
||||
_doc = new HtmlDocument();
|
||||
_doc.Load(new StringReader(Details.ResponseText));
|
||||
@@ -221,7 +224,7 @@ namespace Orchard.Specs.Bindings {
|
||||
|
||||
[Then(@"I should see ""(.*)""")]
|
||||
public void ThenIShouldSee(string text) {
|
||||
Assert.That(Details.ResponseText, Is.StringContaining(text));
|
||||
Assert.That(Details.ResponseText, Is.StringMatching(text));
|
||||
}
|
||||
|
||||
[Then(@"I should not see ""(.*)""")]
|
||||
|
94
src/Orchard.Specs/Blogs.feature
Normal file
94
src/Orchard.Specs/Blogs.feature
Normal file
@@ -0,0 +1,94 @@
|
||||
Feature: Blog management
|
||||
In order to add blogs to my site
|
||||
As an author
|
||||
I want to create blogs and create, publish and edit blog posts
|
||||
|
||||
Scenario: In the admin (menu) there is a link to create a Blog
|
||||
Given I have installed Orchard
|
||||
When I go to "admin"
|
||||
Then I should see "<a href="/Admin/Blogs/Create">Blogs</a>"
|
||||
|
||||
Scenario: I can create a new blog and blog post
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/blogs/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Blog |
|
||||
And I hit "Save"
|
||||
And I go to "my-blog"
|
||||
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
|
||||
When I go to "admin/blogs/my-blog/posts/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
| Body.Text | Hi there. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "my-blog/my-post"
|
||||
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
|
||||
And I should see "Hi there."
|
||||
|
||||
Scenario: I can create a new blog with multiple blog posts each with the same title and unique slugs are generated or given for said posts
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/blogs/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Blog |
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs/my-blog/posts/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
| Body.Text | Hi there. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "my-blog/my-post"
|
||||
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
|
||||
And I should see "Hi there."
|
||||
When I go to "admin/blogs/my-blog/posts/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
| Body.Text | Hi there, again. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "my-blog/my-post-2"
|
||||
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
|
||||
And I should see "Hi there, again."
|
||||
When I go to "admin/blogs/my-blog/posts/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
| Routable.Slug | my-post |
|
||||
| Body.Text | Are you still there? |
|
||||
And I hit "Publish Now"
|
||||
And I go to "my-blog/my-post-3"
|
||||
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
|
||||
And I should see "Are you still there?"
|
||||
|
||||
Scenario: I can create a new blog and blog post and when I change the slug of the blog the path of the plog post is updated
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/blogs/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Blog |
|
||||
And I hit "Save"
|
||||
And I go to "my-blog"
|
||||
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
|
||||
When I go to "admin/blogs/my-blog/posts/create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
| Body.Text | Hi there. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "my-blog/my-post"
|
||||
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
|
||||
And I should see "Hi there."
|
||||
When I go to "admin/blogs/my-blog"
|
||||
And I follow "Blog Properties"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Slug | my-other-blog |
|
||||
And I hit "Save"
|
||||
And I go to "my-other-blog"
|
||||
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
|
||||
When I go to "my-other-blog/my-post"
|
||||
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
|
||||
And I should see "Hi there."
|
302
src/Orchard.Specs/Blogs.feature.cs
generated
Normal file
302
src/Orchard.Specs/Blogs.feature.cs
generated
Normal file
@@ -0,0 +1,302 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.4.0.0
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
#region Designer generated code
|
||||
namespace Orchard.Specs
|
||||
{
|
||||
using TechTalk.SpecFlow;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Blog management")]
|
||||
public partial class BlogManagementFeature
|
||||
{
|
||||
|
||||
private static TechTalk.SpecFlow.ITestRunner testRunner;
|
||||
|
||||
#line 1 "Blogs.feature"
|
||||
#line hidden
|
||||
|
||||
[NUnit.Framework.TestFixtureSetUpAttribute()]
|
||||
public virtual void FeatureSetup()
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Blog management", "In order to add blogs to my site\r\nAs an author\r\nI want to create blogs and create" +
|
||||
", publish and edit blog posts", GenerationTargetLanguage.CSharp, ((string[])(null)));
|
||||
testRunner.OnFeatureStart(featureInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestFixtureTearDownAttribute()]
|
||||
public virtual void FeatureTearDown()
|
||||
{
|
||||
testRunner.OnFeatureEnd();
|
||||
testRunner = null;
|
||||
}
|
||||
|
||||
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
|
||||
{
|
||||
testRunner.OnScenarioStart(scenarioInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.TearDownAttribute()]
|
||||
public virtual void ScenarioTearDown()
|
||||
{
|
||||
testRunner.OnScenarioEnd();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("In the admin (menu) there is a link to create a Blog")]
|
||||
public virtual void InTheAdminMenuThereIsALinkToCreateABlog()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("In the admin (menu) there is a link to create a Blog", ((string[])(null)));
|
||||
#line 6
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 7
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 8
|
||||
testRunner.When("I go to \"admin\"");
|
||||
#line 9
|
||||
testRunner.Then("I should see \"<a href=\"/Admin/Blogs/Create\">Blogs</a>\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can create a new blog and blog post")]
|
||||
public virtual void ICanCreateANewBlogAndBlogPost()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new blog and blog post", ((string[])(null)));
|
||||
#line 11
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 12
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 13
|
||||
testRunner.When("I go to \"admin/blogs/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table1.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Blog"});
|
||||
#line 14
|
||||
testRunner.And("I fill in", ((string)(null)), table1);
|
||||
#line 17
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 18
|
||||
testRunner.And("I go to \"my-blog\"");
|
||||
#line 19
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
|
||||
#line 20
|
||||
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table2.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Post"});
|
||||
table2.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"Hi there."});
|
||||
#line 21
|
||||
testRunner.And("I fill in", ((string)(null)), table2);
|
||||
#line 25
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 26
|
||||
testRunner.And("I go to \"my-blog/my-post\"");
|
||||
#line 27
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
|
||||
#line 28
|
||||
testRunner.And("I should see \"Hi there.\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can create a new blog with multiple blog posts each with the same title and uni" +
|
||||
"que slugs are generated or given for said posts")]
|
||||
public virtual void ICanCreateANewBlogWithMultipleBlogPostsEachWithTheSameTitleAndUniqueSlugsAreGeneratedOrGivenForSaidPosts()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new blog with multiple blog posts each with the same title and uni" +
|
||||
"que slugs are generated or given for said posts", ((string[])(null)));
|
||||
#line 30
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 31
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 32
|
||||
testRunner.When("I go to \"admin/blogs/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table3.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Blog"});
|
||||
#line 33
|
||||
testRunner.And("I fill in", ((string)(null)), table3);
|
||||
#line 36
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 37
|
||||
testRunner.And("I go to \"admin/blogs/my-blog/posts/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table4.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Post"});
|
||||
table4.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"Hi there."});
|
||||
#line 38
|
||||
testRunner.And("I fill in", ((string)(null)), table4);
|
||||
#line 42
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 43
|
||||
testRunner.And("I go to \"my-blog/my-post\"");
|
||||
#line 44
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
|
||||
#line 45
|
||||
testRunner.And("I should see \"Hi there.\"");
|
||||
#line 46
|
||||
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table5.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Post"});
|
||||
table5.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"Hi there, again."});
|
||||
#line 47
|
||||
testRunner.And("I fill in", ((string)(null)), table5);
|
||||
#line 51
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 52
|
||||
testRunner.And("I go to \"my-blog/my-post-2\"");
|
||||
#line 53
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
|
||||
#line 54
|
||||
testRunner.And("I should see \"Hi there, again.\"");
|
||||
#line 55
|
||||
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table6.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Post"});
|
||||
table6.AddRow(new string[] {
|
||||
"Routable.Slug",
|
||||
"my-post"});
|
||||
table6.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"Are you still there?"});
|
||||
#line 56
|
||||
testRunner.And("I fill in", ((string)(null)), table6);
|
||||
#line 61
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 62
|
||||
testRunner.And("I go to \"my-blog/my-post-3\"");
|
||||
#line 63
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
|
||||
#line 64
|
||||
testRunner.And("I should see \"Are you still there?\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can create a new blog and blog post and when I change the slug of the blog the " +
|
||||
"path of the plog post is updated")]
|
||||
public virtual void ICanCreateANewBlogAndBlogPostAndWhenIChangeTheSlugOfTheBlogThePathOfThePlogPostIsUpdated()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new blog and blog post and when I change the slug of the blog the " +
|
||||
"path of the plog post is updated", ((string[])(null)));
|
||||
#line 66
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 67
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 68
|
||||
testRunner.When("I go to \"admin/blogs/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table7 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table7.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Blog"});
|
||||
#line 69
|
||||
testRunner.And("I fill in", ((string)(null)), table7);
|
||||
#line 72
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 73
|
||||
testRunner.And("I go to \"my-blog\"");
|
||||
#line 74
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
|
||||
#line 75
|
||||
testRunner.When("I go to \"admin/blogs/my-blog/posts/create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table8.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"My Post"});
|
||||
table8.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"Hi there."});
|
||||
#line 76
|
||||
testRunner.And("I fill in", ((string)(null)), table8);
|
||||
#line 80
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 81
|
||||
testRunner.And("I go to \"my-blog/my-post\"");
|
||||
#line 82
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
|
||||
#line 83
|
||||
testRunner.And("I should see \"Hi there.\"");
|
||||
#line 84
|
||||
testRunner.When("I go to \"admin/blogs/my-blog\"");
|
||||
#line 85
|
||||
testRunner.And("I follow \"Blog Properties\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table9 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table9.AddRow(new string[] {
|
||||
"Routable.Slug",
|
||||
"my-other-blog"});
|
||||
#line 86
|
||||
testRunner.And("I fill in", ((string)(null)), table9);
|
||||
#line 89
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 90
|
||||
testRunner.And("I go to \"my-other-blog\"");
|
||||
#line 91
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
|
||||
#line 92
|
||||
testRunner.When("I go to \"my-other-blog/my-post\"");
|
||||
#line 93
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
|
||||
#line 94
|
||||
testRunner.And("I should see \"Hi there.\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
@@ -69,9 +69,10 @@ namespace Orchard.Specs.Hosting {
|
||||
var targetModule = _tempSite.Combine(extensionFolder).Combine(extensionName);
|
||||
|
||||
sourceModule.ShallowCopy("*.txt", targetModule);
|
||||
sourceModule.ShallowCopy("*.info", targetModule);
|
||||
|
||||
//sourceModule.ShallowCopy("*.csproj", targetModule);
|
||||
//sourceModule.DeepCopy("*.cs", targetModule);
|
||||
//sourceModule.DeepCopy("*.cs", targetModule);)
|
||||
|
||||
if (sourceModule.Combine("bin").IsDirectory) {
|
||||
sourceModule.Combine("bin").ShallowCopy("*.dll", targetModule.Combine("bin"));
|
||||
|
@@ -127,6 +127,11 @@
|
||||
<Compile Include="Bindings\CommandLine.cs" />
|
||||
<Compile Include="Bindings\ContentRights.cs" />
|
||||
<Compile Include="Bindings\OrchardSiteFactory.cs" />
|
||||
<Compile Include="Blogs.feature.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Blogs.feature</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ContentRights.feature.cs">
|
||||
<DependentUpon>ContentRights.feature</DependentUpon>
|
||||
<AutoGen>True</AutoGen>
|
||||
@@ -154,6 +159,11 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>MultiTenancy.feature</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Pages.feature.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Pages.feature</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Util\PathExtensions.cs" />
|
||||
<Compile Include="WebHosting.feature.cs">
|
||||
<DependentUpon>WebHosting.feature</DependentUpon>
|
||||
@@ -195,6 +205,10 @@
|
||||
<Content Include="Hosting\Orchard.Web\Config\Sites.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Blogs.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Blogs.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="ContentRights.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ContentRights.feature.cs</LastGenOutput>
|
||||
@@ -220,6 +234,10 @@
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>MultiTenancy.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Pages.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Pages.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="WebHosting.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>WebHosting.feature.cs</LastGenOutput>
|
||||
|
42
src/Orchard.Specs/Pages.feature
Normal file
42
src/Orchard.Specs/Pages.feature
Normal file
@@ -0,0 +1,42 @@
|
||||
Feature: Content Page management
|
||||
In order to add content pages to my site
|
||||
As an author
|
||||
I want to create, publish and edit pages
|
||||
|
||||
Scenario: In the admin (menu) there is a link to create a Page
|
||||
Given I have installed Orchard
|
||||
When I go to "admin"
|
||||
Then I should see "<a href="/Admin/Contents/Create/Page">Page</a>"
|
||||
|
||||
Scenario: I can create and publish a new Page
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/contents/create/page"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | Super Duper |
|
||||
| Body.Text | This is super. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "super-duper"
|
||||
Then I should see "<h1[^>]*>.*?Super Duper.*?</h1>"
|
||||
And I should see "This is super."
|
||||
|
||||
Scenario: If I create a page which gets a conflicting path generated its path is made to be unique
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/contents/create/page"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | Super Duper |
|
||||
| Body.Text | This is super. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "super-duper"
|
||||
Then I should see "<h1[^>]*>.*?Super Duper.*?</h1>"
|
||||
And I should see "This is super."
|
||||
When I go to "admin/contents/create/page"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | Super Duper |
|
||||
| Body.Text | This is super number two. |
|
||||
And I hit "Publish Now"
|
||||
And I go to "super-duper-2"
|
||||
Then I should see "<h1[^>]*>.*?Super Duper.*?</h1>"
|
||||
And I should see "This is super number two."
|
168
src/Orchard.Specs/Pages.feature.cs
generated
Normal file
168
src/Orchard.Specs/Pages.feature.cs
generated
Normal file
@@ -0,0 +1,168 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.4.0.0
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
#region Designer generated code
|
||||
namespace Orchard.Specs
|
||||
{
|
||||
using TechTalk.SpecFlow;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Content Page management")]
|
||||
public partial class ContentPageManagementFeature
|
||||
{
|
||||
|
||||
private static TechTalk.SpecFlow.ITestRunner testRunner;
|
||||
|
||||
#line 1 "Pages.feature"
|
||||
#line hidden
|
||||
|
||||
[NUnit.Framework.TestFixtureSetUpAttribute()]
|
||||
public virtual void FeatureSetup()
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Content Page management", "In order to add content pages to my site\r\nAs an author\r\nI want to create, publish" +
|
||||
" and edit pages", GenerationTargetLanguage.CSharp, ((string[])(null)));
|
||||
testRunner.OnFeatureStart(featureInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestFixtureTearDownAttribute()]
|
||||
public virtual void FeatureTearDown()
|
||||
{
|
||||
testRunner.OnFeatureEnd();
|
||||
testRunner = null;
|
||||
}
|
||||
|
||||
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
|
||||
{
|
||||
testRunner.OnScenarioStart(scenarioInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.TearDownAttribute()]
|
||||
public virtual void ScenarioTearDown()
|
||||
{
|
||||
testRunner.OnScenarioEnd();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("In the admin (menu) there is a link to create a Page")]
|
||||
public virtual void InTheAdminMenuThereIsALinkToCreateAPage()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("In the admin (menu) there is a link to create a Page", ((string[])(null)));
|
||||
#line 6
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 7
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 8
|
||||
testRunner.When("I go to \"admin\"");
|
||||
#line 9
|
||||
testRunner.Then("I should see \"<a href=\"/Admin/Contents/Create/Page\">Page</a>\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can create and publish a new Page")]
|
||||
public virtual void ICanCreateAndPublishANewPage()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create and publish a new Page", ((string[])(null)));
|
||||
#line 11
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 12
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 13
|
||||
testRunner.When("I go to \"admin/contents/create/page\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table1.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"Super Duper"});
|
||||
table1.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"This is super."});
|
||||
#line 14
|
||||
testRunner.And("I fill in", ((string)(null)), table1);
|
||||
#line 18
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 19
|
||||
testRunner.And("I go to \"super-duper\"");
|
||||
#line 20
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
|
||||
#line 21
|
||||
testRunner.And("I should see \"This is super.\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("If I create a page which gets a conflicting path generated its path is made to be" +
|
||||
" unique")]
|
||||
public virtual void IfICreateAPageWhichGetsAConflictingPathGeneratedItsPathIsMadeToBeUnique()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("If I create a page which gets a conflicting path generated its path is made to be" +
|
||||
" unique", ((string[])(null)));
|
||||
#line 23
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 24
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 25
|
||||
testRunner.When("I go to \"admin/contents/create/page\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table2.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"Super Duper"});
|
||||
table2.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"This is super."});
|
||||
#line 26
|
||||
testRunner.And("I fill in", ((string)(null)), table2);
|
||||
#line 30
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 31
|
||||
testRunner.And("I go to \"super-duper\"");
|
||||
#line 32
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
|
||||
#line 33
|
||||
testRunner.And("I should see \"This is super.\"");
|
||||
#line 34
|
||||
testRunner.When("I go to \"admin/contents/create/page\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table3.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"Super Duper"});
|
||||
table3.AddRow(new string[] {
|
||||
"Body.Text",
|
||||
"This is super number two."});
|
||||
#line 35
|
||||
testRunner.And("I fill in", ((string)(null)), table3);
|
||||
#line 39
|
||||
testRunner.And("I hit \"Publish Now\"");
|
||||
#line 40
|
||||
testRunner.And("I go to \"super-duper-2\"");
|
||||
#line 41
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
|
||||
#line 42
|
||||
testRunner.And("I should see \"This is super number two.\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
@@ -6,7 +6,7 @@ Feature: Setup
|
||||
Scenario: Root request shows setup form
|
||||
Given I have a clean site with
|
||||
| extension | names |
|
||||
| module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
|
||||
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
|
||||
| core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
|
||||
| theme | SafeMode |
|
||||
When I go to "/Default.aspx"
|
||||
@@ -17,7 +17,7 @@ Scenario: Root request shows setup form
|
||||
Scenario: Setup folder also shows setup form
|
||||
Given I have a clean site with
|
||||
| extension | names |
|
||||
| module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
|
||||
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
|
||||
| core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
|
||||
| theme | SafeMode |
|
||||
When I go to "/Setup"
|
||||
@@ -28,7 +28,7 @@ Scenario: Setup folder also shows setup form
|
||||
Scenario: Some of the initial form values are required
|
||||
Given I have a clean site with
|
||||
| extension | names |
|
||||
| module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
|
||||
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce |
|
||||
| core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
|
||||
| theme | SafeMode |
|
||||
When I go to "/Setup"
|
||||
@@ -39,7 +39,7 @@ Scenario: Some of the initial form values are required
|
||||
Scenario: Calling setup on a brand new install
|
||||
Given I have a clean site with
|
||||
| extension | names |
|
||||
| module | Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce |
|
||||
| module | Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLater, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce |
|
||||
| core | Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Scheduling, Settings, Shapes, XmlRpc |
|
||||
| theme | SafeMode, TheThemeMachine |
|
||||
And I am on "/Setup"
|
||||
|
67
src/Orchard.Specs/Setup.feature.cs
generated
67
src/Orchard.Specs/Setup.feature.cs
generated
@@ -1,7 +1,7 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.3.2.0
|
||||
// SpecFlow Version:1.4.0.0
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
@@ -14,7 +14,7 @@ namespace Orchard.Specs
|
||||
using TechTalk.SpecFlow;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.3.2.0")]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Setup")]
|
||||
@@ -31,7 +31,7 @@ namespace Orchard.Specs
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Setup", "In order to install orchard\r\nAs a new user\r\nI want to setup a new site from the d" +
|
||||
"efault screen", ((string[])(null)));
|
||||
"efault screen", GenerationTargetLanguage.CSharp, ((string[])(null)));
|
||||
testRunner.OnFeatureStart(featureInfo);
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"names"});
|
||||
table1.AddRow(new string[] {
|
||||
"module",
|
||||
"Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" +
|
||||
"er, Orchard.Themes, Orchard.jQuery, TinyMce"});
|
||||
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orc" +
|
||||
"hard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce"});
|
||||
table1.AddRow(new string[] {
|
||||
"core",
|
||||
"Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" +
|
||||
@@ -76,15 +76,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"theme",
|
||||
"SafeMode"});
|
||||
#line 7
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table1);
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table1);
|
||||
#line 12
|
||||
testRunner.When("I go to \"/Default.aspx\"");
|
||||
testRunner.When("I go to \"/Default.aspx\"");
|
||||
#line 13
|
||||
testRunner.Then("I should see \"Welcome to Orchard\"");
|
||||
testRunner.Then("I should see \"Welcome to Orchard\"");
|
||||
#line 14
|
||||
testRunner.And("I should see \"Finish Setup\"");
|
||||
testRunner.And("I should see \"Finish Setup\"");
|
||||
#line 15
|
||||
testRunner.And("the status should be 200 \"OK\"");
|
||||
testRunner.And("the status should be 200 \"OK\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
@@ -102,8 +102,8 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"names"});
|
||||
table2.AddRow(new string[] {
|
||||
"module",
|
||||
"Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" +
|
||||
"er, Orchard.Themes, Orchard.jQuery, TinyMce"});
|
||||
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orc" +
|
||||
"hard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce"});
|
||||
table2.AddRow(new string[] {
|
||||
"core",
|
||||
"Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" +
|
||||
@@ -112,15 +112,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"theme",
|
||||
"SafeMode"});
|
||||
#line 18
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table2);
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table2);
|
||||
#line 23
|
||||
testRunner.When("I go to \"/Setup\"");
|
||||
testRunner.When("I go to \"/Setup\"");
|
||||
#line 24
|
||||
testRunner.Then("I should see \"Welcome to Orchard\"");
|
||||
testRunner.Then("I should see \"Welcome to Orchard\"");
|
||||
#line 25
|
||||
testRunner.And("I should see \"Finish Setup\"");
|
||||
testRunner.And("I should see \"Finish Setup\"");
|
||||
#line 26
|
||||
testRunner.And("the status should be 200 \"OK\"");
|
||||
testRunner.And("the status should be 200 \"OK\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
@@ -138,8 +138,8 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"names"});
|
||||
table3.AddRow(new string[] {
|
||||
"module",
|
||||
"Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" +
|
||||
"er, Orchard.Themes, Orchard.jQuery, TinyMce"});
|
||||
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orc" +
|
||||
"hard.PublishLater, Orchard.Themes, Orchard.jQuery, TinyMce"});
|
||||
table3.AddRow(new string[] {
|
||||
"core",
|
||||
"Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" +
|
||||
@@ -148,16 +148,16 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"theme",
|
||||
"SafeMode"});
|
||||
#line 29
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table3);
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table3);
|
||||
#line 34
|
||||
testRunner.When("I go to \"/Setup\"");
|
||||
testRunner.When("I go to \"/Setup\"");
|
||||
#line 35
|
||||
testRunner.And("I hit \"Finish Setup\"");
|
||||
testRunner.And("I hit \"Finish Setup\"");
|
||||
#line 36
|
||||
testRunner.Then("I should see \"<input autofocus=\"autofocus\" class=\"input-validation-error\" id=\"Sit" +
|
||||
testRunner.Then("I should see \"<input autofocus=\"autofocus\" class=\"input-validation-error\" id=\"Sit" +
|
||||
"eName\" name=\"SiteName\" type=\"text\" value=\"\" />\"");
|
||||
#line 37
|
||||
testRunner.And("I should see \"<input class=\"input-validation-error\" id=\"AdminPassword\" name=\"Admi" +
|
||||
testRunner.And("I should see \"<input class=\"input-validation-error\" id=\"AdminPassword\" name=\"Admi" +
|
||||
"nPassword\" type=\"password\" />\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
@@ -176,8 +176,9 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"names"});
|
||||
table4.AddRow(new string[] {
|
||||
"module",
|
||||
"Orchard.Setup, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.PublishLat" +
|
||||
"er, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQuery, TinyMce"});
|
||||
"Orchard.Setup, Orchard.Pages, Orchard.Users, Orchard.Roles, Orchard.Comments, Orc" +
|
||||
"hard.PublishLater, Orchard.Themes, Orchard.Modules, Orchard.Widgets, Orchard.jQu" +
|
||||
"ery, TinyMce"});
|
||||
table4.AddRow(new string[] {
|
||||
"core",
|
||||
"Common, Contents, Dashboard, Feeds, HomePage, Messaging, Navigation, Routable, Sc" +
|
||||
@@ -186,9 +187,9 @@ this.ScenarioSetup(scenarioInfo);
|
||||
"theme",
|
||||
"SafeMode, TheThemeMachine"});
|
||||
#line 40
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table4);
|
||||
testRunner.Given("I have a clean site with", ((string)(null)), table4);
|
||||
#line 45
|
||||
testRunner.And("I am on \"/Setup\"");
|
||||
testRunner.And("I am on \"/Setup\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -203,15 +204,15 @@ testRunner.And("I am on \"/Setup\"");
|
||||
"ConfirmPassword",
|
||||
"6655321"});
|
||||
#line 46
|
||||
testRunner.When("I fill in", ((string)(null)), table5);
|
||||
testRunner.When("I fill in", ((string)(null)), table5);
|
||||
#line 51
|
||||
testRunner.And("I hit \"Finish Setup\"");
|
||||
testRunner.And("I hit \"Finish Setup\"");
|
||||
#line 52
|
||||
testRunner.And("I go to \"/Default.aspx\"");
|
||||
testRunner.And("I go to \"/Default.aspx\"");
|
||||
#line 53
|
||||
testRunner.Then("I should see \"My Site\"");
|
||||
testRunner.Then("I should see \"My Site\"");
|
||||
#line 54
|
||||
testRunner.And("I should see \"Welcome, <strong>admin</strong>!\"");
|
||||
testRunner.And("I should see \"Welcome, <strong>admin</strong>!\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
@@ -6,14 +6,21 @@ using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Containers.Models;
|
||||
using Orchard.Core.Containers.ViewModels;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Core.Routable.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Core.Containers.Drivers {
|
||||
public class ContainablePartDriver : ContentPartDriver<ContainablePart> {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IRoutableService _routableService;
|
||||
private readonly IOrchardServices _services;
|
||||
|
||||
public ContainablePartDriver(IContentManager contentManager) {
|
||||
public ContainablePartDriver(IContentManager contentManager, IRoutableService routableService, IOrchardServices services) {
|
||||
_contentManager = contentManager;
|
||||
_routableService = routableService;
|
||||
_services = services;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -37,9 +44,8 @@ namespace Orchard.Core.Containers.Drivers {
|
||||
if (updater != null) {
|
||||
var oldContainerId = model.ContainerId;
|
||||
updater.TryUpdateModel(model, "Containable", null, null);
|
||||
if (oldContainerId != model.ContainerId) {
|
||||
if (oldContainerId != model.ContainerId)
|
||||
commonPart.Container = _contentManager.Get(model.ContainerId, VersionOptions.Latest);
|
||||
}
|
||||
}
|
||||
|
||||
var containers = _contentManager.Query<ContainerPart, ContainerPartRecord>(VersionOptions.Latest).List();
|
||||
|
@@ -213,10 +213,7 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
if (!Services.Authorizer.Authorize(Permissions.PublishContent, contentItem, T("Couldn't create content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var isDraftable = contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable;
|
||||
_contentManager.Create(
|
||||
contentItem,
|
||||
isDraftable ? VersionOptions.Draft : VersionOptions.Published);
|
||||
_contentManager.Create(contentItem, VersionOptions.Draft);
|
||||
|
||||
var model = _contentManager.UpdateEditor(contentItem, this);
|
||||
if (!ModelState.IsValid) {
|
||||
|
@@ -412,6 +412,8 @@
|
||||
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
|
||||
<Content Include="Containers\Views\Parts\ContainerWidget.cshtml" />
|
||||
<Content Include="Containers\Views\EditorTemplates\ContainerCustom.cshtml" />
|
||||
<Content Include="Routable\Views\Parts\RoutableTitle_Summary.cshtml" />
|
||||
<Content Include="Routable\Views\Parts\RoutableTitle_SummaryAdmin.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
|
@@ -4,6 +4,7 @@ using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Core.Routable.Services;
|
||||
using Orchard.Data;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Localization;
|
||||
@@ -62,7 +63,7 @@ namespace Orchard.Core.Routable.Controllers {
|
||||
contentItem = _contentManager.Get((int)id, VersionOptions.Latest);
|
||||
|
||||
if (contentItem == null) {
|
||||
contentItem = _contentManager.New(contentType);
|
||||
contentItem = _contentManager.Create(contentType, VersionOptions.Draft);
|
||||
|
||||
if (containerId != null) {
|
||||
var containerItem = _contentManager.Get((int)containerId);
|
||||
@@ -71,9 +72,10 @@ namespace Orchard.Core.Routable.Controllers {
|
||||
}
|
||||
|
||||
_contentManager.UpdateEditor(contentItem, this);
|
||||
_contentManager.Publish(contentItem);
|
||||
_transactionManager.Cancel();
|
||||
|
||||
return Json(contentItem.As<IRoutableAspect>().Slug ?? slug);
|
||||
return Json(contentItem.As<IRoutableAspect>().GetEffectiveSlug() ?? slug);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -20,7 +20,7 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
public RoutePartDriver(IOrchardServices services, IRoutableService routableService, IEnumerable<IHomePageProvider> homePageProviders) {
|
||||
_services = services;
|
||||
_routableService = routableService;
|
||||
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name); ;
|
||||
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,14 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Display(RoutePart part, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Parts_RoutableTitle",
|
||||
() => shapeHelper.Parts_RoutableTitle(ContentPart: part, Title: part.Title, Path: part.Path));
|
||||
return Combined(
|
||||
ContentShape("Parts_RoutableTitle",
|
||||
() => shapeHelper.Parts_RoutableTitle(ContentPart: part, Title: part.Title, Path: part.Path)),
|
||||
ContentShape("Parts_RoutableTitle_Summary",
|
||||
() => shapeHelper.Parts_RoutableTitle_Summary(ContentPart: part, Title: part.Title, Path: part.Path)),
|
||||
ContentShape("Parts_RoutableTitle_SummaryAdmin",
|
||||
() => shapeHelper.Parts_RoutableTitle_SummaryAdmin(ContentPart: part, Title: part.Title, Path: part.Path))
|
||||
);
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(RoutePart part, dynamic shapeHelper) {
|
||||
@@ -54,18 +60,10 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
ContainerId = GetContainerId(part),
|
||||
};
|
||||
|
||||
// TEMP: path format patterns replaces this logic
|
||||
var path = part.Path;
|
||||
var slug = part.Slug ?? "";
|
||||
if (path != null && path.EndsWith(slug)) {
|
||||
model.DisplayLeadingPath = path.Substring(0, path.Length - slug.Length);
|
||||
}
|
||||
else {
|
||||
var containerPath = part.GetContainerPath();
|
||||
model.DisplayLeadingPath = !string.IsNullOrWhiteSpace(containerPath)
|
||||
? string.Format("{0}/", containerPath)
|
||||
: "";
|
||||
}
|
||||
var containerPath = part.GetContainerPath();
|
||||
model.DisplayLeadingPath = !string.IsNullOrWhiteSpace(containerPath)
|
||||
? string.Format("{0}/", containerPath)
|
||||
: "";
|
||||
|
||||
model.PromoteToHomePage = model.Id != 0 && part.Path != null && _routableHomePageProvider != null && _services.WorkContext.CurrentSite.HomePage == _routableHomePageProvider.GetSettingValue(model.Id);
|
||||
return ContentShape("Parts_Routable_Edit",
|
||||
@@ -73,34 +71,22 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(RoutePart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
|
||||
var model = new RoutableEditorViewModel();
|
||||
updater.TryUpdateModel(model, Prefix, null, null);
|
||||
|
||||
part.Title = model.Title;
|
||||
part.Slug = model.Slug;
|
||||
|
||||
if ( !_routableService.IsSlugValid(part.Slug) ) {
|
||||
var slug = (part.Slug ?? String.Empty);
|
||||
if ( slug.StartsWith(".") || slug.EndsWith(".") ) {
|
||||
if ( slug.StartsWith(".") || slug.EndsWith(".") )
|
||||
updater.AddModelError("Routable.Slug", T("The \".\" can't be used around routes."));
|
||||
}
|
||||
else {
|
||||
else
|
||||
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead)."));
|
||||
}
|
||||
}
|
||||
|
||||
string originalSlug = part.Slug;
|
||||
if (!_routableService.ProcessSlug(part)) {
|
||||
_services.Notifier.Warning(T("Slugs in conflict. \"{0}\" is already set for a previously created {2} so now it has the slug \"{1}\"",
|
||||
originalSlug, part.Slug, part.ContentItem.ContentType));
|
||||
}
|
||||
|
||||
// TEMP: path format patterns replaces this logic
|
||||
part.Path = part.GetPathWithSlug(part.Slug);
|
||||
|
||||
if (part.ContentItem.Id != 0 && model.PromoteToHomePage && _routableHomePageProvider != null) {
|
||||
if (part.ContentItem.Id != 0 && model.PromoteToHomePage && _routableHomePageProvider != null)
|
||||
_services.WorkContext.CurrentSite.HomePage = _routableHomePageProvider.GetSettingValue(part.ContentItem.Id);
|
||||
}
|
||||
|
||||
return Editor(part, shapeHelper);
|
||||
}
|
||||
|
@@ -24,25 +24,36 @@ namespace Orchard.Core.Routable.Handlers {
|
||||
|
||||
Action<RoutePart> processSlug = (
|
||||
routable => {
|
||||
var originalSlug = routable.Slug;
|
||||
if (!_routableService.ProcessSlug(routable)) {
|
||||
if (!_routableService.ProcessSlug(routable))
|
||||
_services.Notifier.Warning(T("Slugs in conflict. \"{0}\" is already set for a previously created {2} so now it has the slug \"{1}\"",
|
||||
originalSlug, routable.Slug, routable.ContentItem.ContentType));
|
||||
}
|
||||
|
||||
// TEMP: path format patterns replaces this logic
|
||||
routable.Path = routable.GetPathWithSlug(routable.Slug);
|
||||
routable.Slug, routable.GetEffectiveSlug(), routable.ContentItem.ContentType));
|
||||
});
|
||||
|
||||
OnGetDisplayShape<RoutePart>(SetModelProperties);
|
||||
OnGetEditorShape<RoutePart>(SetModelProperties);
|
||||
OnUpdateEditorShape<RoutePart>(SetModelProperties);
|
||||
|
||||
OnPublished<RoutePart>((context, routable) => {
|
||||
OnPublished<RoutePart>((context, route) => {
|
||||
var path = route.Path;
|
||||
route.Path = route.GetPathWithSlug(route.Slug);
|
||||
|
||||
if (context.PublishingItemVersionRecord != null)
|
||||
processSlug(routable);
|
||||
if (!string.IsNullOrEmpty(routable.Path))
|
||||
_routablePathConstraint.AddPath(routable.Path);
|
||||
processSlug(route);
|
||||
|
||||
// if the path has changed by having the slug changed on the way in (e.g. user input) or to avoid conflict
|
||||
// then update and publish all contained items
|
||||
if (path != route.Path) {
|
||||
_routablePathConstraint.RemovePath(path);
|
||||
_routableService.FixContainedPaths(route);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(route.Path))
|
||||
_routablePathConstraint.AddPath(route.Path);
|
||||
});
|
||||
|
||||
OnRemoved<RoutePart>((context, route) => {
|
||||
if (!string.IsNullOrWhiteSpace(route.Path))
|
||||
_routablePathConstraint.RemovePath(route.Path);
|
||||
});
|
||||
|
||||
OnIndexing<RoutePart>((context, part) => context.DocumentIndex.Add("title", part.Record.Title).RemoveTags().Analyze());
|
||||
|
@@ -17,25 +17,5 @@ namespace Orchard.Core.Routable.Models {
|
||||
get { return Record.Path; }
|
||||
set { Record.Path = value; }
|
||||
}
|
||||
|
||||
public string GetContainerPath() {
|
||||
var commonAspect = this.As<ICommonPart>();
|
||||
if (commonAspect != null && commonAspect.Container != null) {
|
||||
var routable = commonAspect.Container.As<IRoutableAspect>();
|
||||
if (routable != null) {
|
||||
return routable.Path;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetPathWithSlug(string slug) {
|
||||
// TEMP: path format patterns replaces this logic
|
||||
var containerPath = GetContainerPath();
|
||||
if (string.IsNullOrEmpty(containerPath)) {
|
||||
return slug;
|
||||
}
|
||||
return containerPath + "/" + slug;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +1,15 @@
|
||||
<Placement>
|
||||
<!-- available display shapes -->
|
||||
<!--
|
||||
Parts_RoutableTitle
|
||||
Parts_RoutableTitle_Summary
|
||||
Parts_RoutableTitle_SummaryAdmin
|
||||
-->
|
||||
<Place Parts_Routable_Edit="Content:before.5"/>
|
||||
<Match DisplayType="Detail">
|
||||
<Place Parts_RoutableTitle="Header:5"/>
|
||||
</Match>
|
||||
<Match DisplayType="Summary">
|
||||
<Place Parts_RoutableTitle="Header:5"/>
|
||||
<Place Parts_RoutableTitle_Summary="Header:5"/>
|
||||
</Match>
|
||||
</Placement>
|
@@ -1,16 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
|
||||
namespace Orchard.Core.Routable.Services {
|
||||
public interface IRoutableService : IDependency {
|
||||
void FillSlugFromTitle<TModel>(TModel model) where TModel : RoutePart;
|
||||
string GenerateUniqueSlug(RoutePart part, IEnumerable<string> existingPaths);
|
||||
void FillSlugFromTitle<TModel>(TModel model) where TModel : IRoutableAspect;
|
||||
string GenerateUniqueSlug(IRoutableAspect part, IEnumerable<string> existingPaths);
|
||||
|
||||
/// <summary>
|
||||
/// Returns any content item with similar path
|
||||
/// </summary>
|
||||
IEnumerable<RoutePart> GetSimilarPaths(string path);
|
||||
IEnumerable<IRoutableAspect> GetSimilarPaths(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Validates the given slug
|
||||
@@ -21,7 +20,11 @@ namespace Orchard.Core.Routable.Services {
|
||||
/// Defines the slug of a RoutableAspect and validate its unicity
|
||||
/// </summary>
|
||||
/// <returns>True if the slug has been created, False if a conflict occured</returns>
|
||||
bool ProcessSlug(RoutePart part);
|
||||
bool ProcessSlug(IRoutableAspect part);
|
||||
|
||||
/// <summary>
|
||||
/// Updated the paths of all contained items to reflect the current path of this item
|
||||
/// </summary>
|
||||
void FixContainedPaths(IRoutableAspect part);
|
||||
}
|
||||
}
|
@@ -45,7 +45,8 @@ namespace Orchard.Core.Routable.Services {
|
||||
|
||||
public void RemovePath(string path) {
|
||||
lock (_syncLock) {
|
||||
_paths.Remove(path);
|
||||
if (path != null && _paths.ContainsKey(path))
|
||||
_paths.Remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Routable.Models;
|
||||
|
||||
namespace Orchard.Core.Routable.Services {
|
||||
@@ -13,7 +15,19 @@ namespace Orchard.Core.Routable.Services {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public void FillSlugFromTitle<TModel>(TModel model) where TModel : RoutePart {
|
||||
public void FixContainedPaths(IRoutableAspect part) {
|
||||
var items = _contentManager.Query(VersionOptions.Published)
|
||||
.Join<CommonPartRecord>().Where(cr => cr.Container.Id == part.Id)
|
||||
.List()
|
||||
.Select(item => item.As<IRoutableAspect>()).Where(item => item != null);
|
||||
|
||||
foreach (var itemRoute in items) {
|
||||
itemRoute.ContentItem.VersionRecord.Published = false; // <- to force a republish
|
||||
_contentManager.Publish(itemRoute.ContentItem);
|
||||
}
|
||||
}
|
||||
|
||||
public void FillSlugFromTitle<TModel>(TModel model) where TModel : IRoutableAspect {
|
||||
if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title))
|
||||
return;
|
||||
|
||||
@@ -32,21 +46,20 @@ namespace Orchard.Core.Routable.Services {
|
||||
model.Slug = slug.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public string GenerateUniqueSlug(RoutePart part, IEnumerable<string> existingPaths) {
|
||||
var slugCandidate = part.Slug;
|
||||
public string GenerateUniqueSlug(IRoutableAspect part, IEnumerable<string> existingPaths) {
|
||||
if (existingPaths == null || !existingPaths.Contains(part.Path))
|
||||
return slugCandidate;
|
||||
return part.Slug;
|
||||
|
||||
int? version = existingPaths.Select(s => GetSlugVersion(slugCandidate, s)).OrderBy(i => i).LastOrDefault();
|
||||
int? version = existingPaths.Select(s => GetSlugVersion(part.Path, s)).OrderBy(i => i).LastOrDefault();
|
||||
|
||||
return version != null
|
||||
? string.Format("{0}-{1}", slugCandidate, version)
|
||||
: slugCandidate;
|
||||
? string.Format("{0}-{1}", part.Slug, version)
|
||||
: part.Slug;
|
||||
}
|
||||
|
||||
private static int? GetSlugVersion(string slugCandidate, string slug) {
|
||||
private static int? GetSlugVersion(string path, string potentialConflictingPath) {
|
||||
int v;
|
||||
string[] slugParts = slug.Split(new []{slugCandidate}, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] slugParts = potentialConflictingPath.Split(new[] { path }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (slugParts.Length == 0)
|
||||
return 2;
|
||||
@@ -56,12 +69,12 @@ namespace Orchard.Core.Routable.Services {
|
||||
: null;
|
||||
}
|
||||
|
||||
public IEnumerable<RoutePart> GetSimilarPaths(string path) {
|
||||
public IEnumerable<IRoutableAspect> GetSimilarPaths(string path) {
|
||||
return
|
||||
_contentManager.Query().Join<RoutePartRecord>()
|
||||
.List()
|
||||
.Select(i => i.As<RoutePart>())
|
||||
.Where(routable => routable.Path != null && routable.Path.StartsWith(path, StringComparison.OrdinalIgnoreCase)) // todo: for some reason the filter doesn't work within the query, even without StringComparison or StartsWith
|
||||
.Where(routable => routable.Path != null && routable.Path.StartsWith(path, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
@@ -69,7 +82,7 @@ namespace Orchard.Core.Routable.Services {
|
||||
return String.IsNullOrWhiteSpace(slug) || Regex.IsMatch(slug, @"^[^:?#\[\]@!$&'()*+,;=\s]+$") && !(slug.StartsWith(".") || slug.EndsWith("."));
|
||||
}
|
||||
|
||||
public bool ProcessSlug(RoutePart part) {
|
||||
public bool ProcessSlug(IRoutableAspect part) {
|
||||
FillSlugFromTitle(part);
|
||||
|
||||
if (string.IsNullOrEmpty(part.Slug))
|
||||
@@ -84,15 +97,48 @@ namespace Orchard.Core.Routable.Services {
|
||||
|
||||
if (pathsLikeThis.Count() > 0) {
|
||||
var originalSlug = part.Slug;
|
||||
//todo: (heskew) make auto-uniqueness optional
|
||||
part.Slug = GenerateUniqueSlug(part, pathsLikeThis.Select(p => p.Path));
|
||||
var newSlug = GenerateUniqueSlug(part, pathsLikeThis.Select(p => p.Path));
|
||||
part.Path = part.GetPathWithSlug(newSlug);
|
||||
part.Slug = newSlug;
|
||||
|
||||
if (originalSlug != part.Slug) {
|
||||
if (originalSlug != newSlug)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RoutableAspectExtensions {
|
||||
public static string GetContainerPath(this IRoutableAspect routableAspect) {
|
||||
var commonAspect = routableAspect.As<ICommonPart>();
|
||||
if (commonAspect != null && commonAspect.Container != null) {
|
||||
var routable = commonAspect.Container.As<IRoutableAspect>();
|
||||
if (routable != null)
|
||||
return routable.Path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetPathWithSlug(this IRoutableAspect routableAspect, string slug) {
|
||||
var containerPath = routableAspect.GetContainerPath();
|
||||
return !string.IsNullOrEmpty(containerPath)
|
||||
? string.Format("{0}/{1}", containerPath, slug)
|
||||
: slug;
|
||||
}
|
||||
|
||||
public static string GetChildPath(this IRoutableAspect routableAspect, string slug) {
|
||||
return string.Format("{0}/{1}", routableAspect.Path, slug);
|
||||
}
|
||||
|
||||
public static string GetEffectiveSlug(this IRoutableAspect routableAspect) {
|
||||
var containerPath = routableAspect.GetContainerPath();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(routableAspect.Path))
|
||||
return "";
|
||||
|
||||
var slugParts = routableAspect.Path.Split(new []{string.Format("{0}/", containerPath)}, StringSplitOptions.RemoveEmptyEntries);
|
||||
return slugParts.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1 @@
|
||||
@{
|
||||
Orchard.ContentManagement.ContentItem contentItem = Model.ContentPart.ContentItem;
|
||||
string title = Model.Title.ToString();
|
||||
}
|
||||
|
||||
<h1>@Html.ItemDisplayLink(title, contentItem)</h1>
|
||||
<h1>@Model.Title</h1>
|
@@ -0,0 +1,6 @@
|
||||
@{
|
||||
Orchard.ContentManagement.ContentItem contentItem = Model.ContentPart.ContentItem;
|
||||
string title = Model.Title.ToString();
|
||||
}
|
||||
|
||||
<h1>@Html.ItemDisplayLink(title, contentItem)</h1>
|
@@ -0,0 +1,6 @@
|
||||
@{
|
||||
Orchard.ContentManagement.ContentItem contentItem = Model.ContentPart.ContentItem;
|
||||
string title = Model.Title.ToString();
|
||||
}
|
||||
|
||||
<h1>@Html.ItemEditLink(title, contentItem)</h1>
|
@@ -1,5 +1,7 @@
|
||||
using System.Linq;
|
||||
using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
@@ -30,12 +32,12 @@ namespace Orchard.Blogs {
|
||||
}
|
||||
else if (singleBlog != null)
|
||||
menu.Add(T("Manage Blog"), "1.0",
|
||||
item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.Slug }).Permission(Permissions.MetaListBlogs));
|
||||
item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.As<IRoutableAspect>().Path }).Permission(Permissions.MetaListBlogs));
|
||||
|
||||
if (singleBlog != null)
|
||||
menu.Add(T("Create New Post"), "1.1",
|
||||
item =>
|
||||
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.Slug }).Permission(Permissions.PublishBlogPost));
|
||||
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.As<IRoutableAspect>().Path }).Permission(Permissions.PublishBlogPost));
|
||||
|
||||
menu.Add(T("Create New Blog"), "1.2",
|
||||
item =>
|
||||
|
@@ -8,6 +8,7 @@ using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Navigation.Models;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Core.Routable.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.Blogs.Services;
|
||||
using Orchard.Core.Navigation.Services;
|
||||
|
@@ -6,6 +6,7 @@ using Orchard.Blogs.Routing;
|
||||
using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Routable.Services;
|
||||
using Orchard.Data;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Localization;
|
||||
@@ -71,18 +72,17 @@ namespace Orchard.Blogs.Controllers {
|
||||
return View(model);
|
||||
}
|
||||
|
||||
if (!blog.Has<IPublishingControlAspect>())
|
||||
_contentManager.Publish(blog.ContentItem);
|
||||
_contentManager.Publish(blog.ContentItem);
|
||||
_blogSlugConstraint.AddSlug(blog.As<IRoutableAspect>().GetEffectiveSlug());
|
||||
|
||||
_blogSlugConstraint.AddSlug((string)model.Slug);
|
||||
return Redirect(Url.BlogForAdmin((string)model.Slug));
|
||||
return Redirect(Url.BlogForAdmin(blog));
|
||||
}
|
||||
|
||||
public ActionResult Edit(string blogSlug) {
|
||||
public ActionResult Edit(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to edit blog")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var blog = _blogService.Get(blogSlug);
|
||||
var blog = _blogService.Get(id, VersionOptions.Latest);
|
||||
if (blog == null)
|
||||
return HttpNotFound();
|
||||
|
||||
@@ -91,20 +91,24 @@ namespace Orchard.Blogs.Controllers {
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
public ActionResult EditPOST(string blogSlug) {
|
||||
public ActionResult EditPOST(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't edit blog")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var blog = _blogService.Get(blogSlug);
|
||||
var blog = _blogService.Get(id, VersionOptions.DraftRequired);
|
||||
if (blog == null)
|
||||
return HttpNotFound();
|
||||
|
||||
var model = Services.ContentManager.UpdateEditor(blog, this);
|
||||
if (!ModelState.IsValid)
|
||||
if (!ModelState.IsValid) {
|
||||
Services.TransactionManager.Cancel();
|
||||
return View(model);
|
||||
}
|
||||
|
||||
_blogSlugConstraint.AddSlug(blog.Slug);
|
||||
_contentManager.Publish(blog);
|
||||
_blogSlugConstraint.AddSlug(blog.As<IRoutableAspect>().GetEffectiveSlug());
|
||||
Services.Notifier.Information(T("Blog information updated"));
|
||||
|
||||
return Redirect(Url.BlogsForAdmin());
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Blogs.Extensions;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc.AntiForgery;
|
||||
using Orchard.UI.Admin;
|
||||
@@ -39,7 +42,21 @@ namespace Orchard.Blogs.Controllers {
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Create")]
|
||||
[FormValueRequired("submit.Save")]
|
||||
public ActionResult CreatePOST() {
|
||||
return CreatePOST(contentItem => {
|
||||
if (!contentItem.Has<IPublishingControlAspect>() && !contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
|
||||
Services.ContentManager.Publish(contentItem);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Create")]
|
||||
[FormValueRequired("submit.Publish")]
|
||||
public ActionResult CreateAndPublishPOST() {
|
||||
return CreatePOST(contentItem => Services.ContentManager.Publish(contentItem));
|
||||
}
|
||||
|
||||
public ActionResult CreatePOST(Action<ContentItem> conditionallyPublish) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't create blog post")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
@@ -55,11 +72,10 @@ namespace Orchard.Blogs.Controllers {
|
||||
return View(model);
|
||||
}
|
||||
|
||||
if (!blogPost.Has<IPublishingControlAspect>())
|
||||
Services.ContentManager.Publish(blogPost.ContentItem);
|
||||
conditionallyPublish(blogPost.ContentItem);
|
||||
|
||||
Services.Notifier.Information(T("Your {0} has been created.", blogPost.TypeDefinition.DisplayName));
|
||||
return Redirect(Url.BlogPostEdit((string)model.Blog.Slug, (int)model.ContentItem.Id));
|
||||
return Redirect(Url.BlogPostEdit(blogPost));
|
||||
}
|
||||
|
||||
//todo: the content shape template has extra bits that the core contents module does not (remove draft functionality)
|
||||
@@ -82,7 +98,21 @@ namespace Orchard.Blogs.Controllers {
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
public ActionResult EditPOST(string blogSlug, int postId) {
|
||||
[FormValueRequired("submit.Save")]
|
||||
public ActionResult EditPOST(string blogSlug, int postId, string returnUrl) {
|
||||
return EditPOST(blogSlug, postId, returnUrl, contentItem => {
|
||||
if (!contentItem.Has<IPublishingControlAspect>() && !contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
|
||||
Services.ContentManager.Publish(contentItem);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[FormValueRequired("submit.Publish")]
|
||||
public ActionResult EditAndPublishPOST(string blogSlug, int postId, string returnUrl) {
|
||||
return EditPOST(blogSlug, postId, returnUrl, contentItem => Services.ContentManager.Publish(contentItem));
|
||||
}
|
||||
|
||||
public ActionResult EditPOST(string blogSlug, int postId, string returnUrl, Action<ContentItem> conditionallyPublish) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
@@ -102,8 +132,14 @@ namespace Orchard.Blogs.Controllers {
|
||||
return View(model);
|
||||
}
|
||||
|
||||
conditionallyPublish(blogPost.ContentItem);
|
||||
|
||||
Services.Notifier.Information(T("Your {0} has been saved.", blogPost.TypeDefinition.DisplayName));
|
||||
return Redirect(Url.BlogPostEdit((BlogPostPart)model.ContentItem.Get(typeof(BlogPostPart))));
|
||||
|
||||
if (!String.IsNullOrEmpty(returnUrl))
|
||||
return Redirect(returnUrl);
|
||||
|
||||
return Redirect(Url.BlogPostEdit(blogPost));
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
@@ -142,7 +178,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
ActionResult RedirectToEdit(IContent item) {
|
||||
if (item == null || item.As<BlogPostPart>() == null)
|
||||
return HttpNotFound();
|
||||
return RedirectToAction("Edit", new { BlogSlug = item.As<BlogPostPart>().BlogPart.Slug, PostId = item.ContentItem.Id });
|
||||
return RedirectToAction("Edit", new { BlogSlug = item.As<IRoutableAspect>().Path, PostId = item.ContentItem.Id });
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
@@ -162,7 +198,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
_blogPostService.Delete(post);
|
||||
Services.Notifier.Information(T("Blog post was successfully deleted"));
|
||||
|
||||
return Redirect(Url.BlogForAdmin(blogSlug));
|
||||
return Redirect(Url.BlogForAdmin(blog));
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
@@ -181,7 +217,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
_blogPostService.Publish(post);
|
||||
Services.Notifier.Information(T("Blog post successfully published."));
|
||||
|
||||
return Redirect(Url.BlogForAdmin(blog.Slug));
|
||||
return Redirect(Url.BlogForAdmin(blog));
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
@@ -200,7 +236,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
_blogPostService.Unpublish(post);
|
||||
Services.Notifier.Information(T("Blog post successfully unpublished."));
|
||||
|
||||
return Redirect(Url.BlogForAdmin(blog.Slug));
|
||||
return Redirect(Url.BlogForAdmin(blog));
|
||||
}
|
||||
|
||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||
@@ -211,4 +247,17 @@ namespace Orchard.Blogs.Controllers {
|
||||
ModelState.AddModelError(key, errorMessage.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class FormValueRequiredAttribute : ActionMethodSelectorAttribute {
|
||||
private readonly string _submitButtonName;
|
||||
|
||||
public FormValueRequiredAttribute(string submitButtonName) {
|
||||
_submitButtonName = submitButtonName;
|
||||
}
|
||||
|
||||
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
|
||||
var value = controllerContext.HttpContext.Request.Form[_submitButtonName];
|
||||
return !string.IsNullOrEmpty(value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Environment.Extensions;
|
||||
|
||||
@@ -8,7 +10,7 @@ namespace Orchard.Blogs.Drivers {
|
||||
[OrchardFeature("Orchard.Blogs.RemotePublishing")]
|
||||
public class RemoteBlogPublishingDriver : ContentPartDriver<BlogPart> {
|
||||
protected override DriverResult Display(BlogPart part, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Parts_Blogs_RemotePublishing", shape => shape.Slug(part.Slug));
|
||||
return ContentShape("Parts_Blogs_RemotePublishing", shape => shape.Path(part.As<IRoutableAspect>().Path));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,8 @@
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Routable.Services;
|
||||
using Orchard.Mvc.Extensions;
|
||||
|
||||
namespace Orchard.Blogs.Extensions {
|
||||
@@ -12,92 +15,68 @@ namespace Orchard.Blogs.Extensions {
|
||||
return urlHelper.Action("List", "BlogAdmin", new {area = "Orchard.Blogs"});
|
||||
}
|
||||
|
||||
public static string Blog(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.Action("Item", "Blog", new {blogSlug, area = "Orchard.Blogs"});
|
||||
public static string Blog(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.Action("Item", "Blog", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogLiveWriterManifest(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.AbsoluteAction(() => urlHelper.Action("LiveWriterManifest", "Blog", new { blogSlug, area = "Orchard.Blogs" }));
|
||||
public static string BlogLiveWriterManifest(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.AbsoluteAction(() => urlHelper.Action("LiveWriterManifest", "Blog", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" }));
|
||||
}
|
||||
|
||||
public static string BlogRsd(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "Blog", new { blogSlug, area = "Orchard.Blogs" }));
|
||||
public static string BlogRsd(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "Blog", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" }));
|
||||
}
|
||||
|
||||
public static string BlogArchiveYear(this UrlHelper urlHelper, string blogSlug, int year) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug, archiveData = year.ToString(), area = "Orchard.Blogs" });
|
||||
public static string BlogArchiveYear(this UrlHelper urlHelper, BlogPart blogPart, int year) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = year.ToString(), area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogArchiveMonth(this UrlHelper urlHelper, string blogSlug, int year, int month) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" });
|
||||
public static string BlogArchiveMonth(this UrlHelper urlHelper, BlogPart blogPart, int year, int month) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogArchiveDay(this UrlHelper urlHelper, string blogSlug, int year, int month, int day) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new {blogSlug, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs"});
|
||||
public static string BlogArchiveDay(this UrlHelper urlHelper, BlogPart blogPart, int year, int month, int day) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogForAdmin(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.Action("Item", "BlogAdmin", new {blogSlug, area = "Orchard.Blogs"});
|
||||
public static string BlogForAdmin(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.Action("Item", "BlogAdmin", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogCreate(this UrlHelper urlHelper) {
|
||||
return urlHelper.Action("Create", "BlogAdmin", new {area = "Orchard.Blogs"});
|
||||
}
|
||||
|
||||
public static string BlogEdit(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.Action("Edit", "BlogAdmin", new {blogSlug, area = "Orchard.Blogs"});
|
||||
public static string BlogEdit(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.Action("Edit", "BlogAdmin", new { blogPart.Id, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogRemove(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.Action("Remove", "BlogAdmin", new {blogSlug, area = "Orchard.Blogs"});
|
||||
}
|
||||
|
||||
public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||
return urlHelper.BlogPost(blogPostPart.BlogPart.Slug, blogPostPart.Slug);
|
||||
}
|
||||
|
||||
public static string BlogPost(this UrlHelper urlHelper, string blogSlug, string postSlug) {
|
||||
return urlHelper.Action("Item", "BlogPost", new {blogSlug, postSlug, area = "Orchard.Blogs"});
|
||||
public static string BlogRemove(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.Action("Remove", "BlogAdmin", new { blogPart.Id, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogPostCreate(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||
return urlHelper.BlogPostCreate(blogPart.Slug);
|
||||
return urlHelper.Action("Create", "BlogPostAdmin", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogPostCreate(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.Action("Create", "BlogPostAdmin", new {blogSlug, area = "Orchard.Blogs"});
|
||||
public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||
return urlHelper.Action("Item", "BlogPost", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postSlug = blogPostPart.As<IRoutableAspect>().GetEffectiveSlug(), area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogPostEdit(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||
return urlHelper.BlogPostEdit(blogPostPart.BlogPart.Slug, blogPostPart.Id);
|
||||
}
|
||||
|
||||
public static string BlogPostEdit(this UrlHelper urlHelper, string blogSlug, int postId) {
|
||||
return urlHelper.Action("Edit", "BlogPostAdmin", new {blogSlug, postId, area = "Orchard.Blogs"});
|
||||
return urlHelper.Action("Edit", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogPostDelete(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||
return urlHelper.BlogPostDelete(blogPostPart.BlogPart.Slug, blogPostPart.Id);
|
||||
}
|
||||
|
||||
public static string BlogPostDelete(this UrlHelper urlHelper, string blogSlug, int postId) {
|
||||
return urlHelper.Action("Delete", "BlogPostAdmin", new {blogSlug, postId, area = "Orchard.Blogs"});
|
||||
return urlHelper.Action("Delete", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogPostPublish(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||
return urlHelper.BlogPostPublish(blogPostPart.BlogPart.Slug, blogPostPart.Id);
|
||||
}
|
||||
|
||||
public static string BlogPostPublish(this UrlHelper urlHelper, string blogSlug, int postId) {
|
||||
return urlHelper.Action("Publish", "BlogPostAdmin", new { blogSlug, postId, area = "Orchard.Blogs" });
|
||||
return urlHelper.Action("Publish", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogPostUnpublish(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||
return urlHelper.BlogPostUnpublish(blogPostPart.BlogPart.Slug, blogPostPart.Id);
|
||||
}
|
||||
|
||||
public static string BlogPostUnpublish(this UrlHelper urlHelper, string blogSlug, int postId) {
|
||||
return urlHelper.Action("Unpublish", "BlogPostAdmin", new { blogSlug, postId, area = "Orchard.Blogs" });
|
||||
return urlHelper.Action("Unpublish", "BlogPostAdmin", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postId = blogPostPart.Id, area = "Orchard.Blogs" });
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,11 +9,6 @@ namespace Orchard.Blogs.Models {
|
||||
set { this.As<RoutePart>().Title = value; }
|
||||
}
|
||||
|
||||
public string Slug {
|
||||
get { return this.As<RoutePart>().Slug; }
|
||||
set { this.As<RoutePart>().Slug = value; }
|
||||
}
|
||||
|
||||
public string Description {
|
||||
get { return Record.Description; }
|
||||
set { Record.Description = value; }
|
||||
|
@@ -35,15 +35,13 @@ namespace Orchard.Blogs {
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"Admin/Blogs/{blogSlug}/Edit",
|
||||
"Admin/Blogs/{id}/Edit",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Blogs"},
|
||||
{"controller", "BlogAdmin"},
|
||||
{"action", "Edit"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"blogSlug", _blogSlugConstraint}
|
||||
},
|
||||
new RouteValueDictionary (),
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Blogs"}
|
||||
},
|
||||
@@ -51,15 +49,13 @@ namespace Orchard.Blogs {
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"Admin/Blogs/{blogSlug}/Remove",
|
||||
"Admin/Blogs/{id}/Remove",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Blogs"},
|
||||
{"controller", "BlogAdmin"},
|
||||
{"action", "Remove"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"blogSlug", _blogSlugConstraint}
|
||||
},
|
||||
new RouteValueDictionary (),
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Blogs"}
|
||||
},
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Tasks;
|
||||
|
||||
@@ -27,7 +29,7 @@ namespace Orchard.Blogs.Routing {
|
||||
}
|
||||
|
||||
private void Refresh() {
|
||||
_blogSlugConstraint.SetSlugs(_blogService.Get().Select(b => b.Slug));
|
||||
_blogSlugConstraint.SetSlugs(_blogService.Get().Select(b => b.As<IRoutableAspect>().Path));
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,9 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Core.Routable.Services;
|
||||
using Orchard.Data;
|
||||
using Orchard.Tasks.Scheduling;
|
||||
|
||||
@@ -27,8 +29,9 @@ namespace Orchard.Blogs.Services {
|
||||
}
|
||||
|
||||
public BlogPostPart Get(BlogPart blogPart, string slug, VersionOptions versionOptions) {
|
||||
var postSlug = blogPart.As<IRoutableAspect>().GetChildPath(slug);
|
||||
return
|
||||
_contentManager.Query(versionOptions, "BlogPost").Join<RoutePartRecord>().Where(rr => rr.Slug == slug).
|
||||
_contentManager.Query(versionOptions, "BlogPost").Join<RoutePartRecord>().Where(rr => rr.Path == postSlug).
|
||||
Join<CommonPartRecord>().Where(cr => cr.Container == blogPart.Record.ContentItemRecord).List().
|
||||
SingleOrDefault().As<BlogPostPart>();
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ using JetBrains.Annotations;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.Blogs.Routing;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Routable.Models;
|
||||
|
||||
namespace Orchard.Blogs.Services {
|
||||
@@ -17,12 +18,16 @@ namespace Orchard.Blogs.Services {
|
||||
_blogSlugConstraint = blogSlugConstraint;
|
||||
}
|
||||
|
||||
public BlogPart Get(string slug) {
|
||||
public BlogPart Get(string path) {
|
||||
return _contentManager.Query<BlogPart, BlogPartRecord>()
|
||||
.Join<RoutePartRecord>().Where(rr => rr.Slug == slug)
|
||||
.Join<RoutePartRecord>().Where(rr => rr.Path == path)
|
||||
.List().FirstOrDefault();
|
||||
}
|
||||
|
||||
public ContentItem Get(int id, VersionOptions versionOptions) {
|
||||
return _contentManager.Get(id, versionOptions);
|
||||
}
|
||||
|
||||
public IEnumerable<BlogPart> Get() {
|
||||
return _contentManager.Query<BlogPart, BlogPartRecord>()
|
||||
.Join<RoutePartRecord>()
|
||||
@@ -32,7 +37,7 @@ namespace Orchard.Blogs.Services {
|
||||
|
||||
public void Delete(BlogPart blogPart) {
|
||||
_contentManager.Remove(blogPart.ContentItem);
|
||||
_blogSlugConstraint.RemoveSlug(blogPart.Slug);
|
||||
_blogSlugConstraint.RemoveSlug(blogPart.As<IRoutableAspect>().Path);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Blogs.Services {
|
||||
public interface IBlogService : IDependency {
|
||||
BlogPart Get(string slug);
|
||||
ContentItem Get(int id, VersionOptions versionOptions);
|
||||
IEnumerable<BlogPart> Get();
|
||||
void Delete(BlogPart blogPart);
|
||||
}
|
||||
|
@@ -117,8 +117,9 @@ namespace Orchard.Blogs.Services {
|
||||
|
||||
var array = new XRpcArray();
|
||||
foreach (var blog in _blogService.Get()) {
|
||||
var thisBlog = blog;
|
||||
array.Add(new XRpcStruct()
|
||||
.Set("url", urlHelper.AbsoluteAction(() => urlHelper.Blog(blog.Slug)))
|
||||
.Set("url", urlHelper.AbsoluteAction(() => urlHelper.Blog(thisBlog)))
|
||||
.Set("blogid", blog.Id)
|
||||
.Set("blogName", blog.Name));
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
@using Orchard.Blogs.Extensions;
|
||||
@using Orchard.Blogs.Models;
|
||||
<h1 class="page-title">@Html.TitleForPage(T("Archives").Text, (string)Model.ArchiveData.Year.ToString(), (string)(Model.ArchiveData.Month > 0 ? new DateTime(Model.ArchiveData.Year, Model.ArchiveData.Month, 1).ToString("MMMM") : null), (string)(Model.ArchiveData.Day > 0 ? Model.ArchiveData.Day.ToString() : null))</h1>
|
||||
<div class="archive-trail">
|
||||
@T("Archives") /
|
||||
@Html.Link((string)Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear((string)Model.Blog.Slug, (int)Model.ArchiveData.Year))
|
||||
@(new MvcHtmlString(Model.ArchiveData.Month > 0 ? string.Format(" / {0}", Html.Link((string)Model.ArchiveData.ToDateTime().ToString("MMMM"), Url.BlogArchiveMonth((string)Model.Blog.Slug,(int) Model.ArchiveData.Year, (int)Model.ArchiveData.Month))) : ""))
|
||||
@(new MvcHtmlString(Model.ArchiveData.Day > 0 ? string.Format(" / {0}", Html.Link((string)Model.ArchiveData.Day.ToString(), Url.BlogArchiveDay((string)Model.Blog.Slug, (int)Model.ArchiveData.Year, (int)Model.ArchiveData.Month, (int)Model.ArchiveData.Day))) : ""))
|
||||
@Html.Link((string)Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear((BlogPart)Model.Blog, (int)Model.ArchiveData.Year))
|
||||
@(new MvcHtmlString(Model.ArchiveData.Month > 0 ? string.Format(" / {0}", Html.Link((string)Model.ArchiveData.ToDateTime().ToString("MMMM"), Url.BlogArchiveMonth((BlogPart)Model.Blog, (int)Model.ArchiveData.Year, (int)Model.ArchiveData.Month))) : ""))
|
||||
@(new MvcHtmlString(Model.ArchiveData.Day > 0 ? string.Format(" / {0}", Html.Link((string)Model.ArchiveData.Day.ToString(), Url.BlogArchiveDay((BlogPart)Model.Blog, (int)Model.ArchiveData.Year, (int)Model.ArchiveData.Month, (int)Model.ArchiveData.Day))) : ""))
|
||||
</div>
|
||||
@Display(Model.ContentItems)
|
@@ -5,12 +5,13 @@
|
||||
@{
|
||||
Script.Require("ShapesBase");
|
||||
ContentItem contentItem = Model.ContentItem;
|
||||
BlogPart blog = (BlogPart)contentItem.Get(typeof(BlogPart));
|
||||
var returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString();
|
||||
}
|
||||
<div class="summary" itemscope="itemscope" itemid="@contentItem.Id" itemtype="http://orchardproject.net/data/ContentItem">
|
||||
<div class="properties">
|
||||
<input type="checkbox" value="@contentItem.Id" name="itemIds"/>
|
||||
<h3>@Html.Link((string)Model.Title, Url.BlogForAdmin((string)Model.Slug))</h3>
|
||||
<h3>@Html.Link((string)Model.Title, Url.BlogForAdmin((BlogPart)blog))</h3>
|
||||
@if (Model.Header != null) {
|
||||
<div class="header">@Display(Model.Header)</div>
|
||||
}
|
||||
@@ -20,11 +21,11 @@
|
||||
</div>
|
||||
<div class="related">
|
||||
@Display(Model.Actions)
|
||||
<a href="@Url.Blog((string)Model.Slug)" title="@T("View")">@T("View")</a>@T(" | ")
|
||||
<a href="@Url.BlogForAdmin((string)Model.Slug)" title="@T("List Posts")">@T("List Posts")</a>@T(" | ")
|
||||
<a href="@Url.BlogPostCreate((BlogPart)Model.ContentItem.Get(typeof(BlogPart)))" title="@T("New Post")">@T("New Post")</a>@T(" | ")
|
||||
<a href="@Url.BlogEdit((string)Model.Slug)" title="@T("Edit")">@T("Edit")</a>@T(" | ")
|
||||
<a href="@Url.BlogRemove((string)Model.Slug)" title="@T("Remove")" itemprop="RemoveUrl UnsafeUrl">@T("Remove")</a>
|
||||
<a href="@Url.Blog(blog)" title="@T("View")">@T("View")</a>@T(" | ")
|
||||
<a href="@Url.BlogForAdmin(blog)" title="@T("List Posts")">@T("List Posts")</a>@T(" | ")
|
||||
<a href="@Url.BlogPostCreate(blog)" title="@T("New Post")">@T("New Post")</a>@T(" | ")
|
||||
<a href="@Url.BlogEdit(blog)" title="@T("Edit")">@T("Edit")</a>@T(" | ")
|
||||
<a href="@Url.BlogRemove(blog)" title="@T("Remove")" itemprop="RemoveUrl UnsafeUrl">@T("Remove")</a>
|
||||
</div>
|
||||
@if (Model.Content != null) {
|
||||
<div class="primary">@Display(Model.Content)</div>
|
||||
|
@@ -1,9 +1,10 @@
|
||||
@using Orchard.Blogs.Extensions;
|
||||
@using Orchard.Blogs.Models;
|
||||
@{
|
||||
Style.Require("BlogsAdmin");
|
||||
}
|
||||
@if (AuthorizedFor(Orchard.Blogs.Permissions.ManageBlogs)) {
|
||||
<div class="item-properties actions">
|
||||
<p><a href="@Url.BlogEdit((string)Model.ContentPart.Slug)" class="edit">@T("Blog Properties")</a></p>
|
||||
<p><a href="@Url.BlogEdit((BlogPart)Model.ContentPart)" class="edit">@T("Blog Properties")</a></p>
|
||||
</div>
|
||||
}
|
@@ -25,14 +25,14 @@
|
||||
if (year != lastYear) {
|
||||
<li class="previous">
|
||||
<h4>@year <span>(@yearMonths.Sum(ym => ym.Value))</span></h4>
|
||||
@Html.UnorderedList(yearMonths, (t, i) => Html.Link(string.Format("{0:MMMM} ({1})", t.Key.ToDateTime(), t.Value), Url.BlogArchiveMonth((string)Model.BlogPart.Slug, t.Key.Year, t.Key.Month)), "archiveMonthList")
|
||||
@Html.UnorderedList(yearMonths, (t, i) => Html.Link(string.Format("{0:MMMM} ({1})", t.Key.ToDateTime(), t.Value), Url.BlogArchiveMonth((BlogPart)Model.BlogPart, t.Key.Year, t.Key.Month)), "archiveMonthList")
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
else if (archives.Count() > 0) {
|
||||
@Html.UnorderedList(archives, (t, i) => Html.Link(string.Format("{0:MMMM yyyy} ({1})", t.Key.ToDateTime(), t.Value), Url.BlogArchiveMonth((string)Model.BlogPart.Slug, t.Key.Year, t.Key.Month)), "archiveMonthList")
|
||||
@Html.UnorderedList(archives, (t, i) => Html.Link(string.Format("{0:MMMM yyyy} ({1})", t.Key.ToDateTime(), t.Value), Url.BlogArchiveMonth((BlogPart)Model.BlogPart, t.Key.Year, t.Key.Month)), "archiveMonthList")
|
||||
}
|
||||
else {
|
||||
<div class="message info">@T("None found")</div>
|
||||
|
@@ -1,6 +1,8 @@
|
||||
@using Orchard.Blogs.Extensions;
|
||||
@using Orchard.Blogs.Models;
|
||||
@using Orchard.UI.Resources;
|
||||
@{
|
||||
RegisterLink(new LinkEntry { Rel = "wlwmanifest", Type = "application/wlwmanifest+xml", Href = Url.BlogLiveWriterManifest((string)Model.Slug) });
|
||||
RegisterLink(new LinkEntry { Rel = "EditURI", Type = "application/rsd+xml", Title = "RSD", Href = Url.BlogRsd((string)Model.Slug) });
|
||||
BlogPart blog = Model;
|
||||
RegisterLink(new LinkEntry { Rel = "wlwmanifest", Type = "application/wlwmanifest+xml", Href = Url.BlogLiveWriterManifest(blog) });
|
||||
RegisterLink(new LinkEntry { Rel = "EditURI", Type = "application/rsd+xml", Title = "RSD", Href = Url.BlogRsd(blog) });
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
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
|
||||
@@ -9,7 +10,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyProduct("Orchard")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyCopyright("Copyright <20> Outercurve Foundation 2009")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -30,5 +31,6 @@ using System.Runtime.InteropServices;
|
||||
//
|
||||
// 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")]
|
||||
[assembly: AssemblyVersion("0.8.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.8.0.0")]
|
||||
[assembly: SecurityTransparent]
|
||||
|
19
src/Orchard.Web/Modules/Orchard.Pages/Migrations.cs
Normal file
19
src/Orchard.Web/Modules/Orchard.Pages/Migrations.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Core.Contents.Extensions;
|
||||
using Orchard.Data.Migration;
|
||||
|
||||
namespace Orchard.Pages {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
public int Create() {
|
||||
ContentDefinitionManager.AlterTypeDefinition("Page",
|
||||
cfg=>cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("PublishLaterPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
.Creatable());
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
12
src/Orchard.Web/Modules/Orchard.Pages/Module.txt
Normal file
12
src/Orchard.Web/Modules/Orchard.Pages/Module.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Name: Pages
|
||||
AntiForgery: enabled
|
||||
Author: The Orchard Team
|
||||
Website: http://orchardproject.net
|
||||
Version: 0.8.0
|
||||
OrchardVersion: 0.8.0
|
||||
Description: Introduces a preconfigured page content type.
|
||||
Features:
|
||||
Orchard.Pages:
|
||||
Description: A basic page content type.
|
||||
Dependencies: Contents
|
||||
Category: Content
|
96
src/Orchard.Web/Modules/Orchard.Pages/Orchard.Pages.csproj
Normal file
96
src/Orchard.Web/Modules/Orchard.Pages/Orchard.Pages.csproj
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{3420C92A-747F-4990-BA08-F2C9531E44AD}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Orchard.Pages</RootNamespace>
|
||||
<AssemblyName>Orchard.Pages</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
</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>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
<Reference Include="System.Web.Entity" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Web.Services" />
|
||||
<Reference Include="System.EnterpriseServices" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Module.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
|
||||
<Name>Orchard.Framework</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
|
||||
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
|
||||
<Name>Orchard.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>6857</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>
|
||||
</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>True</UseCustomServer>
|
||||
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<!-- 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">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
@@ -0,0 +1,36 @@
|
||||
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.Pages")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyProduct("Orchard")]
|
||||
[assembly: AssemblyCopyright("Copyright © Outercurve Foundation 2009")]
|
||||
[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("0d852f97-2bc9-42ee-91b6-90e90dbbe6ca")]
|
||||
|
||||
// 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("0.8.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.8.0.0")]
|
||||
[assembly: SecurityTransparent]
|
@@ -86,6 +86,7 @@ namespace Orchard.Setup.Services {
|
||||
"Orchard.Roles",
|
||||
"TinyMce",
|
||||
"PackagingServices",
|
||||
"Orchard.Pages",
|
||||
"Orchard.Modules",
|
||||
"Orchard.Themes",
|
||||
"Orchard.PublishLater",
|
||||
@@ -213,7 +214,7 @@ namespace Orchard.Setup.Services {
|
||||
//hackInstallationGenerator.GenerateInstallEvents();
|
||||
|
||||
var contentDefinitionManager = environment.Resolve<IContentDefinitionManager>();
|
||||
//todo: (heskew) pull these definitions (and initial content creation) out into more appropriate modules
|
||||
//todo: (heskew) pull these definitions (and initial content creation) out into a distribution configuration when we have that capability
|
||||
contentDefinitionManager.AlterTypeDefinition("BlogPost", cfg => cfg
|
||||
.WithPart("CommentsPart")
|
||||
.WithPart("TagsPart")
|
||||
@@ -222,13 +223,8 @@ namespace Orchard.Setup.Services {
|
||||
.Indexed()
|
||||
);
|
||||
contentDefinitionManager.AlterTypeDefinition("Page", cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("PublishLaterPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
.WithPart("TagsPart")
|
||||
.WithPart("LocalizationPart")
|
||||
.Creatable()
|
||||
.Draftable()
|
||||
.Indexed()
|
||||
);
|
||||
|
@@ -94,6 +94,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.PublishLater", "Orc
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Lists", "Orchard.Web\Modules\Orchard.Lists\Orchard.Lists.csproj", "{137906EA-15FE-4AD8-A6A0-27528F0477D6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Pages", "Orchard.Web\Modules\Orchard.Pages\Orchard.Pages.csproj", "{3420C92A-747F-4990-BA08-F2C9531E44AD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeCoverage|Any CPU = CodeCoverage|Any CPU
|
||||
@@ -500,6 +502,16 @@ Global
|
||||
{137906EA-15FE-4AD8-A6A0-27528F0477D6}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{137906EA-15FE-4AD8-A6A0-27528F0477D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{137906EA-15FE-4AD8-A6A0-27528F0477D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.Coverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.FxCop|Any CPU.Build.0 = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -530,6 +542,7 @@ Global
|
||||
{EA4F1DA7-F2AB-4384-9AA4-9B756E2026B1} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{C889167C-E52C-4A65-A419-224B3D1B957D} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{137906EA-15FE-4AD8-A6A0-27528F0477D6} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{3420C92A-747F-4990-BA08-F2C9531E44AD} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
|
||||
{F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
|
||||
{6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
|
||||
|
Reference in New Issue
Block a user