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:
Renaud Paquay
2010-07-25 11:50:23 -07:00
parent 0d4b1e6c42
commit 590613786d
10 changed files with 121 additions and 40 deletions

View File

@@ -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(
@@ -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;
}
}
}

View 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;
}
}
}

View File

@@ -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" />

View File

@@ -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 });

View File

@@ -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>");
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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" />

View File

@@ -0,0 +1,5 @@
namespace Orchard.Services {
public interface IHtmlFilter : IDependency {
string ProcessContent(string text);
}
}