mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 11:44:58 +08:00
Validating content type names, and displaying technical names
Work Item: 16471 --HG-- branch : dev
This commit is contained in:
84
src/Orchard.Specs/ContentTypes.feature
Normal file
84
src/Orchard.Specs/ContentTypes.feature
Normal file
@@ -0,0 +1,84 @@
|
||||
Feature: Content Types
|
||||
In order to add new types to my site
|
||||
As an adminitrator
|
||||
I want to create create content types
|
||||
|
||||
Scenario: I can create a new content type
|
||||
Given I have installed Orchard
|
||||
And I have installed "Orchard.ContentTypes"
|
||||
When I go to "Admin/ContentTypes"
|
||||
Then I should see "<a[^>]*>.*?Create new type</a>"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Event |
|
||||
| Name | Event |
|
||||
And I hit "Create"
|
||||
And I go to "Admin/ContentTypes/"
|
||||
Then I should see "Event"
|
||||
|
||||
Scenario: I can't create a content type with an already existing name
|
||||
Given I have installed Orchard
|
||||
And I have installed "Orchard.ContentTypes"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Event |
|
||||
| Name | Event |
|
||||
And I hit "Create"
|
||||
And I go to "Admin/ContentTypes/"
|
||||
Then I should see "Event"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Event |
|
||||
| Name | Event-2 |
|
||||
And I hit "Create"
|
||||
Then I should see "<h1[^>]*>.*?New Content Type.*?</h1>"
|
||||
And I should see "validation-summary-errors"
|
||||
|
||||
Scenario: I can't create a content type with an already existing technical name
|
||||
Given I have installed Orchard
|
||||
And I have installed "Orchard.ContentTypes"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Dinner |
|
||||
| Name | Dinner |
|
||||
And I hit "Create"
|
||||
And I go to "Admin/ContentTypes/"
|
||||
Then I should see "Dinner"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Dinner2 |
|
||||
| Name | Dinner |
|
||||
And I hit "Create"
|
||||
Then I should see "<h1[^>]*>.*?New Content Type.*?</h1>"
|
||||
And I should see "validation-summary-errors"
|
||||
|
||||
Scenario: I can't rename a content type with an already existing name
|
||||
Given I have installed Orchard
|
||||
And I have installed "Orchard.ContentTypes"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Dinner |
|
||||
| Name | Dinner |
|
||||
And I hit "Create"
|
||||
And I go to "Admin/ContentTypes/"
|
||||
Then I should see "Dinner"
|
||||
When I go to "Admin/ContentTypes/Create"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Event |
|
||||
| Name | Event |
|
||||
And I hit "Create"
|
||||
And I go to "Admin/ContentTypes/"
|
||||
Then I should see "Event"
|
||||
When I go to "Admin/ContentTypes/Edit/Dinner"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| DisplayName | Event |
|
||||
And I hit "Save"
|
||||
Then I should see "validation-summary-errors"
|
276
src/Orchard.Specs/ContentTypes.feature.cs
generated
Normal file
276
src/Orchard.Specs/ContentTypes.feature.cs
generated
Normal file
@@ -0,0 +1,276 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.3.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.3.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Content Types")]
|
||||
public partial class ContentTypesFeature
|
||||
{
|
||||
|
||||
private static TechTalk.SpecFlow.ITestRunner testRunner;
|
||||
|
||||
#line 1 "ContentTypes.feature"
|
||||
#line hidden
|
||||
|
||||
[NUnit.Framework.TestFixtureSetUpAttribute()]
|
||||
public virtual void FeatureSetup()
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Content Types", "In order to add new types to my site\r\nAs an adminitrator\r\nI want to create create" +
|
||||
" content types", ((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 content type")]
|
||||
public virtual void ICanCreateANewContentType()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new content type", ((string[])(null)));
|
||||
#line 6
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 7
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 8
|
||||
testRunner.And("I have installed \"Orchard.ContentTypes\"");
|
||||
#line 9
|
||||
testRunner.When("I go to \"Admin/ContentTypes\"");
|
||||
#line 10
|
||||
testRunner.Then("I should see \"<a[^>]*>.*?Create new type</a>\"");
|
||||
#line 11
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table1.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Event"});
|
||||
table1.AddRow(new string[] {
|
||||
"Name",
|
||||
"Event"});
|
||||
#line 12
|
||||
testRunner.And("I fill in", ((string)(null)), table1);
|
||||
#line 16
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 17
|
||||
testRunner.And("I go to \"Admin/ContentTypes/\"");
|
||||
#line 18
|
||||
testRunner.Then("I should see \"Event\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can\'t create a content type with an already existing name")]
|
||||
public virtual void ICanTCreateAContentTypeWithAnAlreadyExistingName()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t create a content type with an already existing name", ((string[])(null)));
|
||||
#line 20
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 21
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 22
|
||||
testRunner.And("I have installed \"Orchard.ContentTypes\"");
|
||||
#line 23
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table2.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Event"});
|
||||
table2.AddRow(new string[] {
|
||||
"Name",
|
||||
"Event"});
|
||||
#line 24
|
||||
testRunner.And("I fill in", ((string)(null)), table2);
|
||||
#line 28
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 29
|
||||
testRunner.And("I go to \"Admin/ContentTypes/\"");
|
||||
#line 30
|
||||
testRunner.Then("I should see \"Event\"");
|
||||
#line 31
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table3.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Event"});
|
||||
table3.AddRow(new string[] {
|
||||
"Name",
|
||||
"Event-2"});
|
||||
#line 32
|
||||
testRunner.And("I fill in", ((string)(null)), table3);
|
||||
#line 36
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 37
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?New Content Type.*?</h1>\"");
|
||||
#line 38
|
||||
testRunner.And("I should see \"validation-summary-errors\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can\'t create a content type with an already existing technical name")]
|
||||
public virtual void ICanTCreateAContentTypeWithAnAlreadyExistingTechnicalName()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t create a content type with an already existing technical name", ((string[])(null)));
|
||||
#line 40
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 41
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 42
|
||||
testRunner.And("I have installed \"Orchard.ContentTypes\"");
|
||||
#line 43
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table4.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Dinner"});
|
||||
table4.AddRow(new string[] {
|
||||
"Name",
|
||||
"Dinner"});
|
||||
#line 44
|
||||
testRunner.And("I fill in", ((string)(null)), table4);
|
||||
#line 48
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 49
|
||||
testRunner.And("I go to \"Admin/ContentTypes/\"");
|
||||
#line 50
|
||||
testRunner.Then("I should see \"Dinner\"");
|
||||
#line 51
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table5.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Dinner2"});
|
||||
table5.AddRow(new string[] {
|
||||
"Name",
|
||||
"Dinner"});
|
||||
#line 52
|
||||
testRunner.And("I fill in", ((string)(null)), table5);
|
||||
#line 56
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 57
|
||||
testRunner.Then("I should see \"<h1[^>]*>.*?New Content Type.*?</h1>\"");
|
||||
#line 58
|
||||
testRunner.And("I should see \"validation-summary-errors\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can\'t rename a content type with an already existing name")]
|
||||
public virtual void ICanTRenameAContentTypeWithAnAlreadyExistingName()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t rename a content type with an already existing name", ((string[])(null)));
|
||||
#line 60
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 61
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 62
|
||||
testRunner.And("I have installed \"Orchard.ContentTypes\"");
|
||||
#line 63
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table6.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Dinner"});
|
||||
table6.AddRow(new string[] {
|
||||
"Name",
|
||||
"Dinner"});
|
||||
#line 64
|
||||
testRunner.And("I fill in", ((string)(null)), table6);
|
||||
#line 68
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 69
|
||||
testRunner.And("I go to \"Admin/ContentTypes/\"");
|
||||
#line 70
|
||||
testRunner.Then("I should see \"Dinner\"");
|
||||
#line 71
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Create\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table7 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table7.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Event"});
|
||||
table7.AddRow(new string[] {
|
||||
"Name",
|
||||
"Event"});
|
||||
#line 72
|
||||
testRunner.And("I fill in", ((string)(null)), table7);
|
||||
#line 76
|
||||
testRunner.And("I hit \"Create\"");
|
||||
#line 77
|
||||
testRunner.And("I go to \"Admin/ContentTypes/\"");
|
||||
#line 78
|
||||
testRunner.Then("I should see \"Event\"");
|
||||
#line 79
|
||||
testRunner.When("I go to \"Admin/ContentTypes/Edit/Dinner\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table8.AddRow(new string[] {
|
||||
"DisplayName",
|
||||
"Event"});
|
||||
#line 80
|
||||
testRunner.And("I fill in", ((string)(null)), table8);
|
||||
#line 83
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 84
|
||||
testRunner.Then("I should see \"validation-summary-errors\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
@@ -142,6 +142,11 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="ContentTypes.feature.cs">
|
||||
<DependentUpon>ContentTypes.feature</DependentUpon>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="Hosting\ExtensionDeploymentOptions.cs" />
|
||||
<Compile Include="SiteCompilation.feature.cs">
|
||||
<DependentUpon>SiteCompilation.feature</DependentUpon>
|
||||
@@ -228,6 +233,10 @@
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ContentRights.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="ContentTypes.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ContentTypes.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="SiteCompilation.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>SiteCompilation.feature.cs</LastGenOutput>
|
||||
|
@@ -47,8 +47,12 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
if(String.IsNullOrWhiteSpace(viewModel.DisplayName)) {
|
||||
ModelState.AddModelError("DisplayName", T("The Content Type name can't be empty.").ToString());
|
||||
}
|
||||
|
||||
if ( _contentDefinitionService.GetTypes().Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase)) ) {
|
||||
ModelState.AddModelError("Name", T("A type with the same technical name already exists.").ToString());
|
||||
}
|
||||
|
||||
if(_contentDefinitionService.GetTypes().Any(t => t.DisplayName == viewModel.DisplayName)) {
|
||||
if ( _contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase)) ) {
|
||||
ModelState.AddModelError("DisplayName", T("A type with the same name already exists.").ToString());
|
||||
}
|
||||
|
||||
@@ -57,13 +61,19 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
var typeViewModel = _contentDefinitionService.AddType(viewModel);
|
||||
var contentTypeDefinition = _contentDefinitionService.AddType(viewModel.Name, viewModel.DisplayName);
|
||||
var typeViewModel = new EditTypeViewModel(contentTypeDefinition);
|
||||
|
||||
|
||||
Services.Notifier.Information(T("The \"{0}\" content type has been created.", typeViewModel.DisplayName));
|
||||
|
||||
return RedirectToAction("Edit", new { id = typeViewModel.Name });
|
||||
}
|
||||
|
||||
public ActionResult ContentTypeName(string displayName) {
|
||||
return Json(_contentDefinitionService.GenerateName(displayName));
|
||||
}
|
||||
|
||||
public ActionResult Edit(string id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateContentTypes, T("Not allowed to edit a content type.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
@@ -90,9 +100,18 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
TryUpdateModel(edited);
|
||||
typeViewModel.DisplayName = edited.DisplayName;
|
||||
|
||||
if ( String.IsNullOrWhiteSpace(typeViewModel.DisplayName) ) {
|
||||
ModelState.AddModelError("DisplayName", T("The Content Type name can't be empty.").ToString());
|
||||
}
|
||||
|
||||
if ( _contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), typeViewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase) && !String.Equals(t.Name, id)) ) {
|
||||
ModelState.AddModelError("DisplayName", T("A type with the same name already exists.").ToString());
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return View(typeViewModel);
|
||||
|
||||
|
||||
_contentDefinitionService.AlterType(typeViewModel, this);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
|
@@ -65,18 +65,24 @@ namespace Orchard.ContentTypes.Services {
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
public EditTypeViewModel AddType(CreateTypeViewModel typeViewModel) {
|
||||
var name = GenerateName(typeViewModel.DisplayName);
|
||||
public ContentTypeDefinition AddType(string name, string displayName) {
|
||||
if(String.IsNullOrWhiteSpace(displayName)) {
|
||||
throw new ArgumentException("displayName");
|
||||
}
|
||||
|
||||
while (_contentDefinitionManager.GetTypeDefinition(name) != null)
|
||||
if(String.IsNullOrWhiteSpace(name)) {
|
||||
name = GenerateName(displayName);
|
||||
}
|
||||
|
||||
while ( _contentDefinitionManager.GetTypeDefinition(name) != null )
|
||||
name = VersionName(name);
|
||||
|
||||
var contentTypeDefinition = new ContentTypeDefinition(name, typeViewModel.DisplayName);
|
||||
var contentTypeDefinition = new ContentTypeDefinition(name, displayName);
|
||||
_contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition);
|
||||
_contentDefinitionManager.AlterTypeDefinition(name,
|
||||
cfg => cfg.Creatable().Draftable());
|
||||
|
||||
return new EditTypeViewModel(contentTypeDefinition);
|
||||
return contentTypeDefinition;
|
||||
}
|
||||
|
||||
public void AlterType(EditTypeViewModel typeViewModel, IUpdateModel updateModel) {
|
||||
@@ -210,20 +216,21 @@ namespace Orchard.ContentTypes.Services {
|
||||
}
|
||||
|
||||
//gratuitously stolen from the RoutableService
|
||||
private static string GenerateName(string displayName) {
|
||||
if (string.IsNullOrWhiteSpace(displayName))
|
||||
return "";
|
||||
public string GenerateName(string name) {
|
||||
if ( string.IsNullOrWhiteSpace(name) )
|
||||
return String.Empty;
|
||||
|
||||
var name = displayName;
|
||||
//todo: might need to be made more restrictive depending on how name is used (like as an XML node name, for instance)
|
||||
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s]+");
|
||||
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""<>]+");
|
||||
|
||||
name = dissallowed.Replace(name, "-");
|
||||
name = name.Trim('-');
|
||||
name = dissallowed.Replace(name, String.Empty);
|
||||
name = name.Trim();
|
||||
|
||||
if (name.Length > 128)
|
||||
name = name.Substring(0, 128);
|
||||
|
||||
while ( _contentDefinitionManager.GetTypeDefinition(name) != null )
|
||||
name = VersionName(name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@@ -1,17 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentTypes.ViewModels;
|
||||
|
||||
namespace Orchard.ContentTypes.Services {
|
||||
public interface IContentDefinitionService : IDependency {
|
||||
IEnumerable<EditTypeViewModel> GetTypes();
|
||||
EditTypeViewModel GetType(string name);
|
||||
EditTypeViewModel AddType(CreateTypeViewModel typeViewModel);
|
||||
ContentTypeDefinition AddType(string name, string displayName);
|
||||
void AlterType(EditTypeViewModel typeViewModel, IUpdateModel updater);
|
||||
void RemoveType(string name);
|
||||
void AddPartToType(string partName, string typeName);
|
||||
void RemovePartFromType(string partName, string typeName);
|
||||
string GenerateName(string displayName);
|
||||
|
||||
IEnumerable<EditPartViewModel> GetParts();
|
||||
EditPartViewModel GetPart(string name);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace Orchard.ContentTypes.ViewModels {
|
||||
public class CreateTypeViewModel {
|
||||
public string DisplayName { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,40 @@
|
||||
@model Orchard.ContentTypes.ViewModels.CreateTypeViewModel
|
||||
|
||||
<h1>@Html.TitleForPage(T("New Content Type").ToString())</h1>@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
<fieldset>
|
||||
<label for="DisplayName">@T("Display Name")</label>
|
||||
@Html.TextBoxFor(m => m.DisplayName, new {@class = "textMedium", autofocus = "autofocus"})
|
||||
<label for="Name">@T("Technical Name")</label>
|
||||
@Html.TextBoxFor(m => m.Name, new {@class = "text"})
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<button class="primaryAction" type="submit">@T("Create")</button>
|
||||
</fieldset>}
|
||||
</fieldset>}
|
||||
|
||||
@using(Script.Foot()){
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
$(function(){
|
||||
//pull slug input from tab order
|
||||
$("#@Html.FieldIdFor(m=>m.Name)").attr("tabindex",-1);
|
||||
$("#@Html.FieldIdFor(m=>m.DisplayName)").blur(function(){
|
||||
var name = $("#@Html.FieldIdFor(m=>m.Name)");
|
||||
if (name.val()) { return true; }
|
||||
var displayName = $("#@Html.FieldIdFor(m=>m.DisplayName)").val();
|
||||
jQuery.post(
|
||||
"@Url.Action("ContentTypeName","Admin",new RouteValueDictionary{{"Area","Orchard.ContentTypes"}})",
|
||||
{
|
||||
displayName: $("#@Html.FieldIdFor(m=>m.DisplayName)").val(),
|
||||
__RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
|
||||
},
|
||||
function(data) {
|
||||
name.val(data);
|
||||
},
|
||||
"json"
|
||||
);
|
||||
})
|
||||
})
|
||||
//]]>
|
||||
</script>
|
||||
}
|
@@ -12,7 +12,7 @@
|
||||
@Html.ValidationSummary()
|
||||
<fieldset>
|
||||
<label for="DisplayName">@T("Display Name")</label>
|
||||
@Html.TextBoxFor(m => m.DisplayName, new { @class = "textMedium" })
|
||||
@Html.TextBoxFor(m => m.DisplayName, new { @class = "textMedium" }) @T("Technical name: {0}", Model.Name)
|
||||
@* todo: if we continue to go down the midrodata route, some helpers would be nice *@
|
||||
<meta itemprop="DisplayName" content="@Model.DisplayName" />
|
||||
@* has unintended consequences (renamging the type) - changing the name creates a new type of that name *@
|
||||
|
Reference in New Issue
Block a user