Code Monkey home page Code Monkey logo

localizationprovider's Introduction

Quality Gate Status

Supporting LocalizationProvider

If you find this library useful, cup of coffee would be awesome! You can support further development of the library via Paypal.

Localization Provider v8.0 IS OUT!

I'm pleased to announce that Localization Provider v8.0 is finally out. Again - took a bit longer than expected :)

What's new?

  • .NET8 set as default target
  • Added provider model for translations - starting with Azure AI for automatic translations
  • ConfigurationContext now supports config configuration as well (you can change some settings after you have added and configured default settings for localization provider). This is very useful in unit test scenarios when you need to adjust some settings for specific test.
  • Various bug fixes
  • Some performance improvements (resource key comparison, pagination in Admin UI)
  • Security improvements (by default upgrading insecure connections)
  • Dependencies upgrade

More info in this blog post.

What is the LocalizationProvider project?

LocalizationProvider project is ASP.NET Mvc web application localization provider on steroids.

Giving you the main following features:

  • Database-driven localization provider for Asp.Net Mvc applications projects
  • Easy resource registrations via code
  • Supports hierarchical resource organization (with help of child classes)
  • Administration UI for editors to change or add new translations for required languages

Source Code Repos

The whole package of libraries is split into multiple git repos (with submodule linkage in between). Below is list of all related repositories:

Getting Started (.NET)

Working with DbLocalizationProvider Package

Integrating with Optimizely

  • For more information about Optimizely integration - read here

Other Versions

Localization Provider v7.x Released

Please read more in this blog post!

Upgrade to v7.x?

Please read more details in this blog post!

What was new in v6.x?

Please refer to this post to read more about new features in v6.

More Info

localizationprovider's People

Contributors

gatisb avatar kaspars-ozols avatar marisks avatar mattisolsson avatar mend-bolt-for-github[bot] avatar surjitbharath-hiddenfoundry avatar svenrog avatar tholee avatar valdisiljuconoks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

localizationprovider's Issues

Plugin breaks Xforms validation

Xforms validation rules are ignored and forms are submitted regardless of whether it passes or not. Removing the plugin fixes this problem.

Exception when trying to use DbLocalizationProvider in test server

[InvalidOperationException: Collection was modified; enumeration operation may not execute.]
System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +56
System.Collections.Generic.Enumerator.MoveNextRare() +13711134
EPiServer.Framework.Localization.ProviderBasedLocalizationService.LoadString(String[] normalizedKey, String originalKey, CultureInfo culture) +149
EPiServer.Framework.Localization.LocalizationService.TryGetStringByCulture(String originalKey, String[] normalizedKey, CultureInfo culture, String& localizedString) +88
EPiServer.Framework.Localization.LocalizationService.TryGetStringByCulture(String resourceKey, CultureInfo culture, String& localizedString) +103
CustomCore.Framework.EPi.UI.Core.Rendering.Resolutions.DisplayResolutionBase.Translate(String resurceKey) +114
CustomCore.Framework.EPi.UI.Core.Rendering.Resolutions.DisplayResolutionBase..ctor(String name, Int32 width, Int32 height) +64
lambda_method(Closure , IBuildSession , IContext ) +179

[StructureMapBuildException: Error while building type CustomCore.Framework.EPi.UI.Core.Rendering.Resolutions.AndroidVerticalResolution. See the inner exception for details
1.) new AndroidVerticalResolution()
2.) CustomCore.Framework.EPi.UI.Core.Rendering.Resolutions.AndroidVerticalResolution
3.) Instance of CustomCore.Framework.EPi.UI.Core.Rendering.Resolutions.AndroidVerticalResolution
4.) Container.GetInstance(CustomCore.Framework.EPi.UI.Core.Rendering.Resolutions.AndroidVerticalResolution)
]
lambda_method(Closure , IBuildSession , IContext ) +1033
StructureMap.Building.BuildPlan.Build(IBuildSession session, IContext context) +130
StructureMap.SessionCache.GetObject(Type pluginType, Instance instance, ILifecycle lifecycle) +203
StructureMap.SessionCache.GetDefault(Type pluginType, IPipelineGraph pipelineGraph) +171
StructureMap.Container.GetInstance(Type pluginType) +351
EPiServer.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) +55

[ActivationException: Activation error occurred while trying to get instance of type AndroidVerticalResolution, key ""]
EPiServer.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) +156
EPiServer.Initialization.Internal.CmsCoreInitialization.InitializeDisplayOptionsAndResolutions(InitializationEngine context) +751
EPiServer.Initialization.Internal.CmsCoreInitialization.Initialize(InitializationEngine context) +52
EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key) +56
EPiServer.Framework.Initialization.InitializationEngine.InitializeModules() +348

[InitializationException: Initialize action failed for Initialize on class EPiServer.Initialization.Internal.CmsCoreInitialization, EPiServer, Version=9.12.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7]
EPiServer.Framework.Initialization.InitializationEngine.InitializeModules() +886
EPiServer.Framework.Initialization.InitializationEngine.ExecuteTransition(Boolean continueTransitions) +153
EPiServer.Framework.Initialization.InitializationModule.EngineExecute(HostType hostType, Action`1 engineAction) +786
EPiServer.Framework.Initialization.InitializationModule.FrameworkInitialization(HostType hostType) +190
EPiServer.Global..ctor() +84
ASP.global_asax..ctor() +9

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +138
System.Activator.CreateInstance(Type type, Boolean nonPublic) +105
System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark) +1481
System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) +191
System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) +27
System.Web.HttpRuntime.CreateNonPublicInstance(Type type, Object[] args) +82
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +300
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +343

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +579
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +112
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +712

Request: Adding automatic handling for Categories

Right now i manually add it foreach category:
var key = $"/categories/category[@name="{cat.Name}"]/description";

var synchronizer = new ResourceSynchronizer();
synchronizer.RegisterManually(new[] { new ManualResource(key, cat.Name) });

if
DbLocalizationProvider.LocalizationProvider.Current.GetString(key) returns empty.

Add rich WYSIWYG text editor

Localized resources might contain simple HTML markup. One might argue that HTML should not be in resources at all, and message should be formed from separate pieces.
In most cases it would add huge overhead and would not make sense for resource editors as they would loose context of each translation piece and how they fit together.

Example:

[LocalizedResource]
public static class MyResources
{
    public static string StatusMessage => "Inserted <b>{0}</b> records, updated <b>{1}</b> records.";
}

For such cases rich editor might be helpful as for regular resources (without HTML tags) it would render as usual.

Compatibility with Episerver nuget packages above v.10.0.0

The current version of LocalizationProvider doesn't allow Episerver.Cms.Core or Episerver.Cms.UI.Core above 10.0.0. This blocks a lot of other packages from updating. It would be very helpful if you released a version with support for the latest versions of those packages.
Thank you!

Add support to generate page/block type property translations for EPiServer UI automatically

[ContentType(...)]
[LocalizedModel(Prefix = "/contenttypes/startpage/")]
public class StartPage : PageData
{
    [PropertyCaption("This is page header")]
    [PropertyHelp("Please fill in this property for title of the page")]
    public virtual string PageHeader { get; set; }
}

This should generate:

  • /contenttypes/startpage/properties/pageheader/caption = "This is page header"
  • /contenttypes/startpage/properties/pageheader/help = "Please fill in this property for title of the page"

Store default resource value in invariant culture

Could be used in fallback mechanism for built-in localization provider.
Case: during startup preferred culture is set to "no" -> default values for resources are stored in "no" culture. When opening admin interface and set UI culture no "en" -> nothing is translated, user will see resource keys instead of values.

Invariant default culture could be used to store default resource translations coming from code, to provide resource value for the cases when translation is not found in requested culture.

Add localization for plugin

Since this is a localization tool, it would be logical to add translations to the UI components. i.e. UI menus.

Reuse the same resource from other property

[LocalizedResource]
public class MyResources
{
    public static string SharedResource => "This is translation";
}

[LocalizedModel]
class MyViewModel
{
    [UseResource(typeof(MyResources), nameof(MyResources.SharedResource))]
    string MyProperty { get; }
}

Invalid object name 'dbo.LocalizationResources'

When I connect empty database to project with installed DbLocalizationProvider, sometimes I get

[SqlException (0x80131904): Invalid object name 'dbo.LocalizationResources'.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action'1 wrapCloseInAction) +282
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +807
   System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +5055
   System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) +1305
   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) +367
   System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +386
   DbLocalizationProvider.Sync.ResourceSynchronizer.ResetSyncStatus() +200
   DbLocalizationProvider.Sync.ResourceSynchronizer.DiscoverAndRegister() +405
   DbLocalizationProvider.EPiServer.DbLocalizationProviderInitializationModule.DiscoverAndRegister(Object sender, EventArgs eventArgs) +186

It looks like ResetSyncStatus called before EF creates tables in database.

Add possibility to use placeholders in translated texts

Localization becomes messy when there are multiple format arguments passed in. Also, editor has no clue about what type of information will be inserted in indexed placeholder.

[LocalizedResource]
public static class WelcomeResources
{
    public static string HelloMessage => "{0} {1}! You look great today!";
}

@Html.Translate(() => WelcomeResources.HelloMessage, userViewModel.FirstName, userViewModel.LastName);

Would be great if I could use it as follows

[LocalizedResource]
public static class WelcomeResources
{
    public static string HelloMessage => "{FirstName} {LastName}! You look great today!";
}


@Html.Translate(() => WelcomeResources.HelloMessage, new { FirstName = userViewModel.FirstName, LastName = userViewModel.LastName});

or even

@Html.Translate(() => WelcomeResources.HelloMessage, userViewModel);

Add support for class fields

If string property in viewmodel is assigned with "=" instead of getter "=>", property is not registered.

This will not register as resource:

[LocalizedResource]
public class SampleResources
{
    public string MyResource = "this is test";
}

Add support for LoadBalance scenarios

Hello Valdis,

This is great stuff, I have previously used the Localization Provider from Jeroen and it really improved the Editor Experience.
Now that you have created a new alternative, I wanted to give you my two cents of one of the scenarios that sometimes adds complexity:

  • Handling of Load Balanced scenarios, to invalidate cache in web-fronts upon update of translations.

Jeroen solved the issue by adding event handlers to the remote events on EPiServer (since the translations are pages)

In your implementation, it seems like you are using CacheManager, correct?
If so, I can see two options to enable NLB scenarios:

Please let me know if my comments makes sense, and happy to help/further converse :)

Keep up the library creation! It is quite refreshing.

Regards,
. Wacdany

Default translation values defined in code are never updated again

Steps to reproduce:

  1. Add new resource with default translations;
  2. Start web site;
  3. Change default value in code;
  4. Start web site;
  5. Default values stays the same as defined in step 1;

Expected:

Default values should be taken from code, unless editor defines non-default value.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.