NopCommerce多语言的实现

通过语言包xml文件导入导出语言字符串

数据库方面,以下数据表:

Language

LocaleStringResource

LocalizedProperty

接口IWorkContext真正实现类是Nop.Web.Framework.WebWorkContext,里面有一个获取语言的属性。

  1. public virtual Language WorkingLanguage
  2. {
  3. get
  4. {
  5. if (_cachedLanguage != null)
  6. return _cachedLanguage;
  7. Language detectedLanguage = null;
  8. if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
  9. {
  10. //从URL中获取语言
  11. detectedLanguage = GetLanguageFromUrl();
  12. }
  13. if (detectedLanguage == null && _localizationSettings.AutomaticallyDetectLanguage)
  14. {
  15. //get language from browser settings
  16. //but we do it only once
  17. if (!this.CurrentCustomer.GetAttribute<bool>(SystemCustomerAttributeNames.LanguageAutomaticallyDetected,
  18. _genericAttributeService, _storeContext.CurrentStore.Id))
  19. {
  20. detectedLanguage = GetLanguageFromBrowserSettings();
  21. if (detectedLanguage != null)
  22. {
  23. _genericAttributeService.SaveAttribute(this.CurrentCustomer, SystemCustomerAttributeNames.LanguageAutomaticallyDetected,
  24. true, _storeContext.CurrentStore.Id);
  25. }
  26. }
  27. }
  28. if (detectedLanguage != null)
  29. {
  30. //the language is detected. now we need to save it
  31. if (this.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.LanguageId,
  32. _genericAttributeService, _storeContext.CurrentStore.Id) != detectedLanguage.Id)
  33. {
  34. _genericAttributeService.SaveAttribute(this.CurrentCustomer, SystemCustomerAttributeNames.LanguageId,
  35. detectedLanguage.Id, _storeContext.CurrentStore.Id);
  36. }
  37. }
  38. var allLanguages = _languageService.GetAllLanguages(storeId: _storeContext.CurrentStore.Id);
  39. //find current customer language
  40. var languageId = this.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.LanguageId,
  41. _genericAttributeService, _storeContext.CurrentStore.Id);
  42. var language = allLanguages.FirstOrDefault(x => x.Id == languageId);
  43. if (language == null)
  44. {
  45. //如果没有指定语言,默认返回系统中的第一种语言
  46. language = allLanguages.FirstOrDefault();
  47. }
  48. if (language == null)
  49. {
  50. //it not specified, then return the first found one
  51. language = _languageService.GetAllLanguages().FirstOrDefault();
  52. }
  53. //cache
  54. _cachedLanguage = language;
  55. return _cachedLanguage;
  56. }
  57. set
  58. {
  59. var languageId = value != null ? value.Id : 0;
  60. _genericAttributeService.SaveAttribute(this.CurrentCustomer,
  61. SystemCustomerAttributeNames.LanguageId,
  62. languageId, _storeContext.CurrentStore.Id);
  63. //reset cache
  64. _cachedLanguage = null;
  65. }
  66. }
  1. string result = string.Empty;
  2. if (resourceKey == null)
  3. resourceKey = string.Empty;
  4. resourceKey = resourceKey.Trim().ToLowerInvariant();
  5. if (_localizationSettings.LoadAllLocaleRecordsOnStartup)
  6. {
  7. //load all records (we know they are cached)
  8. var resources = GetAllResourceValues(languageId);
  9. if (resources.ContainsKey(resourceKey))
  10. {
  11. result = resources[resourceKey].Value;
  12. }
  13. }
  14. else
  15. {
  16. //gradual loading
  17. string key = string.Format(LOCALSTRINGRESOURCES_BY_RESOURCENAME_KEY, languageId, resourceKey);
  18. string lsr = _cacheManager.Get(key, () =>
  19. {
  20. var query = from l in _lsrRepository.Table
  21. where l.ResourceName == resourceKey
  22. && l.LanguageId == languageId
  23. select l.ResourceValue;
  24. return query.FirstOrDefault();
  25. });
  26. if (lsr != null)
  27. result = lsr;
  28. }
  29. if (String.IsNullOrEmpty(result))
  30. {
  31. if (logIfNotFound)
  32. _logger.Warning(string.Format("Resource string ({0}) is not found. Language ID = {1}", resourceKey, languageId));
  33. if (!String.IsNullOrEmpty(defaultValue))
  34. {
  35. result = defaultValue;
  36. }
  37. else
  38. {
  39. if (!returnEmptyIfNotFound)
  40. result = resourceKey;
  41. }
  42. }
  43. return result;
  44. }

 

  1. public virtual string GetResource(string resourceKey)
  2. {
  3. if (_workContext.WorkingLanguage != null)
  4. return GetResource(resourceKey, _workContext.WorkingLanguage.Id);
  5. return "";
  6. }

 

接下来我们来通过一个验证提示信息类BlogPostValidator来看看这个多语言是怎么实现的?

BlogPostValidator.cs:

  1. public class BlogPostValidator : AbstractValidator<BlogPostModel>
  2. {
  3. public BlogPostValidator(ILocalizationService localizationService)
  4. {
  5. RuleFor(x => x.Title)
  6. .NotEmpty()
  7. .WithMessage(localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Fields.Title.Required"));
  8. RuleFor(x => x.Body)
  9. .NotEmpty()
  10. .WithMessage(localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Fields.Body.Required"));
  11. }
  12. }

 

posted @   吾心依旧  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示