Overview Global Content (SiteSettings) Overview Content that you wish to be able to access at any time throughout your project may be stored in a special object referred to as a "Site Settings". This content is a special type of structure content that may be registered with your domain. Only 1 record is accessible once published. Site Settings consists of: A Class that inherits from BusinessObjectSiteSettings A user-control that inherits from ToolControl<T> Once created the Control must be registered: System Administrator -> Data Sections -> Site Settings, and then Referenced in your "Domain Management" screen. Usage Sitesettings can be accessed: AdvantagePageTemplate AdvantageModule AdvantageModuleRewrite AdvantageModuleEngine Using the following methods: this.SiteSettings<T>() -> Expects the object defined by the developer for your domain. this.SiteSettings() -> returns a dynamic reference to the object Site Settings Class SiteSettings : BusinessObjectSiteSettings<T> Overview Custom class designed by the developer based on requirements. Example Class (BusinessObjectSiteSettings) Example Objectusing System; using System.Collections.Generic; using System.Net.Mail; using AdvantageCMS.Core.Admin.BaseClasses; using AdvantageCMS.Core.Admin.Enums; using AdvantageCMS.Core.Admin.Event; using AdvantageCMS.Core.Common.BaseClasses; using AdvantageCMS.Core.Utils; namespace AdvantageClient { /// <summary> /// An example of Site Settings that provides: /// - A list of definitions that can be used forin a mulit-lingual site. /// - Image definition for a company logo /// - Address based on a predefined class /// </summary> /// public class SiteSettings : BusinessObjectSiteSetting<SiteSettings> { #region Language Objects public enum eDisplayType { Text = 0, Html = 1 } public class LanguageObject { public string Id { get; set; } public string GroupName { get; set; } public eDisplayType DisplayType { get; set; } public string Content { get; set; } public int SortOrder { get; set; } public bool IsActive { get; set; } } #endregion private AdvantageImage _logoImage = null; private AdvantageImage _iconImage = null; public AdvantageImage LogoImage { get { if (_logoImage == null) { this._logoImage = new AdvantageImage(); this._logoImage.AddImageElement(new AdvantageImageElement() { ImageName = "Mobile", }); this._logoImage.AddImageElement(new AdvantageImageElement() { ImageName = "Desktop", BreakPointName = "Small" }); this._logoImage.DefaultElementName = "Mobile"; } return _logoImage; } set { _logoImage = value; } } public AdvantageImage IconImage { get { if (_iconImage == null) { this._iconImage = new AdvantageImage(); this._iconImage.AddImageElement(new AdvantageImageElement() { ImageName = "Icon", }); this._iconImage.DefaultElementName = "Icon"; } return _iconImage; } set { _iconImage = value; } } public string CompanyName { get; set; } public string EmailAddress { get; set; } public string PhoneNumber { get; set; } public Address CompanyAddress { get; set; } = new Address(); #region Language Variables private bool _ensureDefaults = false; private DictionarySerializable<string, LanguageObject> _languageSettings = new DictionarySerializable<string, LanguageObject>(); public DictionarySerializable<string, LanguageObject> LanguageSettings { get { if (!_ensureDefaults) _languageSettings = ensureDefaults(_languageSettings); return _languageSettings; } set { _languageSettings = value; _ensureDefaults = false; } } private DictionarySerializable<string, LanguageObject> ensureDefaults(DictionarySerializable<string, LanguageObject> l) { _ensureDefaults = true; //_ensureDefaults = true; if (l == null) l = new DictionarySerializable<string, LanguageObject>(); l = addLanguageEntry(l, "User Name", eDisplayType.Text, "User Name", "Member"); l = addLanguageEntry(l, "Login Button", eDisplayType.Text, "Login", "Member"); l = addLanguageEntry(l, "SignUp Button", eDisplayType.Text, "Sign Up", "Member"); l = addLanguageEntry(l, "Welcome", eDisplayType.Text, "Welcome", "Member"); l = addLanguageEntry(l, "test", eDisplayType.Text, "test", "test"); return l; } private DictionarySerializable<string, LanguageObject> addLanguageEntry(DictionarySerializable<string, LanguageObject> l, string key, eDisplayType dt, string content, string groupName = "") { if (!l.ContainsKey(key)) l.Add(key, new LanguageObject() { Id = key, SortOrder = 1, IsActive = true, DisplayType = dt, Content = content, GroupName = groupName }); return l; } public string GetLanguage(string key) { if (LanguageSettings == null) return key; var l = new LanguageObject(); if (LanguageSettings.TryGetValue(key, out l)) return l.Content; return key; } #endregion Language Variables #region not implemented protected override void SetSummaryDataRow() { return; } protected override void SetSearchableProperties() { return; } #endregion not implemented public override bool Validate(eCMSActions action, ActionArgs e, out eCMSEngineEventStatus status, out string message) { bool valid = true; status = eCMSEngineEventStatus.Success; message = string.Empty; if (action == eCMSActions.Publish) { if (string.IsNullOrEmpty(CompanyName)) message += "Company Name is a required field<br/>"; } if (!string.IsNullOrEmpty(message)) { valid = false; status = eCMSEngineEventStatus.Exception; } return valid; } } } Address class referenceusing System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Linq; using System.Xml.Linq; using System.Net; using System.Web; using System.Configuration; using System.IO; using System.Xml; using Convert = System.Convert; namespace AdvantageClient { [Serializable] public enum LatLngAccurateToTypes : int { Unknown = 0, Country = 1, Region = 2, SubRegion = 3, Town = 4, PostalZip = 5, Street = 6, Intersection = 7, Address = 8, Premises = 9 } [Serializable] public class Address { public double Latitude { get; set; } public double Longitude { get; set; } public string Line1 { get; set; } public string Line2 { get; set; } public string City { get; set; } public string ProvState { get; set; } public string PostalZip { get; set; } public string Country { get; set; } private LatLngAccurateToTypes _LatLngAccuracy = 0; public LatLngAccurateToTypes LatLngAccuracy { get { return _LatLngAccuracy; } } public override string ToString() { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.AppendLine(Line1); if (!string.IsNullOrEmpty(Line2)) sb.AppendLine(Line2); sb.Append(City); sb.Append(", "); sb.Append(ProvState); sb.Append(" "); sb.Append(PostalZip); sb.Append(" "); sb.Append(Country); return sb.ToString(); } public bool GeoCode(string googleMapsAPIKey) { //get the maps key in the web config file //setup a streamreader for retrieving data from Google. StreamReader sr = null; //Check to see if our maps key exists if (string.IsNullOrEmpty(googleMapsAPIKey)) throw new Exception("No valid google maps api key to use for geocode. Please pass in a valid API Key."); //Create the url string to send our request to google. string url = $"https://maps.googleapis.com/maps/api/geocode/xml?address={this.Line1}+{this.City}+{this.ProvState}+{this.PostalZip}+{this.Country}&key={googleMapsAPIKey}"; //string url = $"http://maps.google.com/maps/geo?q={this.Line1} +{this.City} +{this.ProvState} +{this.PostalZip} +{this.Country}&output=xml&oe=utf8&sensor=false&key={googleMapsAPIKey}"; //Create a web request client. WebClient wc = new WebClient(); try { sr = new StreamReader(wc.OpenRead(url)); XmlDocument doc = new XmlDocument(); doc.LoadXml(sr.ReadToEnd()); XmlNodeList nodes = doc.GetElementsByTagName("location"); if (nodes != null && nodes.Count > 0 && nodes[0].ChildNodes != null && nodes[0].ChildNodes.Count == 2) { foreach (XmlNode childNode in nodes[0].ChildNodes) { if (childNode.Name == "lat") Latitude = Convert.ToDouble(childNode.InnerText); if (childNode.Name == "lng") Longitude = Convert.ToDouble(childNode.InnerText); } } } catch (Exception ex) { throw new Exception($"An error occurred while parsing GeoCoded results from Google, the error was: {ex.Message}"); } return true; } } } Control:ToolControl SiteSettings UserControl: ToolControl<T>: Where T BusinessObjectSiteSettings Overview A custom user-control that allows for entry of data that can be used throughout the site. Example User-Control SiteSettings.ascx<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SiteSettingsControl.ascx.cs" Inherits="AdvantageClient.SiteSettingsControl" %> <%@ Register Assembly="AdvantageCMS.Web.UI" TagPrefix="advantage" Namespace="AdvantageCMS.Web.UI" %> <%@ Register Src="LanguageSettings.ascx" TagPrefix="advantage" TagName="LanguageSettings" %> <telerik:RadTabStrip runat="server" ID="tabConfig" SelectedIndex="0" AutoPostBack="false" MultiPageID="mpvConfig" > <Tabs> <telerik:RadTab Text="Company Information" Selected="true" PageViewID="pvCompany"></telerik:RadTab> <telerik:RadTab Text="Logos" Selected="true" PageViewID="pvLogos"></telerik:RadTab> <telerik:RadTab Text="Settings" PageViewID="pvSettings" Visible="false"></telerik:RadTab> <telerik:RadTab Text="Language Entries" PageViewID="pvLanguageSettings" Visible="true"></telerik:RadTab> </Tabs> </telerik:RadTabStrip> <telerik:RadMultiPage id="mpvConfig" runat="server" selectedindex="0"> <telerik:RadPageView runat="server" ID="pvCompany"> <fieldset> <legend>Company Information</legend> <div class="form-row"> <label>Company Name</label> <telerik:RadTextBox ID="txtCompanyName" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label >Email Address</label> <telerik:RadTextBox ID="txtEmailAddress" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Phone Number</label> <telerik:RadTextBox ID="txtPhoneNumber" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Address Line 1</label> <telerik:RadTextBox ID="txtAddressLine1" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Address Line 2</label> <telerik:RadTextBox ID="txtAddressLine2" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>City</label> <telerik:RadTextBox ID="txtCity" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Prov/State</label> <telerik:RadTextBox ID="txtProvState" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Postal/Zip</label> <telerik:RadTextBox ID="txtPostalZip" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Country</label> <telerik:RadTextBox ID="txtCountry" runat="server"></telerik:RadTextBox> </div> </fieldset> <fieldset> <legend>Geo Coding <asp:Button runat="server" text="Call Google geo code API" ID="btnGeoCode" OnClick="btnGeoCode_OnClick"/> </legend> <div class="form-row"> <label>Google MAP API Key</label> <telerik:RadTextBox ID="txtGoogleMapAPIKey" runat="server"></telerik:RadTextBox> </div> <div class="form-row"> <label>Latitude</label> <telerik:RadNumericTextBox ID="txtLatitude" runat="server" MinValue="-90" MaxValue="90"> <NumberFormat AllowRounding="false" DecimalDigits="15" /> </telerik:RadNumericTextBox> </div> <div class="form-row"> <label>Longitude</label> <telerik:RadNumericTextBox ID="txtLongitude" runat="server" MinValue="-180" MaxValue="180" > <NumberFormat AllowRounding="false" DecimalDigits="15" /> </telerik:RadNumericTextBox> </div> <asp:Panel CssClass="form-row" runat="server" id="pnlGeoError" Visible="False"> <div class="infoBox red"> <asp:Literal runat="server" id="litMessage"></asp:Literal> </div> </asp:panel> </fieldset> </telerik:RadPageView> <telerik:RadPageView runat="server" ID="pvLogos"> <fieldset> <legend>Logos</legend> <div class="form-row"> <label>Logo</label> <advantage:AdvantageSelectorImage runat="server" ID="aisLogo" /> </div> <div class="form-row"> <label>Icon</label> <advantage:AdvantageSelectorImage runat="server" ID="aisIcon" /> </div> </fieldset> </telerik:RadPageView> <telerik:RadPageView runat="server" ID="pvSettings"> </telerik:RadPageView> <telerik:RadPageView runat="server" ID="pvLanguageSettings"> <advantage:LanguageSettings runat="server" ID="LanguageSettings1" /> </telerik:RadPageView> </telerik:RadMultiPage> SiteSettings.ascx.csusing System; using AdvantageCMS.Core.Admin.BaseClasses; using AdvantageCMS.Core.Admin.Event; namespace AdvantageClient { public partial class SiteSettingsControl : ToolControl<SiteSettings> { protected override void OnInit(EventArgs e) { base.OnInit(e); pnlGeoError.Visible = false; LanguageSettings1.SetActionState += this.LanguageSettings1_OnSetActionState; } private void LanguageSettings1_OnSetActionState(ActionArgs e) { if ((bool)e.SelectedObject== true) EnableActions(); else DisableActions(); } protected override void SaveDataToObject() { MyObject.CompanyName = txtCompanyName.Text; MyObject.EmailAddress = txtEmailAddress.Text; MyObject.PhoneNumber = txtPhoneNumber.Text; MyObject.CompanyAddress.Line1 = txtAddressLine1.Text; MyObject.CompanyAddress.Line2 = txtAddressLine2.Text; MyObject.CompanyAddress.City = txtCity.Text; MyObject.CompanyAddress.ProvState=txtProvState.Text; MyObject.CompanyAddress.Country=txtCountry.Text; MyObject.CompanyAddress.Latitude = txtLatitude.Value ?? 0; MyObject.CompanyAddress.Longitude = txtLongitude.Value ?? 0; MyObject.LogoImage = aisLogo.GetAdvantageImage(); MyObject.IconImage=aisIcon.GetAdvantageImage(); MyObject.LanguageSettings = LanguageSettings1.SaveLanguages(); } protected override void LoadDataFromObject(ActionArgs e) { txtAddressLine1.Text = MyObject.CompanyAddress.Line1; txtAddressLine2.Text = MyObject.CompanyAddress.Line2; txtCity.Text = MyObject.CompanyAddress.City; txtProvState.Text = MyObject.CompanyAddress.ProvState; txtCountry.Text = MyObject.CompanyAddress.Country; txtLatitude.Value = MyObject.CompanyAddress.Latitude; txtLongitude.Value = MyObject.CompanyAddress.Longitude; txtEmailAddress.Text= MyObject.EmailAddress; txtPhoneNumber.Text= MyObject.PhoneNumber; aisLogo.SetAdvantageImage(MyObject.LogoImage); aisIcon.SetAdvantageImage(MyObject.IconImage); LanguageSettings1.LoadLangauges(MyObject.LanguageSettings); } protected void btnGeoCode_OnClick(object sender, EventArgs e) { try { var result=MyObject.CompanyAddress.GeoCode(txtGoogleMapAPIKey.Text); if (result) { txtLatitude.Value = MyObject.CompanyAddress.Latitude; txtLongitude.Value = MyObject.CompanyAddress.Longitude; } else { throw new Exception("Unable to execute geocode api."); } } catch (Exception ex) { pnlGeoError.Visible = true; litMessage.Text = ex.Message; } } } }