/// <summary> /// Read shopify theme settings from 'config' folder /// </summary> /// <param name="defaultValue"></param> /// <returns></returns> public IDictionary <string, object> GetSettings(string defaultValue = null) { var cacheKey = CacheKey.With(GetType(), "GetSettings", CurrentThemeSettingPath, defaultValue); return(_memoryCache.GetOrCreateExclusive(cacheKey, (cacheItem) => { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(CurrentThemeSettingPath) })); var retVal = new Dictionary <string, object>().WithDefaultValue(defaultValue); //Load all data from current theme config var resultSettings = InnerGetAllSettings(_themeBlobProvider, CurrentThemeSettingPath); if (resultSettings == null && BaseThemeSettingPath != null) { resultSettings = InnerGetAllSettings(_themeBlobProvider, BaseThemeSettingPath); } if (resultSettings != null) { //Get actual preset from merged config var currentPreset = resultSettings.GetValue("current"); if (currentPreset is JValue) { var currentPresetName = ((JValue)currentPreset).Value.ToString(); if (!(resultSettings.GetValue("presets") is JObject presets) || !presets.Children().Any()) { throw new StorefrontException("Setting presets not defined"); } IList <JProperty> allPresets = presets.Children().Cast <JProperty>().ToList(); resultSettings = allPresets.FirstOrDefault(p => p.Name == currentPresetName).Value as JObject; if (resultSettings == null) { throw new StorefrontException($"Setting preset with name '{currentPresetName}' not found"); } }
/// <summary> /// Read shopify theme settings from 'config' folder /// </summary> /// <param name="defaultValue"></param> /// <returns></returns> public IDictionary <string, object> GetSettings(string defaultValue = null) { var cacheKey = CacheKey.With(GetType(), "GetSettings", CurrentThemeSettingPath, defaultValue); return(_memoryCache.GetOrCreateExclusive(cacheKey, cacheItem => { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(CurrentThemeSettingPath) })); JObject result; var baseThemeSettings = new JObject(); var currentThemeSettings = result = InnerGetAllSettings(_themeBlobProvider, CurrentThemeSettingPath); //Try to load settings from base theme path and merge them with resources for local theme if ((_options.MergeBaseSettings || currentThemeSettings == null) && !string.IsNullOrEmpty(BaseThemeSettingPath)) { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(BaseThemeSettingPath) })); baseThemeSettings = InnerGetAllSettings(_themeBlobProvider, BaseThemeSettingPath); } result = _options.MergeBaseSettings ? SettingsManager.Merge(baseThemeSettings, currentThemeSettings ?? new JObject()) : SettingsManager.ReadSettings(currentThemeSettings ?? new JObject()).CurrentPreset.Json; return result.ToObject <Dictionary <string, object> >().ToDictionary(x => x.Key, x => x.Value).WithDefaultValue(defaultValue); })); }
/// <summary> /// Render template by content and parameters /// </summary> /// <param name="templateContent"></param> /// <param name="parameters"></param> /// <returns></returns> public ValueTask<string> RenderTemplateAsync(string templateContent, string templatePath, object context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (!(context is IScriptObject scriptObject)) { throw new StorefrontException($"{ nameof(context) } must implement IScriptObject"); } if (string.IsNullOrEmpty(templateContent)) { return new ValueTask<string>(templateContent); } var isLiquidTemplate = _isLiquid.Match(templateContent); if (!isLiquidTemplate.Success) { return new ValueTask<string>(templateContent); } //TODO: Handle _options.RethrowLiquidRenderErrors var cacheKey = CacheKey.With(GetType(), "ParseTemplate", templatePath ?? templateContent); var parsedTemplate = _memoryCache.GetOrCreate(cacheKey, (cacheItem) => { if (!string.IsNullOrEmpty(templatePath)) { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(templatePath) })); } else { cacheItem.AddExpirationToken(ThemeEngineCacheRegion.CreateChangeToken()); } return Template.ParseLiquid(templateContent, templatePath); }); if (parsedTemplate.HasErrors) { throw new InvalidOperationException(string.Join("\n", parsedTemplate.Messages)); } var templateContext = new TemplateContext() { TemplateLoader = this, EnableRelaxedMemberAccess = true, NewLine = Environment.NewLine, TemplateLoaderLexerOptions = new LexerOptions { Mode = ScriptMode.Liquid } }; templateContext.PushGlobal(scriptObject); var result = parsedTemplate.Render(templateContext); return new ValueTask<string>(result); }
/// <summary> /// Read localization resources /// </summary> /// <returns></returns> public JObject ReadLocalization() { var cacheKey = CacheKey.With(GetType(), "ReadLocalization", CurrentThemeLocalePath, WorkContext.CurrentLanguage.CultureName); return(_memoryCache.GetOrCreate(cacheKey, (cacheItem) => { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(CurrentThemeLocalePath + "/*") })); return InnerReadLocalization(_themeBlobProvider, CurrentThemeLocalePath, WorkContext.CurrentLanguage) ?? new JObject(); })); }
/// <summary> /// Return hash of requested asset (used for file versioning) /// </summary> /// <param name="filePath"></param> /// <returns></returns> public string GetAssetHash(string filePath) { var cacheKey = CacheKey.With(GetType(), "GetAssetHash", filePath); return(_memoryCache.GetOrCreate(cacheKey, (cacheEntry) => { cacheEntry.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(filePath) })); using (var stream = GetAssetStream(filePath)) { var hashAlgorithm = CryptoConfig.AllowOnlyFipsAlgorithms ? (SHA256) new SHA256CryptoServiceProvider() : new SHA256Managed(); return WebEncoders.Base64UrlEncode(hashAlgorithm.ComputeHash(stream)); } })); }
private string ReadTemplateByPath(string templatePath) { if (string.IsNullOrEmpty(templatePath)) { throw new ArgumentNullException(nameof(templatePath)); } var cacheKey = CacheKey.With(GetType(), "ReadTemplateByName", templatePath); return(_memoryCache.GetOrCreateExclusive(cacheKey, (cacheItem) => { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(templatePath) })); using (var stream = _themeBlobProvider.OpenRead(templatePath)) { return stream.ReadToString(); } })); }
/// <summary> /// Return hash of requested asset (used for file versioning) /// </summary> /// <param name="filePath"></param> /// <returns></returns> public string GetAssetHash(string filePath) { var cacheKey = CacheKey.With(GetType(), "GetAssetHash", filePath); return _memoryCache.GetOrCreateExclusive(cacheKey, (cacheEntry) => { cacheEntry.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(filePath) })); using (var stream = GetAssetStreamAsync(filePath).GetAwaiter().GetResult()) { if (stream == null) { throw new StorefrontException($"Theme resource for path '{filePath}' not found"); } var hashAlgorithm = CryptoConfig.AllowOnlyFipsAlgorithms ? (SHA256)new SHA256CryptoServiceProvider() : new SHA256Managed(); return WebEncoders.Base64UrlEncode(hashAlgorithm.ComputeHash(stream)); } }); }
/// <summary> /// Read localization resources /// </summary> /// <returns></returns> public JObject ReadLocalization() { var cacheKey = CacheKey.With(GetType(), "ReadLocalization", CurrentThemeLocalePath, WorkContext.CurrentLanguage.CultureName); return(_memoryCache.GetOrCreateExclusive(cacheKey, (cacheItem) => { var result = new JObject(); cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(CurrentThemeLocalePath + "/*") })); //Try to load localization resources from base theme path and merge them with resources for local theme if (BaseThemeLocalePath != null) { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(BaseThemeLocalePath + "/*") })); result = InnerReadLocalization(_themeBlobProvider, BaseThemeLocalePath, WorkContext.CurrentLanguage) ?? new JObject(); } result.Merge(InnerReadLocalization(_themeBlobProvider, CurrentThemeLocalePath, WorkContext.CurrentLanguage) ?? new JObject(), new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Merge }); return result; })); }
private string ReadTemplateByName(string templateName) { var templatePath = ResolveTemplatePath(templateName); if (string.IsNullOrEmpty(templatePath)) { throw new FileSystemException($"The template '{templateName}' was not found. The following locations were searched:<br/>{string.Join("<br/>", DiscoveryPaths)}"); } var cacheKey = CacheKey.With(GetType(), "ReadTemplateByName", templatePath); return(_memoryCache.GetOrCreate(cacheKey, (cacheItem) => { cacheItem.AddExpirationToken(new CompositeChangeToken(new[] { ThemeEngineCacheRegion.CreateChangeToken(), _themeBlobProvider.Watch(templatePath) })); using (var stream = _themeBlobProvider.OpenRead(templatePath)) { return stream.ReadToString(); } })); }
public bool IsFeatureActive(string featureName) { var cacheKey = CacheKey.With(GetType(), nameof(IsFeatureActive), featureName); return(_memoryCache.GetOrCreateExclusive(cacheKey, cacheEntry => { var changeToken = ThemeEngineCacheRegion.CreateChangeToken(); var watchChangeToken = _themeBlobProvider.Watch(CurrentThemeSettingPath); var tokens = new[] { changeToken, watchChangeToken }; var compositeChangeToken = new CompositeChangeToken(tokens); cacheEntry.AddExpirationToken(compositeChangeToken); var settingJObject = InnerGetAllSettings(_themeBlobProvider, CurrentThemeSettingPath); var result = _featuresAgent.IsActive(featureName, settingJObject); return result; })); }
public ActionResult ResetCache() { //TODO: Replace to some other (maybe with using reflection) ThemeEngineCacheRegion.ExpireRegion(); CartCacheRegion.ExpireRegion(); CatalogCacheRegion.ExpireRegion(); ContentBlobCacheRegion.ExpireRegion(); CustomerCacheRegion.ExpireRegion(); MarketingCacheRegion.ExpireRegion(); PricingCacheRegion.ExpireRegion(); QuoteCacheRegion.ExpireRegion(); RecommendationsCacheRegion.ExpireRegion(); StaticContentCacheRegion.ExpireRegion(); StoreCacheRegion.ExpireRegion(); TaxCacheRegion.ExpireRegion(); SubscriptionCacheRegion.ExpireRegion(); SecurityCacheRegion.ExpireRegion(); return(StoreFrontRedirect("~/")); }