mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Theming items
Changing the extension to hide several old files Adjusting BuildDisplayModel family to return shape for display --HG-- branch : theming
This commit is contained in:
+2
-2
@@ -45,7 +45,7 @@ namespace Orchard.Tests.ContentManagement.Handlers.Coordinators {
|
||||
var contentHandler = _container.Resolve<IContentHandler>();
|
||||
|
||||
var contentItem = new ContentItem();
|
||||
var context = new BuildDisplayModelContext(contentItem, "");
|
||||
var context = new BuildDisplayModelContext(contentItem, "", null, null);
|
||||
|
||||
driver1.Verify(x => x.BuildDisplayShape(context), Times.Never());
|
||||
driver2.Verify(x => x.BuildDisplayShape(context), Times.Never());
|
||||
@@ -66,7 +66,7 @@ namespace Orchard.Tests.ContentManagement.Handlers.Coordinators {
|
||||
var contentItem = new ContentItem();
|
||||
contentItem.Weld(new StubPart { Foo = new[] { "a", "b", "c" } });
|
||||
|
||||
var ctx = new BuildDisplayModelContext(contentItem, "");
|
||||
var ctx = new BuildDisplayModelContext(contentItem, "", null, null);
|
||||
var context = shapeHelperFactory.CreateHelper().Context(ctx);
|
||||
Assert.That(context.TopMeta, Is.Null);
|
||||
contentHandler.BuildDisplayShape(ctx);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Orchard.Tests.ContentManagement.Models {
|
||||
public class AlphaHandler : ContentHandler {
|
||||
public AlphaHandler() {
|
||||
OnGetDisplayShape<Alpha>((ctx, part) => ctx.ContentItem.Zones["Main"].Add(part, "3"));
|
||||
OnGetDisplayShape<Alpha>((ctx, part) => ctx.Model.Zones["Main"].Add(part, "3"));
|
||||
}
|
||||
|
||||
protected override void Activating(ActivatingContentContext context) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Orchard.Tests.ContentManagement.Models {
|
||||
public class FlavoredHandler : ContentHandler {
|
||||
public FlavoredHandler() {
|
||||
OnGetDisplayShape<Flavored>((ctx, part) => ctx.ContentItem.Zones["Main"].Add(part));
|
||||
OnGetDisplayShape<Flavored>((ctx, part) => ctx.Model.Zones["Main"].Add(part));
|
||||
}
|
||||
protected override void Activating(ActivatingContentContext context) {
|
||||
if (context.ContentType == "beta" || context.ContentType == "alpha") {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Orchard.Tests.ContentManagement.Models {
|
||||
public class StyledHandler : ContentHandler {
|
||||
public StyledHandler() {
|
||||
OnGetDisplayShape<Styled>((ctx, part) => ctx.ContentItem.Zones["Main"].Add(part, "10"));
|
||||
OnGetDisplayShape<Styled>((ctx, part) => ctx.Model.Zones["Main"].Add(part, "10"));
|
||||
}
|
||||
|
||||
protected override void Activating(ActivatingContentContext context) {
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
|
||||
Services.Notifier.Information(string.IsNullOrWhiteSpace(model.TypeDefinition.DisplayName)
|
||||
? T("Your content has been created.")
|
||||
: T("Your {0} has been created.", model.TypeDefinition.DisplayName));
|
||||
: T("Your {0} has been created.", contentItem.TypeDefinition.DisplayName));
|
||||
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
|
||||
Services.Notifier.Information(string.IsNullOrWhiteSpace(model.TypeDefinition.DisplayName)
|
||||
? T("Your content has been saved.")
|
||||
: T("Your {0} has been saved.", model.TypeDefinition.DisplayName));
|
||||
: T("Your {0} has been saved.", contentItem.TypeDefinition.DisplayName));
|
||||
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace Orchard.DevTools.Handlers {
|
||||
protected override void BuildDisplayShape(BuildDisplayModelContext context) {
|
||||
var devToolsSettings = context.ContentItem.TypeDefinition.Settings.GetModel<Settings.DevToolsSettings>();
|
||||
if (devToolsSettings.ShowDebugLinks)
|
||||
context.ContentItem.Zones["Recap"].Add(new ShowDebugLink { ContentItem = context.ContentItem }, "9999");
|
||||
context.Model.Zones["Recap"].Add(new ShowDebugLink { ContentItem = context.ContentItem }, "9999");
|
||||
}
|
||||
protected override void BuildEditorShape(BuildEditorModelContext context) {
|
||||
var devToolsSettings = context.ContentItem.TypeDefinition.Settings.GetModel<Settings.DevToolsSettings>();
|
||||
if (devToolsSettings.ShowDebugLinks)
|
||||
context.ContentItem.Zones["Recap"].Add(new ShowDebugLink { ContentItem = context.ContentItem }, "9999");
|
||||
context.Model.Zones["Recap"].Add(new ShowDebugLink { ContentItem = context.ContentItem }, "9999");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,16 +104,18 @@
|
||||
<Content Include="Views\Admin\Install.aspx" />
|
||||
<Content Include="Views\Admin\ThemePreview.ascx" />
|
||||
<Content Include="Views\DisplayTemplates\Items\ContentItem.ascx" />
|
||||
<Content Include="Views\_Document.aspx" />
|
||||
<None Include="Views\Document.aspx_" />
|
||||
<Content Include="Views\EditorTemplates\Items\ContentItem.ascx" />
|
||||
<Content Include="Views\Header.ascx" />
|
||||
<Content Include="Views\HeadPreload.ascx" />
|
||||
<Content Include="Views\Layout.ascx" />
|
||||
<Content Include="Views\Menu.ascx" />
|
||||
<Content Include="Views\Messages.ascx" />
|
||||
<None Include="Views\Layout.ascx_" />
|
||||
<None Include="Views\Menu.ascx_" />
|
||||
<None Include="Views\Menu.cshtml" />
|
||||
<None Include="Views\MenuItem.cshtml" />
|
||||
<None Include="Views\Messages.ascx_" />
|
||||
<Content Include="Views\NotFound.ascx" />
|
||||
<Content Include="Views\UI\Switchable.ascx" />
|
||||
<Content Include="Views\User.ascx" />
|
||||
<None Include="Views\User.ascx_" />
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<ul id="Menu-@Model.MenuName" class="Menu Menu-@Model.MenuName">
|
||||
@foreach(var item in Model) {@Display(item);}
|
||||
</ul><!-- /Menu-@Model.MenuName -->
|
||||
@@ -0,0 +1,9 @@
|
||||
@{
|
||||
// odd formatting in this file is to cause more attractive results in the output.
|
||||
var items = (IEnumerable<dynamic>)Enumerable.Cast<dynamic>(Model);
|
||||
}
|
||||
<li><a href="@Model.Href">@Model.Text</a>@{ if (items.Any()) {
|
||||
<ul>
|
||||
@foreach(var item in Model) {@Display(item);}
|
||||
</ul>}}
|
||||
</li>
|
||||
@@ -143,7 +143,7 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Config\Sample.Host.config" />
|
||||
<None Include="Themes\Contoso\Views\HomePage\Home\Index.cshtml" />
|
||||
<None Include="Themes\Contoso\Views\Layout.HomePage.cshtml" />
|
||||
<None Include="Themes\Contoso\Views\Layout-HomePage.cshtml" />
|
||||
<None Include="Themes\TheAdmin\Styles\images\icons.psd" />
|
||||
<Content Include="Themes\ClassicDark\Content\Images\bodyBackgroundgrey.gif" />
|
||||
<Content Include="Themes\ClassicDark\Content\Images\sidebarBackground.gif" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BaseViewModel>" %>
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.ViewModels" %>
|
||||
<div class="footer group">
|
||||
<ul class="group">
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BaseViewModel>" %>
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
|
||||
<%@ Import Namespace="Orchard.DisplayManagement.Shapes" %>
|
||||
|
||||
<%
|
||||
Html.RegisterStyle("site.css", "1");
|
||||
|
||||
Model.Zones.AddRenderPartial("header", "Header", Model);
|
||||
Model.Zones.AddRenderPartial("menu", "Menu", Model);
|
||||
Model.Zones.AddRenderPartial("footer", "Footer", Model);
|
||||
|
||||
Model.Header.Add(New.Header());
|
||||
Model.Header.Add(New.Footer());
|
||||
Model.Content.Add(Model.Metadata.ChildContent, "5");
|
||||
%>
|
||||
|
||||
<div id="container">
|
||||
<%-- Header --%>
|
||||
<% Html.Zone("header"); %>
|
||||
<%: Display(Model.Header)) %>
|
||||
|
||||
<%-- Main Menu --%>
|
||||
<div id="nav">
|
||||
<% Html.Zone("menu");
|
||||
Html.Zone("search"); %>
|
||||
<%: Display(Model.Navigation) %>
|
||||
<%: Display(Model.Search) %>
|
||||
</div>
|
||||
|
||||
<%-- Main Content Area --%>
|
||||
@@ -25,14 +26,16 @@
|
||||
<div class="content sub">
|
||||
<div class="content-items group">
|
||||
<div class="main">
|
||||
<% Html.ZoneBody("content"); %>
|
||||
<%: Display(Model.Content) %>
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
|
||||
<%-- START Blog Sidebars --%>
|
||||
<%Html.Zone("sidebar");%>
|
||||
<%: Display(Model.Sidebar) %>
|
||||
<%-- END Blog Sidebars --%>
|
||||
|
||||
|
||||
<%--these would be widgets--%>
|
||||
<%--
|
||||
<div class="side-block">
|
||||
<% Html.Zone("sidebar-w1"); %>
|
||||
</div>
|
||||
@@ -41,11 +44,11 @@
|
||||
</div>
|
||||
<div class="side-block">
|
||||
<% Html.Zone("sidebar-w3"); %>
|
||||
</div>
|
||||
</div>--%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%-- Footer --%>
|
||||
<% Html.Zone("footer"); %>
|
||||
<%: Display(Model.Footer) %>
|
||||
|
||||
@@ -15,13 +15,6 @@ namespace Orchard.ContentManagement {
|
||||
private readonly IList<ContentPart> _parts;
|
||||
ContentItem IContent.ContentItem { get { return this; } }
|
||||
|
||||
private readonly IZoneCollection _zones = new ZoneCollection();
|
||||
public virtual IZoneCollection Zones {
|
||||
get {
|
||||
return _zones;
|
||||
}
|
||||
}
|
||||
|
||||
public int Id { get { return Record == null ? 0 : Record.Id; } }
|
||||
public int Version { get { return VersionRecord == null ? 0 : VersionRecord.Number; } }
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using ClaySharp.Implementation;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
@@ -19,6 +21,7 @@ namespace Orchard.ContentManagement {
|
||||
private readonly IRepository<ContentItemVersionRecord> _contentItemVersionRepository;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly Func<IContentManagerSession> _contentManagerSession;
|
||||
private readonly IShapeHelperFactory _shapeHelperFactory;
|
||||
|
||||
public DefaultContentManager(
|
||||
IComponentContext context,
|
||||
@@ -26,13 +29,15 @@ namespace Orchard.ContentManagement {
|
||||
IRepository<ContentItemRecord> contentItemRepository,
|
||||
IRepository<ContentItemVersionRecord> contentItemVersionRepository,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
Func<IContentManagerSession> contentManagerSession) {
|
||||
Func<IContentManagerSession> contentManagerSession,
|
||||
IShapeHelperFactory shapeHelperFactory) {
|
||||
_context = context;
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_contentItemRepository = contentItemRepository;
|
||||
_contentItemVersionRepository = contentItemVersionRepository;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentManagerSession = contentManagerSession;
|
||||
_shapeHelperFactory = shapeHelperFactory;
|
||||
}
|
||||
|
||||
private IEnumerable<IContentHandler> _handlers;
|
||||
@@ -393,28 +398,31 @@ namespace Orchard.ContentManagement {
|
||||
return context.Metadata;
|
||||
}
|
||||
|
||||
public TContent BuildDisplayModel<TContent>(TContent content, string displayType) where TContent : IContent {
|
||||
var context = new BuildDisplayModelContext(content, displayType);
|
||||
public dynamic BuildDisplayModel<TContent>(TContent content, string displayType) where TContent : IContent {
|
||||
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
||||
var context = new BuildDisplayModelContext(content, displayType, shapeHelper.Create("Item", Arguments.Empty()), _shapeHelperFactory);
|
||||
foreach (var handler in Handlers) {
|
||||
handler.BuildDisplayShape(context);
|
||||
}
|
||||
return content;
|
||||
return context.Model;
|
||||
}
|
||||
|
||||
public TContent BuildEditorModel<TContent>(TContent content) where TContent : IContent {
|
||||
var context = new BuildEditorModelContext(content);
|
||||
public dynamic BuildEditorModel<TContent>(TContent content) where TContent : IContent {
|
||||
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
||||
var context = new BuildEditorModelContext(content, shapeHelper.Create("Item", Arguments.Empty()), _shapeHelperFactory);
|
||||
foreach (var handler in Handlers) {
|
||||
handler.BuildEditorShape(context);
|
||||
}
|
||||
return content;
|
||||
return context.Model;
|
||||
}
|
||||
|
||||
public TContent UpdateEditorModel<TContent>(TContent content, IUpdateModel updater) where TContent : IContent {
|
||||
var context = new UpdateEditorModelContext(content, updater);
|
||||
public dynamic UpdateEditorModel<TContent>(TContent content, IUpdateModel updater) where TContent : IContent {
|
||||
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
||||
var context = new UpdateEditorModelContext(content, updater, shapeHelper.Create("Item", Arguments.Empty()), _shapeHelperFactory);
|
||||
foreach (var handler in Handlers) {
|
||||
handler.UpdateEditorShape(context);
|
||||
}
|
||||
return content;
|
||||
return context.Model;
|
||||
}
|
||||
|
||||
public IContentQuery<ContentItem> Query() {
|
||||
|
||||
@@ -16,14 +16,13 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
}
|
||||
|
||||
public override void Apply(BuildDisplayModelContext context) {
|
||||
context.ContentItem.Zones[Zone].Add(Model, Position);
|
||||
//Zone + ":" + Position, Model, TemplateName, Prefix);
|
||||
var templateShape = context.Shape.DisplayTemplate(TemplateName: TemplateName, Model: Model, Prefix: Prefix);
|
||||
context.Model.Zones[Zone].Add(templateShape, Position);
|
||||
}
|
||||
|
||||
public override void Apply(BuildEditorModelContext context) {
|
||||
context.ContentItem.Zones[Zone].Add(Model, Position);
|
||||
//context.ViewModel.Zones.AddEditorPart(
|
||||
// Zone + ":" + Position, Model, TemplateName, Prefix);
|
||||
var templateShape = context.Shape.EditorTemplate(TemplateName: TemplateName, Model: Model, Prefix: Prefix);
|
||||
context.Model.Zones[Zone].Add(templateShape, Position);
|
||||
}
|
||||
|
||||
public ContentTemplateResult Location(string zone) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class BuildDisplayModelContext {
|
||||
public BuildDisplayModelContext(IContent content, string displayType) {
|
||||
ContentItem = content.ContentItem;
|
||||
public class BuildDisplayModelContext : BuildModelContext {
|
||||
public BuildDisplayModelContext(IContent content, string displayType, IShape model, IShapeHelperFactory shapeHelperFactory)
|
||||
: base(content, model, shapeHelperFactory) {
|
||||
DisplayType = displayType;
|
||||
}
|
||||
|
||||
public ContentItem ContentItem { get; private set; }
|
||||
public string DisplayType { get; private set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class BuildEditorModelContext {
|
||||
public BuildEditorModelContext(IContent content) {
|
||||
ContentItem = content.ContentItem;
|
||||
}
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
public ContentItem ContentItem { get; set; }
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class BuildEditorModelContext : BuildModelContext {
|
||||
public BuildEditorModelContext(IContent content, IShape model, IShapeHelperFactory shapeHelperFactory) : base(content, model, shapeHelperFactory) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class BuildModelContext {
|
||||
protected BuildModelContext(IContent content, IShape model, IShapeHelperFactory shapeHelperFactory) {
|
||||
ContentItem = content.ContentItem;
|
||||
Model = model;
|
||||
Shape = shapeHelperFactory.CreateHelper();
|
||||
}
|
||||
|
||||
public ContentItem ContentItem { get; private set; }
|
||||
public dynamic Model { get; private set; }
|
||||
public dynamic Shape { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Orchard.ContentManagement.Records;
|
||||
using System;
|
||||
using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
[Obsolete]
|
||||
public class TemplateFilterForRecord<TRecord> : TemplateFilterBase<ContentPart<TRecord>> where TRecord : ContentPartRecord, new() {
|
||||
private readonly string _prefix;
|
||||
private string _location;
|
||||
@@ -22,13 +24,13 @@ namespace Orchard.ContentManagement.Handlers {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override void BuildEditorShape(BuildEditorModelContext context, ContentPart<TRecord> part) {
|
||||
context.ContentItem.Zones[_location].Add(part.Record, _position);
|
||||
}
|
||||
//protected override void BuildEditorShape(BuildEditorModelContext context, ContentPart<TRecord> part) {
|
||||
// context.ContentItem.Zones[_location].Add(part.Record, _position);
|
||||
//}
|
||||
|
||||
protected override void UpdateEditorShape(UpdateEditorModelContext context, ContentPart<TRecord> part) {
|
||||
context.Updater.TryUpdateModel(part.Record, _prefix, null, null);
|
||||
BuildEditorShape(context, part);
|
||||
}
|
||||
//protected override void UpdateEditorShape(UpdateEditorModelContext context, ContentPart<TRecord> part) {
|
||||
// context.Updater.TryUpdateModel(part.Record, _prefix, null, null);
|
||||
// BuildEditorShape(context, part);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class UpdateEditorModelContext : BuildEditorModelContext {
|
||||
public UpdateEditorModelContext(IContent content, IUpdateModel updater)
|
||||
: base(content) {
|
||||
public UpdateEditorModelContext(IContent content, IUpdateModel updater, IShape model, IShapeHelperFactory shapeHelperFactory)
|
||||
: base(content, model, shapeHelperFactory) {
|
||||
Updater = updater;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
namespace Orchard.ContentManagement {
|
||||
public interface IContent {
|
||||
ContentItem ContentItem { get; }
|
||||
IZoneCollection Zones { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
@@ -27,9 +28,9 @@ namespace Orchard.ContentManagement {
|
||||
|
||||
ContentItemMetadata GetItemMetadata(IContent contentItem);
|
||||
|
||||
TContent BuildDisplayModel<TContent>(TContent content, string displayType) where TContent : IContent;
|
||||
TContent BuildEditorModel<TContent>(TContent content) where TContent : IContent;
|
||||
TContent UpdateEditorModel<TContent>(TContent content, IUpdateModel updater) where TContent : IContent;
|
||||
dynamic BuildDisplayModel<TContent>(TContent content, string displayType) where TContent : IContent;
|
||||
dynamic BuildEditorModel<TContent>(TContent content) where TContent : IContent;
|
||||
dynamic UpdateEditorModel<TContent>(TContent content, IUpdateModel updater) where TContent : IContent;
|
||||
}
|
||||
|
||||
public class VersionOptions {
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ContentManagement\Handlers\BuildModelContext.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeDescriptor.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeDescriptorAlteration.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeDescriptorAlterationBuilder.cs" />
|
||||
|
||||
Reference in New Issue
Block a user