add support for body content
This commit is contained in:
@ -96,7 +96,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Section Name="Appearance" ResourceKey="Appearance">
|
||||
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
|
||||
@ -133,13 +133,23 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="bodycontent" HelpText="Optionally enter content to be included in the page body (ie. script tags)" ResourceKey="BodyContent">Body Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
}
|
||||
</TabPanel>
|
||||
@ -169,20 +179,21 @@
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _name;
|
||||
private string _title;
|
||||
private string _path = string.Empty;
|
||||
private string _parentid = "-1";
|
||||
private string _insert = ">>";
|
||||
private List<Page> _children;
|
||||
private int _childid = -1;
|
||||
private string _isnavigation = "True";
|
||||
private string _isclickable = "True";
|
||||
private string _url;
|
||||
private string _path = string.Empty;
|
||||
private string _url;
|
||||
private string _ispersonalizable = "False";
|
||||
private string _themetype = string.Empty;
|
||||
private string _title;
|
||||
private string _icon = string.Empty;
|
||||
private string _themetype = string.Empty;
|
||||
private string _containertype = string.Empty;
|
||||
private string _headcontent;
|
||||
private string _icon = string.Empty;
|
||||
private string _bodycontent;
|
||||
private string _permissions = null;
|
||||
private PermissionGrid _permissionGrid;
|
||||
private Type _themeSettingsType;
|
||||
@ -297,7 +308,6 @@
|
||||
page = new Page();
|
||||
page.SiteId = PageState.Page.SiteId;
|
||||
page.Name = _name;
|
||||
page.Title = _title;
|
||||
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
{
|
||||
@ -365,7 +375,13 @@
|
||||
|
||||
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
||||
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
||||
page.Url = _url;
|
||||
page.Url = _url;
|
||||
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
||||
page.UserId = null;
|
||||
|
||||
// appearance
|
||||
page.Title = _title;
|
||||
page.Icon = (_icon == null ? string.Empty : _icon);
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
@ -376,11 +392,13 @@
|
||||
{
|
||||
page.DefaultContainerType = string.Empty;
|
||||
}
|
||||
|
||||
// page content
|
||||
page.HeadContent = _headcontent;
|
||||
page.Icon = (_icon == null ? string.Empty : _icon);
|
||||
page.BodyContent = _bodycontent;
|
||||
|
||||
// permissions
|
||||
page.PermissionList = _permissionGrid.GetPermissionList();
|
||||
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
||||
page.UserId = null;
|
||||
|
||||
page = await PageService.AddPageAsync(page);
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||
|
@ -140,12 +140,22 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="bodycontent" HelpText="Optionally enter content to be included in the page body (ie. script tags)" ResourceKey="BodyContent">Body Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<br />
|
||||
@ -196,323 +206,339 @@
|
||||
</form>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private List<Module> _pageModules;
|
||||
private int _pageId;
|
||||
private string _name;
|
||||
private string _title;
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private int _pageId;
|
||||
private string _name;
|
||||
private string _currentparentid;
|
||||
private string _parentid = "-1";
|
||||
private string _insert = "=";
|
||||
private List<Page> _children;
|
||||
private int _childid = -1;
|
||||
private string _isnavigation;
|
||||
private string _isclickable;
|
||||
private string _path;
|
||||
private string _currentparentid;
|
||||
private string _parentid = "-1";
|
||||
private string _insert = "=";
|
||||
private List<Page> _children;
|
||||
private int _childid = -1;
|
||||
private string _isnavigation;
|
||||
private string _isclickable;
|
||||
private string _url;
|
||||
private string _ispersonalizable;
|
||||
private string _themetype;
|
||||
private string _containertype = "-";
|
||||
private string _headcontent;
|
||||
private string _url;
|
||||
private string _ispersonalizable;
|
||||
private string _title;
|
||||
private string _icon;
|
||||
private List<Permission> _permissions = null;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
private PermissionGrid _permissionGrid;
|
||||
private Type _themeSettingsType;
|
||||
private object _themeSettings;
|
||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||
private bool _refresh = false;
|
||||
protected Page page;
|
||||
private string _themetype;
|
||||
private string _containertype = "-";
|
||||
private Type _themeSettingsType;
|
||||
private object _themeSettings;
|
||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||
private string _headcontent;
|
||||
private string _bodycontent;
|
||||
private List<Permission> _permissions = null;
|
||||
private PermissionGrid _permissionGrid;
|
||||
private List<Module> _pageModules;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
private bool _refresh = false;
|
||||
protected Page page;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
|
||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
|
||||
if (page != null)
|
||||
{
|
||||
_name = page.Name;
|
||||
_title = page.Title;
|
||||
_path = page.Path;
|
||||
_pageModules = PageState.Modules.Where(m => m.PageId == page.PageId).ToList();
|
||||
if (page != null)
|
||||
{
|
||||
_name = page.Name;
|
||||
if (page.ParentId == null)
|
||||
{
|
||||
_parentid = "-1";
|
||||
}
|
||||
else
|
||||
{
|
||||
_parentid = page.ParentId.ToString();
|
||||
}
|
||||
_currentparentid = _parentid;
|
||||
_isnavigation = page.IsNavigation.ToString();
|
||||
_isclickable = page.IsClickable.ToString();
|
||||
_path = page.Path;
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
{
|
||||
_path = "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
}
|
||||
_url = page.Url;
|
||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
{
|
||||
_path = "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (page.ParentId == null)
|
||||
{
|
||||
_parentid = "-1";
|
||||
}
|
||||
else
|
||||
{
|
||||
_parentid = page.ParentId.ToString();
|
||||
}
|
||||
|
||||
_currentparentid = _parentid;
|
||||
_isnavigation = page.IsNavigation.ToString();
|
||||
_isclickable = page.IsClickable.ToString();
|
||||
_url = page.Url;
|
||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||
_themetype = page.ThemeType;
|
||||
if (string.IsNullOrEmpty(_themetype))
|
||||
{
|
||||
_themetype = PageState.Site.DefaultThemeType;
|
||||
}
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = page.DefaultContainerType;
|
||||
if (string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
_containertype = PageState.Site.DefaultContainerType;
|
||||
}
|
||||
_headcontent = page.HeadContent;
|
||||
// appearance
|
||||
_title = page.Title;
|
||||
_icon = page.Icon;
|
||||
_permissions = page.PermissionList;
|
||||
_createdby = page.CreatedBy;
|
||||
_createdon = page.CreatedOn;
|
||||
_modifiedby = page.ModifiedBy;
|
||||
_modifiedon = page.ModifiedOn;
|
||||
_deletedby = page.DeletedBy;
|
||||
_deletedon = page.DeletedOn;
|
||||
_themetype = page.ThemeType;
|
||||
if (string.IsNullOrEmpty(_themetype))
|
||||
{
|
||||
_themetype = PageState.Site.DefaultThemeType;
|
||||
}
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = page.DefaultContainerType;
|
||||
if (string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
_containertype = PageState.Site.DefaultContainerType;
|
||||
}
|
||||
|
||||
ThemeSettings();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
// page content
|
||||
_headcontent = page.HeadContent;
|
||||
_bodycontent = page.BodyContent;
|
||||
|
||||
private async Task DeleteModule(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(page.PageId, module.ModuleId);
|
||||
pagemodule.IsDeleted = true;
|
||||
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
||||
await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title);
|
||||
_pageModules.RemoveAll(item => item.PageModuleId == pagemodule.PageModuleId);
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri + "&tab=PageModules");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Module {Title} {Error}", module.Title, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
// permissions
|
||||
_permissions = page.PermissionList;
|
||||
|
||||
private async void ParentChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_parentid = (string)e.Value;
|
||||
_children = new List<Page>();
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_parentid == _currentparentid)
|
||||
{
|
||||
_insert = "=";
|
||||
}
|
||||
else
|
||||
{
|
||||
_insert = ">>";
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
// page modules
|
||||
_pageModules = PageState.Modules.Where(m => m.PageId == page.PageId).ToList();
|
||||
|
||||
private async void ThemeChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = "-";
|
||||
ThemeSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
// audit
|
||||
_createdby = page.CreatedBy;
|
||||
_createdon = page.CreatedOn;
|
||||
_modifiedby = page.ModifiedBy;
|
||||
_modifiedon = page.ModifiedOn;
|
||||
_deletedby = page.DeletedBy;
|
||||
_deletedon = page.DeletedOn;
|
||||
|
||||
private void ThemeSettings()
|
||||
{
|
||||
_themeSettingsType = null;
|
||||
if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel
|
||||
{
|
||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||
{
|
||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||
if (_themeSettingsType != null)
|
||||
{
|
||||
ThemeSettingsComponent = builder =>
|
||||
{
|
||||
builder.OpenComponent(0, _themeSettingsType);
|
||||
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
||||
builder.CloseComponent();
|
||||
};
|
||||
}
|
||||
_refresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ThemeSettings();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SavePage()
|
||||
{
|
||||
validated = true;
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
||||
{
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
string currentPath = page.Path;
|
||||
private async Task DeleteModule(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(page.PageId, module.ModuleId);
|
||||
pagemodule.IsDeleted = true;
|
||||
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
||||
await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title);
|
||||
_pageModules.RemoveAll(item => item.PageModuleId == pagemodule.PageModuleId);
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri + "&tab=PageModules");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Module {Title} {Error}", module.Title, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
page.Name = _name;
|
||||
page.Title = _title;
|
||||
private async void ParentChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_parentid = (string)e.Value;
|
||||
_children = new List<Page>();
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_parentid == _currentparentid)
|
||||
{
|
||||
_insert = "=";
|
||||
}
|
||||
else
|
||||
{
|
||||
_insert = ">>";
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
{
|
||||
_path = _name;
|
||||
}
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
if (_path.EndsWith("/") && _path != "/")
|
||||
{
|
||||
_path = _path.Substring(0, _path.Length - 1);
|
||||
}
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
private async void ThemeChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = "-";
|
||||
ThemeSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
page.ParentId = null;
|
||||
page.Path = Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.ParentId = Int32.Parse(_parentid);
|
||||
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
|
||||
if (parent.Path == string.Empty)
|
||||
{
|
||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
private void ThemeSettings()
|
||||
{
|
||||
_themeSettingsType = null;
|
||||
if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel
|
||||
{
|
||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||
{
|
||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||
if (_themeSettingsType != null)
|
||||
{
|
||||
ThemeSettingsComponent = builder =>
|
||||
{
|
||||
builder.OpenComponent(0, _themeSettingsType);
|
||||
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
||||
builder.CloseComponent();
|
||||
};
|
||||
}
|
||||
_refresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
||||
if (_pages.Any(item => item.Path == page.Path && item.PageId != page.PageId))
|
||||
{
|
||||
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
private async Task SavePage()
|
||||
{
|
||||
validated = true;
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
||||
{
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
string currentPath = page.Path;
|
||||
|
||||
if (page.ParentId == null && Constants.ReservedRoutes.Contains(page.Name.ToLower()))
|
||||
{
|
||||
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
page.Name = _name;
|
||||
|
||||
if (_insert != "=")
|
||||
{
|
||||
Page child;
|
||||
switch (_insert)
|
||||
{
|
||||
case "<<":
|
||||
page.Order = 0;
|
||||
break;
|
||||
case "<":
|
||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||
if (child != null) page.Order = child.Order - 1;
|
||||
break;
|
||||
case ">":
|
||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||
if (child != null) page.Order = child.Order + 1;
|
||||
break;
|
||||
case ">>":
|
||||
page.Order = int.MaxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
||||
page.Url = _url;
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
page.ThemeType = string.Empty;
|
||||
}
|
||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
page.DefaultContainerType = string.Empty;
|
||||
}
|
||||
page.HeadContent = _headcontent;
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
{
|
||||
_path = _name;
|
||||
}
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
if (_path.EndsWith("/") && _path != "/")
|
||||
{
|
||||
_path = _path.Substring(0, _path.Length - 1);
|
||||
}
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
page.ParentId = null;
|
||||
page.Path = Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.ParentId = Int32.Parse(_parentid);
|
||||
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
|
||||
if (parent.Path == string.Empty)
|
||||
{
|
||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
||||
if (_pages.Any(item => item.Path == page.Path && item.PageId != page.PageId))
|
||||
{
|
||||
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (page.ParentId == null && Constants.ReservedRoutes.Contains(page.Name.ToLower()))
|
||||
{
|
||||
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_insert != "=")
|
||||
{
|
||||
Page child;
|
||||
switch (_insert)
|
||||
{
|
||||
case "<<":
|
||||
page.Order = 0;
|
||||
break;
|
||||
case "<":
|
||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||
if (child != null) page.Order = child.Order - 1;
|
||||
break;
|
||||
case ">":
|
||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||
if (child != null) page.Order = child.Order + 1;
|
||||
break;
|
||||
case ">>":
|
||||
page.Order = int.MaxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
||||
page.Url = _url;
|
||||
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
||||
page.UserId = null;
|
||||
|
||||
// appearance
|
||||
page.Title = _title;
|
||||
page.Icon = _icon ?? string.Empty;
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
page.ThemeType = string.Empty;
|
||||
}
|
||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
page.DefaultContainerType = string.Empty;
|
||||
}
|
||||
|
||||
// page content
|
||||
page.HeadContent = _headcontent;
|
||||
page.BodyContent = _bodycontent;
|
||||
|
||||
// permissions
|
||||
page.PermissionList = _permissionGrid.GetPermissionList();
|
||||
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
||||
page.UserId = null;
|
||||
|
||||
page = await PageService.UpdatePageAsync(page);
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||
|
@ -55,59 +55,71 @@
|
||||
</div>
|
||||
<br />
|
||||
<Section Name="Appearance" ResourceKey="Appearance">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||
<div class="col-sm-9">
|
||||
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||
<div class="col-sm-9">
|
||||
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="favicon" HelpText="Specify a Favicon" ResourceKey="FavoriteIcon">Favicon: </Label>
|
||||
<div class="col-sm-9">
|
||||
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
||||
<option value="-"><@Localizer["Theme.Select"]></option>
|
||||
@foreach (var theme in _themes)
|
||||
{
|
||||
<option value="@theme.TypeName">@theme.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="defaultContainer" class="form-select" @bind="@_containertype" required>
|
||||
<option value="-"><@Localizer["Container.Select"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="defaultAdminContainer" class="form-select" @bind="@_admincontainertype" required>
|
||||
<option value="-"><@Localizer["Container.Select"]></option>
|
||||
<option value="@Constants.DefaultAdminContainer"><@Localizer["DefaultAdminContainer"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="favicon" HelpText="Specify a Favicon" ResourceKey="FavoriteIcon">Favicon: </Label>
|
||||
<div class="col-sm-9">
|
||||
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" />
|
||||
</Section>
|
||||
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
||||
<option value="-"><@Localizer["Theme.Select"]></option>
|
||||
@foreach (var theme in _themes)
|
||||
{
|
||||
<option value="@theme.TypeName">@theme.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="defaultContainer" class="form-select" @bind="@_containertype" required>
|
||||
<option value="-"><@Localizer["Container.Select"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="defaultAdminContainer" class="form-select" @bind="@_admincontainertype" required>
|
||||
<option value="-"><@Localizer["Container.Select"]></option>
|
||||
<option value="@Constants.DefaultAdminContainer"><@Localizer["DefaultAdminContainer"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="bodycontent" HelpText="Optionally enter content to be included in the page body (ie. script tags)" ResourceKey="BodyContent">Body Content: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
@ -322,12 +334,9 @@
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _name = string.Empty;
|
||||
private List<Alias> _aliases;
|
||||
private int _aliasid = -1;
|
||||
private string _aliasname;
|
||||
private string _defaultalias;
|
||||
private string _runtime = "";
|
||||
private string _prerender = "";
|
||||
private string _homepageid = "-";
|
||||
private string _isdeleted;
|
||||
private string _sitemap = "";
|
||||
private int _logofileid = -1;
|
||||
private FileManager _logofilemanager;
|
||||
private int _faviconfileid = -1;
|
||||
@ -336,8 +345,7 @@
|
||||
private string _containertype = "-";
|
||||
private string _admincontainertype = "-";
|
||||
private string _headcontent = string.Empty;
|
||||
private string _homepageid = "-";
|
||||
private string _sitemap = "";
|
||||
private string _bodycontent = string.Empty;
|
||||
private string _smtphost = string.Empty;
|
||||
private string _smtpport = string.Empty;
|
||||
private string _smtpssl = "False";
|
||||
@ -353,6 +361,12 @@
|
||||
private FileManager _pwaappiconfilemanager;
|
||||
private int _pwasplashiconfileid = -1;
|
||||
private FileManager _pwasplashiconfilemanager;
|
||||
private List<Alias> _aliases;
|
||||
private int _aliasid = -1;
|
||||
private string _aliasname;
|
||||
private string _defaultalias;
|
||||
private string _runtime = "";
|
||||
private string _prerender = "";
|
||||
private string _tenant = string.Empty;
|
||||
private string _database = string.Empty;
|
||||
private string _connectionstring = string.Empty;
|
||||
@ -362,7 +376,6 @@
|
||||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
private string _isdeleted;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
@ -375,13 +388,14 @@
|
||||
if (site != null)
|
||||
{
|
||||
_name = site.Name;
|
||||
_runtime = site.Runtime;
|
||||
_prerender = site.RenderMode.Replace(_runtime, "");
|
||||
if (site.HomePageId != null)
|
||||
{
|
||||
_homepageid = site.HomePageId.Value.ToString();
|
||||
}
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
_sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml";
|
||||
|
||||
await GetAliases();
|
||||
|
||||
// appearance
|
||||
if (site.LogoFileId != null)
|
||||
{
|
||||
_logofileid = site.LogoFileId.Value;
|
||||
@ -391,19 +405,17 @@
|
||||
{
|
||||
_faviconfileid = site.FaviconFileId.Value;
|
||||
}
|
||||
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
|
||||
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
|
||||
|
||||
// page content
|
||||
_headcontent = site.HeadContent;
|
||||
_bodycontent = site.BodyContent;
|
||||
|
||||
if (site.HomePageId != null)
|
||||
{
|
||||
_homepageid = site.HomePageId.Value.ToString();
|
||||
}
|
||||
|
||||
// PWA
|
||||
_pwaisenabled = site.PwaIsEnabled.ToString();
|
||||
if (site.PwaAppIconFileId != null)
|
||||
{
|
||||
@ -414,6 +426,7 @@
|
||||
_pwasplashiconfileid = site.PwaSplashIconFileId.Value;
|
||||
}
|
||||
|
||||
// SMTP
|
||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
|
||||
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
|
||||
@ -425,6 +438,14 @@
|
||||
_smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False");
|
||||
_retention = SettingService.GetSetting(settings, "NotificationRetention", "30");
|
||||
|
||||
// aliases
|
||||
await GetAliases();
|
||||
|
||||
// hosting model
|
||||
_runtime = site.Runtime;
|
||||
_prerender = site.RenderMode.Replace(_runtime, "");
|
||||
|
||||
// database
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
var tenants = await TenantService.GetTenantsAsync();
|
||||
@ -438,6 +459,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// audit
|
||||
_createdby = site.CreatedBy;
|
||||
_createdon = site.CreatedOn;
|
||||
_modifiedby = site.ModifiedBy;
|
||||
@ -496,17 +518,10 @@
|
||||
bool reload = false;
|
||||
|
||||
site.Name = _name;
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
|
||||
{
|
||||
site.Runtime = _runtime;
|
||||
site.RenderMode = _runtime + _prerender;
|
||||
reload = true; // needs to be reloaded on server
|
||||
}
|
||||
}
|
||||
site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
|
||||
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
||||
|
||||
// appearance
|
||||
site.LogoFileId = null;
|
||||
var logofileid = _logofilemanager.GetFileId();
|
||||
if (logofileid != -1)
|
||||
@ -531,9 +546,20 @@
|
||||
refresh = true; // needs to be refreshed on client
|
||||
}
|
||||
site.AdminContainerType = _admincontainertype;
|
||||
site.HeadContent = _headcontent;
|
||||
site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
|
||||
|
||||
// page content
|
||||
if (site.HeadContent != _headcontent)
|
||||
{
|
||||
site.HeadContent = _headcontent;
|
||||
reload = true;
|
||||
}
|
||||
if (site.BodyContent != _bodycontent)
|
||||
{
|
||||
site.BodyContent = _bodycontent;
|
||||
reload = true;
|
||||
}
|
||||
|
||||
// PWA
|
||||
if (site.PwaIsEnabled.ToString() != _pwaisenabled)
|
||||
{
|
||||
site.PwaIsEnabled = Boolean.Parse(_pwaisenabled);
|
||||
@ -554,8 +580,20 @@
|
||||
reload = true; // needs to be reloaded on server
|
||||
}
|
||||
|
||||
// hosting model
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
|
||||
{
|
||||
site.Runtime = _runtime;
|
||||
site.RenderMode = _runtime + _prerender;
|
||||
reload = true; // needs to be reloaded on server
|
||||
}
|
||||
}
|
||||
|
||||
site = await SiteService.UpdateSiteAsync(site);
|
||||
|
||||
// SMTP
|
||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||
settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true);
|
||||
settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true);
|
||||
|
@ -237,4 +237,13 @@
|
||||
<data name="Message.Page.Reserved" xml:space="preserve">
|
||||
<value>The page name {0} is reserved. Please enter a different name for your page.</value>
|
||||
</data>
|
||||
<data name="BodyContent.HelpText" xml:space="preserve">
|
||||
<value>Optionally enter content to be included in the page body (ie. script tags)</value>
|
||||
</data>
|
||||
<data name="BodyContent.Text" xml:space="preserve">
|
||||
<value>Body Content:</value>
|
||||
</data>
|
||||
<data name="PageContent.Heading" xml:space="preserve">
|
||||
<value>Page Content</value>
|
||||
</data>
|
||||
</root>
|
@ -273,4 +273,13 @@
|
||||
<data name="Message.Page.Reserved" xml:space="preserve">
|
||||
<value>The page name {0} is reserved. Please enter a different name for your page.</value>
|
||||
</data>
|
||||
<data name="BodyContent.HelpText" xml:space="preserve">
|
||||
<value>Optionally enter content to be included in the page body (ie. script tags)</value>
|
||||
</data>
|
||||
<data name="BodyContent.Text" xml:space="preserve">
|
||||
<value>Body Content:</value>
|
||||
</data>
|
||||
<data name="PageContent.Heading" xml:space="preserve">
|
||||
<value>Page Content</value>
|
||||
</data>
|
||||
</root>
|
@ -360,4 +360,13 @@
|
||||
<data name="HeadContent.Text" xml:space="preserve">
|
||||
<value>Head Content:</value>
|
||||
</data>
|
||||
<data name="BodyContent.HelpText" xml:space="preserve">
|
||||
<value>Optionally enter content to be included in the page body (ie. script tags)</value>
|
||||
</data>
|
||||
<data name="BodyContent.Text" xml:space="preserve">
|
||||
<value>Body Content:</value>
|
||||
</data>
|
||||
<data name="PageContent.Heading" xml:space="preserve">
|
||||
<value>Page Content</value>
|
||||
</data>
|
||||
</root>
|
@ -63,81 +63,90 @@
|
||||
};
|
||||
}
|
||||
|
||||
private string CreateLink(string url, string integrity, string crossorigin)
|
||||
{
|
||||
return "<link rel=\"stylesheet\" href=\"" + url + "\"" + (!string.IsNullOrEmpty(integrity) ? " integrity=\"" + integrity + "\"" : "") + (!string.IsNullOrEmpty(crossorigin) ? " crossorigin=\"" + crossorigin + "\"" : "") + " type=\"text/css\"/>";
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
|
||||
{
|
||||
// inject scripts into page dynamically
|
||||
var interop = new Interop(JSRuntime);
|
||||
var scripts = new List<object>();
|
||||
var count = 0;
|
||||
var index = PageState.Page.HeadContent.IndexOf("<script");
|
||||
while (index >= 0)
|
||||
{
|
||||
var script = PageState.Page.HeadContent.Substring(index, PageState.Page.HeadContent.IndexOf("</script>", index) + 9 - index);
|
||||
// get script attributes
|
||||
var attributes = script.Substring(0, script.IndexOf(">")).Replace("\"", "").Split(" ");
|
||||
string id = "";
|
||||
string src = "";
|
||||
string integrity = "";
|
||||
string crossorigin = "";
|
||||
string type = "";
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
if (attribute.Contains("="))
|
||||
{
|
||||
var value = attribute.Split("=");
|
||||
switch (value[0])
|
||||
{
|
||||
case "id":
|
||||
id = value[1];
|
||||
break;
|
||||
case "src":
|
||||
src = value[1];
|
||||
break;
|
||||
case "integrity":
|
||||
integrity = value[1];
|
||||
break;
|
||||
case "crossorigin":
|
||||
crossorigin = value[1];
|
||||
break;
|
||||
case "type":
|
||||
type = value[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// inject script
|
||||
if (!string.IsNullOrEmpty(src))
|
||||
{
|
||||
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
||||
scripts.Add(new { href = src, bundle = "", integrity = integrity, crossorigin = crossorigin, es6module = (type == "module"), location = "head" });
|
||||
}
|
||||
else
|
||||
{
|
||||
// inline script must have an id attribute
|
||||
if (id == "")
|
||||
{
|
||||
count += 1;
|
||||
id = $"page{PageState.Page.PageId}-script{count}";
|
||||
}
|
||||
index = script.IndexOf(">") + 1;
|
||||
await interop.IncludeScript(id, "", "", "", "", script.Substring(index, script.IndexOf("</script>") - index), "head");
|
||||
}
|
||||
index = PageState.Page.HeadContent.IndexOf("<script", index + 1);
|
||||
}
|
||||
if (scripts.Any())
|
||||
{
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
await InjectScripts(PageState.Page.HeadContent, "head");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(PageState.Page.BodyContent) && PageState.Page.BodyContent.Contains("<script"))
|
||||
{
|
||||
await InjectScripts(PageState.Page.BodyContent, "body");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string CreateLink(string url, string integrity, string crossorigin)
|
||||
private async Task InjectScripts(string content, string location)
|
||||
{
|
||||
return "<link rel=\"stylesheet\" href=\"" + url + "\"" + (!string.IsNullOrEmpty(integrity) ? " integrity=\"" + integrity + "\"" : "") + (!string.IsNullOrEmpty(crossorigin) ? " crossorigin=\"" + crossorigin + "\"" : "") + " type=\"text/css\"/>";
|
||||
// inject scripts into page dynamically
|
||||
var interop = new Interop(JSRuntime);
|
||||
var scripts = new List<object>();
|
||||
var count = 0;
|
||||
var index = content.IndexOf("<script");
|
||||
while (index >= 0)
|
||||
{
|
||||
var script = content.Substring(index, content.IndexOf("</script>", index) + 9 - index);
|
||||
// get script attributes
|
||||
var attributes = script.Substring(0, script.IndexOf(">")).Replace("\"", "").Split(" ");
|
||||
string id = "";
|
||||
string src = "";
|
||||
string integrity = "";
|
||||
string crossorigin = "";
|
||||
string type = "";
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
if (attribute.Contains("="))
|
||||
{
|
||||
var value = attribute.Split("=");
|
||||
switch (value[0])
|
||||
{
|
||||
case "id":
|
||||
id = value[1];
|
||||
break;
|
||||
case "src":
|
||||
src = value[1];
|
||||
break;
|
||||
case "integrity":
|
||||
integrity = value[1];
|
||||
break;
|
||||
case "crossorigin":
|
||||
crossorigin = value[1];
|
||||
break;
|
||||
case "type":
|
||||
type = value[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// inject script
|
||||
if (!string.IsNullOrEmpty(src))
|
||||
{
|
||||
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
||||
scripts.Add(new { href = src, bundle = "", integrity = integrity, crossorigin = crossorigin, es6module = (type == "module"), location = location });
|
||||
}
|
||||
else
|
||||
{
|
||||
// inline script must have an id attribute
|
||||
if (id == "")
|
||||
{
|
||||
count += 1;
|
||||
id = $"page{PageState.Page.PageId}-script{count}";
|
||||
}
|
||||
index = script.IndexOf(">") + 1;
|
||||
await interop.IncludeScript(id, "", "", "", "", script.Substring(index, script.IndexOf("</script>") - index), location);
|
||||
}
|
||||
index = content.IndexOf("<script", index + 1);
|
||||
}
|
||||
if (scripts.Any())
|
||||
{
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
Oqtane.Server/Migrations/Tenant/04000002_AddBodyContent.cs
Normal file
32
Oqtane.Server/Migrations/Tenant/04000002_AddBodyContent.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Migrations.EntityBuilders;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Migrations.Tenant
|
||||
{
|
||||
[DbContext(typeof(TenantDBContext))]
|
||||
[Migration("Tenant.04.00.00.02")]
|
||||
public class AddBodyContent : MultiDatabaseMigration
|
||||
{
|
||||
public AddBodyContent(IDatabase database) : base(database)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
siteEntityBuilder.AddStringColumn("BodyContent", 4000, true);
|
||||
|
||||
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
pageEntityBuilder.AddStringColumn("BodyContent", 4000, true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
}
|
||||
}
|
@ -131,6 +131,7 @@ namespace Oqtane.Pages
|
||||
}
|
||||
// site level scripts
|
||||
HeadResources += ParseScripts(site.HeadContent);
|
||||
BodyResources += ParseScripts(site.BodyContent);
|
||||
|
||||
// get jwt token for downstream APIs
|
||||
if (User.Identity.IsAuthenticated)
|
||||
|
@ -69,6 +69,11 @@ namespace Oqtane.Models
|
||||
/// </summary>
|
||||
public string HeadContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content to be included in the body of the page
|
||||
/// </summary>
|
||||
public string BodyContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Icon file for this page.
|
||||
/// TODO: unclear what this is for, and what icon library is used. Probably FontAwesome?
|
||||
|
@ -93,6 +93,11 @@ namespace Oqtane.Models
|
||||
/// </summary>
|
||||
public string HeadContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content to be included in the body of the page
|
||||
/// </summary>
|
||||
public string BodyContent { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Dictionary<string, string> Settings { get; set; }
|
||||
|
||||
|
Reference in New Issue
Block a user