allow page and module settings to be included in site templates, improve terms and privacy default content, add Settings for HtmlText module

This commit is contained in:
sbwalker 2025-03-06 14:46:17 -05:00
parent f2bd47d8bc
commit 5b4db0de3b
10 changed files with 320 additions and 17 deletions

View File

@ -2,6 +2,7 @@
@namespace Oqtane.Modules.HtmlText
@inherits ModuleBase
@inject IHtmlTextService HtmlTextService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@if (PageState.EditMode)
@ -36,6 +37,10 @@
{
content = htmltext.Content;
content = Utilities.FormatContent(content, PageState.Alias, "render");
if (bool.Parse(SettingService.GetSetting(ModuleState.Settings, "DynamicTokens", "false")))
{
content = ReplaceTokens(content);
}
}
else
{

View File

@ -15,7 +15,7 @@ namespace Oqtane.Modules.HtmlText
Version = "1.0.1",
ServerManagerType = "Oqtane.Modules.HtmlText.Manager.HtmlTextManager, Oqtane.Server",
ReleaseVersions = "1.0.0,1.0.1",
SettingsType = string.Empty,
SettingsType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client",
Resources = new List<Resource>()
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Module.css" }

View File

@ -0,0 +1,55 @@
@namespace Oqtane.Modules.HtmlText
@inherits ModuleBase
@inject ISettingService SettingService
@implements Oqtane.Interfaces.ISettingsControl
@inject IStringLocalizer<Settings> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="dynamictokens" ResourceKey="DynamicTokens" ResourceType="@resourceType" HelpText="Do you wish to allow tokens to be dynamically replaced? Please note that this will affect the performance of your site.">Dynamic Tokens? </Label>
<div class="col-sm-9">
<select id="dynamictokens" class="form-select" @bind="@_dynamictokens">
<option value="true">@SharedLocalizer["Yes"]</option>
<option value="false">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
</div>
</form>
@code {
private string resourceType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client"; // for localization
private ElementReference form;
private bool validated = false;
private string _dynamictokens;
protected override void OnInitialized()
{
try
{
_dynamictokens = SettingService.GetSetting(ModuleState.Settings, "DynamicTokens", "false");
}
catch (Exception ex)
{
AddModuleMessage(ex.Message, MessageType.Error);
}
}
public async Task UpdateSettings()
{
try
{
var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
settings = SettingService.SetSetting(settings, "DynamicTokens", _dynamictokens);
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
}
catch (Exception ex)
{
AddModuleMessage(ex.Message, MessageType.Error);
}
}
}

View File

@ -10,6 +10,7 @@ using System.Collections.Generic;
using Microsoft.JSInterop;
using System.Linq;
using System.Dynamic;
using System.Reflection;
namespace Oqtane.Modules
{
@ -35,7 +36,7 @@ namespace Oqtane.Modules
protected PageState PageState { get; set; }
[CascadingParameter]
protected Module ModuleState { get; set; }
protected Models.Module ModuleState { get; set; }
[Parameter]
public RenderModeBoundary RenderModeBoundary { get; set; }
@ -413,6 +414,79 @@ namespace Oqtane.Modules
await interop.ScrollTo(0, 0, "smooth");
}
public string ReplaceTokens(string content)
{
return ReplaceTokens(content, null);
}
public string ReplaceTokens(string content, object obj)
{
var tokens = new List<string>();
var pos = content.IndexOf("[");
if (pos != -1)
{
if (content.IndexOf("]", pos) != -1)
{
var token = content.Substring(pos, content.IndexOf("]", pos) - pos + 1);
if (token.Contains(":"))
{
tokens.Add(token.Substring(1, token.Length - 2));
}
}
pos = content.IndexOf("[", pos + 1);
}
if (tokens.Count != 0)
{
foreach (string token in tokens)
{
var segments = token.Split(":");
if (segments.Length >= 2 && segments.Length <= 3)
{
var objectName = string.Join(":", segments, 0, segments.Length - 1);
var propertyName = segments[segments.Length - 1];
var propertyValue = "";
switch (objectName)
{
case "ModuleState":
propertyValue = ModuleState.GetType().GetProperty(propertyName)?.GetValue(ModuleState, null).ToString();
break;
case "PageState":
propertyValue = PageState.GetType().GetProperty(propertyName)?.GetValue(PageState, null).ToString();
break;
case "PageState:Alias":
propertyValue = PageState.Alias.GetType().GetProperty(propertyName)?.GetValue(PageState.Alias, null).ToString();
break;
case "PageState:Site":
propertyValue = PageState.Site.GetType().GetProperty(propertyName)?.GetValue(PageState.Site, null).ToString();
break;
case "PageState:Page":
propertyValue = PageState.Page.GetType().GetProperty(propertyName)?.GetValue(PageState.Page, null).ToString();
break;
case "PageState:User":
propertyValue = PageState.User?.GetType().GetProperty(propertyName)?.GetValue(PageState.User, null).ToString();
break;
case "PageState:Route":
propertyValue = PageState.Route.GetType().GetProperty(propertyName)?.GetValue(PageState.Route, null).ToString();
break;
default:
if (obj != null && obj.GetType().Name == objectName)
{
propertyValue = obj.GetType().GetProperty(propertyName)?.GetValue(obj, null).ToString();
}
break;
}
if (propertyValue != null)
{
content = content.Replace("[" + token + "]", propertyValue);
}
}
}
}
return content;
}
// logging methods
public async Task Log(Alias alias, LogLevel level, string function, Exception exception, string message, params object[] args)
{

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DynamicTokens.HelpText" xml:space="preserve">
<value>Do you wish to allow tokens to be dynamically replaced? Please note that this will affect the performance of your site.</value>
</data>
<data name="DynamicTokens.Text" xml:space="preserve">
<value>Dynamic Tokens?</value>
</data>
</root>

View File

@ -199,6 +199,9 @@ namespace Oqtane.Infrastructure.SiteTemplates
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
},
Settings = new List<Setting> {
new Setting { SettingName = "DynamicTokens", SettingValue = "true" }
},
Content = _localizer["Privacy"]
}
}
@ -226,6 +229,9 @@ namespace Oqtane.Infrastructure.SiteTemplates
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
},
Settings = new List<Setting> {
new Setting { SettingName = "DynamicTokens", SettingValue = "true" }
},
Content = _localizer["Terms"]
}
}

View File

@ -490,6 +490,9 @@ namespace Oqtane.Infrastructure
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
},
Settings = new List<Setting> {
new Setting { SettingName = "DynamicTokens", SettingValue = "true" }
},
Content = localizer["Privacy"]
}
}
@ -516,6 +519,9 @@ namespace Oqtane.Infrastructure
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
},
Settings = new List<Setting> {
new Setting { SettingName = "DynamicTokens", SettingValue = "true" }
},
Content = localizer["Terms"]
}
}

View File

@ -9,6 +9,7 @@ using Oqtane.Enums;
using Oqtane.Infrastructure;
using Oqtane.Models;
using Oqtane.Modules;
using Oqtane.Modules.Admin.Modules;
using Oqtane.Shared;
using Module = Oqtane.Models.Module;
@ -25,6 +26,7 @@ namespace Oqtane.Repository
private readonly IPageModuleRepository _pageModuleRepository;
private readonly IModuleDefinitionRepository _moduleDefinitionRepository;
private readonly IThemeRepository _themeRepository;
private readonly ISettingRepository _settingRepository;
private readonly IServiceProvider _serviceProvider;
private readonly IConfigurationRoot _config;
private readonly IServerStateManager _serverState;
@ -32,8 +34,8 @@ namespace Oqtane.Repository
private static readonly object _lock = new object();
public SiteRepository(IDbContextFactory<TenantDBContext> factory, IRoleRepository roleRepository, IProfileRepository profileRepository, IFolderRepository folderRepository, IPageRepository pageRepository,
IModuleRepository moduleRepository, IPageModuleRepository pageModuleRepository, IModuleDefinitionRepository moduleDefinitionRepository, IThemeRepository themeRepository, IServiceProvider serviceProvider,
IConfigurationRoot config, IServerStateManager serverState, ILogManager logger)
IModuleRepository moduleRepository, IPageModuleRepository pageModuleRepository, IModuleDefinitionRepository moduleDefinitionRepository, IThemeRepository themeRepository, ISettingRepository settingRepository,
IServiceProvider serviceProvider, IConfigurationRoot config, IServerStateManager serverState, ILogManager logger)
{
_factory = factory;
_roleRepository = roleRepository;
@ -44,6 +46,7 @@ namespace Oqtane.Repository
_pageModuleRepository = pageModuleRepository;
_moduleDefinitionRepository = moduleDefinitionRepository;
_themeRepository = themeRepository;
_settingRepository = settingRepository;
_serviceProvider = serviceProvider;
_config = config;
_serverState = serverState;
@ -391,6 +394,7 @@ namespace Oqtane.Repository
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Update, "Page Updated {Page}", page);
}
UpdateSettings(EntityNames.Page, page.PageId, pageTemplate.Settings);
}
}
else
@ -401,6 +405,7 @@ namespace Oqtane.Repository
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Create, "Page Added {Page}", page);
}
UpdateSettings(EntityNames.Page, page.PageId, pageTemplate.Settings);
}
}
catch (Exception ex)
@ -457,6 +462,7 @@ namespace Oqtane.Repository
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Update, "Page Module Updated {PageModule}", pageModule);
}
UpdateSettings(EntityNames.Module, pageModule.Module.ModuleId, pageTemplateModule.Settings);
}
else
{
@ -475,6 +481,7 @@ namespace Oqtane.Repository
{
_logger.Log(LogLevel.Information, "Site Template", LogFunction.Create, "Page Module Added {PageModule}", pageModule);
}
UpdateSettings(EntityNames.Module, pageModule.Module.ModuleId, pageTemplateModule.Settings);
}
}
@ -522,5 +529,25 @@ namespace Oqtane.Repository
}
}
}
private void UpdateSettings(string entityName, int entityId, List<Setting> templateSettings)
{
foreach (var templateSetting in templateSettings)
{
var setting = _settingRepository.GetSetting(entityName, entityId, templateSetting.SettingName);
if (setting == null)
{
templateSetting.EntityName = entityName;
templateSetting.EntityId = entityId;
_settingRepository.AddSetting(templateSetting);
}
else
{
setting.SettingValue = templateSetting.SettingValue;
setting.IsPrivate = templateSetting.IsPrivate;
_settingRepository.UpdateSetting(setting);
}
}
}
}
}

View File

@ -118,9 +118,9 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Privacy" xml:space="preserve">
<value>&lt;p&gt;This privacy policy ("policy") will help you understand how [COMPANY] ("us", "we", "our") uses and protects the data you provide to us when you visit and use this website.&lt;/p&gt;
<value>&lt;p&gt;This privacy policy ("policy") will help you understand how [PageState:Site:Name] ("us", "we", "our") uses and protects the data you provide to us when you visit and use this website.&lt;/p&gt;
&lt;p&gt;We reserve the right to change this policy at any time. We shall let our users know of these changes through electronic mail. If you want to make sure that you are up to date with the latest changes, we advise you to frequently visit this page.&lt;/p&gt;
&lt;p&gt;We reserve the right to change this policy at any time. If you want to make sure that you are up to date with the latest changes, we advise you to frequently visit this page.&lt;/p&gt;
&lt;h2&gt;What User Data We Collect&lt;/h2&gt;
@ -132,7 +132,7 @@
&lt;h2&gt;Safeguarding and Securing the Data&lt;/h2&gt;
&lt;p&gt;[COMPANY] is committed to securing your data and keeping it confidential. [COMPANY] has done everything in its power to prevent data theft, unauthorized access, and disclosure by implementing the latest technologies and software, which help us safeguard all the information we collect online.&lt;/p&gt;
&lt;p&gt;[PageState:Site:Name] is committed to securing your data and keeping it confidential. [PageState:Site:Name] has done everything in its power to prevent data theft, unauthorized access, and disclosure by implementing the latest technologies and software, which help us safeguard all the information we collect online.&lt;/p&gt;
&lt;h2&gt;Our Cookie Policy&lt;/h2&gt;
@ -146,20 +146,20 @@
&lt;h2&gt;Links to Other Websites&lt;/h2&gt;
&lt;p&gt;Our website contains links that lead to other websites. If you click on these links [COMPANY] is not held responsible for your data and privacy protection. Visiting those websites is not governed by this privacy policy agreement. Make sure to read the privacy policy documentation of the website you go to from our website.&lt;/p&gt;
&lt;p&gt;Our website contains links that lead to other websites. If you click on these links [PageState:Site:Name] is not held responsible for your data and privacy protection. Visiting those websites is not governed by this privacy policy agreement. Make sure to read the privacy policy documentation of any website you navigate to from our website.&lt;/p&gt;
&lt;h2&gt;Restricting the Collection of your Personal Data&lt;/h2&gt;
&lt;p&gt;At some point, you might wish to restrict the use and collection of your personal data. If you previously agreed to share your information with us, feel free to contact us via email and we will be more than happy to change this for you.&lt;/p&gt;
&lt;p&gt;[COMPANY] will not lease, sell or distribute your personal information to any third parties, unless we have your permission. Your personal information will only be used when we need to send you promotional materials if you agree to this privacy policy.&lt;/p&gt;</value>
&lt;p&gt;[PageState:Site:Name] will not lease, sell or distribute your personal information to any third parties, unless we have your permission. Your personal information will only be used when we need to send you promotional materials if you agree to this privacy policy.&lt;/p&gt;</value>
</data>
<data name="Terms" xml:space="preserve">
<value>&lt;p&gt;Please read these terms and conditions carefully before using this website operated by [COMPANY] ("us", "we", "our").&lt;/p&gt;
<value>&lt;p&gt;Please read these terms and conditions carefully before using this website operated by [PageState:Site:Name] ("us", "we", "our").&lt;/p&gt;
&lt;h2&gt;Conditions of Use&lt;/h2&gt;
&lt;p&gt;By using this website, you certify that you have read and reviewed this Agreement and that you agree to comply with its terms. If you do not want to be bound by the terms of this Agreement, you are advised to stop using the website accordingly. [COMPANY] only grants use and access of this website, its products, and its services to those who have accepted its terms.&lt;/p&gt;
&lt;p&gt;By using this website, you certify that you have read and reviewed this Agreement and that you agree to comply with its terms. If you do not want to be bound by the terms of this Agreement, you are advised to stop using the website accordingly. [PageState:Site:Name] only grants use and access of this website, its products, and its services to those who have accepted its terms.&lt;/p&gt;
&lt;h2&gt;Privacy Policy&lt;/h2&gt;
@ -167,9 +167,9 @@
&lt;h2&gt;Intellectual Property&lt;/h2&gt;
&lt;p&gt;You agree that all materials, products, and services provided on this website are the property of [COMPANY], its affiliates, directors, officers, employees, agents, suppliers, or licensors including all copyrights, trade secrets, trademarks, patents, and other intellectual property. You also agree that you will not reproduce or redistribute the [COMPANY]s intellectual property in any way, including electronic, digital, or new trademark registrations.&lt;/p&gt;
&lt;p&gt;You agree that all materials, products, and services provided on this website are the property of [PageState:Site:Name], its affiliates, directors, officers, employees, agents, suppliers, or licensors including all copyrights, trade secrets, trademarks, patents, and other intellectual property. You also agree that you will not reproduce or redistribute the [PageState:Site:Name]s intellectual property in any way, including electronic, digital, or new trademark registrations.&lt;/p&gt;
&lt;p&gt;You grant [COMPANY] a royalty-free and non-exclusive license to display, use, copy, transmit, and broadcast the content you upload and publish. For issues regarding intellectual property claims, you should contact us in order to come to an agreement.&lt;/p&gt;
&lt;p&gt;You grant [PageState:Site:Name] a royalty-free and non-exclusive license to display, use, copy, transmit, and broadcast the content you upload and publish. For issues regarding intellectual property claims, you should contact us in order to come to an agreement.&lt;/p&gt;
&lt;h2&gt;User Accounts&lt;/h2&gt;
@ -181,19 +181,19 @@
&lt;h2&gt;Applicable Law&lt;/h2&gt;
&lt;p&gt;By using this website, you agree that the laws of [LOCATION], without regard to principles of conflict laws, will govern these terms and conditions, or any dispute of any sort that might come between [COMPANY] and you, or its business partners and associates.&lt;/p&gt;
&lt;p&gt;By using this website, you agree that the laws of the jurisdiction associated to [PageState:Site:Name], without regard to principles of conflict laws, will govern these terms and conditions, or any dispute of any sort that might come between [PageState:Site:Name] and you, or its business partners and associates.&lt;/p&gt;
&lt;h2&gt;Disputes&lt;/h2&gt;
&lt;p&gt;Any dispute related in any way to your use of this website or to products you purchase from us shall be arbitrated by state or federal court [your location] and you consent to exclusive jurisdiction and venue of such courts.&lt;/p&gt;
&lt;p&gt;Any dispute related in any way to your use of this website or to products you purchase from us shall be arbitrated by a court of law and you consent to exclusive jurisdiction and venue of such courts.&lt;/p&gt;
&lt;h2&gt;Indemnification&lt;/h2&gt;
&lt;p&gt;You agree to indemnify [COMPANY] and its affiliates and hold [COMPANY] harmless against legal claims and demands that may arise from your use or misuse of our services. We reserve the right to select our own legal counsel.&lt;/p&gt;
&lt;p&gt;You agree to indemnify [PageState:Site:Name] and its affiliates and hold [PageState:Site:Name] harmless against legal claims and demands that may arise from your use or misuse of our services. We reserve the right to select our own legal counsel.&lt;/p&gt;
&lt;h2&gt;Limitation on Liability&lt;/h2&gt;
&lt;p&gt;[COMPANY] is not liable for any damages that may occur to you as a result of your misuse of our website. [COMPANY] reserves the right to edit, modify, and change this Agreement at any time. We shall let our users know of these changes through electronic mail. This Agreement is an understanding between [COMPANY] and the user, and this supersedes and replaces all prior agreements regarding the use of this website.&lt;/p&gt;
&lt;p&gt;[PageState:Site:Name] is not liable for any damages that may occur to you as a result of your misuse of our website. [PageState:Site:Name] reserves the right to edit, modify, and change this Agreement at any time. We shall let our users know of these changes through electronic mail. This Agreement is an understanding between [PageState:Site:Name] and the user, and this supersedes and replaces all prior agreements regarding the use of this website.&lt;/p&gt;
</value>
</data>
</root>

View File

@ -35,6 +35,7 @@ namespace Oqtane.Models
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
};
Settings = new List<Setting>();
PageTemplateModules = new List<PageTemplateModule>();
// properties used by IModule
@ -60,6 +61,7 @@ namespace Oqtane.Models
public bool IsPersonalizable { get; set; }
public bool IsDeleted { get; set; }
public List<Permission> PermissionList { get; set; }
public List<Setting> Settings { get; set; }
public List<PageTemplateModule> PageTemplateModules { get; set; }
// properties used by IModule
@ -99,6 +101,7 @@ namespace Oqtane.Models
new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
};
Settings = new List<Setting>();
Content = "";
}
@ -109,6 +112,7 @@ namespace Oqtane.Models
public string ContainerType { get; set; }
public bool IsDeleted { get; set; }
public List<Permission> PermissionList { get; set; }
public List<Setting> Settings { get; set; }
public string Content { get; set; }
[Obsolete("The ModulePermissions property is deprecated. Use PermissionList instead", false)]