add support for body content

This commit is contained in:
sbwalker
2023-05-22 15:02:36 -04:00
parent ded326c822
commit 20c7bf3c48
11 changed files with 613 additions and 452 deletions

View File

@ -96,7 +96,7 @@
</div> </div>
</div> </div>
<Section Name="Appearance" ResourceKey="Appearance"> <Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center"> <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> <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> </select>
</div> </div>
</div> </div>
</div>
</Section>
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
<div class="container">
<div class="row mb-1 align-items-center"> <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> <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"> <div class="col-sm-9">
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea> <textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
</div> </div>
</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> </Section>
} }
</TabPanel> </TabPanel>
@ -169,20 +179,21 @@
private List<ThemeControl> _themes = new List<ThemeControl>(); private List<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>(); private List<ThemeControl> _containers = new List<ThemeControl>();
private string _name; private string _name;
private string _title;
private string _path = string.Empty;
private string _parentid = "-1"; private string _parentid = "-1";
private string _insert = ">>"; private string _insert = ">>";
private List<Page> _children; private List<Page> _children;
private int _childid = -1; private int _childid = -1;
private string _isnavigation = "True"; private string _isnavigation = "True";
private string _isclickable = "True"; private string _isclickable = "True";
private string _url; private string _path = string.Empty;
private string _url;
private string _ispersonalizable = "False"; 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 _containertype = string.Empty;
private string _headcontent; private string _headcontent;
private string _icon = string.Empty; private string _bodycontent;
private string _permissions = null; private string _permissions = null;
private PermissionGrid _permissionGrid; private PermissionGrid _permissionGrid;
private Type _themeSettingsType; private Type _themeSettingsType;
@ -297,7 +308,6 @@
page = new Page(); page = new Page();
page.SiteId = PageState.Page.SiteId; page.SiteId = PageState.Page.SiteId;
page.Name = _name; page.Name = _name;
page.Title = _title;
if (string.IsNullOrEmpty(_path)) if (string.IsNullOrEmpty(_path))
{ {
@ -365,7 +375,13 @@
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation)); page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable)); 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; page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
{ {
@ -376,11 +392,13 @@
{ {
page.DefaultContainerType = string.Empty; page.DefaultContainerType = string.Empty;
} }
// page content
page.HeadContent = _headcontent; page.HeadContent = _headcontent;
page.Icon = (_icon == null ? string.Empty : _icon); page.BodyContent = _bodycontent;
// permissions
page.PermissionList = _permissionGrid.GetPermissionList(); page.PermissionList = _permissionGrid.GetPermissionList();
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
page.UserId = null;
page = await PageService.AddPageAsync(page); page = await PageService.AddPageAsync(page);
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId); await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);

View File

@ -140,12 +140,22 @@
</select> </select>
</div> </div>
</div> </div>
</div>
</Section>
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
<div class="container">
<div class="row mb-1 align-items-center"> <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> <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"> <div class="col-sm-9">
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea> <textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
</div> </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> </div>
</Section> </Section>
<br /> <br />
@ -196,323 +206,339 @@
</form> </form>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
private ElementReference form; private ElementReference form;
private bool validated = false; private bool validated = false;
private List<Theme> _themeList; private List<Theme> _themeList;
private List<ThemeControl> _themes = new List<ThemeControl>(); private List<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>(); private List<ThemeControl> _containers = new List<ThemeControl>();
private List<Module> _pageModules; private int _pageId;
private int _pageId; private string _name;
private string _name; private string _currentparentid;
private string _title; 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 _path;
private string _currentparentid; private string _url;
private string _parentid = "-1"; private string _ispersonalizable;
private string _insert = "="; private string _title;
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 _icon; private string _icon;
private List<Permission> _permissions = null; private string _themetype;
private string _createdby; private string _containertype = "-";
private DateTime _createdon; private Type _themeSettingsType;
private string _modifiedby; private object _themeSettings;
private DateTime _modifiedon; private RenderFragment ThemeSettingsComponent { get; set; }
private string _deletedby; private string _headcontent;
private DateTime? _deletedon; private string _bodycontent;
private PermissionGrid _permissionGrid; private List<Permission> _permissions = null;
private Type _themeSettingsType; private PermissionGrid _permissionGrid;
private object _themeSettings; private List<Module> _pageModules;
private RenderFragment ThemeSettingsComponent { get; set; } private string _createdby;
private bool _refresh = false; private DateTime _createdon;
protected Page page; private string _modifiedby;
private DateTime _modifiedon;
private string _deletedby;
private DateTime? _deletedon;
private bool _refresh = false;
protected Page page;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
try try
{ {
_children = PageState.Pages.Where(item => item.ParentId == null).ToList(); _children = PageState.Pages.Where(item => item.ParentId == null).ToList();
_themeList = await ThemeService.GetThemesAsync(); _themeList = await ThemeService.GetThemesAsync();
_themes = ThemeService.GetThemeControls(_themeList); _themes = ThemeService.GetThemeControls(_themeList);
_pageId = Int32.Parse(PageState.QueryString["id"]); _pageId = Int32.Parse(PageState.QueryString["id"]);
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId); page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
if (page != null) if (page != null)
{ {
_name = page.Name; _name = page.Name;
_title = page.Title; if (page.ParentId == null)
_path = page.Path; {
_pageModules = PageState.Modules.Where(m => m.PageId == page.PageId).ToList(); _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)) // appearance
{ _title = page.Title;
_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;
_icon = page.Icon; _icon = page.Icon;
_permissions = page.PermissionList; _themetype = page.ThemeType;
_createdby = page.CreatedBy; if (string.IsNullOrEmpty(_themetype))
_createdon = page.CreatedOn; {
_modifiedby = page.ModifiedBy; _themetype = PageState.Site.DefaultThemeType;
_modifiedon = page.ModifiedOn; }
_deletedby = page.DeletedBy; _containers = ThemeService.GetContainerControls(_themeList, _themetype);
_deletedon = page.DeletedOn; _containertype = page.DefaultContainerType;
if (string.IsNullOrEmpty(_containertype))
{
_containertype = PageState.Site.DefaultContainerType;
}
ThemeSettings(); // page content
} _headcontent = page.HeadContent;
} _bodycontent = page.BodyContent;
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 DeleteModule(Module module) // permissions
{ _permissions = page.PermissionList;
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);
}
}
private async void ParentChanged(ChangeEventArgs e) // page modules
{ _pageModules = PageState.Modules.Where(m => m.PageId == page.PageId).ToList();
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);
}
}
private async void ThemeChanged(ChangeEventArgs e) // audit
{ _createdby = page.CreatedBy;
try _createdon = page.CreatedOn;
{ _modifiedby = page.ModifiedBy;
_themetype = (string)e.Value; _modifiedon = page.ModifiedOn;
_containers = ThemeService.GetContainerControls(_themeList, _themetype); _deletedby = page.DeletedBy;
_containertype = "-"; _deletedon = page.DeletedOn;
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);
}
}
private void ThemeSettings() ThemeSettings();
{ }
_themeSettingsType = null; }
if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel catch (Exception ex)
{ {
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype))); await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message);
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType)) AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
{ }
_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;
}
}
}
private async Task SavePage() private async Task DeleteModule(Module module)
{ {
validated = true; try
var interop = new Interop(JSRuntime); {
if (await interop.FormValid(form)) PageModule pagemodule = await PageModuleService.GetPageModuleAsync(page.PageId, module.ModuleId);
{ pagemodule.IsDeleted = true;
Page page = null; await PageModuleService.UpdatePageModuleAsync(pagemodule);
try await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title);
{ _pageModules.RemoveAll(item => item.PageModuleId == pagemodule.PageModuleId);
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-") StateHasChanged();
{ NavigationManager.NavigateTo(NavigationManager.Uri + "&tab=PageModules");
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId); }
string currentPath = page.Path; 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; private async void ParentChanged(ChangeEventArgs e)
page.Title = _title; {
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)) private async void ThemeChanged(ChangeEventArgs e)
{ {
_path = _name; try
} {
if (_path.Contains("/")) _themetype = (string)e.Value;
{ _containers = ThemeService.GetContainerControls(_themeList, _themetype);
if (_path.EndsWith("/") && _path != "/") _containertype = "-";
{ ThemeSettings();
_path = _path.Substring(0, _path.Length - 1); StateHasChanged();
} }
_path = _path.Substring(_path.LastIndexOf("/") + 1); 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") private void ThemeSettings()
{ {
page.ParentId = null; _themeSettingsType = null;
page.Path = Utilities.GetFriendlyUrl(_path); if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel
} {
else var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
{ if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
page.ParentId = Int32.Parse(_parentid); {
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId); _themeSettingsType = Type.GetType(theme.ThemeSettingsType);
if (parent.Path == string.Empty) if (_themeSettingsType != null)
{ {
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); ThemeSettingsComponent = builder =>
} {
else builder.OpenComponent(0, _themeSettingsType);
{ builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); builder.CloseComponent();
} };
} }
_refresh = true;
}
}
}
var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId); private async Task SavePage()
if (_pages.Any(item => item.Path == page.Path && item.PageId != page.PageId)) {
{ validated = true;
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning); var interop = new Interop(JSRuntime);
return; 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())) page.Name = _name;
{
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning);
return;
}
if (_insert != "=") if (string.IsNullOrEmpty(_path))
{ {
Page child; _path = _name;
switch (_insert) }
{ if (_path.Contains("/"))
case "<<": {
page.Order = 0; if (_path.EndsWith("/") && _path != "/")
break; {
case "<": _path = _path.Substring(0, _path.Length - 1);
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); }
if (child != null) page.Order = child.Order - 1; _path = _path.Substring(_path.LastIndexOf("/") + 1);
break; }
case ">":
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); if (_parentid == "-1")
if (child != null) page.Order = child.Order + 1; {
break; page.ParentId = null;
case ">>": page.Path = Utilities.GetFriendlyUrl(_path);
page.Order = int.MaxValue; }
break; else
} {
} page.ParentId = Int32.Parse(_parentid);
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable)); if (parent.Path == string.Empty)
page.Url = _url; {
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) }
{ else
page.ThemeType = string.Empty; {
} page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty; }
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType) }
{
page.DefaultContainerType = string.Empty; var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
} if (_pages.Any(item => item.Path == page.Path && item.PageId != page.PageId))
page.HeadContent = _headcontent; {
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.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.PermissionList = _permissionGrid.GetPermissionList();
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
page.UserId = null;
page = await PageService.UpdatePageAsync(page); page = await PageService.UpdatePageAsync(page);
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId); await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);

View File

@ -55,59 +55,71 @@
</div> </div>
<br /> <br />
<Section Name="Appearance" ResourceKey="Appearance"> <Section Name="Appearance" ResourceKey="Appearance">
<div class="row mb-1 align-items-center"> <div class="container">
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label> <div class="row mb-1 align-items-center">
<div class="col-sm-9"> <Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" /> <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="-">&lt;@Localizer["Theme.Select"]&gt;</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="-">&lt;@Localizer["Container.Select"]&gt;</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="-">&lt;@Localizer["Container.Select"]&gt;</option>
<option value="@Constants.DefaultAdminContainer">&lt;@Localizer["DefaultAdminContainer"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
}
</select>
</div>
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> </Section>
<Label Class="col-sm-3" For="favicon" HelpText="Specify a Favicon" ResourceKey="FavoriteIcon">Favicon: </Label> <Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
<div class="col-sm-9"> <div class="container">
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" /> <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> <div class="row mb-1 align-items-center">
<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>
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label> <div class="col-sm-9">
<div class="col-sm-9"> <textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required> </div>
<option value="-">&lt;@Localizer["Theme.Select"]&gt;</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="-">&lt;@Localizer["Container.Select"]&gt;</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="-">&lt;@Localizer["Container.Select"]&gt;</option>
<option value="@Constants.DefaultAdminContainer">&lt;@Localizer["DefaultAdminContainer"]&gt;</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> </div>
</div> </div>
</Section> </Section>
@ -322,12 +334,9 @@
private List<ThemeControl> _themes = new List<ThemeControl>(); private List<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>(); private List<ThemeControl> _containers = new List<ThemeControl>();
private string _name = string.Empty; private string _name = string.Empty;
private List<Alias> _aliases; private string _homepageid = "-";
private int _aliasid = -1; private string _isdeleted;
private string _aliasname; private string _sitemap = "";
private string _defaultalias;
private string _runtime = "";
private string _prerender = "";
private int _logofileid = -1; private int _logofileid = -1;
private FileManager _logofilemanager; private FileManager _logofilemanager;
private int _faviconfileid = -1; private int _faviconfileid = -1;
@ -336,8 +345,7 @@
private string _containertype = "-"; private string _containertype = "-";
private string _admincontainertype = "-"; private string _admincontainertype = "-";
private string _headcontent = string.Empty; private string _headcontent = string.Empty;
private string _homepageid = "-"; private string _bodycontent = string.Empty;
private string _sitemap = "";
private string _smtphost = string.Empty; private string _smtphost = string.Empty;
private string _smtpport = string.Empty; private string _smtpport = string.Empty;
private string _smtpssl = "False"; private string _smtpssl = "False";
@ -353,6 +361,12 @@
private FileManager _pwaappiconfilemanager; private FileManager _pwaappiconfilemanager;
private int _pwasplashiconfileid = -1; private int _pwasplashiconfileid = -1;
private FileManager _pwasplashiconfilemanager; 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 _tenant = string.Empty;
private string _database = string.Empty; private string _database = string.Empty;
private string _connectionstring = string.Empty; private string _connectionstring = string.Empty;
@ -362,7 +376,6 @@
private DateTime _modifiedon; private DateTime _modifiedon;
private string _deletedby; private string _deletedby;
private DateTime? _deletedon; private DateTime? _deletedon;
private string _isdeleted;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -375,13 +388,14 @@
if (site != null) if (site != null)
{ {
_name = site.Name; _name = site.Name;
_runtime = site.Runtime; if (site.HomePageId != null)
_prerender = site.RenderMode.Replace(_runtime, ""); {
_homepageid = site.HomePageId.Value.ToString();
}
_isdeleted = site.IsDeleted.ToString(); _isdeleted = site.IsDeleted.ToString();
_sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml"; _sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml";
await GetAliases(); // appearance
if (site.LogoFileId != null) if (site.LogoFileId != null)
{ {
_logofileid = site.LogoFileId.Value; _logofileid = site.LogoFileId.Value;
@ -391,19 +405,17 @@
{ {
_faviconfileid = site.FaviconFileId.Value; _faviconfileid = site.FaviconFileId.Value;
} }
_themes = ThemeService.GetThemeControls(_themeList); _themes = ThemeService.GetThemeControls(_themeList);
_themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme; _themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme;
_containers = ThemeService.GetContainerControls(_themeList, _themetype); _containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer; _containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer; _admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
// page content
_headcontent = site.HeadContent; _headcontent = site.HeadContent;
_bodycontent = site.BodyContent;
if (site.HomePageId != null) // PWA
{
_homepageid = site.HomePageId.Value.ToString();
}
_pwaisenabled = site.PwaIsEnabled.ToString(); _pwaisenabled = site.PwaIsEnabled.ToString();
if (site.PwaAppIconFileId != null) if (site.PwaAppIconFileId != null)
{ {
@ -414,6 +426,7 @@
_pwasplashiconfileid = site.PwaSplashIconFileId.Value; _pwasplashiconfileid = site.PwaSplashIconFileId.Value;
} }
// SMTP
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty); _smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty); _smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
@ -425,6 +438,14 @@
_smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False"); _smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False");
_retention = SettingService.GetSetting(settings, "NotificationRetention", "30"); _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)) if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
var tenants = await TenantService.GetTenantsAsync(); var tenants = await TenantService.GetTenantsAsync();
@ -438,6 +459,7 @@
} }
} }
// audit
_createdby = site.CreatedBy; _createdby = site.CreatedBy;
_createdon = site.CreatedOn; _createdon = site.CreatedOn;
_modifiedby = site.ModifiedBy; _modifiedby = site.ModifiedBy;
@ -496,17 +518,10 @@
bool reload = false; bool reload = false;
site.Name = _name; site.Name = _name;
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
{
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
{
site.Runtime = _runtime;
site.RenderMode = _runtime + _prerender;
reload = true; // needs to be reloaded on server
}
}
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
// appearance
site.LogoFileId = null; site.LogoFileId = null;
var logofileid = _logofilemanager.GetFileId(); var logofileid = _logofilemanager.GetFileId();
if (logofileid != -1) if (logofileid != -1)
@ -531,9 +546,20 @@
refresh = true; // needs to be refreshed on client refresh = true; // needs to be refreshed on client
} }
site.AdminContainerType = _admincontainertype; 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) if (site.PwaIsEnabled.ToString() != _pwaisenabled)
{ {
site.PwaIsEnabled = Boolean.Parse(_pwaisenabled); site.PwaIsEnabled = Boolean.Parse(_pwaisenabled);
@ -554,8 +580,20 @@
reload = true; // needs to be reloaded on server 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); site = await SiteService.UpdateSiteAsync(site);
// SMTP
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true); settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true);
settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true); settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true);

View File

@ -237,4 +237,13 @@
<data name="Message.Page.Reserved" xml:space="preserve"> <data name="Message.Page.Reserved" xml:space="preserve">
<value>The page name {0} is reserved. Please enter a different name for your page.</value> <value>The page name {0} is reserved. Please enter a different name for your page.</value>
</data> </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> </root>

View File

@ -273,4 +273,13 @@
<data name="Message.Page.Reserved" xml:space="preserve"> <data name="Message.Page.Reserved" xml:space="preserve">
<value>The page name {0} is reserved. Please enter a different name for your page.</value> <value>The page name {0} is reserved. Please enter a different name for your page.</value>
</data> </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> </root>

View File

@ -360,4 +360,13 @@
<data name="HeadContent.Text" xml:space="preserve"> <data name="HeadContent.Text" xml:space="preserve">
<value>Head Content:</value> <value>Head Content:</value>
</data> </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> </root>

View File

@ -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) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
if (!firstRender) if (!firstRender)
{ {
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script")) if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
{ {
// inject scripts into page dynamically await InjectScripts(PageState.Page.HeadContent, "head");
var interop = new Interop(JSRuntime); }
var scripts = new List<object>(); if (!string.IsNullOrEmpty(PageState.Page.BodyContent) && PageState.Page.BodyContent.Contains("<script"))
var count = 0; {
var index = PageState.Page.HeadContent.IndexOf("<script"); await InjectScripts(PageState.Page.BodyContent, "body");
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());
}
} }
} }
} }
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());
}
} }
} }

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

View File

@ -131,6 +131,7 @@ namespace Oqtane.Pages
} }
// site level scripts // site level scripts
HeadResources += ParseScripts(site.HeadContent); HeadResources += ParseScripts(site.HeadContent);
BodyResources += ParseScripts(site.BodyContent);
// get jwt token for downstream APIs // get jwt token for downstream APIs
if (User.Identity.IsAuthenticated) if (User.Identity.IsAuthenticated)

View File

@ -69,6 +69,11 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public string HeadContent { get; set; } public string HeadContent { get; set; }
/// <summary>
/// Content to be included in the body of the page
/// </summary>
public string BodyContent { get; set; }
/// <summary> /// <summary>
/// Icon file for this page. /// Icon file for this page.
/// TODO: unclear what this is for, and what icon library is used. Probably FontAwesome? /// TODO: unclear what this is for, and what icon library is used. Probably FontAwesome?

View File

@ -93,6 +93,11 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public string HeadContent { get; set; } public string HeadContent { get; set; }
/// <summary>
/// Content to be included in the body of the page
/// </summary>
public string BodyContent { get; set; }
[NotMapped] [NotMapped]
public Dictionary<string, string> Settings { get; set; } public Dictionary<string, string> Settings { get; set; }