using System.Net; using System.Text; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Routing; using Nop.Core.Infrastructure; using Nop.Services.Localization; using Nop.Services.Stores; using Nop.Web.Framework.Events; using Nop.Web.Framework.Models; namespace Nop.Web.Framework.Extensions; /// /// HTML extensions /// public static class HtmlExtensions { #region Admin area extensions /// /// Generate editor for localizable entities /// /// Model type /// Locale model type /// HTML helper /// ID of control /// Template with localizable values /// Template for standard (default) values /// A value indicating whether to ignore localization if we have multiple stores /// CSS class for localizedTemplate /// /// A task that represents the asynchronous operation /// The task result contains the localized editor /// public static async Task LocalizedEditorAsync(this IHtmlHelper helper, string name, Func localizedTemplate, Func standardTemplate, bool ignoreIfSeveralStores = false, string cssClass = null) where TModel : ILocalizedModel where TLocalizedModelLocal : ILocalizedLocaleModel { var localizationSupported = helper.ViewData.Model.Locales.Count > 1; if (ignoreIfSeveralStores) { var storeService = EngineContext.Current.Resolve(); if ((await storeService.GetAllStoresAsync()).Count >= 2) localizationSupported = false; } if (!localizationSupported) return new HtmlString(await standardTemplate(helper.ViewData.Model).RenderHtmlContentAsync()); var localizationService = EngineContext.Current.Resolve(); var languageService = EngineContext.Current.Resolve(); var urlHelper = EngineContext.Current.Resolve().GetUrlHelper(helper.ViewContext); var tabStrip = new StringBuilder(); var cssClassWithSpace = !string.IsNullOrEmpty(cssClass) ? $" {cssClass}" : null; tabStrip.AppendLine($"
"); //render input contains selected tab name var tabNameToSelect = GetSelectedTabName(helper, name); var selectedTabInput = new TagBuilder("input"); selectedTabInput.Attributes.Add("type", "hidden"); selectedTabInput.Attributes.Add("id", $"selected-tab-name-{name}"); selectedTabInput.Attributes.Add("name", $"selected-tab-name-{name}"); selectedTabInput.Attributes.Add("value", tabNameToSelect); tabStrip.AppendLine(await selectedTabInput.RenderHtmlContentAsync()); tabStrip.AppendLine($"
"); tabStrip.AppendLine($"
"); tabStrip.AppendLine("
    "); //default tab var standardTabName = $"{name}-standard-tab"; var standardTabSelected = string.IsNullOrEmpty(tabNameToSelect) || standardTabName == tabNameToSelect; tabStrip.AppendLine(string.Format("
  • ")); if (standardTabSelected) { tabStrip.AppendLine($"{await localizationService.GetResourceAsync("Admin.Common.Standard")}"); } else { tabStrip.AppendLine($"{await localizationService.GetResourceAsync("Admin.Common.Standard")}"); } tabStrip.AppendLine("
  • "); foreach (var locale in helper.ViewData.Model.Locales) { //languages var language = await languageService.GetLanguageByIdAsync(locale.LanguageId) ?? throw new Exception("Language cannot be loaded"); var localizedTabName = $"{name}-{language.Id}-tab"; tabStrip.AppendLine(string.Format("
  • ")); var iconUrl = urlHelper.Content("~/images/flags/" + language.FlagImageFileName); var active = localizedTabName == tabNameToSelect ? "active" : null; tabStrip.AppendLine($"{WebUtility.HtmlEncode(language.Name)}"); tabStrip.AppendLine("
  • "); } tabStrip.AppendLine("
"); tabStrip.AppendLine("
"); tabStrip.AppendLine("
"); //default tab tabStrip.AppendLine("
"); tabStrip.AppendLine(string.Format("
", standardTabSelected ? " show active" : null, standardTabName)); tabStrip.AppendLine(await standardTemplate(helper.ViewData.Model).RenderHtmlContentAsync()); tabStrip.AppendLine("
"); for (var i = 0; i < helper.ViewData.Model.Locales.Count; i++) { //languages var language = await languageService.GetLanguageByIdAsync(helper.ViewData.Model.Locales[i].LanguageId) ?? throw new Exception("Language cannot be loaded"); var localizedTabName = $"{name}-{language.Id}-tab"; tabStrip.AppendLine(string.Format("
", localizedTabName == tabNameToSelect ? " show active" : null, localizedTabName)); tabStrip.AppendLine(await localizedTemplate(i).RenderHtmlContentAsync()); tabStrip.AppendLine("
"); } tabStrip.AppendLine("
"); tabStrip.AppendLine("
"); tabStrip.AppendLine("
"); tabStrip.AppendLine("
"); //render tabs script var script = new TagBuilder("script"); script.InnerHtml.AppendHtml( "$(function() {" + "bindBootstrapTabSelectEvent('" + name + "', 'selected-tab-name-" + name + "');" + "});"); var scriptTag = await script.RenderHtmlContentAsync(); tabStrip.AppendLine(scriptTag); return new HtmlString(tabStrip.ToString()); } /// /// Gets a selected card name (used in admin area to store selected panel name) /// /// HtmlHelper /// Name public static string GetSelectedCardName(this IHtmlHelper helper) { //keep this method synchronized with //"SaveSelectedCardName" method of \Area\Admin\Controllers\BaseAdminController.cs var cardName = string.Empty; const string dataKey = "nop.selected-card-name"; if (helper.ViewData.ContainsKey(dataKey)) cardName = helper.ViewData[dataKey].ToString(); if (helper.ViewContext.TempData.TryGetValue(dataKey, out var value)) cardName = value.ToString(); return cardName; } /// /// Gets a selected tab name (used in admin area to store selected tab name) /// /// HtmlHelper /// Key prefix. Pass null to ignore /// Name public static string GetSelectedTabName(this IHtmlHelper helper, string dataKeyPrefix = null) { //keep this method synchronized with //"SaveSelectedTab" method of \Area\Admin\Controllers\BaseAdminController.cs var tabName = string.Empty; var dataKey = "nop.selected-tab-name"; if (!string.IsNullOrEmpty(dataKeyPrefix)) dataKey += $"-{dataKeyPrefix}"; if (helper.ViewData.ContainsKey(dataKey)) tabName = helper.ViewData[dataKey].ToString(); if (helper.ViewContext.TempData.TryGetValue(dataKey, out var value)) tabName = value.ToString(); return tabName; } /// /// Add a tab to TabStrip /// /// AdminTabStripCreated /// Tab Id /// Tab name /// url /// Html content of new Tab public static IHtmlContent TabContentByURL(this AdminTabStripCreated eventMessage, string tabId, string tabName, string url) { return new HtmlString($@" "); } /// /// Add a tab to TabStrip /// /// AdminTabStripCreated /// Tab Id /// Tab name /// Content model /// Html content of new Tab public static IHtmlContent TabContentByModel(this AdminTabStripCreated eventMessage, string tabId, string tabName, string contentModel) { return new HtmlString($@" "); } #region Form fields /// /// Generate hint control /// /// HTML helper /// TexHint text /// /// A task that represents the asynchronous operation /// The task result contains the result /// public static async Task HintAsync(this IHtmlHelper helper, string value) { //create tag builder var builder = new TagBuilder("div"); builder.MergeAttribute("title", value); builder.MergeAttribute("class", "ico-help"); builder.MergeAttribute("data-toggle", "tooltip"); var icon = new StringBuilder(); icon.Append(""); builder.InnerHtml.AppendHtml(icon.ToString()); //render tag return new HtmlString(await builder.RenderHtmlContentAsync()); } #endregion #endregion #region Common extensions /// /// Convert IHtmlContent to string /// /// HTML content /// /// A task that represents the asynchronous operation /// The task result contains the result /// public static async Task RenderHtmlContentAsync(this IHtmlContent htmlContent) { await using var writer = new StringWriter(); htmlContent.WriteTo(writer, HtmlEncoder.Default); return writer.ToString(); } #endregion }