mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using JetBrains.Annotations;
|
||||
@@ -9,7 +8,6 @@ using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.Settings;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Core.ContentsLocation.Models;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Services;
|
||||
|
||||
@@ -49,10 +47,6 @@ namespace Orchard.Core.Common.Drivers {
|
||||
);
|
||||
}
|
||||
|
||||
private string IfThen(bool predicate, string value) {
|
||||
return predicate ? value : null;
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(BodyPart part, dynamic shapeHelper) {
|
||||
var model = BuildEditorViewModel(part);
|
||||
return ContentShape("Parts_Common_Body_Edit",
|
||||
|
@@ -2,7 +2,6 @@
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Core.ContentsLocation.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.Services;
|
||||
@@ -48,8 +47,8 @@ namespace Orchard.Core.Common.Drivers {
|
||||
|
||||
protected override DriverResult Editor(CommonPart part, dynamic shapeHelper) {
|
||||
return Combined(
|
||||
OwnerEditor(part, null),
|
||||
ContainerEditor(part, null));
|
||||
OwnerEditor(part, null, shapeHelper),
|
||||
ContainerEditor(part, null, shapeHelper));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(CommonPart instance, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -58,11 +57,11 @@ namespace Orchard.Core.Common.Drivers {
|
||||
instance.VersionModifiedUtc = _clock.UtcNow;
|
||||
|
||||
return Combined(
|
||||
OwnerEditor(instance, updater),
|
||||
ContainerEditor(instance, updater));
|
||||
OwnerEditor(instance, updater, shapeHelper),
|
||||
ContainerEditor(instance, updater, shapeHelper));
|
||||
}
|
||||
|
||||
DriverResult OwnerEditor(CommonPart part, IUpdateModel updater) {
|
||||
DriverResult OwnerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var currentUser = _authenticationService.GetAuthenticatedUser();
|
||||
if (!_authorizationService.TryCheckAccess(Permissions.ChangeOwner, currentUser, part)) {
|
||||
return null;
|
||||
@@ -87,10 +86,11 @@ namespace Orchard.Core.Common.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
return ContentPartTemplate(model, "Parts/Common.Owner", TemplatePrefix).Location(part.GetLocation("Editor"));
|
||||
return ContentShape("Parts_Common_Owner_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Common.Owner", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
DriverResult ContainerEditor(CommonPart part, IUpdateModel updater) {
|
||||
DriverResult ContainerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var currentUser = _authenticationService.GetAuthenticatedUser();
|
||||
if (!_authorizationService.TryCheckAccess(Permissions.ChangeOwner, currentUser, part)) {
|
||||
return null;
|
||||
@@ -115,7 +115,8 @@ namespace Orchard.Core.Common.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
return ContentPartTemplate(model, "Parts/Common.Container", TemplatePrefix).Location(part.GetLocation("Editor"));
|
||||
return ContentShape("Parts_Common_Container_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Common.Container", Model: model, Prefix: Prefix));
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,39 +2,32 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Fields;
|
||||
using Orchard.Core.ContentsLocation.Models;
|
||||
|
||||
namespace Orchard.Core.Common.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class TextFieldDriver : ContentFieldDriver<TextField> {
|
||||
public IOrchardServices Services { get; set; }
|
||||
private const string TemplateName = "Fields/Common.TextField";
|
||||
|
||||
public TextFieldDriver(IOrchardServices services) {
|
||||
Services = services;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
private static string GetPrefix(TextField field, ContentPart part) {
|
||||
return part.PartDefinition.Name + "." + field.Name;
|
||||
}
|
||||
|
||||
protected override DriverResult Display(ContentPart part, TextField field, string displayType) {
|
||||
var location = field.GetLocation(displayType, "Primary", "1");
|
||||
|
||||
return ContentFieldTemplate(field, TemplateName, GetPrefix(field, part))
|
||||
.Location(location);
|
||||
protected override DriverResult Display(ContentPart part, TextField field, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Common_Text", () => shapeHelper.Fields_Common_Text(ContentField: field, Name: field.Name, Value: field.Value));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, TextField field) {
|
||||
var location = field.GetLocation("Editor", "Primary", "1");
|
||||
|
||||
return ContentFieldTemplate(field, TemplateName, GetPrefix(field, part))
|
||||
.Location(location);
|
||||
protected override DriverResult Editor(ContentPart part, TextField field, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Common_Text_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Fields/Common.Text.Edit", Model: field, Prefix: GetPrefix(field, part)));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, TextField field, IUpdateModel updater) {
|
||||
protected override DriverResult Editor(ContentPart part, TextField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
updater.TryUpdateModel(field, GetPrefix(field, part), null, null);
|
||||
return Editor(part, field);
|
||||
return Editor(part, field, shapeHelper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,23 +1,13 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc.Html;
|
||||
|
||||
namespace Orchard.Core.Common.Extensions {
|
||||
public static class HtmlHelperExtensions {
|
||||
public static LocalizedString PublishedStateForModel(this HtmlHelper<CommonMetadataViewModel> htmlHelper, Localizer T) {
|
||||
return htmlHelper.PublishedState(htmlHelper.ViewData.Model, T);
|
||||
public static LocalizedString PublishedState(this HtmlHelper htmlHelper, DateTime? versionPublishedUtc, Localizer T) {
|
||||
return htmlHelper.DateTime(versionPublishedUtc, T("Draft"));
|
||||
}
|
||||
|
||||
public static LocalizedString PublishedState(this HtmlHelper htmlHelper, CommonMetadataViewModel metadata, Localizer T) {
|
||||
return htmlHelper.DateTime(metadata.VersionPublishedUtc, T("Draft"));
|
||||
}
|
||||
|
||||
public static LocalizedString PublishedWhenForModel(this HtmlHelper<CommonMetadataViewModel> htmlHelper, Localizer T) {
|
||||
return htmlHelper.PublishedWhen(htmlHelper.ViewData.Model.VersionPublishedUtc, T);
|
||||
}
|
||||
|
||||
public static LocalizedString PublishedWhen(this HtmlHelper htmlHelper, DateTime? versionPublishedUtc, Localizer T) {
|
||||
return htmlHelper.DateTimeRelative(versionPublishedUtc, T("as a Draft"), T);
|
||||
}
|
||||
|
@@ -1,15 +1,32 @@
|
||||
<Placement>
|
||||
<Place Parts_Common_Metadata="-"/>
|
||||
<Place Parts_Common_Metadata_Summary="-"/>
|
||||
<Place Parts_Common_Metadata_SummaryAdmin="-"/>
|
||||
<!-- available display shapes -->
|
||||
<!--
|
||||
Parts_Common_Body
|
||||
Parts_Common_Body_Summary
|
||||
Parts_Common_Metadata
|
||||
Parts_Common_Metadata_Summary
|
||||
Parts_Common_Metadata_SummaryAdmin
|
||||
Fields_Common_Text
|
||||
-->
|
||||
<!-- edit shapes getting default placements -->
|
||||
<!-- edit "shape" -->
|
||||
<Place Parts_Common_Body_Edit="Primary:2"/>
|
||||
<Place Parts_Common_Owner_Edit="Primary:20"/>
|
||||
<Place Parts_Common_Container_Edit="Primary:20"/>
|
||||
<Place Fields_Common_Text_Edit="Primary:2.5"/>
|
||||
<!-- default positioning -->
|
||||
<!-- show summary for all DisplayType by default -->
|
||||
<Place Parts_Common_Body_Summary="Content:5"/>
|
||||
<!-- with text fields a little before -->
|
||||
<Place Fields_Common_Text="Content:2.5"/>
|
||||
<Match DisplayType="Detail">
|
||||
<!-- hide summary, show full content, for Detail -->
|
||||
<Place Parts_Common_Body_Summary="-"
|
||||
Parts_Common_Body="Content:5" />
|
||||
</Match>
|
||||
<Match DisplayType="Summary">
|
||||
<Place Parts_Common_Metadata_Summary="Meta:2"/>
|
||||
</Match>
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_Common_Body_Summary="-"
|
||||
Parts_Common_Metadata_SummaryAdmin="Meta:5"/>
|
||||
|
@@ -1,9 +0,0 @@
|
||||
using System.Web;
|
||||
using Orchard.Core.Common.Models;
|
||||
|
||||
namespace Orchard.Core.Common.ViewModels {
|
||||
public class BodyDisplayViewModel {
|
||||
public BodyPart BodyPart { get; set; }
|
||||
public IHtmlString Html { get; set; }
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Security;
|
||||
|
||||
namespace Orchard.Core.Common.ViewModels {
|
||||
public class CommonMetadataViewModel {
|
||||
private readonly CommonPart _commonPart;
|
||||
|
||||
public CommonMetadataViewModel(CommonPart commonPart) {
|
||||
_commonPart = commonPart;
|
||||
}
|
||||
|
||||
public IUser Creator { get { return _commonPart.Owner; } }
|
||||
|
||||
public DateTime? CreatedUtc { get { return _commonPart.CreatedUtc; } }
|
||||
public DateTime? PublishedUtc { get { return _commonPart.PublishedUtc; } }
|
||||
public DateTime? ModifiedUtc { get { return _commonPart.ModifiedUtc; } }
|
||||
|
||||
public DateTime? VersionCreatedUtc { get { return _commonPart.VersionCreatedUtc; } }
|
||||
public DateTime? VersionPublishedUtc { get { return _commonPart.VersionPublishedUtc; } }
|
||||
public DateTime? VersionModifiedUtc { get { return _commonPart.VersionModifiedUtc; } }
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
@model Orchard.Core.Common.Fields.TextField
|
||||
@using Orchard.Utility.Extensions;
|
||||
<p class="text-field"><span class="name">@Model.Name.CamelFriendly():</span> @Model.Value</p>
|
@@ -1 +0,0 @@
|
||||
@model Orchard.Core.Common.ViewModels.BodyDisplayViewModel
|
@@ -1,5 +0,0 @@
|
||||
@model BodyDisplayViewModel
|
||||
@using Orchard.Core.Common.ViewModels;
|
||||
<div class="manage">
|
||||
@Html.ItemEditLinkWithReturnUrl(T("Edit").ToString(), Model.BodyPart.ContentItem)
|
||||
</div>
|
@@ -1 +0,0 @@
|
||||
@model Orchard.Core.Common.ViewModels.BodyDisplayViewModel
|
@@ -1,7 +0,0 @@
|
||||
@model BodyDisplayViewModel
|
||||
@using Orchard.Core.Common.ViewModels;
|
||||
@* begin: knowingly broken HTML (hence the ManageWrapperPre and ManageWrapperPost templates)
|
||||
we need "wrapper templates" (among other functionality) in the future of UI composition
|
||||
please do not delete or the front end will be broken when the user is authenticated. *@
|
||||
</div>
|
||||
@* begin: knowingly broken HTML *@
|
@@ -1 +0,0 @@
|
||||
@model Orchard.Core.Common.ViewModels.BodyDisplayViewModel
|
@@ -1,3 +0,0 @@
|
||||
@model BodyDisplayViewModel
|
||||
@using Orchard.Core.Common.ViewModels;
|
||||
<div class="managewrapper">
|
@@ -0,0 +1,8 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@{
|
||||
string name = Model.Name;
|
||||
string value = Model.Value;
|
||||
}
|
||||
@if (HasText(name) && HasText(value)) {
|
||||
<p class="text-field"><span class="name">@name.CamelFriendly():</span> <span class="value">@value</span></p>
|
||||
}
|
@@ -0,0 +1,2 @@
|
||||
@using Orchard.Core.Common.Extensions;
|
||||
<div class="published">@Html.PublishedState((DateTime?)Model.ContentPart.VersionPublishedUtc, T)</div>
|
@@ -1,6 +1,2 @@
|
||||
@model Orchard.Core.Common.ViewModels.CommonMetadataViewModel
|
||||
@using Orchard.Core.Common.Extensions;
|
||||
@if (Model.Creator != null) {
|
||||
<div class="metadata">
|
||||
<div class="posted">@T("Published by {0} {1}", Model.Creator.UserName, Html.PublishedWhen(Model, T))</div>
|
||||
</div>}
|
||||
@using Orchard.Core.Common.Extensions;
|
||||
<div class="published">@Html.PublishedState((DateTime?)Model.ContentPart.VersionPublishedUtc, T)</div>
|
1
src/Orchard.Web/Core/Contents/Views/Item/Display.cshtml
Normal file
1
src/Orchard.Web/Core/Contents/Views/Item/Display.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@Display(Model)
|
@@ -5,7 +5,7 @@
|
||||
<div class="secondary">
|
||||
@Display(Model.Secondary)
|
||||
<fieldset>
|
||||
<input class="button primaryAction" type="submit" name="submit.Save" value="@T("Save")"/>
|
||||
<button class="primaryAction" type="submit" name="submit.Save">@T("Save")</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
@@ -1,11 +0,0 @@
|
||||
<div class="sections">
|
||||
<div class="primary">
|
||||
@Display(Model.Primary)
|
||||
</div>
|
||||
<div class="secondary">
|
||||
@Display(Model.Secondary)
|
||||
<fieldset>
|
||||
<input class="button primaryAction" type="submit" name="submit.Save" value="@T("Save")"/>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
@@ -1,3 +0,0 @@
|
||||
content item -> @Model.ContentItem.ContentType
|
||||
|
||||
@Display(Model.Primary)
|
@@ -1,8 +1,21 @@
|
||||
<article>
|
||||
@using Orchard.Utility.Extensions;
|
||||
@{
|
||||
Layout.Title = Model.Title;
|
||||
var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
|
||||
}
|
||||
<article class="content-item @contentTypeClassName">
|
||||
<header>
|
||||
@Display(Model.Header)
|
||||
@Display(Model.Header)
|
||||
@if (Model.Meta != null) {
|
||||
<div class="metadata">
|
||||
@Display(Model.Meta)
|
||||
</div>
|
||||
}
|
||||
</header>
|
||||
<section>
|
||||
@Display(Model.Content)
|
||||
</section>
|
||||
@Display(Model.Content)
|
||||
@if(Model.Footer != null) {
|
||||
<footer>
|
||||
@Display(Model.Footer)
|
||||
</footer>
|
||||
}
|
||||
</article>
|
@@ -82,7 +82,6 @@
|
||||
<Compile Include="ContentsLocation\Models\LocationSettings.cs" />
|
||||
<Compile Include="ContentsLocation\Settings\LocationSettingsEditorEvents.cs" />
|
||||
<Compile Include="ContentsLocation\ViewModels\LocationSettingsViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\CommonMetadataViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\ContainerEditorViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\TextContentFieldDisplayViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\TextContentFieldEditorViewModel.cs" />
|
||||
@@ -148,7 +147,6 @@
|
||||
<Compile Include="Common\Models\BodyPart.cs" />
|
||||
<Compile Include="Common\Models\BodyPartRecord.cs" />
|
||||
<Compile Include="Common\Models\CommonPartRecord.cs" />
|
||||
<Compile Include="Common\ViewModels\BodyDisplayViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\BodyEditorViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\OwnerEditorViewModel.cs" />
|
||||
<Compile Include="Contents\AdminMenu.cs" />
|
||||
@@ -255,11 +253,8 @@
|
||||
<Content Include="Common\Module.txt" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyTypePartSettings.cshtml" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyPartSettings.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Fields\Common.TextField.cshtml" />
|
||||
<Content Include="Common\Views\Fields\Common.Text.cshtml" />
|
||||
<Content Include="Common\Views\Parts\Common.Body.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.Manage.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ManageWrapperPost.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ManageWrapperPre.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\Parts\Common.Metadata.cshtml" />
|
||||
<Content Include="Common\Views\Parts\Common.Metadata.SummaryAdmin.cshtml" />
|
||||
<Content Include="ContentsLocation\Module.txt" />
|
||||
@@ -281,7 +276,7 @@
|
||||
<Content Include="PublishLater\Content\Admin\images\scheduled.gif" />
|
||||
<Content Include="PublishLater\Views\Parts\PublishLater.Metadata.cshtml" />
|
||||
<Content Include="PublishLater\Views\Parts\PublishLater.Metadata.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Fields\Common.TextField.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Fields\Common.Text.Edit.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Container.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\PlainTextEditor.cshtml" />
|
||||
<Content Include="Contents\Module.txt" />
|
||||
@@ -328,7 +323,6 @@
|
||||
<Content Include="Web.config" />
|
||||
<Content Include="XmlRpc\Module.txt" />
|
||||
<Content Include="Settings\Views\EditorTemplates\Parts\Settings.SiteSettingsPart.cshtml" />
|
||||
<Content Include="Shapes\Views\Display.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Orchard\Orchard.Framework.csproj">
|
||||
@@ -360,9 +354,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\Parts\Common.Body.Summary.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ManageWrapperPost.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ManageWrapperPre.cshtml" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.Manage.cshtml" />
|
||||
<Content Include="Dashboard\Views\Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
@@ -377,8 +368,6 @@
|
||||
<Content Include="ContentsLocation\Views\Web.config" />
|
||||
<Content Include="Messaging\Views\Web.config" />
|
||||
<Content Include="Contents\Views\Items\Content.cshtml" />
|
||||
<Content Include="Contents\Views\Items\Content.Edit.cshtml" />
|
||||
<Content Include="Contents\Views\Items\Content.Summary.cshtml" />
|
||||
<Content Include="Contents\Views\Items\Content.SummaryAdmin.cshtml" />
|
||||
<Content Include="Shapes\Views\Document.cshtml" />
|
||||
<Content Include="Shapes\Views\User.cshtml" />
|
||||
@@ -389,11 +378,16 @@
|
||||
<Content Include="Shapes\Views\Web.config" />
|
||||
<Content Include="Dashboard\Views\Helper\Index.cshtml" />
|
||||
<None Include="Common\Placement.info" />
|
||||
<Content Include="Common\Views\Parts\Common.Metadata.Summary.cshtml" />
|
||||
<None Include="Contents\Placement.info" />
|
||||
<Content Include="Contents\Views\Content.ControlWrapper.cshtml" />
|
||||
<Content Include="Contents\Views\Item\Display.cshtml" />
|
||||
<None Include="Localization\Placement.info" />
|
||||
<None Include="PublishLater\Placement.info" />
|
||||
<Content Include="Routable\Views\Parts\RoutableTitle.cshtml" />
|
||||
<None Include="PublishLater\Views\Parts\PublishLater.Metadata.Summary.cshtml" />
|
||||
<Content Include="Routable\Views\Item\Display.cshtml" />
|
||||
<Content Include="Routable\Views\Routable.HomePage.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
|
@@ -1,14 +1,14 @@
|
||||
<Placement>
|
||||
<Place Parts_PublishLater_Metadata="-"/>
|
||||
<Place Parts_PublishLater_Metadata_Summary="-"/>
|
||||
<Place Parts_PublishLater_Metadata_SummaryAdmin="-"/>
|
||||
<!-- available display shapes -->
|
||||
<!--
|
||||
Parts_PublishLater_Metadata
|
||||
Parts_PublishLater_Metadata_Summary
|
||||
Parts_PublishLater_Metadata_SummaryAdmin
|
||||
-->
|
||||
<!-- edit shape just get default placement -->
|
||||
<!-- edit "shape" -->
|
||||
<Place Parts_PublishLater_Edit="Secondary:1"/>
|
||||
<Match DisplayType="Detail">
|
||||
<Place Parts_PublishLater_Metadata="Meta:1"/>
|
||||
</Match>
|
||||
<Match DisplayType="Summary">
|
||||
<Place Parts_PublishLater_Metadata_Summary="Meta:1"/>
|
||||
</Match>
|
||||
<!-- default positioning -->
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_PublishLater_Metadata_SummaryAdmin="Meta:1"/>
|
||||
</Match>
|
||||
|
@@ -45,7 +45,7 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Display(RoutePart part, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Parts_RoutableTitle", "Header:5", () => shapeHelper.Parts_RoutableTitle(ContentPart: part, Title: part.Title));
|
||||
return ContentShape("Parts_RoutableTitle", "Header:5", () => shapeHelper.Parts_RoutableTitle(ContentPart: part, Title: part.Title, Path: part.Path));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(RoutePart part, dynamic shapeHelper) {
|
||||
|
@@ -42,7 +42,7 @@ namespace Orchard.Core.Routable.Services {
|
||||
var model = _contentManager.BuildDisplay(contentItem);
|
||||
|
||||
return new ViewResult {
|
||||
ViewName = "Display",
|
||||
ViewName = "Routable.HomePage",
|
||||
ViewData = new ViewDataDictionary<dynamic>(model)
|
||||
};
|
||||
}
|
||||
|
1
src/Orchard.Web/Core/Routable/Views/Item/Display.cshtml
Normal file
1
src/Orchard.Web/Core/Routable/Views/Item/Display.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@Display(Model)
|
@@ -1 +1 @@
|
||||
<h1>@Model.Title</h1>
|
||||
<h1><a href="@Model.Path">@Model.Title</a></h1>
|
@@ -0,0 +1 @@
|
||||
@Display(Model)
|
@@ -1,4 +0,0 @@
|
||||
@{
|
||||
Html.AddTitleParts((string)Model.Title);
|
||||
}
|
||||
@Display(Model)
|
@@ -76,10 +76,9 @@ namespace Orchard.Blogs.Controllers {
|
||||
var list = Shape.List();
|
||||
list.AddRange(blogPosts);
|
||||
|
||||
blog.ContentItem = blogPart;
|
||||
blog.Content.Add(Shape.Parts_Blogs_BlogPost_List(ContentItems: list), "5");
|
||||
|
||||
return View("Display", blog);
|
||||
return View(blog);
|
||||
}
|
||||
|
||||
public ActionResult LiveWriterManifest(string blogSlug) {
|
||||
|
@@ -2,7 +2,6 @@
|
||||
using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.ContentsLocation.Models;
|
||||
|
||||
namespace Orchard.Blogs.Drivers {
|
||||
public class BlogArchivesPartDriver : ContentPartDriver<BlogArchivesPart> {
|
||||
@@ -24,13 +23,13 @@ namespace Orchard.Blogs.Drivers {
|
||||
if (blog == null)
|
||||
return null;
|
||||
|
||||
return shapeHelper.Parts_Blogs_BlogArchives(ContentItem: part, Blog: blog, Archives: _blogPostService.GetArchives(blog));
|
||||
return shapeHelper.Parts_Blogs_BlogArchives(ContentItem: part.ContentItem, Blog: blog, Archives: _blogPostService.GetArchives(blog));
|
||||
}).Location("Content");
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(BlogArchivesPart part, dynamic shapeHelper) {
|
||||
var location = part.GetLocation("Editor", "Primary", "5");
|
||||
return ContentPartTemplate(part, "Parts/Blogs.BlogArchives").Location(location);
|
||||
return ContentShape("Parts_Blogs_BlogArchives_Editor",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Blogs.BlogArchives", Model: part, Prefix: Prefix));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(BlogArchivesPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
|
@@ -6,7 +6,6 @@ using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Feeds;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Blogs.Drivers {
|
||||
@@ -41,6 +40,8 @@ namespace Orchard.Blogs.Drivers {
|
||||
() => shapeHelper.Parts_Blogs_Blog_Manage(ContentPart: part)),
|
||||
ContentShape("Parts_Blogs_Blog_Description",
|
||||
() => shapeHelper.Parts_Blogs_Blog_Description(ContentPart: part, Description: part.Description)),
|
||||
ContentShape("Parts_Blogs_Blog_BlogPostCount",
|
||||
() => shapeHelper.Parts_Blogs_Blog_BlogPostCount(ContentPart: part, PostCount: part.PostCount)),
|
||||
// todo: (heskew) implement a paging solution that doesn't require blog posts to be tied to the blog within the controller
|
||||
ContentShape("Parts_Blogs_BlogPost_List",
|
||||
() => {
|
||||
|
@@ -5,7 +5,6 @@ using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.ContentsLocation.Models;
|
||||
|
||||
namespace Orchard.Blogs.Drivers {
|
||||
public class RecentBlogPostsPartDriver : ContentPartDriver<RecentBlogPostsPart> {
|
||||
@@ -44,12 +43,12 @@ namespace Orchard.Blogs.Drivers {
|
||||
|
||||
var blogPostList = shapeHelper.Parts_Blogs_BlogPost_List(ContentPart: part, ContentItems: list);
|
||||
|
||||
return ContentShape(shapeHelper.Parts_Blogs_RecentBlogPosts(ContentItem: part, ContentItems: blogPostList));
|
||||
return ContentShape(shapeHelper.Parts_Blogs_RecentBlogPosts(ContentItem: part.ContentItem, ContentItems: blogPostList));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(RecentBlogPostsPart part, dynamic shapeHelper) {
|
||||
var location = part.GetLocation("Editor", "Primary", "5");
|
||||
return ContentPartTemplate(part, "Parts/Blogs.RecentBlogPosts").Location(location);
|
||||
return ContentShape("Parts_Blogs_RecentBlogPosts_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Blogs.RecentBlogPosts", Model: part, Prefix: Prefix));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(RecentBlogPostsPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
|
@@ -137,10 +137,6 @@
|
||||
<Content Include="Views\Parts\Blogs.BlogPost.List.Admin.cshtml">
|
||||
<SubType>Code</SubType>
|
||||
</Content>
|
||||
<Content Include="Views\Items\Content-Blog.cshtml" />
|
||||
<Content Include="Views\Items\Content-BlogPost.cshtml" />
|
||||
<Content Include="Views\Items\Content-Blog.Summary.cshtml" />
|
||||
<Content Include="Views\Items\Content-BlogPost.Summary.cshtml" />
|
||||
<Content Include="Views\Items\Content-Blog.SummaryAdmin.cshtml" />
|
||||
<Content Include="Web.config" />
|
||||
<Content Include="Views\Web.config" />
|
||||
@@ -165,12 +161,13 @@
|
||||
<Content Include="Views\EditorTemplates\Parts\Blogs.RecentBlogPosts.cshtml" />
|
||||
<Content Include="Views\EditorTemplates\Parts\Blogs.BlogArchives.cshtml" />
|
||||
<Content Include="Views\Items\Content-Blog.DetailAdmin.cshtml" />
|
||||
<Content Include="Views\Items\Content-Blog.Editor.cshtml" />
|
||||
<Content Include="Views\Items\Content-Blog.Edit.cshtml" />
|
||||
<Content Include="Views\Items\Content-BlogPost.Editor.cshtml" />
|
||||
<Content Include="Views\Items\Content-BlogPost.SummaryAdmin.cshtml" />
|
||||
<Content Include="Views\Parts\Blogs.BlogPost.List.cshtml" />
|
||||
<Content Include="Views\Parts\Blogs.Blog.Pager.cshtml" />
|
||||
<Content Include="Views\Parts\Blogs.RecentBlogPosts.cshtml" />
|
||||
<Content Include="Views\Parts\Blogs.Blog.BlogPostCount.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
|
@@ -3,6 +3,7 @@
|
||||
<!--
|
||||
Parts_Blogs_Blog_Manage
|
||||
Parts_Blogs_Blog_Description
|
||||
Parts_Blogs_Blog_BlogPostCount
|
||||
Parts_Blogs_Blog_Pager
|
||||
Parts_Blogs_BlogPost_List -> when in the blog detail display the blog post list is currently hard-coded to Content:5 to enable the current state of blog paging
|
||||
Parts_Blogs_BlogPost_List_Admin
|
||||
@@ -10,9 +11,12 @@
|
||||
<!-- widget and edit shapes just get default placement -->
|
||||
<!-- edit "shapes" -->
|
||||
<Place Parts_Blogs_Blog_Fields="Primary:2"/>
|
||||
<Place Parts_Blogs_BlogArchives_Editor="Primary:5"/>
|
||||
<Place Parts_Blogs_RecentBlogPosts_Editor="Primary:5"/>
|
||||
<!-- widgets -->
|
||||
<Place Parts_Blogs_BlogArchives="Content"/>
|
||||
<Place Parts_Blogs_RecentBlogPosts="Content"/>
|
||||
<!-- default positioning -->
|
||||
<Match ContentType="Blog">
|
||||
<Match DisplayType="Detail">
|
||||
<!-- blog posts currently added to the blog within the controller into Content:5 <Place Parts_Blogs_BlogPost_List="Content:5" />-->
|
||||
@@ -25,7 +29,8 @@
|
||||
Parts_Blogs_Blog_Description="Manage:after"/>
|
||||
</Match>
|
||||
<Match DisplayType="Summary">
|
||||
<Place Parts_Blogs_Blog_Description="Content:before"/>
|
||||
<Place Parts_Blogs_Blog_Description="Content:before"
|
||||
Parts_Blogs_Blog_BlogPostCount="Meta:3"/>
|
||||
</Match>
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_Blogs_Blog_Description="Content:before"/>
|
||||
|
@@ -1,2 +1 @@
|
||||
@Display(Model.Meta)
|
||||
@Display(Model.Content)
|
||||
@Display(Model)
|
@@ -1,4 +1 @@
|
||||
@{
|
||||
Html.AddTitleParts((string)Model.Title);
|
||||
}
|
||||
@Display(Model)
|
@@ -0,0 +1,7 @@
|
||||
@using Orchard.Mvc.Html;
|
||||
@{
|
||||
Html.AddTitleParts((string)Model.Title);
|
||||
}
|
||||
@Display(Model.Primary)
|
||||
@Display(Model.Secondary)
|
||||
<fieldset><button class="primaryAction" type="submit">@T("Save")</button></fieldset>
|
@@ -1,6 +0,0 @@
|
||||
@using Orchard.Mvc.Html;
|
||||
@{
|
||||
Html.AddTitleParts((string)Model.Title);
|
||||
}
|
||||
@Display(Model.Primary)
|
||||
<fieldset><input class="button primaryAction" type="submit" value="@T("Add")" /></fieldset>
|
@@ -1,10 +0,0 @@
|
||||
@using Orchard.Blogs.Extensions;
|
||||
@using Orchard.Blogs.Models;
|
||||
<h2>@Html.Link((string)Model.Title, Url.Blog((string)Model.Slug))</h2>
|
||||
<div class="blog metadata">
|
||||
@T.Plural("1 post", "{0} posts", (int)Model.PostCount)
|
||||
@if (Model.Meta != null) {
|
||||
@T(" | ")@Display(Model.Meta)
|
||||
}
|
||||
</div>
|
||||
@Display(Model.Content)
|
@@ -1,3 +0,0 @@
|
||||
<h1>@Html.TitleForPage((string)Model.Title)</h1>
|
||||
@Display(Model.Meta)
|
||||
@Display(Model.Content)
|
@@ -10,7 +10,7 @@
|
||||
<div class="secondary">
|
||||
@Display(Model.Secondary)
|
||||
<fieldset>
|
||||
<input class="button primaryAction" type="submit" name="submit.Save" value="@T("Save")"/>
|
||||
<button class="primaryAction" type="submit" name="submit.Save">@T("Save")</button>
|
||||
@* TODO: (erikpo) In the future, remove the HasPublished check so the user can delete the content item from here if the choose to *@
|
||||
@if (blogPost.HasDraft && blogPost.HasPublished) {
|
||||
@Html.AntiForgeryTokenValueOrchardLink(T("Discard Draft").ToString(), Url.Action("DiscardDraft", new {Area = "Orchard.Blogs", Controller = "BlogPostAdmin", id = Model.Item.Id}), new {@class = "button"})
|
||||
|
@@ -1,8 +0,0 @@
|
||||
@using Orchard.Blogs.Extensions;
|
||||
@using Orchard.Blogs.Models;
|
||||
@using Orchard.Core.Common.Extensions;
|
||||
@using Orchard.Core.Common.Models;
|
||||
@using Orchard.Core.Common.ViewModels;
|
||||
<h2>@Html.Link((string)Model.Title, Url.BlogPost((BlogPostPart)Model.ContentItem.Get(typeof(BlogPostPart))))</h2>
|
||||
<div class="meta">@Html.PublishedState(new CommonMetadataViewModel((CommonPart)Model.ContentItem.Get(typeof(CommonPart))), T) | @Display(Model.Meta)</div>
|
||||
<div class="content">@Display(Model.Content)</div>
|
@@ -1,11 +0,0 @@
|
||||
<article>
|
||||
<header>
|
||||
@Display(Model.Header)
|
||||
<p class="metadata">
|
||||
@Display(Model.Meta)
|
||||
</p>
|
||||
</header>
|
||||
<section>
|
||||
@Display(Model.Content)
|
||||
</section>
|
||||
</article>
|
@@ -0,0 +1 @@
|
||||
<div class="blogpost-count">@T.Plural("1 post", "{0} posts", (int)Model.PostCount)</div>
|
@@ -20,13 +20,13 @@ namespace Orchard.Email.Drivers {
|
||||
protected override string Prefix { get { return "SmtpSettings"; } }
|
||||
|
||||
protected override DriverResult Editor(SmtpSettingsPart part, dynamic shapeHelper) {
|
||||
return ContentShape("Parts_SmtpSettings_Editor",
|
||||
return ContentShape("Parts_SmtpSettings_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: part, Prefix: Prefix));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(SmtpSettingsPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
updater.TryUpdateModel(part, Prefix, null, null);
|
||||
return ContentShape("Parts_SmtpSettings_Editor",
|
||||
return ContentShape("Parts_SmtpSettings_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: part, Prefix: Prefix));
|
||||
}
|
||||
}
|
||||
|
@@ -6,14 +6,8 @@
|
||||
var shapeTable = workContext.Resolve<IShapeTableManager>().GetShapeTable(workContext.CurrentTheme.ThemeName);
|
||||
<!--
|
||||
<ul>
|
||||
@foreach(var descriptor in shapeTable.Descriptors) {
|
||||
<li>@descriptor.Key : @descriptor.Value.BindingSource
|
||||
@if(descriptor.Value.Wrappers.Any()){
|
||||
foreach(var wrapper in descriptor.Value.Wrappers) {
|
||||
@(" +"+wrapper)
|
||||
}
|
||||
}
|
||||
</li>
|
||||
@foreach(var binding in shapeTable.Bindings) {
|
||||
<li>@binding.Key : @binding.Value.BindingSource</li>
|
||||
}
|
||||
</ul>
|
||||
-->
|
||||
|
@@ -36,7 +36,7 @@ namespace Orchard.Tags.Drivers {
|
||||
if (!_authorizationService.TryCheckAccess(Permissions.ApplyTag, CurrentUser, part))
|
||||
return null;
|
||||
|
||||
return ContentShape("Parts_Tags_Editor",
|
||||
return ContentShape("Parts_Tags_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: BuildEditorViewModel(part), Prefix: Prefix));
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Orchard.Tags.Drivers {
|
||||
_tagService.UpdateTagsForContentItem(part.ContentItem.Id, tagNames);
|
||||
}
|
||||
|
||||
return ContentShape("Parts_Tags_Editor",
|
||||
return ContentShape("Parts_Tags_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
|
@@ -3,22 +3,23 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.ContentManagement.Drivers {
|
||||
public abstract class ContentFieldDriver<TField> : IContentFieldDriver where TField : ContentField, new() {
|
||||
protected virtual string Prefix { get { return ""; } }
|
||||
protected virtual string Zone { get { return "body"; } }
|
||||
protected virtual string Zone { get { return "Content"; } }
|
||||
|
||||
DriverResult IContentFieldDriver.BuildDisplayShape(BuildDisplayContext context) {
|
||||
return Process(context.ContentItem, (part, field) => Display(part, field, context.DisplayType));
|
||||
return Process(context.ContentItem, (part, field) => Display(part, field, context.DisplayType, context.New));
|
||||
}
|
||||
|
||||
DriverResult IContentFieldDriver.BuildEditorShape(BuildEditorContext context) {
|
||||
return Process(context.ContentItem, Editor);
|
||||
return Process(context.ContentItem, (part, field) => Editor(part, field, context.New));
|
||||
}
|
||||
|
||||
DriverResult IContentFieldDriver.UpdateEditorShape(UpdateEditorContext context) {
|
||||
return Process(context.ContentItem, (part, field) => Editor(part, field, context.Updater));
|
||||
return Process(context.ContentItem, (part, field) => Editor(part, field, context.Updater, context.New));
|
||||
}
|
||||
|
||||
DriverResult Process(ContentItem item, Func<ContentPart, TField, DriverResult> effort) {
|
||||
@@ -43,19 +44,44 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
}
|
||||
|
||||
|
||||
protected virtual DriverResult Display(ContentPart part, TField field, string displayType) { return null; }
|
||||
protected virtual DriverResult Editor(ContentPart part, TField field) { return null; }
|
||||
protected virtual DriverResult Editor(ContentPart part, TField field, IUpdateModel updater) { return null; }
|
||||
protected virtual DriverResult Display(ContentPart part, TField field, string displayType, dynamic shapeHelper) { return null; }
|
||||
protected virtual DriverResult Editor(ContentPart part, TField field, dynamic shapeHelper) { return null; }
|
||||
protected virtual DriverResult Editor(ContentPart part, TField field, IUpdateModel updater, dynamic shapeHelper) { return null; }
|
||||
|
||||
public ContentShapeResult ContentShape(string shapeType, Func<dynamic> factory) {
|
||||
return ContentShapeImplementation(shapeType, null, ctx => factory());
|
||||
}
|
||||
|
||||
public ContentShapeResult ContentShape(string shapeType, string defaultLocation, Func<dynamic> factory) {
|
||||
return ContentShapeImplementation(shapeType, defaultLocation, ctx => factory());
|
||||
}
|
||||
|
||||
public ContentShapeResult ContentShape(string shapeType, Func<dynamic, dynamic> factory) {
|
||||
return ContentShapeImplementation(shapeType, null, ctx=>factory(CreateShape(ctx, shapeType)));
|
||||
}
|
||||
|
||||
public ContentShapeResult ContentShape(string shapeType, string defaultLocation, Func<dynamic, dynamic> factory) {
|
||||
return ContentShapeImplementation(shapeType, defaultLocation, factory);
|
||||
}
|
||||
|
||||
private ContentShapeResult ContentShapeImplementation(string shapeType, string defaultLocation, Func<BuildShapeContext, object> shapeBuilder) {
|
||||
return new ContentShapeResult(shapeType, Prefix, shapeBuilder).Location(defaultLocation);
|
||||
}
|
||||
|
||||
private object CreateShape(BuildShapeContext context, string shapeType) {
|
||||
IShapeFactory shapeFactory = context.New;
|
||||
return shapeFactory.Create(shapeType);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public ContentTemplateResult ContentFieldTemplate(object model) {
|
||||
return new ContentTemplateResult(model, null, Prefix).Location(Zone);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public ContentTemplateResult ContentFieldTemplate(object model, string template) {
|
||||
return new ContentTemplateResult(model, template, Prefix).Location(Zone);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public ContentTemplateResult ContentFieldTemplate(object model, string template, string prefix) {
|
||||
return new ContentTemplateResult(model, template, prefix).Location(Zone);
|
||||
}
|
||||
@@ -64,4 +90,4 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
return new CombinedResult(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ using Orchard.DisplayManagement;
|
||||
namespace Orchard.ContentManagement.Drivers {
|
||||
public abstract class ContentPartDriver<TContent> : IContentPartDriver where TContent : ContentPart, new() {
|
||||
protected virtual string Prefix { get { return ""; } }
|
||||
protected virtual string Zone { get { return "Primary"; } }
|
||||
protected virtual string Zone { get { return "Content"; } }
|
||||
|
||||
DriverResult IContentPartDriver.BuildDisplay(BuildDisplayContext context) {
|
||||
var part = context.ContentItem.As<TContent>();
|
||||
@@ -45,7 +45,6 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
return ContentShapeImplementation(shapeType, null, ctx=>factory(CreateShape(ctx, shapeType)));
|
||||
}
|
||||
|
||||
|
||||
public ContentShapeResult ContentShape(string shapeType, string defaultLocation, Func<dynamic, dynamic> factory) {
|
||||
return ContentShapeImplementation(shapeType, defaultLocation, factory);
|
||||
}
|
||||
|
@@ -29,6 +29,8 @@ namespace Orchard.Utility.Extensions {
|
||||
}
|
||||
|
||||
public static string HtmlClassify(this string text) {
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return text;
|
||||
var friendlier = text.CamelFriendly();
|
||||
return Regex.Replace(friendlier, @"[^a-zA-Z]+", m => m.Index == 0 ? "" : "-").ToLowerInvariant();
|
||||
}
|
||||
|
Reference in New Issue
Block a user