// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Data; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace Spludlow { /// /// Provide a simple web menu /// Configured through App_Data/Pages.txt /// Looks for Literal on master page and sets it to a HTML table /// Works for indefinate levels /// Can also set page meta data /// public class WebMenu { public static void PageLoad(MasterPage masterPage, string webKey) { PageLoad(masterPage, webKey, "width:100%;"); } public static void PageLoad(MasterPage masterPage, string webKey, string tableStyle) { webKey = "Spludlow.WebMenu." + webKey; DataSet dataSet = LoadData(webKey); DataTable pagesTable = dataSet.Tables["Pages"]; Literal literalMenuDebug = (Literal)masterPage.FindControl("LiteralMenuDebug"); Literal literalMenu = (Literal)masterPage.FindControl("LiteralMenu"); Literal literalContents = (Literal)Spludlow.WebControls.Find("LiteralSectionContents", masterPage); int length = masterPage.Request.ApplicationPath.Length; if (length == 1) length = 0; string pageUrl = masterPage.Request.Url.PathAndQuery.Substring(length); int index = pageUrl.IndexOf("?"); if (index != -1) pageUrl = pageUrl.Substring(0, index); DataRow pageRow = pagesTable.Rows.Find(pageUrl); string pageTitle = null; if (pageRow != null && pageRow.IsNull("PageTitle") == false) pageTitle = (string)pageRow["PageTitle"]; DisplayHeadFoot(masterPage, pageTitle); if (pageRow != null) DisplayMeta(masterPage, pageRow); bool pageNotInMenu = false; if (pageRow == null) { index = pageUrl.LastIndexOf("/"); if (index != -1) { pageUrl = pageUrl.Substring(0, index) + "/Default.aspx"; pageRow = pagesTable.Rows.Find(pageUrl); } pageNotInMenu = true; } if (pageRow != null) { int currentId = (int)pageRow["Id"]; int currentParentId = (int)pageRow["ParentId"]; int currentLevel = (int)pageRow["Level"]; List menuRows = new List(); // Reverse Level order List currentIds = new List(); currentIds.Add(currentId); DataRow[] rows; if (currentParentId != 0) { rows = pagesTable.Select("ParentId = " + currentId); if (rows.Length > 0) // Below current menuRows.Add(rows); } int nextParentId = currentParentId; for (int level = currentLevel; level > 0; --level) { if (level == 1) // Always all { rows = pagesTable.Select("Level = 1"); } else { rows = pagesTable.Select("ParentId = " + nextParentId); currentIds.Add(nextParentId); DataRow[] tempRows = pagesTable.Select("Id = " + nextParentId); nextParentId = (int)tempRows[0]["ParentId"]; } menuRows.Add(rows); } if (pageNotInMenu == true && pageUrl == "/Default.aspx") currentIds.Clear(); //literalMenuDebug.Text = pageUrl + " # " + currentId + "selected: "; //foreach (int id in currentIds) // literalMenuDebug.Text += id + ", "; StringBuilder text = new StringBuilder(); for (int levelIndex = menuRows.Count - 1; levelIndex >= 0; --levelIndex) { rows = menuRows[levelIndex]; if (tableStyle != "") { text.AppendLine(""); } else { text.AppendLine("
"); } foreach (DataRow levelRow in rows) { string styleClass = "M0"; if (currentIds.Contains((int)levelRow["Id"]) == true) { styleClass = "M1"; } string title = ""; if (levelRow.IsNull("PageTitle") == false) title = (string)levelRow["PageTitle"]; if (levelRow.IsNull("PageDescription") == false) title = title + " " + Environment.NewLine + " " + (string)levelRow["PageDescription"]; text.Append(""); text.AppendLine(); } text.AppendLine("
"); text.Append(""); text.Append((string)levelRow["MenuTitle"]); text.Append(""); text.Append("
"); } literalMenu.Text = text.ToString(); if (literalContents != null && menuRows.Count > 0) { text.Length = 0; rows = menuRows[0]; text.Append("

"); string title = (string)pageRow["MenuTitle"]; if (title == "Home") text.Append("Site Sections"); else text.Append(title + " Section Contents"); text.Append("

"); text.AppendLine(""); foreach (DataRow row in rows) { text.AppendLine(""); text.AppendLine(""); text.AppendLine(""); text.AppendLine(""); } text.AppendLine("
"); text.Append(""); text.Append((string)row["MenuTitle"]); text.Append(""); text.AppendLine(""); if (row.IsNull("PageTitle") == false) text.Append((string)row["PageTitle"]); text.AppendLine("
"); text.AppendLine("
"); literalContents.Text = text.ToString(); } } //else //{ // literalMenuDebug.Text = pageUrl + " # Page not found in table"; //} } private static string LinkPageUrl(string url) { if (url.EndsWith("/Default.aspx") == true) url = url.Substring(0, url.Length - 12); return url; } private static void DisplayMeta(MasterPage masterPage, DataRow pageRow) { Literal literal; string text; if (pageRow.IsNull("PageDescription") == false) { text = (string)pageRow["PageDescription"]; SetMetaHead(masterPage, "description", text); literal = (Literal)Spludlow.WebControls.Find("WebContentDescription", masterPage.Page); if (literal != null) literal.Text = text; } if (pageRow.IsNull("PageKeyWords") == false) { text = (string)pageRow["PageKeyWords"]; SetMetaHead(masterPage, "keywords", text); literal = (Literal)Spludlow.WebControls.Find("LiteralWebContentKeyWords", masterPage.Page); if (literal != null) literal.Text = text; } } public static void SetMetaHead(MasterPage masterPage, string name, string content) { HtmlHead htmlHead = (HtmlHead)masterPage.Page.Header; HtmlMeta meta = new HtmlMeta(); meta.Name = name; meta.Content = content; htmlHead.Controls.Add(meta); } private static void DisplayHeadFoot(MasterPage masterPage, string heading) { string pageHeading = GetLiteralText(masterPage, "MenuHead"); if (pageHeading != null && pageHeading.Length > 0) heading = pageHeading; if (heading == null) { heading = masterPage.Request.Url.AbsolutePath; int index; index = heading.LastIndexOf("/"); if (index != -1 && index != (heading.Length - 1)) heading = heading.Substring(index + 1); index = heading.LastIndexOf("."); if (index != -1) heading = heading.Substring(0, index); } SetLiteralText(masterPage, "MenuHead", heading); masterPage.Page.Title = heading; } public static void SetLiteralText(MasterPage masterPage, string controlName, string text) { Literal control = (Literal)masterPage.FindControl(controlName); if (control == null) return; control.Text = text; } public static string GetLiteralText(MasterPage masterPage, string controlName) { Literal control = (Literal)masterPage.FindControl(controlName); if (control == null) return null; return control.Text; } private static DataSet LoadData(string webKey) { DataSet dataSet = (DataSet)Spludlow.Caching.Get(webKey); if (dataSet != null) return dataSet; dataSet = new DataSet(); string webAppDataDirectory = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "App_Data"); if (Directory.Exists(webAppDataDirectory) == false) Directory.CreateDirectory(webAppDataDirectory); string pagesFilename = webAppDataDirectory + @"\Pages.txt"; if (File.Exists(pagesFilename) == false) { throw new ApplicationException(pagesFilename + " needs creating"); } DataTable pagesTable = Spludlow.Data.TextTable.ReadFile(pagesFilename, true); // MenuTitle PageUrl PageTitle PageDescription PageKeyWords DataTable table; table = Spludlow.Data.TextTable.ReadText(new string[] { "Id ParentId Level MenuStyle", "Int32 Int32 Int32 String", }); foreach (DataColumn column in pagesTable.Columns) table.Columns.Add(column.ColumnName, column.DataType); int id = 0; foreach (DataRow sourceRow in pagesTable.Rows) { table.ImportRow(sourceRow); DataRow row = table.Rows[table.Rows.Count - 1]; row["Id"] = ++id; string pageUrl = (string)row["PageUrl"]; if (pageUrl.EndsWith("/") == true) row["PageUrl"] = pageUrl += "Default.aspx"; int level = 0; foreach (char ch in pageUrl) { if (ch == '/') ++level; } if (pageUrl.EndsWith("/Default.aspx") == true) --level; if (level == 0) { level = 1; row["ParentId"] = 0; } row["Level"] = level; row["MenuStyle"] = "M" + level + "-0"; // Not using still just M0 M1 at each level } pagesTable = table; pagesTable.PrimaryKey = new DataColumn[] { pagesTable.Columns["PageUrl"] }; foreach (DataRow row in pagesTable.Rows) { string pageUrl = (string) row["PageUrl"]; if (pageUrl != "/Default.aspx") { int index = pageUrl.LastIndexOf("/"); if (pageUrl.EndsWith("/Default.aspx") == true) index = pageUrl.LastIndexOf("/", index - 1); if (index != -1) { string parentUrl = pageUrl.Substring(0, index) + "/Default.aspx"; DataRow parentRow = pagesTable.Rows.Find(parentUrl); if (parentRow != null) row["ParentId"] = parentRow["Id"]; } } } pagesTable.TableName = "Pages"; dataSet.Tables.Add(pagesTable); Spludlow.Log.Report("Web Menu; Loaded", dataSet); Spludlow.Caching.Set(webKey, dataSet); return dataSet; } } }