mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-02 19:44:02 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Orchard.ContentManagement.MetaData;
|
||||||
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
|
using Orchard.Core.Contents.Extensions;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Environment.Descriptor;
|
using Orchard.Environment.Descriptor;
|
||||||
using Orchard.Environment.Descriptor.Models;
|
using Orchard.Environment.Descriptor.Models;
|
||||||
@@ -59,6 +62,20 @@ namespace Orchard.Specs.Bindings {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Given(@"I have a containable content type ""(.*)\""")]
|
||||||
|
public void GivenIHaveAContainableContentType(string name) {
|
||||||
|
var webApp = Binding<WebAppHosting>();
|
||||||
|
webApp.Host.Execute(() => {
|
||||||
|
using (var environment = MvcApplication.CreateStandaloneEnvironment("Default")) {
|
||||||
|
var cdm = environment.Resolve<IContentDefinitionManager>();
|
||||||
|
|
||||||
|
var contentTypeDefinition = new ContentTypeDefinition(name, name);
|
||||||
|
cdm.StoreTypeDefinition(contentTypeDefinition);
|
||||||
|
cdm.AlterTypeDefinition(name, cfg => cfg.WithPart("CommonPart").WithPart("BodyPart").WithPart("RoutePart").WithPart("ContainablePart").Creatable().Draftable());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Given(@"I have tenant ""(.*)\"" on ""(.*)\"" as ""(.*)\""")]
|
[Given(@"I have tenant ""(.*)\"" on ""(.*)\"" as ""(.*)\""")]
|
||||||
public void GivenIHaveTenantOnSiteAsName(string shellName, string hostName, string siteName) {
|
public void GivenIHaveTenantOnSiteAsName(string shellName, string hostName, string siteName) {
|
||||||
var webApp = Binding<WebAppHosting>();
|
var webApp = Binding<WebAppHosting>();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
using Castle.Core.Logging;
|
using Castle.Core.Logging;
|
||||||
using HtmlAgilityPack;
|
using HtmlAgilityPack;
|
||||||
using log4net.Appender;
|
using log4net.Appender;
|
||||||
@@ -190,7 +191,7 @@ namespace Orchard.Specs.Bindings {
|
|||||||
_doc.Load(new StringReader(Details.ResponseText));
|
_doc.Load(new StringReader(Details.ResponseText));
|
||||||
}
|
}
|
||||||
|
|
||||||
[When(@"I follow ""(.*)""")]
|
[When(@"I follow ""([^""]*)""")]
|
||||||
public void WhenIFollow(string linkText) {
|
public void WhenIFollow(string linkText) {
|
||||||
var link = _doc.DocumentNode
|
var link = _doc.DocumentNode
|
||||||
.SelectNodes("//a")
|
.SelectNodes("//a")
|
||||||
@@ -198,7 +199,24 @@ namespace Orchard.Specs.Bindings {
|
|||||||
?? _doc.DocumentNode
|
?? _doc.DocumentNode
|
||||||
.SelectSingleNode(string.Format("//a[@title='{0}']", linkText));
|
.SelectSingleNode(string.Format("//a[@title='{0}']", linkText));
|
||||||
|
|
||||||
var urlPath = link.Attributes["href"].Value;
|
var urlPath = HttpUtility.HtmlDecode(link.Attributes["href"].Value);
|
||||||
|
|
||||||
|
WhenIGoTo(urlPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[When(@"I follow ""([^""]+)"" where href has ""([^""]+)""")]
|
||||||
|
public void WhenIFollow(string linkText, string hrefFilter) {
|
||||||
|
var link = _doc.DocumentNode
|
||||||
|
.SelectNodes("//a[@href]").Where(elt =>
|
||||||
|
(elt.InnerText == linkText ||
|
||||||
|
(elt.Attributes["title"] != null && elt.Attributes["title"].Value == linkText)) &&
|
||||||
|
elt.Attributes["href"].Value.IndexOf(hrefFilter, StringComparison.OrdinalIgnoreCase) != -1).SingleOrDefault();
|
||||||
|
|
||||||
|
if (link == null) {
|
||||||
|
throw new InvalidOperationException(string.Format("Could not find an anchor with matching text '{0}' and href '{1}'. Document: {2}", linkText, hrefFilter, _doc.DocumentNode.InnerHtml));
|
||||||
|
}
|
||||||
|
var href = link.Attributes["href"].Value;
|
||||||
|
var urlPath = HttpUtility.HtmlDecode(href);
|
||||||
|
|
||||||
WhenIGoTo(urlPath);
|
WhenIGoTo(urlPath);
|
||||||
}
|
}
|
||||||
@@ -269,11 +287,24 @@ namespace Orchard.Specs.Bindings {
|
|||||||
|
|
||||||
var form = Form.LocateAround(submit);
|
var form = Form.LocateAround(submit);
|
||||||
var urlPath = form.Start.GetAttributeValue("action", Details.UrlPath);
|
var urlPath = form.Start.GetAttributeValue("action", Details.UrlPath);
|
||||||
|
|
||||||
|
|
||||||
var inputs = form.Children
|
var inputs = form.Children
|
||||||
.SelectMany(elt => elt.DescendantsAndSelf("input").Concat(elt.Descendants("textarea")))
|
.SelectMany(elt => elt.DescendantsAndSelf("input").Concat(elt.Descendants("textarea")))
|
||||||
.Where(node => !((node.GetAttributeValue("type", "") == "radio" || node.GetAttributeValue("type", "") == "checkbox") && node.GetAttributeValue("checked", "") != "checked"))
|
.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", ""))
|
.GroupBy(elt => elt.GetAttributeValue("name", elt.GetAttributeValue("id", "")), elt => elt.GetAttributeValue("value", ""))
|
||||||
.Where(g => !string.IsNullOrEmpty(g.Key))
|
.Where(g => !string.IsNullOrEmpty(g.Key))
|
||||||
|
// add values of <select>s
|
||||||
|
.Concat(
|
||||||
|
// select all <select> elements
|
||||||
|
form.Children.SelectMany(elt => elt.DescendantsAndSelf("select")).Where(elt => elt.Name.Equals("select", StringComparison.OrdinalIgnoreCase))
|
||||||
|
// group them by their name with value that comes from first of:
|
||||||
|
// (1) value of option with 'selected' attribute,
|
||||||
|
// (2) value of first option (none have 'selected'),
|
||||||
|
// (3) empty value (e.g. select with no options)
|
||||||
|
.GroupBy(
|
||||||
|
sel => sel.GetAttributeValue("name", sel.GetAttributeValue("id", "")),
|
||||||
|
sel => (sel.Descendants("option").SingleOrDefault(opt => opt.Attributes["selected"] != null) ?? sel.Descendants("option").FirstOrDefault() ?? new HtmlNode(HtmlNodeType.Element, _doc, 0)).GetAttributeValue("value", "")))
|
||||||
.ToDictionary(elt => elt.Key, elt => (IEnumerable<string>)elt);
|
.ToDictionary(elt => elt.Key, elt => (IEnumerable<string>)elt);
|
||||||
|
|
||||||
if (submit.Attributes.Contains("name"))
|
if (submit.Attributes.Contains("name"))
|
||||||
|
|||||||
37
src/Orchard.Specs/Lists.feature
Normal file
37
src/Orchard.Specs/Lists.feature
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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 |
|
||||||
|
And I hit "Save"
|
||||||
|
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"
|
||||||
|
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"
|
||||||
|
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"
|
||||||
145
src/Orchard.Specs/Lists.feature.cs
generated
Normal file
145
src/Orchard.Specs/Lists.feature.cs
generated
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// <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("Lists")]
|
||||||
|
public partial class ListsFeature
|
||||||
|
{
|
||||||
|
|
||||||
|
private static TechTalk.SpecFlow.ITestRunner testRunner;
|
||||||
|
|
||||||
|
#line 1 "Lists.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"), "Lists", "In order to add new lists to my site\nAs an administrator\nI want to create lists", 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("I can create a new list")]
|
||||||
|
public virtual void ICanCreateANewList()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new list", ((string[])(null)));
|
||||||
|
#line 6
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 7
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 8
|
||||||
|
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table1.AddRow(new string[] {
|
||||||
|
"Routable.Title",
|
||||||
|
"MyList"});
|
||||||
|
#line 9
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table1);
|
||||||
|
#line 12
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 13
|
||||||
|
testRunner.And("I go to \"Admin/Contents/List/List\"");
|
||||||
|
#line 14
|
||||||
|
testRunner.Then("I should see \"MyList\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
[NUnit.Framework.TestAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("I can add content items to a list")]
|
||||||
|
public virtual void ICanAddContentItemsToAList()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can add content items to a list", ((string[])(null)));
|
||||||
|
#line 16
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 17
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 18
|
||||||
|
testRunner.And("I have a containable content type \"MyType\"");
|
||||||
|
#line 19
|
||||||
|
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table2.AddRow(new string[] {
|
||||||
|
"Routable.Title",
|
||||||
|
"MyList"});
|
||||||
|
#line 20
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table2);
|
||||||
|
#line 23
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 24
|
||||||
|
testRunner.And("I go to \"Admin/Contents/List/List\"");
|
||||||
|
#line 25
|
||||||
|
testRunner.Then("I should see \"MyList\"");
|
||||||
|
#line 26
|
||||||
|
testRunner.When("I follow \"Contained Items\"");
|
||||||
|
#line 27
|
||||||
|
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\"");
|
||||||
|
#line 29
|
||||||
|
testRunner.Then("I should see \"MyType\"");
|
||||||
|
#line 30
|
||||||
|
testRunner.When("I follow \"MyType\" where href has \"ReturnUrl\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"Routable.Title",
|
||||||
|
"MyContentItem"});
|
||||||
|
#line 31
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table3);
|
||||||
|
#line 34
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 35
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 36
|
||||||
|
testRunner.Then("I should see \"Manage Content for MyList\"");
|
||||||
|
#line 37
|
||||||
|
testRunner.And("I should see \"MyContentItem\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
@@ -161,6 +161,11 @@
|
|||||||
<Compile Include="Hosting\RequestExtensions.cs" />
|
<Compile Include="Hosting\RequestExtensions.cs" />
|
||||||
<Compile Include="Hosting\RequestDetails.cs" />
|
<Compile Include="Hosting\RequestDetails.cs" />
|
||||||
<Compile Include="Hosting\Simple.Web\Global.asax.cs" />
|
<Compile Include="Hosting\Simple.Web\Global.asax.cs" />
|
||||||
|
<Compile Include="Lists.feature.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Lists.feature</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Media.feature.cs">
|
<Compile Include="Media.feature.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
@@ -260,6 +265,10 @@
|
|||||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>ContentTypes.feature.cs</LastGenOutput>
|
<LastGenOutput>ContentTypes.feature.cs</LastGenOutput>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Lists.feature">
|
||||||
|
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Lists.feature.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
<None Include="PermissionModel.feature">
|
<None Include="PermissionModel.feature">
|
||||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>PermissionModel.feature.cs</LastGenOutput>
|
<LastGenOutput>PermissionModel.feature.cs</LastGenOutput>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace Orchard.Core.Settings.Drivers {
|
|||||||
|
|
||||||
// ensure the base url is absolute if provided
|
// ensure the base url is absolute if provided
|
||||||
if (!String.IsNullOrWhiteSpace(model.Site.BaseUrl)) {
|
if (!String.IsNullOrWhiteSpace(model.Site.BaseUrl)) {
|
||||||
if (!model.Site.BaseUrl.ToLower().StartsWith("http")) {
|
if (!Uri.IsWellFormedUriString(model.Site.BaseUrl, UriKind.Absolute)) {
|
||||||
updater.AddModelError("BaseUrl", T("The base url must be absolute."));
|
updater.AddModelError("BaseUrl", T("The base url must be absolute."));
|
||||||
}
|
}
|
||||||
// if the base url has been modified, try to ping it
|
// if the base url has been modified, try to ping it
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
.section-settings {
|
.navicon-settings {
|
||||||
padding:12px 0;
|
|
||||||
}
|
|
||||||
.navicon-settings {
|
|
||||||
background-image:url(images/menu.settings.png) !important;
|
background-image:url(images/menu.settings.png) !important;
|
||||||
}
|
}
|
||||||
.navicon-settings:hover {
|
.navicon-settings:hover {
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ namespace Orchard.Web {
|
|||||||
var localCopy = HostingEnvironment.MapPath(virtualFileCopy);
|
var localCopy = HostingEnvironment.MapPath(virtualFileCopy);
|
||||||
|
|
||||||
if (File.Exists(localCopy)) {
|
if (File.Exists(localCopy)) {
|
||||||
|
|
||||||
// result should not be cached, even on proxies
|
// result should not be cached, even on proxies
|
||||||
Context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
|
Context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
|
||||||
Context.Response.Cache.SetValidUntilExpires(false);
|
Context.Response.Cache.SetValidUntilExpires(false);
|
||||||
@@ -69,12 +68,10 @@ namespace Orchard.Web {
|
|||||||
Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||||
Context.Response.Cache.SetNoStore();
|
Context.Response.Cache.SetNoStore();
|
||||||
|
|
||||||
Context.Response.ContentType = "text/html";
|
|
||||||
|
|
||||||
Context.Response.WriteFile(localCopy);
|
Context.Response.WriteFile(localCopy);
|
||||||
Context.Response.End();
|
Context.Response.End();
|
||||||
}
|
}
|
||||||
else {
|
else if(!File.Exists(Request.PhysicalPath)) {
|
||||||
// there is no local copy and the host is not running
|
// there is no local copy and the host is not running
|
||||||
// wait for the host to initialize
|
// wait for the host to initialize
|
||||||
_waitHandle.WaitOne();
|
_waitHandle.WaitOne();
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace Orchard.Comments.Drivers {
|
|||||||
var commentedOnContainer = _contentManager.Get(part.Record.CommentedOnContainer);
|
var commentedOnContainer = _contentManager.Get(part.Record.CommentedOnContainer);
|
||||||
if (commentedOnContainer != null) {
|
if (commentedOnContainer != null) {
|
||||||
var commentedOnContainerIdentity = _contentManager.GetItemMetadata(commentedOnContainer).Identity;
|
var commentedOnContainerIdentity = _contentManager.GetItemMetadata(commentedOnContainer).Identity;
|
||||||
context.Element(part.PartDefinition.Name).SetAttributeValue("commentedOnContainer", commentedOnContainerIdentity.ToString());
|
context.Element(part.PartDefinition.Name).SetAttributeValue("CommentedOnContainer", commentedOnContainerIdentity.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
@Display.Parts_Container_Manage(ContainerDisplayName: Model.ContainerDisplayName, ContainerContentType: Model.ContainerContentType, ContainerId: containerId)
|
@Display.Parts_Container_Manage(ContainerDisplayName: Model.ContainerDisplayName, ContainerContentType: Model.ContainerContentType, ContainerId: containerId)
|
||||||
@if (containerId.HasValue) {
|
@if (containerId.HasValue) {
|
||||||
<div class="manage">
|
<div class="manage">
|
||||||
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = (int)containerId, ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl }, new { @class = "button primaryAction" })
|
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = (int)containerId, ReturnUrl = Url.Action("List", "Admin", new { Area = "Orchard.Lists", ContainerId = (int)containerId }) }, new { @class = "button primaryAction" })
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@using (Html.BeginFormAntiForgeryPost()) {
|
@using (Html.BeginFormAntiForgeryPost()) {
|
||||||
|
|||||||
@@ -76,6 +76,6 @@ if (!Model.DatabaseIsPreconfigured) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<button class="primaryAction" type="submit">@T("Finish Setup")</button>
|
<button class="primaryAction setupButton" type="submit">@T("Finish Setup")</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace Orchard.Tags.Drivers {
|
|||||||
// Merge tags.
|
// Merge tags.
|
||||||
if (tags.Length > 0) {
|
if (tags.Length > 0) {
|
||||||
var currentTags = part.CurrentTags.Select(t => t.TagName);
|
var currentTags = part.CurrentTags.Select(t => t.TagName);
|
||||||
_tagService.UpdateTagsForContentItem(context.ContentItem, tags.Concat(currentTags));
|
_tagService.UpdateTagsForContentItem(context.ContentItem, tags.Concat(currentTags).Distinct());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Contents.Controllers;
|
using Orchard.Core.Contents.Controllers;
|
||||||
|
using Orchard.Environment.Warmup;
|
||||||
|
using Orchard.FileSystems.AppData;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
using Orchard.Warmup.Models;
|
using Orchard.Warmup.Models;
|
||||||
@@ -10,9 +18,14 @@ using Orchard.Warmup.Services;
|
|||||||
namespace Orchard.Warmup.Controllers {
|
namespace Orchard.Warmup.Controllers {
|
||||||
public class AdminController : Controller, IUpdateModel {
|
public class AdminController : Controller, IUpdateModel {
|
||||||
private readonly IWarmupScheduler _warmupScheduler;
|
private readonly IWarmupScheduler _warmupScheduler;
|
||||||
|
private readonly IAppDataFolder _appDataFolder;
|
||||||
|
|
||||||
public AdminController(IOrchardServices services, IWarmupScheduler warmupScheduler) {
|
public AdminController(
|
||||||
|
IOrchardServices services,
|
||||||
|
IWarmupScheduler warmupScheduler,
|
||||||
|
IAppDataFolder appDataFolder) {
|
||||||
_warmupScheduler = warmupScheduler;
|
_warmupScheduler = warmupScheduler;
|
||||||
|
_appDataFolder = appDataFolder;
|
||||||
Services = services;
|
Services = services;
|
||||||
|
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
@@ -63,6 +76,83 @@ namespace Orchard.Warmup.Controllers {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[FormValueRequired("submit.Extract")]
|
||||||
|
[HttpPost, ActionName("Index")]
|
||||||
|
public ActionResult IndexPostExtract() {
|
||||||
|
var baseUrl = Services.WorkContext.CurrentSite.BaseUrl;
|
||||||
|
baseUrl = VirtualPathUtility.AppendTrailingSlash(baseUrl);
|
||||||
|
|
||||||
|
var part = Services.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(baseUrl) || String.IsNullOrWhiteSpace(part.Urls)) {
|
||||||
|
return RedirectToAction("Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
var regex = new Regex(@"<link\s[^>]*href=""(?<url>[^""]*\.css)""|<script\s[^>]*src=""(?<url>[^""]*\.js)""", RegexOptions.IgnoreCase);
|
||||||
|
var resources = new List<string>();
|
||||||
|
|
||||||
|
// add the already registered urls to remove duplicates
|
||||||
|
using (var urlReader = new StringReader(part.Urls)) {
|
||||||
|
string relativeUrl;
|
||||||
|
while (null != (relativeUrl = urlReader.ReadLine())) {
|
||||||
|
if (String.IsNullOrWhiteSpace(relativeUrl)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
relativeUrl = relativeUrl.Trim();
|
||||||
|
resources.Add(relativeUrl);
|
||||||
|
|
||||||
|
try {
|
||||||
|
var contentUrl = VirtualPathUtility.RemoveTrailingSlash(baseUrl) + relativeUrl;
|
||||||
|
var filename = WarmupUtility.EncodeUrl(contentUrl.TrimEnd('/'));
|
||||||
|
var path = _appDataFolder.Combine("Warmup", filename);
|
||||||
|
|
||||||
|
if(!_appDataFolder.FileExists(path)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var content = _appDataFolder.ReadFile(path);
|
||||||
|
|
||||||
|
// process only html files
|
||||||
|
if (!content.Contains("<html") && !content.Contains("</html")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var localPrefix = Request.ApplicationPath ?? "/";
|
||||||
|
|
||||||
|
var matches = regex.Matches(content);
|
||||||
|
foreach (Match m in matches) {
|
||||||
|
var url = m.Groups["url"].Value;
|
||||||
|
|
||||||
|
if (url.StartsWith(localPrefix, StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
resources.Add(url.Substring(localPrefix.Length));
|
||||||
|
}
|
||||||
|
else if (url.StartsWith(baseUrl, StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
resources.Add("/" + url.Substring(baseUrl.Length));
|
||||||
|
}
|
||||||
|
else if (!url.StartsWith("http://") && !url.StartsWith("/")) {
|
||||||
|
// relative urls e.g., ../, foo.js, ...
|
||||||
|
relativeUrl = VirtualPathUtility.AppendTrailingSlash(relativeUrl);
|
||||||
|
url = VirtualPathUtility.Combine(relativeUrl, url);
|
||||||
|
resources.Add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// if something unexpected happens, process next file
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract unique urls
|
||||||
|
var uniqueResources = resources.GroupBy(x => x.ToLowerInvariant()).Select(x => x.First()).ToArray();
|
||||||
|
part.Urls = String.Join(System.Environment.NewLine, uniqueResources);
|
||||||
|
|
||||||
|
return RedirectToAction("Index");
|
||||||
|
}
|
||||||
|
|
||||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||||
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,5 +33,6 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<button class="primaryAction" name="submit" value="@T("Save")" type="submit">@T("Save")</button>
|
<button class="primaryAction" name="submit" value="@T("Save")" type="submit">@T("Save")</button>
|
||||||
<button class="primaryAction" name="submit.Generate" value="@T("Save and generate")" type="submit">@T("Save and generate")</button>
|
<button class="primaryAction" name="submit.Generate" value="@T("Save and generate")" type="submit">@T("Save and generate")</button>
|
||||||
|
<button class="primaryAction" name="submit.Extract" value="@T("Extract resources")" type="submit">@T("Extract resources")</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,42 @@
|
|||||||
/*Yahoo browser reset
|
/* Reset
|
||||||
----------------------------------------------------------*/
|
***************************************************************/
|
||||||
|
|
||||||
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,
|
html, body, div, span, applet, object, iframe,
|
||||||
blockquote,th,td {margin:0; padding:0; }
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
table { border-collapse:collapse; border-spacing:0; }
|
a, abbr, acronym, address, big, cite, code,
|
||||||
fieldset,img { border:0; }
|
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||||
address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
|
small, strike, strong, sub, sup, tt, var,
|
||||||
ol,ul { list-style:none; }
|
dl, dt, dd, ol, ul, li,
|
||||||
caption,th { text-align:left; }
|
fieldset, form, label, legend,
|
||||||
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
|
table, caption, tbody, tfoot, thead, tr, th, td, button, submit {
|
||||||
abbr,acronym { border:0; }
|
margin: 0;
|
||||||
q:before,q:after {content:'';}
|
padding: 0;
|
||||||
abbr,acronym { border:0;}
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
font-weight: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
font-size: 100%;
|
||||||
|
font-family: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember focus styles! */
|
||||||
|
:focus { outline: 0; }
|
||||||
|
|
||||||
|
body { line-height: 1; color: black; background: white; }
|
||||||
|
ol, ul { list-style: none; }
|
||||||
|
|
||||||
|
/* Tables still need 'cellspacing="0"' in the markup */
|
||||||
|
table { border-collapse: separate; border-spacing: 0; }
|
||||||
|
caption, th, td { text-align: left; font-weight: normal; }
|
||||||
|
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after { content: ""; }
|
||||||
|
blockquote, q { quotes: "" ""; }
|
||||||
|
|
||||||
|
/* HTML 5 elements as block */
|
||||||
|
header, footer, aside, nav, article { display: block; }
|
||||||
|
/* end: reset */
|
||||||
|
|
||||||
/*Defaults
|
/*Defaults
|
||||||
----------------------------------------------------------*/
|
----------------------------------------------------------*/
|
||||||
@@ -81,6 +106,11 @@ form {
|
|||||||
border:1px solid #DDDEDF;
|
border:1px solid #DDDEDF;
|
||||||
padding:10px 0;
|
padding:10px 0;
|
||||||
background:transparent url(images/backgroundVines.gif) no-repeat right bottom;
|
background:transparent url(images/backgroundVines.gif) no-repeat right bottom;
|
||||||
|
|
||||||
|
/*----CSS3 properties----*/
|
||||||
|
-webkit-border-radius: 2px;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form h2 {
|
form h2 {
|
||||||
@@ -134,20 +164,7 @@ select {
|
|||||||
width:100%;
|
width:100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.primaryAction, .button.primaryAction, .button.primaryAction:link, .button.primaryAction:visited {
|
/*----buttons----*/
|
||||||
background:#4687ad;
|
|
||||||
border:1px solid #405f71;
|
|
||||||
font-size: 102%;
|
|
||||||
font-weight:600;
|
|
||||||
color:#fff;
|
|
||||||
margin:0 0 20px 20px;
|
|
||||||
padding:3px 28px;
|
|
||||||
|
|
||||||
/*CSS3 properties*/
|
|
||||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#4687AD', endColorstr='#366581');
|
|
||||||
background: -webkit-gradient(linear, left top, left bottom, from(#4687AD), to(#366581));
|
|
||||||
background:-moz-linear-gradient(top , #4687AD, #366581);
|
|
||||||
}
|
|
||||||
button.remove, .remove.button, .remove.button:link, .remove.button:visited {
|
button.remove, .remove.button, .remove.button:link, .remove.button:visited {
|
||||||
background-color:#DECCCA;
|
background-color:#DECCCA;
|
||||||
background-image:url(images/tableHeaderBackgroundRed.gif);
|
background-image:url(images/tableHeaderBackgroundRed.gif);
|
||||||
@@ -167,55 +184,83 @@ button.remove:focus::-moz-focus-inner, .remove.button:focus::-moz-focus-inner {
|
|||||||
.delete.button {
|
.delete.button {
|
||||||
float:right;
|
float:right;
|
||||||
}
|
}
|
||||||
input[type="submit"], input[type="reset"], input[type="button"], button, submit, .button, .button:link, .button:visited
|
.button.disabled, .button.disabled:visited, .button.disabled:hover, .button.disabled:active, .button.disabled:focus {
|
||||||
{
|
background:#eee;
|
||||||
color:#333;
|
border:1px solid #ababab;
|
||||||
background:#F5F5F5;
|
color:#ababab;
|
||||||
border:1px solid #999;
|
cursor:default;
|
||||||
cursor:pointer;
|
text-shadow: none;
|
||||||
padding: 0 12px 2px 12px;
|
box-shadow: none;
|
||||||
text-align:center;
|
-webkit-box-shadow: none;
|
||||||
|
-moz-box-shadow: none;
|
||||||
/*CSS3 properties*/
|
}
|
||||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f5f5f5', endColorstr='#cbcbcb');
|
button, .button, a.button {
|
||||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#cbcbcb));
|
background:#6a7b42;
|
||||||
background: -moz-linear-gradient(top, #f5f5f5, #cbcbcb);
|
border:1px solid #487328;
|
||||||
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
|
||||||
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
|
||||||
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
|
||||||
border-radius: 3px;
|
|
||||||
-webkit-border-radius: 3px;
|
|
||||||
-moz-border-radius: 3px;
|
|
||||||
}
|
|
||||||
input[type="submit"]:hover,input[type="reset"]:hover, input[type="button"]:hover, button:hover, .button:hover, .button.primaryAction:hover {
|
|
||||||
text-decoration:none;
|
|
||||||
background: #ffac40;
|
|
||||||
color:#fff;
|
color:#fff;
|
||||||
border:1px solid #bb8b2d;
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font: 90% Arial,Helvetica,sans-serif;
|
||||||
|
padding: 4px 14px 2px 14px; /*ie9*/
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
/*CSS3 properties*/
|
/*----CSS3 properties----*/
|
||||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffac40', endColorstr='#f9760d');
|
text-shadow: rgba(40,53,9,.2) 0px 0px 1px;
|
||||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(#ffac40), to(#f9760d));
|
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
|
||||||
background: -moz-linear-gradient(top, #ffac40, #f9760d);
|
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
|
||||||
|
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
|
||||||
|
|
||||||
|
|
||||||
|
/*----In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)----*/
|
||||||
|
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
|
||||||
|
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), rgba((106, 123, 66, 1.0)));
|
||||||
|
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(128, 159, 67, 1.0));
|
||||||
|
|
||||||
|
|
||||||
|
-webkit-border-radius: 2px;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
input[type="submit"]:active, input[type="reset"]:active, input[type="button"]:active, button:active, .buton:active, .button.primaryAction:active {
|
button, input.button, x:-moz-any-link {
|
||||||
|
padding: 2px 14px 2px 14px;
|
||||||
|
}
|
||||||
|
button:hover, .button:hover, a.button:hover {
|
||||||
|
border-color:#3a822e;
|
||||||
|
color:#eefcec;
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
background: #62a9e2;
|
background: #809f43;
|
||||||
color:#fff;
|
|
||||||
border:1px solid #bb772d;
|
/*CSS3 properties*/
|
||||||
|
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff6e7f45', endColorstr='#ff6a7b42');
|
||||||
/*CSS3 properties*/
|
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), rgba((106, 123, 66, 1.0)));
|
||||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fece3b', endColorstr='#fe6001');
|
background: -moz-linear-gradient(top, rgba(110, 127, 69, 1.0), rgba(106, 123, 66, 1.0));
|
||||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(#fece3b), to(#fe6001));
|
|
||||||
background: -moz-linear-gradient(top, #fece3b, #fe6001);
|
|
||||||
box-shadow: inset 0px 0px 1px rgba(254, 225, 109, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
|
||||||
-moz-box-shadow: inset 0px 0px 1px rgba(254, 225, 109, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
|
||||||
-webkit-box-shadow: inset 1px 1px 1px rgba(254, 225, 109, 0.6), 1px 1px 1px rgba(102, 102, 102, 0.1);
|
|
||||||
}
|
}
|
||||||
input[type="submit"]:focus::-moz-focus-inner, button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner {
|
button:active, .buton:active, a.button:active {
|
||||||
|
text-decoration:none;
|
||||||
|
background:#6a7b42;
|
||||||
|
border:1px solid #487328;
|
||||||
|
color:#fff;
|
||||||
|
|
||||||
|
/*CSS3 properties*/
|
||||||
|
text-shadow: rgba(0,0,0,.5) 0px 0px 1px;
|
||||||
|
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
|
||||||
|
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), rgba((106, 123, 66, 1.0)));
|
||||||
|
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(128, 159, 67, 1.0));
|
||||||
|
}
|
||||||
|
button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner {
|
||||||
border: 1px dotted transparent;
|
border: 1px dotted transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.setupButton {
|
||||||
|
margin:0 0 20px 20px;
|
||||||
|
padding:4px 28px;
|
||||||
|
font-size: 105%;
|
||||||
|
font-weight:600;
|
||||||
|
}
|
||||||
|
|
||||||
/* Confirmations, Messages and the like
|
/* Confirmations, Messages and the like
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
#throbber {
|
#throbber {
|
||||||
|
|||||||
Reference in New Issue
Block a user