mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-02 19:44:02 +08:00
Fix issue with Contoso and gallery pictures
We now support the BBCode syntax for static html files
serving as the basis for Widgets. All this stuff is still
futures work, but we needed a temporary solution for Alpha.
Here is the new syntax for one of the Widget file:
<div id="slider">
<ul>
<li>[img]~/Themes/Contoso/Content/Images/Gallery/feature01.jpg[/img]</li>
<li>[img]~/Themes/Contoso/Content/Images/Gallery/feature02.jpg[/img]</li>
<li>[img]~/Themes/Contoso/Content/Images/Gallery/feature03.jpg[/img]</li>
</ul>
</div>
--HG--
branch : dev
This commit is contained in:
@@ -1,33 +1,42 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.Services;
|
||||
using Orchard.Core.Common.Settings;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Core.ContentsLocation.Models;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Services;
|
||||
|
||||
namespace Orchard.Core.Common.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class BodyPartDriver : ContentPartDriver<BodyPart> {
|
||||
public IOrchardServices Services { get; set; }
|
||||
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
|
||||
|
||||
private const string TemplateName = "Parts/Common.Body";
|
||||
private const string DefaultTextEditorTemplate = "TinyMceTextEditor";
|
||||
private const string PlainTextEditorTemplate = "PlainTextEditor";
|
||||
|
||||
public BodyPartDriver(IOrchardServices services) {
|
||||
public BodyPartDriver(IOrchardServices services, IEnumerable<IHtmlFilter> htmlFilters) {
|
||||
_htmlFilters = htmlFilters;
|
||||
Services = services;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
protected override string Prefix {
|
||||
get { return "Body"; }
|
||||
}
|
||||
|
||||
// \/\/ Hackalicious on many accounts - don't copy what has been done here for the wrapper \/\/
|
||||
protected override DriverResult Display(BodyPart part, string displayType) {
|
||||
var model = new BodyDisplayViewModel { BodyPart = part, Text = BbcodeReplace(part.Text) };
|
||||
var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text));
|
||||
var model = new BodyDisplayViewModel { BodyPart = part, Text = bodyText };
|
||||
var location = part.GetLocation(displayType);
|
||||
|
||||
return Combined(
|
||||
@@ -36,7 +45,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
ContentPartTemplate(model, TemplateName, Prefix).LongestMatch(displayType, "Summary", "SummaryAdmin").Location(location),
|
||||
Services.Authorizer.Authorize(Permissions.ChangeOwner) ? ContentPartTemplate(model, "Parts/Common.Body.ManageWrapperPost").LongestMatch(displayType, "SummaryAdmin").Location(location) : null);
|
||||
}
|
||||
|
||||
|
||||
protected override DriverResult Editor(BodyPart part) {
|
||||
var model = BuildEditorViewModel(part);
|
||||
var location = part.GetLocation("Editor");
|
||||
@@ -59,7 +68,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
return new BodyEditorViewModel {
|
||||
BodyPart = part,
|
||||
TextEditorTemplate = GetFlavor(part) == "html" ? DefaultTextEditorTemplate : PlainTextEditorTemplate,
|
||||
AddMediaPath= new PathBuilder(part).AddContentType().AddContainerSlug().AddSlug().ToString()
|
||||
AddMediaPath = new PathBuilder(part).AddContentType().AddContainerSlug().AddSlug().ToString()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,25 +127,6 @@ namespace Orchard.Core.Common.Drivers {
|
||||
else
|
||||
_path = _path + "/" + segment;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Can be moved somewhere else once we have IoC enabled body text filters.
|
||||
private static string BbcodeReplace(string bodyText) {
|
||||
|
||||
if ( string.IsNullOrEmpty(bodyText) )
|
||||
return string.Empty;
|
||||
|
||||
Regex urlRegex = new Regex(@"\[url\]([^\]]+)\[\/url\]");
|
||||
Regex urlRegexWithLink = new Regex(@"\[url=([^\]]+)\]([^\]]+)\[\/url\]");
|
||||
Regex imgRegex = new Regex(@"\[img\]([^\]]+)\[\/img\]");
|
||||
|
||||
bodyText = urlRegex.Replace(bodyText, "<a href=\"$1\">$1</a>");
|
||||
bodyText = urlRegexWithLink.Replace(bodyText, "<a href=\"$1\">$2</a>");
|
||||
bodyText = imgRegex.Replace(bodyText, "<img src=\"$1\" />");
|
||||
|
||||
return bodyText;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/Orchard.Web/Core/Common/Services/BbcodeFilter.cs
Normal file
52
src/Orchard.Web/Core/Common/Services/BbcodeFilter.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Services;
|
||||
|
||||
namespace Orchard.Core.Common.Services {
|
||||
public class BbcodeFilter : IHtmlFilter {
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
|
||||
public BbcodeFilter(IVirtualPathProvider virtualPathProvider) {
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
}
|
||||
|
||||
public string ProcessContent(string text) {
|
||||
return BbcodeReplace(text);
|
||||
}
|
||||
|
||||
// Can be moved somewhere else once we have IoC enabled body text filters.
|
||||
private string BbcodeReplace(string text) {
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return string.Empty;
|
||||
|
||||
Regex urlRegex = new Regex(@"\[url\]([^\]]+)\[\/url\]");
|
||||
Regex urlRegexWithLink = new Regex(@"\[url=([^\]]+)\]([^\]]+)\[\/url\]");
|
||||
Regex imgRegex = new Regex(@"\[img\]([^\]]+)\[\/img\]");
|
||||
|
||||
text = urlRegex.Replace(text, "<a href=\"$1\">$1</a>");
|
||||
text = urlRegexWithLink.Replace(text, "<a href=\"$1\">$2</a>");
|
||||
//text = imgRegex.Replace(text, "<img src=\"$1\" />");
|
||||
|
||||
var matches = imgRegex.Matches(text).OfType<Match>().OrderByDescending(m => m.Groups[0].Index);
|
||||
foreach(var match in matches) {
|
||||
var index = match.Groups[0].Index;
|
||||
var length = match.Groups[0].Length;
|
||||
var url = match.Groups[1].Value.Trim();
|
||||
if (!string.IsNullOrEmpty(url)) {
|
||||
if (url[0]=='~')
|
||||
url = VirtualPathUtility.ToAbsolute(url);
|
||||
text =
|
||||
text.Substring(0, index) +
|
||||
string.Format("<img src=\"{0}\" />", url) +
|
||||
text.Substring(index + length);
|
||||
}
|
||||
}
|
||||
|
||||
text = imgRegex.Replace(text, "<img src=\"$1\" />");
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,7 @@
|
||||
<Compile Include="Common\Extensions\HtmlHelperExtensions.cs" />
|
||||
<Compile Include="Common\Fields\TextField.cs" />
|
||||
<Compile Include="Common\Security\AuthorizationEventHandler.cs" />
|
||||
<Compile Include="Common\Services\BbcodeFilter.cs" />
|
||||
<Compile Include="ContentsLocation\Models\LocationDefinition.cs" />
|
||||
<Compile Include="Common\Services\ICommonService.cs" />
|
||||
<Compile Include="Common\Services\CommonService.cs" />
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Futures.Widgets.Models;
|
||||
using Futures.Widgets.ViewModels;
|
||||
using Orchard;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Services;
|
||||
using Orchard.Settings;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Futures.Widgets.Controllers {
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
public AdminController(IOrchardServices services) {
|
||||
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
|
||||
|
||||
public AdminController(IOrchardServices services, IEnumerable<IHtmlFilter> htmlFilters) {
|
||||
_htmlFilters = htmlFilters;
|
||||
Services = services;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
@@ -31,11 +37,14 @@ namespace Futures.Widgets.Controllers {
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
|
||||
var fileText = _htmlFilters
|
||||
.Aggregate(System.IO.File.ReadAllText(physicalPath), (text, filter) => filter.ProcessContent(text));
|
||||
|
||||
var widget = Services.ContentManager.Create<WidgetPart>("HtmlWidget", init => {
|
||||
init.Record.Scope = hasWidgetsRecord;
|
||||
init.Record.Zone = zoneName;
|
||||
init.Record.Position = "1";
|
||||
init.As<BodyPart>().Text = System.IO.File.ReadAllText(physicalPath);
|
||||
init.As<BodyPart>().Text = fileText;
|
||||
});
|
||||
|
||||
return RedirectToAction("Edit", new { widget.ContentItem.Id, returnUrl });
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc.Html;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Security;
|
||||
using Orchard.Services;
|
||||
using Orchard.UI.Zones;
|
||||
|
||||
namespace Orchard.Themes.DesignerNotes {
|
||||
public class ZoneManagerEvents : IZoneManagerEvents {
|
||||
private readonly IThemeService _themeService;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IShellDescriptorManager _shellDescriptorManager;
|
||||
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
|
||||
|
||||
public ZoneManagerEvents(IThemeService themeService,
|
||||
IAuthorizationService authorizationService,
|
||||
IShellDescriptorManager shellDescriptorManager,
|
||||
IEnumerable<IHtmlFilter> htmlFilters) {
|
||||
|
||||
public ZoneManagerEvents(IThemeService themeService, IAuthorizationService authorizationService) {
|
||||
_themeService = themeService;
|
||||
_authorizationService = authorizationService;
|
||||
_shellDescriptorManager = shellDescriptorManager;
|
||||
_htmlFilters = htmlFilters;
|
||||
}
|
||||
|
||||
public virtual IUser CurrentUser { get; set; }
|
||||
@@ -29,6 +40,13 @@ namespace Orchard.Themes.DesignerNotes {
|
||||
|
||||
var accessAdminPanel = _authorizationService.TryCheckAccess(
|
||||
StandardPermissions.AccessAdminPanel, CurrentUser, null);
|
||||
if (accessAdminPanel) {
|
||||
//Temporary: Don't show "edit" button if "Futures.Widgets" is not enabled.
|
||||
accessAdminPanel = _shellDescriptorManager
|
||||
.GetShellDescriptor()
|
||||
.Features
|
||||
.Any(f => f.Name == "Futures.Widgets");
|
||||
}
|
||||
|
||||
var writer = context.Html.ViewContext.Writer;
|
||||
if (accessAdminPanel) {
|
||||
@@ -42,7 +60,11 @@ namespace Orchard.Themes.DesignerNotes {
|
||||
}));
|
||||
writer.Write("</div>");
|
||||
}
|
||||
writer.Write(File.ReadAllText(physicalPath));
|
||||
|
||||
var fileText = _htmlFilters
|
||||
.Aggregate(File.ReadAllText(physicalPath), (text, filter) => filter.ProcessContent(text));
|
||||
|
||||
writer.Write(fileText);
|
||||
if (accessAdminPanel) {
|
||||
writer.Write("</div>");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div id="slider">
|
||||
<ul>
|
||||
<li><img src="/Themes/Contoso/Content/Images/Gallery/feature01.jpg" alt="Orchard Rocks" /></li>
|
||||
<li><img src="/Themes/Contoso/Content/Images/Gallery/feature02.jpg" alt="Orchard FTW" /></li>
|
||||
<li><img src="/Themes/Contoso/Content/Images/Gallery/feature03.jpg" alt="Orchard Time" /></li>
|
||||
<li>[img]~/Themes/Contoso/Content/Images/Gallery/feature01.jpg[/img]</li>
|
||||
<li>[img]~/Themes/Contoso/Content/Images/Gallery/feature02.jpg[/img]</li>
|
||||
<li>[img]~/Themes/Contoso/Content/Images/Gallery/feature03.jpg[/img]</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
<div id="hm-image">
|
||||
<img src="Themes/Corporate/Content/Images/jumping-people.jpg" /></div>
|
||||
[img]~/Themes/Corporate/Content/Images/jumping-people.jpg[/img]
|
||||
</div>
|
||||
@@ -9,16 +9,16 @@
|
||||
</div>
|
||||
<ul id="hm-icons">
|
||||
<li>
|
||||
<img src="Themes/Corporate/Content/Images/icons/icon-1.png" />
|
||||
[img]~/Themes/Corporate/Content/Images/icons/icon-1.png[/img]
|
||||
<a href="#" title="Bullet Point One">
|
||||
Bullet Point One</a></li>
|
||||
<li><img src="Themes/Corporate/Content/Images/icons/icon-2.png" /><a href="#" title="Bullet Point One">
|
||||
<li>[img]~/Themes/Corporate/Content/Images/icons/icon-2.png[/img]<a href="#" title="Bullet Point One">
|
||||
Bullet Point Two</a></li>
|
||||
<li><img src="Themes/Corporate/Content/Images/icons/icon-3.png" /><a href="#" title="Bullet Point One">
|
||||
<li>[img]~/Themes/Corporate/Content/Images/icons/icon-3.png[/img]<a href="#" title="Bullet Point One">
|
||||
Bullet Point Three</a></li>
|
||||
<li><img src="Themes/Corporate/Content/Images/icons/icon-4.png" /><a href="#" title="Bullet Point One">
|
||||
<li>[img]~/Themes/Corporate/Content/Images/icons/icon-4.png[/img]<a href="#" title="Bullet Point One">
|
||||
Bullet Point Four</a></li>
|
||||
<li><img src="Themes/Corporate/Content/Images/icons/icon-5.png" /><a href="#" title="Bullet Point One">
|
||||
<li>[img]~/Themes/Corporate/Content/Images/icons/icon-5.png[/img]<a href="#" title="Bullet Point One">
|
||||
Bullet Point Five</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -369,6 +369,7 @@
|
||||
</Compile>
|
||||
<Compile Include="ContentManagement\DataMigrations\FrameworkDataMigration.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" />
|
||||
<Compile Include="Services\IHtmlFilter.cs" />
|
||||
<Compile Include="Utility\Hash.cs" />
|
||||
<Compile Include="Data\ISessionConfigurationCache.cs" />
|
||||
<Compile Include="Data\Migration\Generator\ISchemaCommandGenerator.cs" />
|
||||
|
||||
5
src/Orchard/Services/IHtmlFilter.cs
Normal file
5
src/Orchard/Services/IHtmlFilter.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace Orchard.Services {
|
||||
public interface IHtmlFilter : IDependency {
|
||||
string ProcessContent(string text);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user