mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : 1.x
This commit is contained in:
10
Orchard.proj
10
Orchard.proj
@@ -276,13 +276,18 @@
|
||||
$(StageFolder)\**\Modules\Lucene\**;
|
||||
$(StageFolder)\**\Modules\Orchard.ArchiveLater\**;
|
||||
$(StageFolder)\**\Modules\Orchard.CodeGeneration\**;
|
||||
$(StageFolder)\**\Modules\Orchard.DesignerTools\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Email\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Experimental\**;
|
||||
$(StageFolder)\**\Modules\Orchard.ImportExport\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Indexing\**;
|
||||
$(StageFolder)\**\Modules\Orchard.MediaPicker\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Migrations\**;
|
||||
$(StageFolder)\**\Modules\Orchard.MultiTenancy\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Recipes\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Scripting.Dlr\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Search\**;
|
||||
$(StageFolder)\**\Modules\Orchard.Warmup\**;
|
||||
" />
|
||||
|
||||
<MsDeploy-Folder-Input Include="$(StageFolder)\**\*" Exclude="$(StageFolder)\**\bin\**\*.xml;@(MsDeploy-Exclude-Modules)" />
|
||||
@@ -375,13 +380,18 @@
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Lucene "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.ArchiveLater "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.CodeGeneration "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.DesignerTools "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Email "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Experimental "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.ImportExport "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Indexing "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.MediaPicker "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Migrations "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.MultiTenancy "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Recipes "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Scripting.Dlr "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Search "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
<Exec Command=""$(GalleryFolder)\bin\Orchard.exe" package create Orchard.Warmup "$(GalleryArtifactFolder)"" WorkingDirectory="$(GalleryFolder)"/>
|
||||
</Target>
|
||||
|
||||
<!-- ValidateProjectFiles-->
|
||||
|
@@ -222,6 +222,23 @@ namespace Orchard.Specs.Bindings {
|
||||
WhenIGoTo(urlPath);
|
||||
}
|
||||
|
||||
[When(@"I follow ""([^""]+)"" where class name has ""([^""]+)""")]
|
||||
public void WhenIFollowClass(string linkText, string className) {
|
||||
var link = _doc.DocumentNode
|
||||
.SelectNodes("//a[@href]").Where(elt =>
|
||||
(elt.InnerText == linkText ||
|
||||
(elt.Attributes["title"] != null && elt.Attributes["title"].Value == linkText)) &&
|
||||
elt.Attributes["class"].Value.IndexOf(className, StringComparison.OrdinalIgnoreCase) != -1).SingleOrDefault();
|
||||
|
||||
if (link == null) {
|
||||
throw new InvalidOperationException(string.Format("Could not find an anchor with matching text '{0}' and class '{1}'. Document: {2}", linkText, className, _doc.DocumentNode.InnerHtml));
|
||||
}
|
||||
var href = link.Attributes["href"].Value;
|
||||
var urlPath = HttpUtility.HtmlDecode(href);
|
||||
|
||||
WhenIGoTo(urlPath);
|
||||
}
|
||||
|
||||
[When(@"I fill in")]
|
||||
public void WhenIFillIn(Table table) {
|
||||
var inputs = _doc.DocumentNode
|
||||
|
@@ -17,7 +17,7 @@ Scenario: I can create a new blog and blog post
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
@@ -39,7 +39,7 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
@@ -50,7 +50,7 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
|
||||
And I should see "Hi there."
|
||||
When I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
@@ -61,7 +61,7 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
|
||||
And I should see "Hi there, again."
|
||||
When I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
@@ -83,7 +83,7 @@ Scenario: I can create a new blog and blog post and when I change the slug of th
|
||||
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
|
||||
When I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
@@ -114,7 +114,7 @@ Scenario: When viewing a blog the user agent is given an RSS feed of the blog's
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
@@ -151,7 +151,7 @@ Scenario: The virtual path of my installation when not at the root is reflected
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
Then I should see "<span>http\://localhost/OrchardLocal/my-blog/</span>"
|
||||
|
||||
Scenario: The virtual path of my installation when at the root is reflected in the URL example for the slug field when creating a blog or blog post
|
||||
@@ -164,7 +164,7 @@ Scenario: The virtual path of my installation when at the root is reflected in t
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
Then I should see "<span>http\://localhost/my-blog/</span>"
|
||||
|
||||
Scenario: I set my blog to be the content for the home page and the posts for the blog be rooted to the app
|
||||
@@ -177,7 +177,7 @@ Scenario: I set my blog to be the content for the home page and the posts for th
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
|
22
src/Orchard.Specs/Blogs.feature.cs
generated
22
src/Orchard.Specs/Blogs.feature.cs
generated
@@ -1,7 +1,7 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.4.0.0
|
||||
// SpecFlow Version:1.5.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.4.0.0")]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.5.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Blog")]
|
||||
@@ -97,7 +97,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 19
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 20
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -157,7 +157,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 41
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 42
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -183,7 +183,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 52
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 53
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -209,7 +209,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 63
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 64
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -270,7 +270,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 85
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 86
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -349,7 +349,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 116
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 117
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table11 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -452,7 +452,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 153
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 154
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line 155
|
||||
testRunner.Then("I should see \"<span>http\\://localhost/OrchardLocal/my-blog/</span>\"");
|
||||
#line hidden
|
||||
@@ -490,7 +490,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 166
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 167
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line 168
|
||||
testRunner.Then("I should see \"<span>http\\://localhost/my-blog/</span>\"");
|
||||
#line hidden
|
||||
@@ -529,7 +529,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 179
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 180
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
|
@@ -12,7 +12,7 @@ Scenario: HTML markup in any given comment is encoded
|
||||
And I hit "Save"
|
||||
And I go to "admin/blogs"
|
||||
And I follow "My Blog"
|
||||
And I follow "New Post"
|
||||
And I follow "New Post" where class name has "primaryAction"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | My Post |
|
||||
|
6
src/Orchard.Specs/Comments.feature.cs
generated
6
src/Orchard.Specs/Comments.feature.cs
generated
@@ -1,7 +1,7 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.4.0.0
|
||||
// SpecFlow Version:1.5.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.4.0.0")]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.5.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Comments")]
|
||||
@@ -80,7 +80,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 14
|
||||
testRunner.And("I follow \"My Blog\"");
|
||||
#line 15
|
||||
testRunner.And("I follow \"New Post\"");
|
||||
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
|
@@ -1,11 +1,11 @@
|
||||
Feature: Lists
|
||||
In order to add new lists to my site
|
||||
As an administrator
|
||||
I want to create lists
|
||||
|
||||
Scenario: I can create a new list
|
||||
Given I have installed Orchard
|
||||
When I go to "Admin/Contents/Create/List"
|
||||
Feature: Lists
|
||||
In order to add new lists to my site
|
||||
As an administrator
|
||||
I want to create lists
|
||||
|
||||
Scenario: I can create a new list
|
||||
Given I have installed Orchard
|
||||
When I go to "Admin/Contents/Create/List"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | MyList |
|
||||
@@ -13,25 +13,25 @@ Scenario: I can create a new list
|
||||
And I go to "Admin/Contents/List/List"
|
||||
Then I should see "MyList"
|
||||
|
||||
Scenario: I can add content items to a list
|
||||
Given I have installed Orchard
|
||||
And I have a containable content type "MyType"
|
||||
When I go to "Admin/Contents/Create/List"
|
||||
Scenario: I can add content items to a list
|
||||
Given I have installed Orchard
|
||||
And I have a containable content type "MyType"
|
||||
When I go to "Admin/Contents/Create/List"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | MyList |
|
||||
And I hit "Save"
|
||||
And I go to "Admin/Contents/List/List"
|
||||
Then I should see "MyList"
|
||||
When I follow "Contained Items"
|
||||
Then I should see "The 'MyList' List has no content items."
|
||||
When I follow "Create New Content" where href has "ReturnUrl"
|
||||
Then I should see "MyType"
|
||||
When I follow "MyType" where href has "ReturnUrl"
|
||||
When I follow "Contained Items"
|
||||
Then I should see "The 'MyList' List has no content items."
|
||||
When I follow "Create New Content" where href has "ReturnUrl"
|
||||
Then I should see "MyType"
|
||||
When I follow "MyType" where href has "ReturnUrl"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | MyContentItem |
|
||||
And I hit "Save"
|
||||
And I am redirected
|
||||
Then I should see "Manage Content for MyList"
|
||||
And I should see "MyContentItem"
|
||||
And I am redirected
|
||||
Then I should see "Manage MyList"
|
||||
And I should see "MyContentItem"
|
||||
|
29
src/Orchard.Specs/Lists.feature.cs
generated
29
src/Orchard.Specs/Lists.feature.cs
generated
@@ -30,7 +30,8 @@ namespace Orchard.Specs
|
||||
public virtual void FeatureSetup()
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Lists", "In order to add new lists to my site\nAs an administrator\nI want to create lists", GenerationTargetLanguage.CSharp, ((string[])(null)));
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Lists", "In order to add new lists to my site\r\nAs an administrator\r\nI want to create lists" +
|
||||
"", GenerationTargetLanguage.CSharp, ((string[])(null)));
|
||||
testRunner.OnFeatureStart(featureInfo);
|
||||
}
|
||||
|
||||
@@ -60,9 +61,9 @@ namespace Orchard.Specs
|
||||
#line 6
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 7
|
||||
testRunner.Given("I have installed Orchard");
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 8
|
||||
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -90,11 +91,11 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 16
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 17
|
||||
testRunner.Given("I have installed Orchard");
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 18
|
||||
testRunner.And("I have a containable content type \"MyType\"");
|
||||
testRunner.And("I have a containable content type \"MyType\"");
|
||||
#line 19
|
||||
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -111,15 +112,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 25
|
||||
testRunner.Then("I should see \"MyList\"");
|
||||
#line 26
|
||||
testRunner.When("I follow \"Contained Items\"");
|
||||
testRunner.When("I follow \"Contained Items\"");
|
||||
#line 27
|
||||
testRunner.Then("I should see \"The \'MyList\' List has no content items.\"");
|
||||
testRunner.Then("I should see \"The \'MyList\' List has no content items.\"");
|
||||
#line 28
|
||||
testRunner.When("I follow \"Create New Content\" where href has \"ReturnUrl\"");
|
||||
testRunner.When("I follow \"Create New Content\" where href has \"ReturnUrl\"");
|
||||
#line 29
|
||||
testRunner.Then("I should see \"MyType\"");
|
||||
testRunner.Then("I should see \"MyType\"");
|
||||
#line 30
|
||||
testRunner.When("I follow \"MyType\" where href has \"ReturnUrl\"");
|
||||
testRunner.When("I follow \"MyType\" where href has \"ReturnUrl\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
@@ -132,11 +133,11 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 34
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 35
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.And("I am redirected");
|
||||
#line 36
|
||||
testRunner.Then("I should see \"Manage Content for MyList\"");
|
||||
testRunner.Then("I should see \"Manage MyList\"");
|
||||
#line 37
|
||||
testRunner.And("I should see \"MyContentItem\"");
|
||||
testRunner.And("I should see \"MyContentItem\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ Scenario: Media admin is available
|
||||
Given I have installed Orchard
|
||||
And I have installed "Orchard.Media"
|
||||
When I go to "admin/media"
|
||||
Then I should see "Manage Media Folders"
|
||||
Then I should see "Media"
|
||||
And the status should be 200 "OK"
|
||||
|
||||
Scenario: Creating a folder
|
||||
@@ -19,7 +19,7 @@ Scenario: Creating a folder
|
||||
| Name | Hello World |
|
||||
And I hit "Save"
|
||||
And I am redirected
|
||||
Then I should see "Manage Media Folders"
|
||||
Then I should see "Media"
|
||||
And I should see "Hello World"
|
||||
And the status should be 200 "OK"
|
||||
|
||||
@@ -28,6 +28,6 @@ Scenario: Limited access
|
||||
And I have installed "Orchard.Media"
|
||||
When I go to "admin/media/edit?name=..\..\bin&mediaPath=..\..\bin"
|
||||
And I am redirected
|
||||
Then I should see "Manage Media Folders"
|
||||
Then I should see "Media"
|
||||
And I should see "Editing failed: Invalid path"
|
||||
And the status should be 200 "OK"
|
||||
|
6
src/Orchard.Specs/Media.feature.cs
generated
6
src/Orchard.Specs/Media.feature.cs
generated
@@ -67,7 +67,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 9
|
||||
testRunner.When("I go to \"admin/media\"");
|
||||
#line 10
|
||||
testRunner.Then("I should see \"Manage Media Folders\"");
|
||||
testRunner.Then("I should see \"Media\"");
|
||||
#line 11
|
||||
testRunner.And("the status should be 200 \"OK\"");
|
||||
#line hidden
|
||||
@@ -101,7 +101,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 21
|
||||
testRunner.And("I am redirected");
|
||||
#line 22
|
||||
testRunner.Then("I should see \"Manage Media Folders\"");
|
||||
testRunner.Then("I should see \"Media\"");
|
||||
#line 23
|
||||
testRunner.And("I should see \"Hello World\"");
|
||||
#line 24
|
||||
@@ -126,7 +126,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 30
|
||||
testRunner.And("I am redirected");
|
||||
#line 31
|
||||
testRunner.Then("I should see \"Manage Media Folders\"");
|
||||
testRunner.Then("I should see \"Media\"");
|
||||
#line 32
|
||||
testRunner.And("I should see \"Editing failed: Invalid path\"");
|
||||
#line 33
|
||||
|
@@ -7,14 +7,14 @@
|
||||
Scenario: There is only one user by default
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/users"
|
||||
Then I should see "Manage Users"
|
||||
Then I should see "Users"
|
||||
And I should see "<a[^>]*>admin</a>"
|
||||
|
||||
@management
|
||||
Scenario: I can create a new user
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/users"
|
||||
Then I should see "Manage Users"
|
||||
Then I should see "Users"
|
||||
When I follow "Add a new user"
|
||||
And I fill in
|
||||
| name | value |
|
||||
|
6
src/Orchard.Specs/Users.feature.cs
generated
6
src/Orchard.Specs/Users.feature.cs
generated
@@ -2,7 +2,7 @@
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.5.0.0
|
||||
// Runtime Version:4.0.30319.225
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -67,7 +67,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 9
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 10
|
||||
testRunner.Then("I should see \"Manage Users\"");
|
||||
testRunner.Then("I should see \"Users\"");
|
||||
#line 11
|
||||
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
|
||||
#line hidden
|
||||
@@ -88,7 +88,7 @@ this.ScenarioSetup(scenarioInfo);
|
||||
#line 16
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 17
|
||||
testRunner.Then("I should see \"Manage Users\"");
|
||||
testRunner.Then("I should see \"Users\"");
|
||||
#line 18
|
||||
testRunner.When("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
@@ -122,5 +124,18 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
Assert.That(username, Is.EqualTo("foo"));
|
||||
Assert.That(validateByUtc, Is.GreaterThan(_clock.UtcNow));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VerifyUserUnicityTurkishTest() {
|
||||
CultureInfo turkishCulture = new CultureInfo("tr-TR");
|
||||
Thread.CurrentThread.CurrentCulture = turkishCulture;
|
||||
|
||||
// Create user lower case
|
||||
_membershipService.CreateUser(new CreateUserParams("admin", "66554321", "foo@bar.com", "", "", true));
|
||||
_container.Resolve<IOrchardServices>().ContentManager.Flush();
|
||||
|
||||
// Verify unicity with upper case which with turkish coallition would yeld admin with an i without the dot and therefore generate a different user name
|
||||
Assert.That(_userService.VerifyUserUnicity("ADMIN", "differentfoo@bar.com"), Is.False); // should fail
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -273,6 +273,7 @@
|
||||
<Compile Include="Stubs\StubVirtualPathMonitor.cs" />
|
||||
<Compile Include="Stubs\StubCacheManager.cs" />
|
||||
<Compile Include="Stubs\StubWebSiteFolder.cs" />
|
||||
<Compile Include="UI\Resources\ResourceManagerTests.cs" />
|
||||
<Compile Include="UI\ShapeTests.cs" />
|
||||
<Compile Include="Utility\ContainerExtensions.cs" />
|
||||
<Compile Include="Environment\TestDependencies\TestDependency.cs" />
|
||||
|
133
src/Orchard.Tests/UI/Resources/ResourceManagerTests.cs
Normal file
133
src/Orchard.Tests/UI/Resources/ResourceManagerTests.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Resources;
|
||||
|
||||
namespace Orchard.Tests.UI.Resources {
|
||||
[TestFixture]
|
||||
public class ResourceManagerTests {
|
||||
private IContainer _container;
|
||||
private IResourceManager _resourceManager;
|
||||
private TestManifestProvider _testManifest;
|
||||
private string _appPath = "/AppPath/";
|
||||
|
||||
private class TestManifestProvider : IResourceManifestProvider {
|
||||
public Action<ResourceManifest> DefineManifest { get; set; }
|
||||
|
||||
public TestManifestProvider() {
|
||||
|
||||
}
|
||||
public void BuildManifests(ResourceManifestBuilder builder) {
|
||||
var manifest = builder.Add();
|
||||
if (DefineManifest != null) {
|
||||
DefineManifest(manifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void VerifyPaths(string resourceType, RequireSettings defaultSettings, string expectedPaths) {
|
||||
defaultSettings = defaultSettings ?? new RequireSettings();
|
||||
var requiredResources = _resourceManager.BuildRequiredResources(resourceType);
|
||||
var renderedResources = string.Join(",", requiredResources.Select(context => context.GetResourceUrl(defaultSettings, _appPath)).ToArray());
|
||||
Assert.That(renderedResources, Is.EqualTo(expectedPaths));
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<ResourceManager>().As<IResourceManager>();
|
||||
builder.RegisterType<TestManifestProvider>().As<IResourceManifestProvider>().SingleInstance();
|
||||
_container = builder.Build();
|
||||
_resourceManager = _container.Resolve<IResourceManager>();
|
||||
_testManifest = _container.Resolve<IResourceManifestProvider>() as TestManifestProvider;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReleasePathIsTheDefaultPath() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1");
|
||||
VerifyPaths("script", null, "script1.min.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DebugPathIsUsedWithDebugMode() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1");
|
||||
VerifyPaths("script", new RequireSettings { DebugMode = true }, "script1.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReleasePathIsUsedWhenNoDebugPath() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1");
|
||||
VerifyPaths("script", new RequireSettings { DebugMode = true }, "script1.min.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultSettingsAreOverriddenByUseDebugMode() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1").UseDebugMode();
|
||||
VerifyPaths("script", new RequireSettings { DebugMode = false }, "script1.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CdnPathIsUsedInCdnMode() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.js").SetCdn("http://cdn/script1.min.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1");
|
||||
VerifyPaths("script", new RequireSettings { CdnMode = true }, "http://cdn/script1.min.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CdnDebugPathIsUsedInCdnModeAndDebugMode() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.js").SetCdn("http://cdn/script1.min.js", "http://cdn/script1.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1");
|
||||
VerifyPaths("script", new RequireSettings { CdnMode = true, DebugMode = true }, "http://cdn/script1.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DebugPathIsUsedInCdnModeAndDebugModeAndThereIsNoCdnDebugPath() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js").SetCdn("http://cdn/script1.min.js");
|
||||
};
|
||||
_resourceManager.Require("script", "Script1");
|
||||
VerifyPaths("script", new RequireSettings { CdnMode = true, DebugMode = true }, "script1.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DependenciesAreAutoIncluded() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js");
|
||||
m.DefineResource("script", "Script2").SetUrl("script2.min.js").SetDependencies("Script1");
|
||||
};
|
||||
_resourceManager.Require("script", "Script2");
|
||||
VerifyPaths("script", null, "script1.min.js,script2.min.js");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DependenciesAssumeTheirParentUseDebugModeSetting() {
|
||||
_testManifest.DefineManifest = m => {
|
||||
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
|
||||
m.DefineResource("script", "Script2").SetUrl("script2.min.js", "script2.js").SetDependencies("Script1");
|
||||
};
|
||||
_resourceManager.Require("script", "Script2").UseDebugMode();
|
||||
VerifyPaths("script", new RequireSettings { DebugMode = false }, "script1.js,script2.js");
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,6 +4,7 @@ using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Containers.Models;
|
||||
using Orchard.Core.Containers.ViewModels;
|
||||
using Orchard.Localization;
|
||||
@@ -27,7 +28,7 @@ namespace Orchard.Core.Containers.Drivers {
|
||||
return ContentShape(
|
||||
"Parts_Containable_Edit",
|
||||
() => {
|
||||
var commonPart = part.As<ICommonPart>();
|
||||
var commonPart = part.As<CommonPart>();
|
||||
|
||||
var model = new ContainableViewModel();
|
||||
if (commonPart != null && commonPart.Container != null) {
|
||||
@@ -37,10 +38,12 @@ 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) {
|
||||
if (commonPart != null) {
|
||||
commonPart.Container = _contentManager.Get(model.ContainerId, VersionOptions.Latest);
|
||||
var containerItem = _contentManager.Get(model.ContainerId, VersionOptions.Latest);
|
||||
commonPart.Record.Container = containerItem == null ? null : containerItem.Record;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// note: string.isnullorempty not being recognized by linq-to-nhibernate hence the inline or
|
||||
@@ -50,7 +53,7 @@ namespace Orchard.Core.Containers.Drivers {
|
||||
var listItems = new[] { new SelectListItem { Text = T("(None)").Text, Value = "0" } }
|
||||
.Concat(containers.Select(x => new SelectListItem {
|
||||
Value = Convert.ToString(x.Id),
|
||||
Text = x.ContentItem.TypeDefinition.DisplayName + ": " + x.As<IRoutableAspect>().Title,
|
||||
Text = x.ContentItem.TypeDefinition.DisplayName + ": " + _contentManager.GetItemMetadata(x.ContentItem).DisplayText,
|
||||
Selected = x.Id == model.ContainerId,
|
||||
}))
|
||||
.ToList();
|
||||
|
@@ -1,4 +1,9 @@
|
||||
@Display(Model.ContentItems)
|
||||
@{
|
||||
IEnumerable<object> items = Model.ContentItems;
|
||||
Model.ContentItems.Classes.Add("content-items");
|
||||
Model.ContentItems.Classes.Add("list-items");
|
||||
}
|
||||
@Display(items)
|
||||
@if (Model.ShowPager) {
|
||||
@Display(Model.Pager)
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
@using Orchard.ContentManagement
|
||||
@{
|
||||
GroupInfo groupInfo = Model.GroupInfo;
|
||||
Layout.Title = (groupInfo != null ? T("Settings for {0}", groupInfo.Name) : T("General Settings")).ToString();
|
||||
Layout.Title = T("Settings").ToString();
|
||||
}
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
}, "Id", "Text", (int)Model.ResourceDebugMode);
|
||||
}
|
||||
<fieldset>
|
||||
<legend>@T("Enter Settings")</legend>
|
||||
<legend>@T("General")</legend>
|
||||
<div>
|
||||
<label for="SiteName">@T("Site name")</label>
|
||||
@Html.EditorFor(m => m.SiteName)
|
||||
|
@@ -2,7 +2,7 @@
|
||||
@using Orchard.Comments.Models;
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Enter Settings")</legend>
|
||||
<legend>@T("Comments")</legend>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.ModerateComments)
|
||||
<label class="forcheckbox" for="CommentSettings_ModerateComments">@T("Comments must be approved before they appear")</label>
|
||||
|
@@ -4,7 +4,6 @@ if (!window.shapeTracingMetadataHost) {
|
||||
window.shapeTracingMetadataHost.placement = {
|
||||
'n/a': 'n/a'
|
||||
};
|
||||
window.shapeTracingMetadataHost.references = {};
|
||||
}
|
||||
|
||||
jQuery(function ($) {
|
||||
@@ -37,7 +36,7 @@ jQuery(function ($) {
|
||||
var previousSize = 0;
|
||||
|
||||
// represents the arrow to add to any collpasible container
|
||||
var glyph = $('<span class="expando-glyph-container closed"><span class="expando-glyph"></span>​</span>');
|
||||
var glyph = '<span class="expando-glyph-container closed"><span class="expando-glyph"></span>​</span>';
|
||||
|
||||
// ensure the ghost has always the same size as the container
|
||||
// and the container is always positionned correctly
|
||||
@@ -118,7 +117,7 @@ jQuery(function ($) {
|
||||
$('#shape-tracing-resize-handle').addClass('ui-resizable-handle ui-resizable-n');
|
||||
shapeTracingContainer.resizable({
|
||||
handles: { n: '#shape-tracing-resize-handle' },
|
||||
grid: 20, // mitigates the number of calls to syncResize(), and aligns to the line height
|
||||
grid: 20, // mitigates the number of calls to syncResize()
|
||||
resize: function () { shapeTracingEnabled = false },
|
||||
stop: function () { shapeTracingEnabled = true }
|
||||
});
|
||||
@@ -192,27 +191,34 @@ jQuery(function ($) {
|
||||
shapeTracingWindowTree.append(shapes);
|
||||
|
||||
// add the expand/collapse logic to the shapes tree
|
||||
shapeTracingWindowTree.find('li:has(ul:has(li))').prepend(glyph);
|
||||
shapeTracingWindowTree.find('li:has(ul:has(li))').prepend($(glyph));
|
||||
|
||||
// collapse all sub uls
|
||||
shapeTracingWindowTree.find('ul ul').toggle(false);
|
||||
|
||||
// expands a list of shapes in the tree
|
||||
var openExpando = function (expando) {
|
||||
if (expando.hasClass("closed") || expando.hasClass("closing")) {
|
||||
expando.siblings('ul').slideDown(100, function () { expando.removeClass("opening").removeClass("closed").addClass("open"); });
|
||||
expando.addClass("opening");
|
||||
if (expando.hasClass("closed")) {
|
||||
expando.siblings('ul').toggle(true);
|
||||
expando.removeClass("closed").addClass("open");
|
||||
}
|
||||
}
|
||||
|
||||
// collapses a list of shapes in the tree
|
||||
var closeExpando = function (expando) {
|
||||
if (!expando.hasClass("closed") && !expando.hasClass("closing")) {
|
||||
expando.siblings('ul').slideUp(100, function () { expando.removeClass("closing").removeClass("open").addClass("closed"); });
|
||||
expando.addClass("closing");
|
||||
if (expando.hasClass("open")) {
|
||||
expando.siblings('ul').toggle(false);
|
||||
expando.removeClass("open").addClass("closed");
|
||||
}
|
||||
}
|
||||
|
||||
shapeTracingWindow.add(shapeTracingResizeHandle).hover(function () {
|
||||
shapeTracingOverlay.hide();
|
||||
}, function () {
|
||||
shapeTracingOverlay.show();
|
||||
}
|
||||
);
|
||||
|
||||
//create an overlay on shapes' descendants
|
||||
var overlayTarget = null;
|
||||
$('[shape-id]').add(shapeTracingOverlay).mousemove(
|
||||
@@ -316,7 +322,7 @@ jQuery(function ($) {
|
||||
$("[shape-id-meta]").detach().prependTo(shapeTracingWindowContent);
|
||||
|
||||
// add the expand/collapse logic to the shape model
|
||||
shapeTracingWindowContent.find('li:has(ul:has(li))').prepend(glyph);
|
||||
shapeTracingWindowContent.find('li:has(ul:has(li))').prepend($(glyph));
|
||||
|
||||
// collapse all sub uls
|
||||
shapeTracingWindowContent.find('ul ul').toggle(false);
|
||||
@@ -328,7 +334,7 @@ jQuery(function ($) {
|
||||
shapeTracingTabsShape.addClass('selected');
|
||||
|
||||
// remove old content
|
||||
shapeTracingMetaContent.empty();
|
||||
shapeTracingMetaContent.children().remove();
|
||||
|
||||
// render the template
|
||||
if (currentShape && shapeTracingMetadataHost[currentShape]) {
|
||||
@@ -338,10 +344,14 @@ jQuery(function ($) {
|
||||
shapeTracingBreadcrumb.text('');
|
||||
|
||||
// create collapsible containers
|
||||
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
|
||||
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend($(glyph));
|
||||
shapeTracingMetaContent.find('ul ul').toggle(false);
|
||||
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
|
||||
|
||||
$('#activeTemplate').click(function () {
|
||||
displayTabTemplate();
|
||||
});
|
||||
|
||||
defaultTab = displayTabShape;
|
||||
};
|
||||
|
||||
@@ -358,7 +368,7 @@ jQuery(function ($) {
|
||||
shapeTracingTabsModel.addClass('selected');
|
||||
|
||||
// remove old content
|
||||
shapeTracingMetaContent.empty();
|
||||
shapeTracingMetaContent.children().remove();
|
||||
|
||||
// render the template
|
||||
if (currentShape && shapeTracingMetadataHost[currentShape]) {
|
||||
@@ -368,7 +378,7 @@ jQuery(function ($) {
|
||||
shapeTracingBreadcrumb.text('');
|
||||
|
||||
// create collapsible containers
|
||||
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
|
||||
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend($(glyph));
|
||||
shapeTracingMetaContent.find('ul ul').toggle(false);
|
||||
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
|
||||
|
||||
@@ -407,7 +417,7 @@ jQuery(function ($) {
|
||||
});
|
||||
|
||||
// open the root node (Model)
|
||||
openExpando(shapeTracingMetaContent.find('.expando-glyph-container:first'))
|
||||
shapeTracingMetaContent.find('.expando-glyph-container:first').click();
|
||||
|
||||
defaultTab = displayTabModel;
|
||||
};
|
||||
@@ -423,7 +433,7 @@ jQuery(function ($) {
|
||||
shapeTracingTabsPlacement.addClass('selected');
|
||||
|
||||
// remove old content
|
||||
shapeTracingMetaContent.empty();
|
||||
shapeTracingMetaContent.children().remove();
|
||||
|
||||
// render the template
|
||||
if (currentShape && shapeTracingMetadataHost[currentShape]) {
|
||||
@@ -450,7 +460,7 @@ jQuery(function ($) {
|
||||
shapeTracingTabsTemplate.addClass('selected');
|
||||
|
||||
// remove old content
|
||||
shapeTracingMetaContent.empty();
|
||||
shapeTracingMetaContent.children().remove();
|
||||
|
||||
// render the template
|
||||
if (currentShape && shapeTracingMetadataHost[currentShape]) {
|
||||
@@ -476,7 +486,7 @@ jQuery(function ($) {
|
||||
shapeTracingTabsHtml.addClass('selected');
|
||||
|
||||
// remove old content
|
||||
shapeTracingMetaContent.empty();
|
||||
shapeTracingMetaContent.children().remove();
|
||||
|
||||
// render the template
|
||||
if (currentShape && shapeTracingMetadataHost[currentShape]) {
|
||||
@@ -507,7 +517,7 @@ jQuery(function ($) {
|
||||
// hooks the click event on expandos
|
||||
var expandCollapseExpando = function () {
|
||||
var _this = $(this);
|
||||
if (_this.hasClass("closed") || _this.hasClass("closing")) {
|
||||
if (_this.hasClass("closed")) {
|
||||
openExpando(_this);
|
||||
}
|
||||
else {
|
||||
|
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Xml.Linq;
|
||||
using ClaySharp;
|
||||
using ClaySharp.Behaviors;
|
||||
@@ -11,25 +10,22 @@ using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.DesignerTools.Services {
|
||||
|
||||
|
||||
public class ObjectDumper {
|
||||
private const int MaxStringLength = 60;
|
||||
|
||||
private readonly Stack<object> _parents = new Stack<object>();
|
||||
private readonly Stack<XElement> _currents = new Stack<XElement>();
|
||||
private readonly int _levels;
|
||||
private readonly Dictionary<int, XElement> _local;
|
||||
private readonly Dictionary<int, XElement> _global;
|
||||
|
||||
private readonly XDocument _xdoc;
|
||||
private XElement _current;
|
||||
|
||||
// object/key/dump
|
||||
|
||||
public ObjectDumper(int levels, Dictionary<int, XElement> local, Dictionary<int, XElement> global) {
|
||||
public ObjectDumper(int levels)
|
||||
{
|
||||
_levels = levels;
|
||||
_local = local;
|
||||
_global = global;
|
||||
_xdoc = new XDocument();
|
||||
_xdoc.Add(_current = new XElement("ul"));
|
||||
}
|
||||
@@ -40,6 +36,7 @@ namespace Orchard.DesignerTools.Services {
|
||||
}
|
||||
|
||||
_parents.Push(o);
|
||||
|
||||
// starts a new container
|
||||
EnterNode("li");
|
||||
|
||||
@@ -51,20 +48,11 @@ namespace Orchard.DesignerTools.Services {
|
||||
DumpValue(o, name);
|
||||
}
|
||||
else {
|
||||
int hashCode = RuntimeHelpers.GetHashCode(o);
|
||||
// if the object has already been processed, return a named ref to it
|
||||
if (_global.ContainsKey(hashCode)) {
|
||||
_current.Add(
|
||||
new XElement("h1", new XText(name)),
|
||||
new XElement("span", FormatType(o)),
|
||||
new XElement("a", new XAttribute("href", hashCode.ToString()))
|
||||
);
|
||||
}
|
||||
else {
|
||||
_global.Add(hashCode, _current);
|
||||
_local.Add(hashCode, _current);
|
||||
DumpObject(o, name);
|
||||
if (_parents.Count >= _levels) {
|
||||
return _current;
|
||||
}
|
||||
|
||||
DumpObject(o, name);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -87,29 +75,31 @@ namespace Orchard.DesignerTools.Services {
|
||||
_current.Add(
|
||||
new XElement("h1", new XText(name)),
|
||||
new XElement("span", FormatType(o))
|
||||
);
|
||||
);
|
||||
|
||||
EnterNode("ul");
|
||||
|
||||
if (_parents.Count >= _levels) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (o is IDictionary) {
|
||||
DumpDictionary((IDictionary) o);
|
||||
}
|
||||
else if (o is IShape) {
|
||||
DumpShape((IShape) o);
|
||||
|
||||
if (o is IDictionary) {
|
||||
DumpDictionary((IDictionary)o);
|
||||
}
|
||||
else if (o is IShape) {
|
||||
DumpShape((IShape)o);
|
||||
|
||||
// a shape can also be IEnumerable
|
||||
if (o is IEnumerable) {
|
||||
// a shape can also be IEnumerable
|
||||
if (o is IEnumerable) {
|
||||
DumpEnumerable((IEnumerable) o);
|
||||
}
|
||||
}
|
||||
else if (o is IEnumerable) {
|
||||
DumpEnumerable((IEnumerable) o);
|
||||
}
|
||||
else {
|
||||
DumpMembers(o);
|
||||
}
|
||||
}
|
||||
else if (o is IEnumerable)
|
||||
{
|
||||
DumpEnumerable((IEnumerable)o);
|
||||
}
|
||||
else {
|
||||
DumpMembers(o);
|
||||
finally {
|
||||
RestoreCurrentNode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,55 +114,46 @@ namespace Orchard.DesignerTools.Services {
|
||||
return;
|
||||
}
|
||||
|
||||
EnterNode("ul");
|
||||
|
||||
try{
|
||||
foreach (var member in members) {
|
||||
if (o is ContentItem && member.Name == "ContentManager"
|
||||
|| o is Delegate) {
|
||||
continue;
|
||||
}
|
||||
SafeCall(() => DumpMember(o, member));
|
||||
foreach (var member in members) {
|
||||
if (o is ContentItem && member.Name == "ContentManager"
|
||||
|| o is Delegate) {
|
||||
continue;
|
||||
}
|
||||
SafeCall(() => DumpMember(o, member));
|
||||
}
|
||||
|
||||
// process ContentItem.Parts specifically
|
||||
foreach (var member in members) {
|
||||
if (o is ContentItem && member.Name == "Parts") {
|
||||
foreach (var part in ((ContentItem) o).Parts) {
|
||||
SafeCall(() => Dump(part, part.PartDefinition.Name));
|
||||
// process ContentItem.Parts specifically
|
||||
foreach (var member in members) {
|
||||
if (o is ContentItem && member.Name == "Parts") {
|
||||
foreach (var part in ((ContentItem) o).Parts) {
|
||||
// ignore contentparts like ContentPart<ContentItemVersionRecord>
|
||||
if(part.GetType().IsGenericType) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var member in members) {
|
||||
// process ContentPart.Fields specifically
|
||||
if (o is ContentPart && member.Name == "Fields") {
|
||||
foreach (var field in ((ContentPart) o).Fields) {
|
||||
SafeCall(() => Dump(field, field.Name));
|
||||
}
|
||||
SafeCall(() => Dump(part, part.PartDefinition.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
RestoreCurrentNode();
|
||||
|
||||
foreach (var member in members) {
|
||||
// process ContentPart.Fields specifically
|
||||
if (o is ContentPart && member.Name == "Fields") {
|
||||
foreach (var field in ((ContentPart) o).Fields) {
|
||||
SafeCall(() => Dump(field, field.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DumpEnumerable(IEnumerable enumerable) {
|
||||
if(!enumerable.GetEnumerator().MoveNext()) {
|
||||
if (!enumerable.GetEnumerator().MoveNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnterNode("ul");
|
||||
|
||||
try {
|
||||
int i = 0;
|
||||
foreach (var child in enumerable) {
|
||||
Dump(child, string.Format("[{0}]", i++));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
RestoreCurrentNode();
|
||||
int i = 0;
|
||||
foreach (var child in enumerable) {
|
||||
Dump(child, string.Format("[{0}]", i++));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,21 +162,14 @@ namespace Orchard.DesignerTools.Services {
|
||||
return;
|
||||
}
|
||||
|
||||
EnterNode("ul");
|
||||
|
||||
try {
|
||||
foreach (var key in dictionary.Keys) {
|
||||
Dump(dictionary[key], string.Format("[\"{0}\"]", key));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
RestoreCurrentNode();
|
||||
foreach (var key in dictionary.Keys) {
|
||||
Dump(dictionary[key], string.Format("[\"{0}\"]", key));
|
||||
}
|
||||
}
|
||||
|
||||
private void DumpShape(IShape shape) {
|
||||
|
||||
var b = ((IClayBehaviorProvider)(dynamic)shape).Behavior as ClayBehaviorCollection;
|
||||
var b = ((IClayBehaviorProvider) (dynamic) shape).Behavior as ClayBehaviorCollection;
|
||||
|
||||
if (b == null)
|
||||
return;
|
||||
@@ -216,19 +190,12 @@ namespace Orchard.DesignerTools.Services {
|
||||
return;
|
||||
}
|
||||
|
||||
EnterNode("ul");
|
||||
|
||||
try {
|
||||
foreach (var key in props.Keys) {
|
||||
// ignore private members (added dynmically by the shape wrapper)
|
||||
if (key.ToString().StartsWith("_")) {
|
||||
continue;
|
||||
}
|
||||
Dump(props[key], key.ToString());
|
||||
foreach (var key in props.Keys) {
|
||||
// ignore private members (added dynmically by the shape wrapper)
|
||||
if (key.ToString().StartsWith("_")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
RestoreCurrentNode();
|
||||
Dump(props[key], key.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,9 +272,10 @@ namespace Orchard.DesignerTools.Services {
|
||||
_current = _currents.Pop();
|
||||
}
|
||||
|
||||
private void EnterNode(string tag) {
|
||||
private XElement EnterNode(string tag) {
|
||||
SaveCurrentNode();
|
||||
_current.Add(_current = new XElement(tag));
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Routing;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
@@ -23,7 +22,6 @@ namespace Orchard.DesignerTools.Services {
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
private readonly IAuthorizer _authorizer;
|
||||
private int _shapeId;
|
||||
private readonly Dictionary<int, XElement> _dumped = new Dictionary<int, XElement>(1000);
|
||||
|
||||
public ShapeTracingFactory(
|
||||
WorkContext workContext,
|
||||
@@ -76,10 +74,12 @@ namespace Orchard.DesignerTools.Services {
|
||||
}
|
||||
|
||||
shapeMetadata.Wrappers.Add("ShapeTracingWrapper");
|
||||
shapeMetadata.OnDisplaying(OnDisplaying);
|
||||
}
|
||||
}
|
||||
public void Displaying(ShapeDisplayingContext context) {}
|
||||
|
||||
public void Displaying(ShapeDisplayingContext context) {
|
||||
public void OnDisplaying(ShapeDisplayingContext context) {
|
||||
if (!IsActivable()) {
|
||||
return;
|
||||
}
|
||||
@@ -96,24 +96,18 @@ namespace Orchard.DesignerTools.Services {
|
||||
var descriptor = shapeTable.Descriptors[shapeMetadata.Type];
|
||||
|
||||
// dump the Shape's content
|
||||
var local = new Dictionary<int, XElement>();
|
||||
new ObjectDumper(6, local, _dumped).Dump(context.Shape, "Model");
|
||||
context.Shape.Reference = RuntimeHelpers.GetHashCode(context.Shape);
|
||||
var dump = new ObjectDumper(6).Dump(context.Shape, "Model");
|
||||
|
||||
var sb = new StringBuilder();
|
||||
context.Shape.LocalReferences = new Dictionary<int, string>();
|
||||
foreach (var key in local.Keys) {
|
||||
sb.Clear();
|
||||
ConvertToJSon(local[key], sb);
|
||||
((Dictionary<int, string>) context.Shape.LocalReferences)[key] = sb.ToString();
|
||||
}
|
||||
ConvertToJSon(dump, sb);
|
||||
shape._Dump = sb.ToString();
|
||||
|
||||
shape.Template = null;
|
||||
shape.OriginalTemplate = descriptor.BindingSource;
|
||||
|
||||
foreach (var extension in new[] { ".cshtml", ".aspx" }) {
|
||||
foreach (var alternate in shapeMetadata.Alternates.Reverse()) {
|
||||
var alternateFilename = currentTheme.Location + "/" + currentTheme.Id + "/Views/" + alternate.Replace("__", "-").Replace("_", ".") + extension;
|
||||
foreach (var alternate in shapeMetadata.Alternates.Reverse().Concat(new [] {shapeMetadata.Type}) ) {
|
||||
var alternateFilename = FormatShapeFilename(alternate, shapeMetadata.Type, shapeMetadata.DisplayType, currentTheme.Location + "/" + currentTheme.Id, extension);
|
||||
if (_webSiteFolder.FileExists(alternateFilename)) {
|
||||
shape.Template = alternateFilename;
|
||||
}
|
||||
@@ -158,47 +152,59 @@ namespace Orchard.DesignerTools.Services {
|
||||
public void Displayed(ShapeDisplayedContext context) {
|
||||
}
|
||||
|
||||
private static void ConvertToJSon(XElement x, StringBuilder sb) {
|
||||
public static void ConvertToJSon(XElement x, StringBuilder sb) {
|
||||
if(x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (x.Name.ToString()) {
|
||||
case "ul" :
|
||||
var first = true;
|
||||
foreach(var li in x.Elements()) {
|
||||
if (!first) sb.Append(",");
|
||||
ConvertToJSon(li, sb);
|
||||
sb.Append(",");
|
||||
first = false;
|
||||
}
|
||||
break;
|
||||
case "li":
|
||||
var name = x.Element("h1").Value;
|
||||
var value = x.Element("span").Value;
|
||||
|
||||
sb.AppendFormat("name: \"{0}\", ", FormatJsonValue(name));
|
||||
sb.AppendFormat("value: \"{0}\"", FormatJsonValue(value));
|
||||
|
||||
var a = x.Element("a");
|
||||
if (a != null) {
|
||||
sb.AppendFormat(", children: shapeTracingMetadataHost.references[{0}]", a.Attribute("href").Value);
|
||||
}
|
||||
sb.AppendFormat("\"name\": \"{0}\", ", FormatJsonValue(name));
|
||||
sb.AppendFormat("\"value\": \"{0}\"", FormatJsonValue(value));
|
||||
|
||||
var ul = x.Element("ul");
|
||||
if (ul != null) {
|
||||
sb.Append(", children: [");
|
||||
if (ul != null && ul.Descendants().Any()) {
|
||||
sb.Append(", \"children\": [");
|
||||
first = true;
|
||||
foreach (var li in ul.Elements()) {
|
||||
sb.Append("{ ");
|
||||
sb.Append(first ? "{ " : ", {");
|
||||
ConvertToJSon(li, sb);
|
||||
sb.Append(" },");
|
||||
sb.Append(" }");
|
||||
first = false;
|
||||
}
|
||||
sb.Append("]");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatJsonValue(string value) {
|
||||
// replace " by \" in json strings
|
||||
return value.Replace("\"", @"\""");
|
||||
return value.Replace(@"\", @"\\").Replace("\"", @"\""").Replace("\r\n", @"\n").Replace("\n", @"\n");
|
||||
}
|
||||
|
||||
private static string FormatShapeFilename(string shape, string shapeType, string displayType, string themePrefix, string extension) {
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(displayType)) {
|
||||
if (shape.StartsWith(shapeType + "_" + displayType)) {
|
||||
shape = shapeType + shape.Substring(shapeType.Length + displayType.Length + 1) + "_" + displayType;
|
||||
}
|
||||
}
|
||||
|
||||
return themePrefix + "/Views/" + shape.Replace("__", "-").Replace("_", ".") + extension;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,16 +1,22 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Mvc.Filters;
|
||||
using Orchard.Security;
|
||||
using Orchard.UI.Admin;
|
||||
|
||||
namespace Orchard.DesignerTools.Services {
|
||||
public class TemplatesFilter : FilterProvider, IResultFilter {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly WorkContext _workContext;
|
||||
private readonly IAuthorizer _authorizer;
|
||||
private readonly dynamic _shapeFactory;
|
||||
|
||||
public TemplatesFilter(
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
WorkContext workContext,
|
||||
IAuthorizer authorizer,
|
||||
IShapeFactory shapeFactory) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_workContext = workContext;
|
||||
_authorizer = authorizer;
|
||||
_shapeFactory = shapeFactory;
|
||||
}
|
||||
|
||||
@@ -19,12 +25,27 @@ namespace Orchard.DesignerTools.Services {
|
||||
if (!(filterContext.Result is ViewResult))
|
||||
return;
|
||||
|
||||
var ctx = _workContextAccessor.GetContext();
|
||||
var tail = ctx.Layout.Tail;
|
||||
if(!IsActivable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tail = _workContext.Layout.Tail;
|
||||
tail.Add(_shapeFactory.ShapeTracingTemplates());
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext) {
|
||||
}
|
||||
|
||||
private bool IsActivable() {
|
||||
// activate on front-end only
|
||||
if (AdminFilter.IsApplied(new RequestContext(_workContext.HttpContext, new RouteData())))
|
||||
return false;
|
||||
|
||||
// if not logged as a site owner, still activate if it's a local request (development machine)
|
||||
if (!_authorizer.Authorize(StandardPermissions.SiteOwner))
|
||||
return _workContext.HttpContext.Request.IsLocal;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -75,7 +75,7 @@ button.create-template, button.create-template:hover, background-image:hover {
|
||||
clear:both;
|
||||
display:block;
|
||||
font-size:10pt;
|
||||
font-family:Segoe;
|
||||
font-family:Segoe UI,Trebuchet,Arial,Sans-Serif;;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
position:fixed;
|
||||
@@ -321,10 +321,14 @@ ul#shape-tracing-tabs {
|
||||
|
||||
#shape-tracing-window-content .grid-display div.type, #shape-tracing-window-content .grid-display div.value {
|
||||
position:absolute;
|
||||
left:66%;
|
||||
left:40%;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
#shape-tracing-window-content div.model div.type, #shape-tracing-window-content div.model div.value {
|
||||
left:66%;
|
||||
}
|
||||
|
||||
#shape-tracing-breadcrumb {
|
||||
background:rgba(236, 241, 242, 1.0);
|
||||
border-bottom:1px solid rgba(182, 188, 189, 1.0);
|
||||
|
@@ -1,8 +1,22 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
@functions {
|
||||
string FormatShapeFilename(string type, string themeId) {
|
||||
return "~/Themes/" + themeId + "/Views/" + type.Replace("__", "-").Replace("_", ".") + ".cshtml";
|
||||
string FormatShapeName(string shape) {
|
||||
string shapeType = Model.ShapeType;
|
||||
string displayType = Model.DisplayType;
|
||||
|
||||
if(!String.IsNullOrWhiteSpace(displayType)) {
|
||||
if(shape.StartsWith(shapeType + "_" + displayType)) {
|
||||
shape = shapeType + shape.Substring(shapeType.Length + displayType.Length + 1) + "_" + displayType;
|
||||
}
|
||||
}
|
||||
|
||||
return shape.Replace("__", "-").Replace("_", ".");
|
||||
}
|
||||
|
||||
string FormatShapeFilename(string shape, string themeId) {
|
||||
shape = FormatShapeName(shape);
|
||||
return "~/Themes/" + themeId + "/Views/" + shape.Replace("__", "-").Replace("_", ".") + ".cshtml";
|
||||
}
|
||||
|
||||
string RemoveBeacons(string htmlContent) {
|
||||
@@ -20,10 +34,6 @@
|
||||
<script type="text/javascript">
|
||||
shapeTracingMetadataHost[@Model.ShapeId] = {};
|
||||
|
||||
@foreach (var pair in Model.LocalReferences) {
|
||||
<text>shapeTracingMetadataHost.references[@pair.Key] = { @(new MvcHtmlString(pair.Value)) };</text>
|
||||
}
|
||||
|
||||
shapeTracingMetadataHost[@Model.ShapeId].shape = {
|
||||
type: '@Model.ShapeType',
|
||||
template: '@Model.Template',
|
||||
@@ -32,10 +42,11 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
|
||||
position: '@(String.IsNullOrEmpty((string)Model.Position) ? T("n/a").Text : Model.Position.ToString())',
|
||||
placement: '@(String.IsNullOrEmpty((string)Model.PlacementSource) ? T("n/a").Text : Model.PlacementSource.ToString())',
|
||||
alternates: [
|
||||
@foreach (var alternate in Model.Alternates) {
|
||||
@foreach (var alternate in (new[] { (string)Model.ShapeType }).Concat((List<string>)Model.Alternates))
|
||||
{
|
||||
<text>{</text>
|
||||
<text>filename: '@FormatShapeFilename(alternate, WorkContext.CurrentTheme.Id)',</text>
|
||||
<text>alternate: '@alternate',</text>
|
||||
<text>alternate: '@FormatShapeName(alternate)',</text>
|
||||
<text>template: '@Model.Template',</text>
|
||||
<text>returnUrl: '@Context.Request.RawUrl'</text>
|
||||
<text>},</text>
|
||||
@@ -50,11 +61,11 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
|
||||
],
|
||||
html: '@RemoveEmptyLines(RemoveBeacons(Display(Model.ChildContent).ToString())).Replace(Environment.NewLine, "\\n")',
|
||||
templateContent: '@(String.IsNullOrWhiteSpace((string)Model.TemplateContent) ? @T("Content not available as coming from source code.") : @Model.TemplateContent.Replace(Environment.NewLine, "\\n"))',
|
||||
model: shapeTracingMetadataHost.references[@Model.Reference]
|
||||
model: { @(new MvcHtmlString((string)@Model.Dump)) }
|
||||
};
|
||||
|
||||
@if(!String.IsNullOrEmpty((string)Model.PlacementSource) && !TempData.ContainsKey((string)Model.PlacementSource)) {
|
||||
TempData[(string)Model.PlacementSource] = new object();
|
||||
@if (!String.IsNullOrEmpty((string)Model.PlacementSource) && (WorkContext.HttpContext.Items[(string)Model.PlacementSource] == null)) {
|
||||
WorkContext.HttpContext.Items[(string)Model.PlacementSource] = new object();
|
||||
<text>shapeTracingMetadataHost.placement['@Model.PlacementSource.ToString()'] = '@Model.PlacementContent.Replace(Environment.NewLine, "\\n")'; </text>
|
||||
}
|
||||
|
||||
|
@@ -7,11 +7,11 @@
|
||||
<div id="shape-tracing-window-tree"></div>
|
||||
<div id="shape-tracing-window-content">
|
||||
<ul id="shape-tracing-tabs">
|
||||
<li id="shape-tracing-tabs-shape" class="selected first">Shape</li>
|
||||
<li id="shape-tracing-tabs-model" class="middle">Model</li>
|
||||
<li id="shape-tracing-tabs-placement" class="middle">Placement</li>
|
||||
<li id="shape-tracing-tabs-template" class="middle">Template</li>
|
||||
<li id="shape-tracing-tabs-html" class="last">HTML</li>
|
||||
<li id="shape-tracing-tabs-shape" class="selected first">@T("Shape")</li>
|
||||
<li id="shape-tracing-tabs-model" class="middle">@T("Model")</li>
|
||||
<li id="shape-tracing-tabs-placement" class="middle">@T("Placement")</li>
|
||||
<li id="shape-tracing-tabs-template" class="middle">@T("Template")</li>
|
||||
<li id="shape-tracing-tabs-html" class="last">@T("HTML")</li>
|
||||
</ul>
|
||||
<div id="shape-tracing-breadcrumb"></div>
|
||||
<div id="shape-tracing-meta-content"></div>
|
||||
@@ -24,11 +24,13 @@
|
||||
<script id="shape-tracing-tabs-shape-template" type="text/x-jquery-tmpl">
|
||||
<div class="shape grid-display">
|
||||
<ul class="properties">
|
||||
<li class="sgd-s"><div class="name">Shape</div><div class="value">${shape.type}</div></li>
|
||||
<li class="sgd-t"><div class="name">Template</div><div class="value"><a href="#">${shape.template}</a></div></li>
|
||||
<li class="sgd-ot"><div class="name">Original Template</div><div class="value">${shape.originalTemplate}</div></li>
|
||||
<li class="sgd-d"><div class="name">Display Type</div><div class="value">${shape.displayType}</div></li>
|
||||
<li class="sgd-a"><div class="name">Alternates (${shape.alternates.length})</div>
|
||||
<li class="sgd-s"><div class="name">@T("Shape").Text</div><div class="value">${shape.type}</div></li>
|
||||
<li class="sgd-t"><div class="name">@T("Active Template").Text</div><div class="value"><a id="activeTemplate" href="#">${shape.template}</a></div></li>
|
||||
{{if shape.template != shape.originalTemplate}}
|
||||
<li class="sgd-ot"><div class="name">@T("Original Template").Text Template</div><div class="value">${shape.originalTemplate}</div></li>
|
||||
{{/if}}
|
||||
<li class="sgd-d"><div class="name">@T("Display Type").Text</div><div class="value">${shape.displayType}</div></li>
|
||||
<li class="sgd-a"><div class="name">@T("Alternate ({0})", "${shape.alternates.length}").Text</div>
|
||||
<div class="value"> </div>
|
||||
<ul>
|
||||
{{each shape.alternates}}
|
||||
@@ -47,7 +49,7 @@
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sgd-w"><div class="name">Wrappers (${shape.wrappers.length})</div>
|
||||
<li class="sgd-w"><div class="name">@T("Wrappers ({0})", "${shape.wrappers.length}")</div>
|
||||
<div class="value"> </div>
|
||||
<ul>
|
||||
{{each shape.wrappers}}
|
||||
|
@@ -40,7 +40,6 @@
|
||||
Wrappers: Model.Metadata.Wrappers,
|
||||
ChildContent: Model.Metadata.ChildContent,
|
||||
ShapeId: Model.ShapeId,
|
||||
Reference: Model.Reference,
|
||||
LocalReferences: Model.LocalReferences
|
||||
Dump: Model._Dump
|
||||
));
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
@using System.Net.Mail;
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("SMTP")</legend>
|
||||
<legend>@T("Email")</legend>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.Address)">@T("Sender email address")</label>
|
||||
@Html.EditorFor(m => m.Address)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
@model Orchard.Indexing.ViewModels.IndexViewModel
|
||||
@using Orchard.Indexing.Services;
|
||||
|
||||
@{ Layout.Title = T("Search Index Management").ToString(); }
|
||||
@{ Layout.Title = T("Settings").ToString(); }
|
||||
|
||||
@using (Html.BeginForm("update", "admin", FormMethod.Post, new {area = "Orchard.Indexing"})) {
|
||||
<fieldset>
|
||||
<legend>@T("Search Index Statistics")</legend>
|
||||
<legend>@T("Search Index")</legend>
|
||||
<ol class="decimal">
|
||||
@if (Model.IndexEntry == null) {
|
||||
|
||||
|
@@ -311,7 +311,7 @@ namespace Lists.Controllers {
|
||||
// ensure the item can be in that container.
|
||||
if (!string.IsNullOrEmpty(itemContentType) && item.ContentType != itemContentType) {
|
||||
Services.TransactionManager.Cancel();
|
||||
Services.Notifier.Information(T("One or more items could not be moved to '{0}' because it is restricted to containing items of type '{1}'.", _contentManager.GetItemMetadata(targetContainer).DisplayText, itemContentType));
|
||||
Services.Notifier.Information(T("One or more items could not be moved to '{0}' because it is restricted to containing items of type '{1}'.", _contentManager.GetItemMetadata(targetContainer).DisplayText ?? targetContainer.ContentItem.ContentType, itemContentType));
|
||||
return true; // todo: transactions
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace Lists.Controllers {
|
||||
FixItemPath(item);
|
||||
}
|
||||
Services.Notifier.Information(T("Content successfully moved to <a href=\"{0}\">{1}</a>.",
|
||||
Url.Action("List", new { containerId = targetContainerId }), _contentManager.GetItemMetadata(targetContainer).DisplayText));
|
||||
Url.Action("List", new { containerId = targetContainerId }), _contentManager.GetItemMetadata(targetContainer).DisplayText ?? targetContainer.ContentItem.ContentType));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -8,14 +8,14 @@
|
||||
|
||||
var targetContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
|
||||
contentItem => new SelectListItem {
|
||||
Text = T("Move to {0}", contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText).ToString(),
|
||||
Text = T("Move to {0}", contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText ?? contentItem.ContentType).ToString(),
|
||||
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
Selected = contentItem.Id == targetContainerId
|
||||
}).ToList();
|
||||
|
||||
var sourceContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
|
||||
contentItem => new SelectListItem {
|
||||
Text = contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText,
|
||||
Text = contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText ?? contentItem.ContentType,
|
||||
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
Selected = contentItem.Id == sourceContainerId
|
||||
}).ToList();
|
||||
|
@@ -31,15 +31,16 @@
|
||||
</div>
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
var options = (ContentOptions) Model.Options;
|
||||
<fieldset class="bulk-actions">
|
||||
<label for="publishActions">@T("Actions:")</label>
|
||||
<select id="publishActions" name="Options.BulkAction">
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.None, T("Choose action...").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.PublishNow, T("Publish Now").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Unpublish, T("Unpublish").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Remove, T("Delete").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.RemoveFromList, T("Remove from List").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.MoveToList, T("Move to List...").ToString())
|
||||
@Html.SelectOption(options.BulkAction, ContentsBulkAction.None, T("Choose action...").ToString())
|
||||
@Html.SelectOption(options.BulkAction, ContentsBulkAction.PublishNow, T("Publish Now").ToString())
|
||||
@Html.SelectOption(options.BulkAction, ContentsBulkAction.Unpublish, T("Unpublish").ToString())
|
||||
@Html.SelectOption(options.BulkAction, ContentsBulkAction.Remove, T("Delete").ToString())
|
||||
@Html.SelectOption(options.BulkAction, ContentsBulkAction.RemoveFromList, T("Remove from List").ToString())
|
||||
@Html.SelectOption(options.BulkAction, ContentsBulkAction.MoveToList, T("Move to List...").ToString())
|
||||
</select>
|
||||
@Html.DropDownList("TargetContainerId", lists, new { id = "TargetContainerId" })
|
||||
<button type="submit" name="submit.BulkEdit" value="yes">@T("Apply")</button>
|
||||
|
@@ -233,16 +233,8 @@ namespace Orchard.Media.Controllers {
|
||||
}
|
||||
}
|
||||
|
||||
public ActionResult EditMedia(string name, DateTime lastUpdated, long size, string folderName, string mediaPath) {
|
||||
var model = new MediaItemEditViewModel();
|
||||
model.Name = name;
|
||||
// todo: reimplement
|
||||
//model.Caption = caption ?? String.Empty;
|
||||
model.LastUpdated = lastUpdated;
|
||||
model.Size = size;
|
||||
model.FolderName = folderName;
|
||||
model.MediaPath = mediaPath;
|
||||
model.PublicUrl = _mediaService.GetPublicUrl(Path.Combine(mediaPath, name));
|
||||
public ActionResult EditMedia(MediaItemEditViewModel model) {
|
||||
model.PublicUrl = _mediaService.GetPublicUrl(Path.Combine(model.MediaPath, model.Name));
|
||||
return View(model);
|
||||
}
|
||||
|
||||
@@ -293,9 +285,8 @@ namespace Orchard.Media.Controllers {
|
||||
mediaPath = viewModel.MediaPath });
|
||||
}
|
||||
catch (Exception exception) {
|
||||
this.Error(exception, T("Editing media file failed: {0}", exception.Message), Logger, Services.Notifier);
|
||||
|
||||
return View(viewModel);
|
||||
this.Error(exception, T("Editing media file failed."), Logger, Services.Notifier);
|
||||
return EditMedia(viewModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -140,7 +140,10 @@ namespace Orchard.Media.Services {
|
||||
Argument.ThrowIfNullOrEmpty(newFileName, "newFileName");
|
||||
|
||||
if (!FileAllowed(newFileName, false)) {
|
||||
throw new ArgumentException(T("New file name {0} is not allowed", newFileName).ToString());
|
||||
if (string.IsNullOrEmpty(Path.GetExtension(newFileName))) {
|
||||
throw new ArgumentException(T("New file name \"{0}\" is not allowed. Please provide a file extension.", newFileName).ToString());
|
||||
}
|
||||
throw new ArgumentException(T("New file name \"{0}\" is not allowed.", newFileName).ToString());
|
||||
}
|
||||
|
||||
_storageProvider.RenameFile(_storageProvider.Combine(folderPath, currentFileName), _storageProvider.Combine(folderPath, newFileName));
|
||||
|
@@ -1,7 +1,7 @@
|
||||
@model Orchard.Media.Models.MediaSettingsPartRecord
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Enter Settings")</legend>
|
||||
<legend>@T("Media")</legend>
|
||||
<div>
|
||||
@Html.LabelFor(m => m.UploadAllowedFileTypeWhitelist, T("Upload allowed file types (list of extensions separated by spaces)"))
|
||||
@Html.TextBoxFor(m => m.UploadAllowedFileTypeWhitelist, new { @class = "textMedium" })
|
||||
|
@@ -11,6 +11,7 @@
|
||||
Layout.Title = T("Modules").ToString();
|
||||
}
|
||||
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost(Url.Action("Index", "Admin"))) {
|
||||
<fieldset class="search-actions">
|
||||
<input type="text" id="searchText" class="text-box single-line" name="@Html.NameOf(m => m.Options.SearchText)" value="@Model.Options.SearchText" />
|
||||
@@ -18,6 +19,10 @@
|
||||
<button type="submit">@T("Search").ToString()</button>
|
||||
</fieldset>
|
||||
|
||||
if (Model.InstallModules) {
|
||||
<span>@Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null)</span>
|
||||
}
|
||||
|
||||
if (Model.Modules.Count() > 0) {
|
||||
<ul class="contentItems">
|
||||
@foreach (ModuleEntry module in Model.Modules.OrderBy(m => m.Descriptor.Name)) {
|
||||
@@ -31,6 +36,3 @@
|
||||
@Display(Model.Pager)
|
||||
}
|
||||
|
||||
@if (Model.InstallModules) {
|
||||
<p id="otherActionsBar">@Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null)</p>
|
||||
}
|
@@ -1,24 +1,8 @@
|
||||
#main .features h2 {
|
||||
margin-top:0;
|
||||
}
|
||||
#main .features h3 {
|
||||
padding:0 3em 0 0;
|
||||
}
|
||||
html.dyn #main ul.features button
|
||||
{
|
||||
display:none;
|
||||
}
|
||||
#otherActionsBar {
|
||||
clear: both;
|
||||
border-top-width: thin;
|
||||
border-top-style: solid;
|
||||
border-top-color: #E4E5E6;
|
||||
margin: 10px 0 0;
|
||||
padding: 10px 0 0;
|
||||
}
|
||||
.pageStatus {
|
||||
clear: both;
|
||||
}
|
||||
#main .features h2 { margin-top:0; }
|
||||
#main .features h3 { padding:0 3em 0 0; }
|
||||
html.dyn #main ul.features button { display:none; }
|
||||
.pageStatus { clear: both; }
|
||||
|
||||
.features.detail-view .category > ul {
|
||||
border:1px solid #EAEAEA;
|
||||
margin-bottom:2em;
|
||||
@@ -162,8 +146,7 @@ h2.recentlyInstalledModule {padding:0 0 0 40px;}
|
||||
.search-actions {
|
||||
float: right;
|
||||
height: auto;
|
||||
margin: 0 0 16px 0;
|
||||
padding-top: 0;
|
||||
padding:0 0 0 0;
|
||||
}
|
||||
|
||||
.manage {
|
||||
|
@@ -73,22 +73,15 @@ namespace Orchard.Packaging.Services {
|
||||
.SelectMany(
|
||||
source => {
|
||||
var galleryFeedContext = new GalleryFeedContext(new Uri(source.FeedUrl));
|
||||
IQueryable<PublishedPackage> packages = galleryFeedContext.Packages;
|
||||
|
||||
IQueryable<PublishedPackage> packages = includeScreenshots
|
||||
? galleryFeedContext.Packages.Expand("Screenshots")
|
||||
: galleryFeedContext.Packages;
|
||||
|
||||
if (query != null) {
|
||||
packages = query(packages);
|
||||
}
|
||||
|
||||
return packages.ToList().Select(
|
||||
p => {
|
||||
PublishedScreenshot firstScreenshot = includeScreenshots
|
||||
? galleryFeedContext.Screenshots
|
||||
.Where(s => s.PublishedPackageId == p.Id && s.PublishedPackageVersion == p.Version)
|
||||
.ToList()
|
||||
.FirstOrDefault()
|
||||
: null;
|
||||
return CreatePackageEntry(p, firstScreenshot, packagingSource, galleryFeedContext.GetReadStreamUri(p));
|
||||
});
|
||||
return packages.ToList().Select(p => CreatePackageEntry(p, packagingSource, galleryFeedContext.GetReadStreamUri(p)));
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -116,12 +109,14 @@ namespace Orchard.Packaging.Services {
|
||||
|
||||
#endregion
|
||||
|
||||
private static PackagingEntry CreatePackageEntry(PublishedPackage package, PublishedScreenshot screenshot, PackagingSource source, Uri downloadUri) {
|
||||
private static PackagingEntry CreatePackageEntry(PublishedPackage package, PackagingSource source, Uri downloadUri) {
|
||||
Uri baseUri = new Uri(string.Format("{0}://{1}:{2}/",
|
||||
downloadUri.Scheme,
|
||||
downloadUri.Host,
|
||||
downloadUri.Port));
|
||||
|
||||
PublishedScreenshot screenshot = package.Screenshots.FirstOrDefault();
|
||||
|
||||
string iconUrl = GetAbsoluteUri(package.IconUrl, baseUri);
|
||||
string firstScreenshot = screenshot != null ? GetAbsoluteUri(screenshot.ScreenshotUri, baseUri) : string.Empty;
|
||||
|
||||
|
@@ -84,7 +84,7 @@
|
||||
@if (!string.IsNullOrEmpty(item.ProjectUrl)) { <a href="@item.ProjectUrl">@item.ProjectUrl</a> } else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
<li class="rating"> | @T("Rating: ")
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", item.Rating, item.RatingsCount)">
|
||||
<div class="score" style="width:@(15 * (item.Rating))px"> </div>
|
||||
</div>
|
||||
</li>
|
||||
|
@@ -1,7 +1,8 @@
|
||||
@model Orchard.Packaging.ViewModels.PackagingSourcesViewModel
|
||||
|
||||
@{ Layout.Title = T("Settings for Gallery").ToString(); }
|
||||
@{ Layout.Title = T("Settings").ToString(); }
|
||||
|
||||
<h2>@T("Gallery")</h2>
|
||||
<div class="manage">
|
||||
@Html.ActionLink(T("Add Feed").Text, "AddSource", new { }, new { @class = "button primaryAction" })
|
||||
</div>
|
||||
|
@@ -88,7 +88,7 @@
|
||||
@if (!string.IsNullOrEmpty(item.ProjectUrl)) { <a href="@item.ProjectUrl">@item.ProjectUrl</a> } else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
<li class="rating"> | @T("Rating: ")
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", item.Rating, item.RatingsCount)">
|
||||
<div class="score" style="width:@(15 * (item.Rating))px"> </div>
|
||||
</div>
|
||||
</li>
|
||||
|
@@ -65,7 +65,7 @@
|
||||
@if (!string.IsNullOrEmpty(module.NewVersionToInstall.ProjectUrl)) { <a href="@module.NewVersionToInstall.ProjectUrl">@module.NewVersionToInstall.ProjectUrl</a> } else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
<li><div> | @T("Rating: ")
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", module.NewVersionToInstall.Rating, module.NewVersionToInstall.RatingsCount)">
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", module.NewVersionToInstall.Rating, module.NewVersionToInstall.RatingsCount)">
|
||||
<div class="score" style="width:@(15 * (module.NewVersionToInstall.Rating))px"> </div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -70,7 +70,7 @@
|
||||
@if (!string.IsNullOrEmpty(theme.NewVersionToInstall.ProjectUrl)) { <a href="@theme.NewVersionToInstall.ProjectUrl">@theme.NewVersionToInstall.ProjectUrl</a> } else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
<li><div> | @T("Rating: ")
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", theme.NewVersionToInstall.Rating, theme.NewVersionToInstall.RatingsCount)">
|
||||
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", theme.NewVersionToInstall.Rating, theme.NewVersionToInstall.RatingsCount)">
|
||||
<div class="score" style="width:@(15 * (theme.NewVersionToInstall.Rating))px"> </div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Commands;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Recipes.Models;
|
||||
using Orchard.Recipes.Services;
|
||||
|
||||
namespace Orchard.Recipes.Commands {
|
||||
public class RecipesCommands : DefaultOrchardCommandHandler {
|
||||
private readonly IRecipeHarvester _recipeHarvester;
|
||||
private readonly IRecipeManager _recipeManager;
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
|
||||
public RecipesCommands(IRecipeHarvester recipeHarvester, IRecipeManager recipeManager, IExtensionManager extensionManager) {
|
||||
_recipeHarvester = recipeHarvester;
|
||||
_recipeManager = recipeManager;
|
||||
_extensionManager = extensionManager;
|
||||
}
|
||||
|
||||
[CommandHelp("recipes harvest <extension-id>\r\n\t" + "Display list of available recipes for an extension")]
|
||||
[CommandName("recipes harvest")]
|
||||
public void HarvestRecipes(string extensionId) {
|
||||
ExtensionDescriptor extensionDescriptor = _extensionManager.GetExtension(extensionId);
|
||||
if (extensionDescriptor == null) {
|
||||
throw new OrchardException(T("Could not discover recipes because module '{0}' was not found.", extensionId));
|
||||
}
|
||||
|
||||
IEnumerable<Recipe> recipes = _recipeHarvester.HarvestRecipes(extensionId);
|
||||
if (recipes == null) {
|
||||
throw new OrchardException(T("No recipes found for extension {0}.", extensionId));
|
||||
}
|
||||
|
||||
Context.Output.WriteLine(T("List of available recipes"));
|
||||
Context.Output.WriteLine(T("--------------------------"));
|
||||
Context.Output.WriteLine();
|
||||
|
||||
foreach (Recipe recipe in recipes) {
|
||||
Context.Output.WriteLine(T("Recipe: {0}", recipe.Name));
|
||||
Context.Output.WriteLine(T(" Version: {0}", recipe.Version));
|
||||
Context.Output.WriteLine(T(" Tags: {0}", recipe.Tags));
|
||||
Context.Output.WriteLine(T(" Description: {0}", recipe.Description));
|
||||
Context.Output.WriteLine(T(" Author: {0}", recipe.Author));
|
||||
Context.Output.WriteLine(T(" Website: {0}", recipe.WebSite));
|
||||
}
|
||||
}
|
||||
|
||||
[CommandHelp("recipes execute <extension-id> <recipe-name>\r\n\t" + "Executes a recipe from a module")]
|
||||
[CommandName("recipes execute")]
|
||||
public void ExecuteRecipe(string extensionId, string recipeName) {
|
||||
ExtensionDescriptor extensionDescriptor = _extensionManager.GetExtension(extensionId);
|
||||
if (extensionDescriptor == null) {
|
||||
throw new OrchardException(T("Could not discover recipes because module '{0}' was not found.", extensionId));
|
||||
}
|
||||
|
||||
IEnumerable<Recipe> recipes = _recipeHarvester.HarvestRecipes(extensionId);
|
||||
if (recipes == null) {
|
||||
throw new OrchardException(T("No recipes found for extension {0}.", extensionId));
|
||||
}
|
||||
|
||||
Recipe recipe = recipes.FirstOrDefault(r => r.Name.Equals(recipeName, StringComparison.OrdinalIgnoreCase));
|
||||
if (recipe == null) {
|
||||
throw new OrchardException(T("Invalid recipe name {0}.", recipeName));
|
||||
}
|
||||
|
||||
try {
|
||||
_recipeManager.Execute(recipe);
|
||||
|
||||
Context.Output.WriteLine(T("Recipe scheduled for execution successfully.").Text);
|
||||
}
|
||||
catch {
|
||||
Context.Output.WriteLine(T("Recipe failed to execute.").Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -51,6 +51,7 @@
|
||||
<Content Include="web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Commands\RecipesCommands.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RecipeHandlers\CommandRecipeHandler.cs" />
|
||||
<Compile Include="RecipeHandlers\FeatureRecipeHandler.cs" />
|
||||
|
@@ -2,7 +2,7 @@
|
||||
@using Orchard.Search.ViewModels;
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Enter Settings")</legend>
|
||||
<legend>@T("Search")</legend>
|
||||
<div>
|
||||
@{var entryIndex = 0;}
|
||||
|
||||
|
@@ -245,7 +245,7 @@ namespace Orchard.Users.Controllers {
|
||||
_siteService.GetSiteSettings().As<SiteSettingsPart>().SuperUser = editModel.UserName;
|
||||
}
|
||||
|
||||
user.NormalizedUserName = editModel.UserName.ToLower();
|
||||
user.NormalizedUserName = editModel.UserName.ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,15 +1,24 @@
|
||||
using Orchard.Data.Migration;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Data.Migration;
|
||||
using Orchard.Users.Models;
|
||||
|
||||
namespace Orchard.Users {
|
||||
public class UsersDataMigration : DataMigrationImpl {
|
||||
|
||||
public UsersDataMigration(IOrchardServices orchardServices) {
|
||||
Services = orchardServices;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
public int Create() {
|
||||
SchemaBuilder.CreateTable("UserPartRecord",
|
||||
table => table
|
||||
.ContentPartRecord()
|
||||
.Column<string>("UserName")
|
||||
.Column<string>("Email")
|
||||
.Column<string>("NormalizedUserName")
|
||||
.Column<string>("NormalizedUserName", c => c.Unique())
|
||||
.Column<string>("Password")
|
||||
.Column<string>("PasswordFormat")
|
||||
.Column<string>("HashAlgorithm")
|
||||
@@ -32,7 +41,17 @@ namespace Orchard.Users {
|
||||
.Column<bool>("EnableLostPassword", c => c.WithDefault(false))
|
||||
);
|
||||
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int UpdateFrom1() {
|
||||
IEnumerable<UserPart> users = Services.ContentManager.Query<UserPart, UserPartRecord>().List();
|
||||
|
||||
foreach (UserPart user in users) {
|
||||
user.NormalizedUserName = user.UserName.ToUpperInvariant();
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
@@ -49,7 +49,7 @@ namespace Orchard.Users.Services {
|
||||
|
||||
user.Record.UserName = createUserParams.Username;
|
||||
user.Record.Email = createUserParams.Email;
|
||||
user.Record.NormalizedUserName = createUserParams.Username.ToLower();
|
||||
user.Record.NormalizedUserName = createUserParams.Username.ToUpperInvariant();
|
||||
user.Record.HashAlgorithm = "SHA1";
|
||||
SetPassword(user.Record, createUserParams.Password);
|
||||
|
||||
@@ -97,18 +97,24 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
|
||||
public IUser GetUser(string username) {
|
||||
var lowerName = username == null ? "" : username.ToLower();
|
||||
var higherName = username == null ? "" : username.ToUpperInvariant();
|
||||
|
||||
return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
|
||||
return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>()
|
||||
.Where(u => u.NormalizedUserName == higherName).List()
|
||||
.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public IUser ValidateUser(string userNameOrEmail, string password) {
|
||||
var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLower();
|
||||
var higherName = userNameOrEmail == null ? "" : userNameOrEmail.ToUpperInvariant();
|
||||
|
||||
var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
|
||||
|
||||
if (user == null)
|
||||
user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.Email == lowerName).List().FirstOrDefault();
|
||||
var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>()
|
||||
.Where(u =>
|
||||
u.NormalizedUserName == higherName ||
|
||||
u.Email == userNameOrEmail)
|
||||
.List()
|
||||
.FirstOrDefault(u =>
|
||||
u.UserName.Equals(userNameOrEmail, StringComparison.OrdinalIgnoreCase) ||
|
||||
u.Email == userNameOrEmail);
|
||||
|
||||
if ( user == null || ValidatePassword(user.As<UserPart>().Record, password) == false )
|
||||
return null;
|
||||
|
@@ -37,13 +37,16 @@ namespace Orchard.Users.Services {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public bool VerifyUserUnicity(string userName, string email) {
|
||||
string normalizedUserName = userName.ToLower();
|
||||
string normalizedUserName = userName.ToUpperInvariant();
|
||||
|
||||
if (_contentManager.Query<UserPart, UserPartRecord>()
|
||||
.Where(user =>
|
||||
user.NormalizedUserName == normalizedUserName ||
|
||||
user.Email == email)
|
||||
.List().Any()) {
|
||||
.List()
|
||||
.Any(user =>
|
||||
user.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase) ||
|
||||
user.Email == email)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,13 +54,17 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
|
||||
public bool VerifyUserUnicity(int id, string userName, string email) {
|
||||
string normalizedUserName = userName.ToLower();
|
||||
string normalizedUserName = userName.ToUpperInvariant();
|
||||
|
||||
if (_contentManager.Query<UserPart, UserPartRecord>()
|
||||
.Where(user =>
|
||||
user.NormalizedUserName == normalizedUserName ||
|
||||
user.Email == email)
|
||||
.List().Any(user => user.Id != id)) {
|
||||
.List()
|
||||
.Any(user =>
|
||||
(user.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase) ||
|
||||
user.Email == email) &&
|
||||
user.Id != id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
@model Orchard.Users.Models.RegistrationSettingsPartRecord
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Enter Settings")</legend>
|
||||
<legend>@T("Users")</legend>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.UsersCanRegister)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.UsersCanRegister)">@T("Users can create new accounts on the site")</label>
|
||||
|
@@ -2,13 +2,13 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@using Orchard.Warmup.Models;
|
||||
|
||||
@{ Layout.Title = T("Settings for Warmup").ToString(); }
|
||||
@{ Layout.Title = T("Settings").ToString(); }
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Enter Settings")</legend>
|
||||
<legend>@T("Warmup")</legend>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.Urls)">@T("Urls for which static warmup pages will be generated")</label>
|
||||
@Html.TextAreaFor(m => m.Urls, new { @class = "textMedium" })
|
||||
|
@@ -544,7 +544,7 @@ span.message {
|
||||
|
||||
form { margin: 0; padding: 0;}
|
||||
legend { font-size: 1.231em; font-weight: normal; border:none;}
|
||||
fieldset { padding:6px 0 0; margin:0 0 1em 0; border: 0px solid #dbdbdb; }
|
||||
fieldset { padding:6px 0 0; margin:0 0 12px 0; border: 0px solid #dbdbdb; }
|
||||
label { font-weight:normal; display:block; padding: 0 0 0.3em 0; }
|
||||
label.forcheckbox { margin:0 0 0 .4em; display:inline; }
|
||||
|
||||
@@ -1032,7 +1032,8 @@ html.dyn #submit-pager, html.dyn .apply-bulk-actions-auto { display:none; }
|
||||
margin:.5em 0;
|
||||
}
|
||||
.settings legend {
|
||||
margin:0 0 -.4em;
|
||||
margin:0 0 0 0;
|
||||
font-size:18px;
|
||||
}
|
||||
/* Core Contents and Orchard.PublishLater */
|
||||
|
||||
|
Reference in New Issue
Block a user