/// <summary> /// Activates a theme. /// </summary> /// <param name="folderName">Theme's folder name.</param> /// <returns></returns> /// <remarks> /// It registers theme and the widget areas used by the theme. /// </remarks> public async Task ActivateThemeAsync(string folderName) { // verify folderName var regex = new Regex(THEME_FOLDER_REGEX); if (!regex.IsMatch(folderName)) { throw new FanException($"Theme {folderName} contains invalid characters."); } // register theme if not exist if (await metaRepository.GetAsync(folderName, EMetaType.Theme) == null) { await metaRepository.CreateAsync(new Meta { Key = folderName.ToLower(), // lower case Value = "", // empty for now Type = EMetaType.Theme, }); } // register theme-defined widget areas var installedThemes = await GetInstalledThemesInfoAsync(); var themeToActivate = installedThemes.Single(t => t.Name.Equals(folderName, StringComparison.OrdinalIgnoreCase)); // check if there is any empty area ids if (themeToActivate.WidgetAreas.Any(a => a.Id.IsNullOrEmpty())) { throw new FanException("Widget area id cannot be empty."); } var themeDefinedAreas = themeToActivate.WidgetAreas.Where(ta => !WidgetService.SystemDefinedWidgetAreaInfos.Any(sa => sa.Id == ta.Id)); foreach (var area in themeDefinedAreas) { var key = string.Format($"{folderName}-{area.Id}").ToLower(); // register only if not exist if (await metaRepository.GetAsync(key, EMetaType.WidgetAreaByTheme) == null) { var widgetArea = new WidgetArea { Id = area.Id }; await metaRepository.CreateAsync(new Meta { Key = key, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaByTheme, }); } } }
// -------------------------------------------------------------------- widget areas /// <summary> /// Registers a widget area by its id and type. /// </summary> /// <param name="areaId">The id of the widget area.</param> /// <param name="type">The <see cref="EMetaType"/> of the area.</param> /// <returns></returns> public async Task <Meta> RegisterAreaAsync(string areaId, EMetaType type = EMetaType.WidgetAreaBySystem) { var key = areaId; if (IsThemeDefinedArea(areaId)) { key = await GetThemeAreaMetaKeyAsync(areaId); type = EMetaType.WidgetAreaByTheme; } return(await metaRepository.CreateAsync(new Meta { Key = key, Value = JsonConvert.SerializeObject(new WidgetArea { Id = areaId }), Type = type, })); }
// -------------------------------------------------------------------- private methods private async Task <IList <Nav> > QueryMenuAsync(EMenu menuId, bool includeNavUrl = false) { // meta var meta = await metaRepository.GetAsync(menuId.ToString().ToLower(), EMetaType.Menu); if (meta == null) { // if not found create a meta meta = await metaRepository.CreateAsync(new Meta { Key = menuId.ToString().ToLower(), Value = JsonConvert.SerializeObject(new List <Nav>()), Type = EMetaType.Menu, }); } // navList var navList = JsonConvert.DeserializeObject <IList <Nav> >(meta.Value); // lookup nav foreach (var nav in navList) { try { if (nav.Type == ENavType.CustomLink || !includeNavUrl) { continue; } var navProvider = navProviders.SingleOrDefault(p => p.CanProvideNav(nav.Type)); nav.Url = await navProvider.GetNavUrlAsync(nav.Id); if (!nav.Url.StartsWith('/')) { nav.Url = $"/{nav.Url}"; } } catch (MokException ex) when(ex.ExceptionType == EExceptionType.ResourceNotFound) { continue; } } return(navList); }