Localization in Blazor Server - How To Change Languages and Cultures

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
blazer server is an excellent choice for web application but unless your audience only speaks one language you probably need to consider localization localization is the ability to present an application in the culture of the user this is more than just about translating text different cultures have different currency different ways of representing numbers different date formats and more in this video we're going to apply localization to blazer server app in a way that will present the user with the site in their culture both their language and their layouts it will also give them the option to change the culture of the site now this is the first video if you watched of mine my name is tim corey and it's my goal to make learning c-sharp easier i provide videos twice a week here on youtube to help you grow as a developer i also have a full set of training courses on iamtimcory.com i encourage you to check out all my resources that i have to offer now if you find a gap in the c-sharp training i provide and want to see me cover a specific topic or area please let me know in the comments below i take suggestions very seriously i'll put yours on a list and i don't guarantee i'll cover it but i definitely guarantee that i'll review it and consider it the more people that ask for a topic or upload a suggested topic the more likely it is that i'll cover that topic in a future video or course okay let's jump into the code we're going to start by creating a new project and we're going to say this is a blazer app which you can find down here under blazer app we hit next and let's call this local blazer and we'll call this our culture demo or let's call it localization demo that seems clear we're going to do a blazer server app they have two choices here blazer server or blazer webassembly i've done intro videos on both of these topics so you won't go in depth here if you have more questions i do have intro videos to blazer server and also web assembly and i talk about the differences now we're not going to add authentication we are going to do https we're not going to enable docker support and i am using the template that's version 3.1.10 that's the latest for the release version of visual studio at the time it's recording if yours is later than that cool um i don't think you'll have any problems following along this demo it'd only be if you're trying to use an earlier version an older version where you might have an issue if certain things aren't supported yet but you should be fine let's hit create and once this template is created we've got a number of things that we're i need to do to this now localization works a bit differently in blazer server than it does in the other types of web applications and the reason for that is because it has one foot in blade in server side and one foot in client side now what that means if you're not familiar blaze or server-side applications what they do is they render the application for you on the server and then give the client just html and css and if javascript if there is any that's a a server side language so you write in c sharp but then that c sharp code goes away by the time it hits the user it's already built the web application and just sent them the final results a client-side application is what you'd normally get from an angular react or view application where all the work is done on the client so you send all of your source code down to the client and then run your source code on the client's browser machine or browser that they are working with so that's a client-side application blazer does kind of both it does some rendering a server and then it does some more rendering on the client but you never send your c sharp code to the client so there's there's a bit of both worlds going on here so you have a little more challenge sometimes when you're dealing with localization because the fact that there is that little bit of both worlds blazer web assembly i've covered this in my webassembly course getting the um that's called exploring blazer web assembly by the way um but getting localization to work there was pretty simple it's just add a new package and away you go because you're doing everything on the client but on the server there's some more work to be done so we're to do is we're going to set up a drop down box let's run this real quick so we'll hit the the run button here i just want to show you what the site looks like right now right on the box no changes you know just a bare bones you'll probably see this before if you've done any blazer web assembly i'm sorry blazer server stuff i've zoomed in here notice the zoom right now is on 175 percent so you can see it a lot clearer but this is a standard application what i want to do is i want to put right about here see my cursor is next to the about uh link up here i'm going to put a drop down that allows the user to select which culture they want which language they want and with the language will come the rest of stuff and so we have a drop down there we'll do sample stuff i am not going to translate this entire site nor am i going to pretend that i know a second language and try to put things in that language i don't want to insult the rest of you who are watching who do know two languages and i look at that and go that ain't right um so i'm not gonna try and do that i'm gonna show you it's gonna we're gonna change the wording we're gonna change by hello world uh i believe in spanish that's ola mundo um so we'll use that but we're gonna you know be say this is hello world in spanish this is hello world in um you know whatever and so we'll do it that way we won't necessarily change all the wording but i'll show you how to okay and then when you do actual translations you can do that one tip here um if you can't get someone that knows the language you're translating into the first step is probably google translate it is not perfect do not think that it's perfect but i tell you what getting 80 of the way there is usually better than having zero percent of the way there okay so i still encourage you to find someone that knows the language you're trying to write in because just doing a literal translation of words is not always ideal okay so that's the app we're gonna put that that um download button right next that's about uh in the upper right hand corner and that will translate this we're also gonna put a date time on here just to show what would be the difference so this is going to take a few steps and normally i like to do you know do a step and then show it and then do the next step and show it but there's quite a few steps in here that have to be done kind of in order before anything can be seen so we're gonna go through those i'm gonna walk you through them step by step by step and we'll talk about them as we go but a lot of these are copy and paste so if you want to copy and paste my example which by the way the source code is down in the description there's a link to get the source code for this video now i do want to point out that's going to ask you for your first name and your email address what that will do is going to email you the link to get the i'm sorry email actual file to you of the source code sometimes spam filters catch that and say hey you're emailing a zip file with code in it that's it that's dangerous it's not but if they catch it just check your spam filter if you can't find it email me help it i am tim corey we'll get that to you right away that will put you on the mailing list just so you know you're paying for the file with your email address but as soon as you say unsubscribe you're off the list now just one note real quick here um some people are saying unsubscribe from a list but not from the entire list there's two options there make sure you get unsubscribed for the entire thing if you don't get emails from me all right now if you stay on that list you'll get discounts you'll get um future giveaways those kind of things i try to spam you you'll probably get two to three maybe four emails in a month um so that's just wanna clear that up make sure you're on the same page and you can get the source code if you want it all right so like i said most of this does copy and paste but there is a few steps to do before you can see this in action so step number one right click on dependencies and manage nuget packages we're going to add a new one so under browse and look for microsoft extensions dot localization looking for this nuget package right here right now it's in version 3.1.9 again if it's a later version that's not a pre-release go ahead and use that hit install accept and that's going to help us with a couple of things we're doing with localization next we're going to go into the place that most applications get um get the changes in and that is startup.cs this is kind of the heart of your application configuration if you're wanting to change your application in some fundamental way if you want to add something that's going to apply the whole application or it's going to modify the whole application in some way probably the place you're going to go is startup.cs in the configure services we want to add a couple of services one services dot add controllers notice i didn't add any using statements it's already there what is this well that's actually adding mvc some of you ask well how do i do asp.net core mvc that's a pretty popular.net framework type the mvc is we don't use nbc as much in net core but the cool thing is we can bring in and use parts of mvc without having to have an entire application built on mvc in fact if you use identity from the built-in authorization identity from microsoft then you're using mvc controllers for things like log on log off register and all the rest so we're going to create one controller that's all we're going to do we're going to create that one control so we have to add controllers here and then we're also going to add localization so services dot add localization and we're gonna say options and the arrow not that i'm trying to name this well instead of just saying x but if you tab with intellisense it's going to say oh did you mean like it just did so this is my made up parameter name it's not heart set in stone you know you could say x and that'll work as well but i feel that it's better to say something like options because this is the options for localization and that's a little clearer so options dot so you're not going to use that name so options dodge resource path equals whoops equals resources there we go so what this is going to do is saying we're going to add localization and we're going to put all of if we spell that right wow you're probably yelling at me right now so we're going to put all of our localization stuff in the resources folder which is where well we don't have one so right click on blazer the project and say new folder and say resources and spell it right so everything we're going to do when it comes to translations is going to go in the resources folder now remember i said that that localization is more than about just translating your words so instead of just saying hello world equals ola mundo there's more to it than that but the resources folder is for those translations so that's where that's going to live is the resources folder so he just pointed out and said that's where it lives if you want to change that cool go for it you want to call it culture call it culture that's rename your folder to culture this is just the folder name where you put your stuff so that's the two settings we have in the configure services method of startup.cs next up right after configure service that's fine it doesn't matter where it goes except you have to make sure it's not inside of a method so outside of a method where it creates a let's move my mouse over there private uh not void it's gonna be private um i forget the type let's just say void for now this is a cheat here if you don't know the return type make a void to start with then figure out your return type is and change the return type so private void let's call this git localization options and what this will be is a helper method that we use in just a minute so we're going to fill this in with some helper stuff so var cultures equals configuration now where'd configuration come from well that comes from right here which is passed in into startup right here what is configuration remember our eye configuration if you watch the video i believe it's called intro to app settings where i talk about app settings and about uh talking to this app settings.json file among a number of other places we used the configuration and we said that that gets built in this create default builder notice if you mouse over it says load host i configuration and all the different setups well we're passing that into startup so that the startup stuff can use that configuration to access the apps.json file or other settings locations so i'm going to say get section and that section's gonna be cultures we don't have one of those yet but we're going to and i'm going to say do on new lines we don't make it too big we can also make this a little smaller but we're going to say dot get children to dictionary of and i will say in here x arrow x dot key x arrow x dot value what am i doing here well i'm loading the section called cultures i don't have those yet well let's create one real quick so i can illustrate this as we go cultures okay so it's gonna add it's gonna add this section so get section cultures cool then it says get children well right now there's not any children in here there will be just a minute and it says okay in those children send them to dictionary where there's a key and there's a value so that's the two things you're going to pass in to our dictionary now what are key and value we know what key and well you may know what key and value are when it comes to dictionary a dictionary has uh two pieces of information it has the key which is the thing you look it up by and the value so for example think of an actual dictionary where if you want to look up a definition you would look up its key that's the word and then when you found that key they would give you a value that's the definition so that's what a dictionary is in c sharp it's a key the value you can only have every key is unique you can't have the same key more than once now you can have multiple values like the same value more than once that's fine but each key has to be unique but in our case this x dot key is saying that's actually a key from the configuration section so you go over to abstains.json let's look at log level as an example this is the key this is the value which sounds an awful lot like a dictionary which is why we're sending the children to a dictionary so this culture will be a dictionary of type string string and the the key will be the app settings.json key and the value will be the app settings.json value so in our cultures we're going to have en us and we'll say usa and then we'll have es-es and we'll say spain and we'll have es dash mx and we'll say mexico now these are three cultures these are actually um predetermined uh culture references so it says the language and then the culture so language is english the culture is u.s the language is spanish yes and the culture is spain the language is spanish but the culture is mexico so these allow us to have the same language but different you see what i'm saying so um both uh people in in england and the us both speak english um you know people in great britain may debate that but um we have we say things differently we do things a little differently and so that's why we have different cultures so the same thing with with spanish spanish spoken across a lot of the world a big portion of the world at least and there's different cultures around that so we're gonna grab this three here just these are just examples um but these are pre-locked in now this over here is just my country description so this is a rough cut of saying okay this is this is from spain this is from mexico this is the u.s there can be some differentiation differentiators in there these are not standard names we're gonna use this in our drop down to say hey select the usa culture versus the you know um the great britain culture or the uk culture or um the spain culture or mexico or whatever so that's the key and the value so key in value that goes in the dictionary that's now our list of cultures supported cultures equals cultures dot keys to array now why i do it this way well i probably could have made it one link statement up here but i want to be kind of clear as what's happening here so i put in a dictionary first and then i broke apart and said just give me the keys that's all i care about now you can use this line right here anywhere in your code as long as you have access to configuration which you should have it everywhere so we can reuse this line other places and that's why i kind of broke it apart like that but in our case we just care about the keys which if we remember that's just the standard way of identifying the language and culture so we have just those keys now in this supported cultures list we're going to say var let's scroll up a little bit so you can see a little better var localization options equals new request localization options i'll go in next line but i'm still continuing notice there's no semicolon here and say dot and supported cultures or i say supported cultures so saying hey add these supported cultures which cultures well this one this one and this one but then we're also going to say add supported ui cultures or say support cultures there as well now what's the difference between supported cultures and supported ui cultures great question i'm glad you asked it supported cultures is all about the date formats i'm sorry not date4 data formats for example date is a big one so in the u.s we say month slash day slash year so if you're um talking about let's give an example february 12th of 2021 you would say 2 12 21. let's write it down so 2 12 21 that would be in the u.s february 12 2021 however in other cultures they read day month year and to be honest i think this makes a whole lot more sense as day month year but the us has always done things a little differently um we also have the imperial system instead of metric which is just again horrible but i can't change that so that would mean that this would be december 2nd of 2021 it's important to know what culture you're dealing with because otherwise if you display a date like this two different people will have two radically different views on what that date means unless it's in the culture that applies to them that's why we have supported cultures that takes care of that the same thing with certain cultures when they write out a number might say here's what the us will do one comma two three four dot five six that would be one thousand two hundred and thirty four uh let's say dollars and fifty six cents whereas other cultures might say and for those of you who deal more in one culture you already know us i'm preaching the choir i understand but for a u.s audience we probably don't so i might say 1.234 comma 5 same number different culture the dots and the commas are flipped so it's important to make sure you change the culture but there's also the idea of it says hello world and i want to say hola mundo well that's where the supported ui cultures comes in that will be your resource files that are in the resource resources folder or whatever you named it that's the translation files we want to change both of these at the same time so we're going to make sure that when we change one way change them both and that that allows us to have the best easiest clearest representation of both our data and our our language or our words so that's the localization options and so we're going to return localization options which localization options is a request localization options see guys change my void to request localization options now it's happy with me we're good to go so now i can just instead of doing all this code somewhere inside of i believe it's configure we're going to just call just this instead all right so let's save this and let's come down here in the configure method under use static files the ordering here can be important so make sure you put it in the same place i do you probably won't have a problem if you move a little bit but let's keep it below static files and above routing so that's what we're gonna do so we're gonna say app dot use request localization and for the value for this the actual configuration where i say get localization options so you see this whole method up here that's going to get returned and put in as options for the use request localization field so that's what i do in the configure and then one last thing in here under use end points we're going to say at the top endpoints dot where i say map controllers again we're using mvc so we have to map the controllers in our our different endpoints we we know how to go to certain paths that are on our controllers so that's what i do there that's going to take care of the last little bit of mvc setup work we have to do that also takes care of everything we do in startup dot cs and in app settings.json so we're done with both of those files which means i think it's time to add our controller our one controller we're gonna add so right click on local blazer and say add folder first and we'll say controllers now again i'm mixing in mvc to a blazer server project that's the beauty of asp.net core because we don't have to lock ourselves into one type if we find there's a benefit to using a razor page somewhere cool go ahead and use it if you want to use a little bit of mvc somewhere else cool go ahead and use it and that's we're gonna do here so under controllers we're gonna keep the same convention that mvc has we're gonna say add controller an mvc controller empty and let's call this the culture controller so in here right above the class but inside the namespace we're going to say route and we'll give it the route which is controller inside square brackets slash action so that specifies hey here's the path to this which is the controller name which is culture slash the action name which in our case is not gonna be indexed we're gonna change this to set culture so say where i say our our url slash culture slash set culture and we're not gonna return a view okay so in here we're going to set the culture but we're going to pass in a couple of things string culture and also string redirect uri make sure i spell that right redirect yep i did if culture is not equal to null i mean if you pass in a value to culture then we're going to say httpcontext.response.cookies yes we're going to set a cookie append and i'll actually do a separate line here for this we're going to say cookie request culture provider dot default cookie name cookie request culture provider dot make cookie value i'm getting hungry now new request culture culture and then at the very bottom here outside the if return local redirect i'm going to explain this in just a minute redirect uri so what this is doing is saying when you call the set culture what i want you to do is if there's a culture being passed in go ahead and set that as the culture for this user this will be very helpful in fact that's what we're going to use when we have that drop down so remember we said that next the about link where i have this drop down it's like set set my culture i'm going to say usa or ken or spain or mexico that's our three options and we're going to choose one and then it's going to change the culture of our browser including the language and the those data formats well this is how it's going to do it it's going to set a cookie on the user's side that says hey you want this site in you know spain culture and it's going to set that information we're going to look at that cooking the browser and see what it does now sometimes people get a little concerned about cookies especially since there's some rulings especially in europe that talk about cookies and what you can can't do with it asp.core is great about cookies there's even a built-in um warning about cookies about what they're used for and this is not one of those bad cookies this is not a tracking cookie instead what it is is a little piece of data on the user side saving their preference that's all it is and so we'll see what that is we'll see how small it is we'll see what it does and we'll even see how to delete it if you want to to reset it back to default so if they set the value we're going to store on their side so they can see it in the the culture they want and then either way we're gonna we're going to redirect to whatever um page they were on when they set this culture now we're using a local redirect this is another way that asp.net core is superior to even asp.net because we have a concept of local redirect and this is taking security to the next level what it does it says we're going to do a redirect but the problem is you're passing in what you want me to redirect to and if we were smart we had some malware we wrote something like that we could inject our own url here our uri um and we could say hey when you're done authentication where we're done saying your culture i want you to go to um you know timquariuscool.com instead of the site you were on and maybe even i make it look like the site you were on so you think you're still on that same site but in fact you're on my site instead local redirect says we'll go ahead and redirect you but only if the url is on the same site we're on right now that's what local redirect is so you can't redirect to google from here you have to redirect to the same root url that you're on right now so if you're on imtimcory.com you can't redirect to timquariuscool.com no matter how much you try because local redirect will not allow you that's a really great safety feature so really simple just local redirect good to go it will redirect you safely so that's our our our whole controller that's everything that's one method all we're gonna do so let's close that out now and now we're gonna create in the shared folder we're almost done we're creating a shared folder a new razer component now again razer components if you've watched my intro to blazer server razer components are just blazer objects they're called razor components so we're going to call this the choose language a hard time spelling today and this is going to be our drop down so we're going to get rid of the h3 tell you the top and we're going to say we have a couple of injections at inject this is from dependency injection so this is the same as asking for from your constructor if it's a c-sharp class navigation manager we'll call this just navigation manager and then inject and this one i don't think we'll have a say i configuration yep doesn't have the using statement in our um our imports call it configuration and i don't like to have these massive things here so let's cut this out it's going to yell at me first because i don't have the using statement i go to imports at using and there we go now it's available to every blazer component so that has made it simpler for me by putting in imports.razer all right now what i do is in the code section i'm going to say private string selected wow hard times huh selected culture equals system dot threading dot thread dot current thread dot current ui culture that name actually let's grab current culture not current ui culture there we go we have the current culture from the the thread we're on so if it doesn't know let's have a default here a default culture that's what that's doing for our selected culture private dictionary of type string string sound familiar cultures well i'm going to have a protected override on the on initialized and that always messes up the um the tabbing so highlight the whole thing and hit shift tab it brings it back once you don't need base dot on initialize but this method is going to get called after we set up all of our injections up here so we can call this and say cultures equals configuration dot get section cultures self layer next line dot get children to dictionary in fact he could have copied and pasted this x dot key comma x arrow x dot value so that's the same line we had earlier i could have copy and paste like i said but that will put that into this dictionary that's the list of all of our cultures but notice we're grabbing the keys and the values and keeping them because now we're gonna have this drop down that will show us all of the available options to us now i haven't mentioned it yet but note that i selected three kind of at random kind of just hey let's grab you know a couple to show off a couple of things but you could put anyone in here and if you add more cultures as long as the the code is correct that you put in then it will add to this application you don't have to change any code in order to get that to work just keep adding uh items or changing you're removing some and your code will continue to work so this is going to populate the drop down based upon the apps.json file and everything else so the only thing to change is just that that settings file okay so now we have our cultures loaded i need to have one unchanged method so private void on change um let's call it unchanged and this is going to get called when we whenever we change the um actually not unchanged let's let's call it request culture change how about that it's clear so whenever the user says i want to change my cultures there i call this method where i say var culture equals selected culture actually we only need to do that line i had originally thought i was going to break that apart and um do something else with it but we're going to grab this selected culture so whatever has been selected it's going to be in this value so let's use that so var uri equals new uri navigation manager that's where we brought that in are you using our inject statement navigationmanager.uri dot get let's put this in the new line because it's gonna be long get components uri components dot path and query uri format unescaped so what it's going to do is get the current uri now we often say url for uniform resource locator uri is slightly different it's uniform resource identifier so this is essentially that thing you find at the top of your browser it's going to have the full path for where you want to go what's going to grab that and it says get the path and the query meaning if there's any query parameters on your um your browser url the path um it's gonna grab those as well and it's gonna not escape them it's gonna say if a special character is there don't escape them what that does is we're just not going to do it twice we're going to grab it once and then we'll escape it later but that way we don't do it twice because we don't need to so next we're going to say var query equals and then we're going to start with our string interpolation which is our dollar sign first now we can stick stuff in the middle of our string and say uh question mark culture equals curly brace open and close it it's easier uri dot escape data string selected culture okay so escape that data stream make sure you don't put any sensor or you know non um that won't work on the url where i put that escaped into our path as culture and then after that we're going to say ampersand and then let's let's add this to a second line because otherwise we're going to again go too long and again we're going to do string interpolation you have to do it again if you say the plus here um this plus here you don't have to have it you can keep going but then it makes it one long line and i like to have it in readable format so you can see it the whole thing on your screen so redirect uri make sure you spell these things right equals open close your curly braces uri dot escape data string uri that's where the escape is gonna come in so we don't have to escape it here if we're gonna escape it down here which we're already gonna do and we're gonna put that into our redirect so we're gonna do is take our current uh path and then we're going to pass in both our culture and our place to go back to so with both of those being done now we can say navigation manager dot navigate to slash culture slash set culture sound from there that's our one mvc controller plus query what's that that's what it is built right here so i put this question mark culture ampersand redirect uri and it's gonna put that at the end of our um in this case relative url which is gonna expand into a full url and then after query you're going to say force re force load colon true what that does make sure you force the loading of this page to after we navigate to it we're going to change our culture so it's going to navigate to the right spot and it's going to apply our culture and it's kind of look like magic but we know what it's doing now it's just saying that when you select that go ahead and navigate to that location which is our mvc controller and once you've done the work of applying which our controller it says okay create that cookie with the new culture and then redirect to the url you give us well that url will be the um this right here the redirect uri and it's going to pass us back to where you were but with the new translations so that's all the code for this page but we don't have a drop down yet let's go back up here under inject before code and say at if cultures is not equal to no notice that cultures right here starts off as not being assigned therefore it's null but as soon as we get the uninitialized we're going to configure it if i didn't do this then what would happen is since i want to loop through the the list of cultures if the culture's list was null then it would crash but since i'm doing a check first for null it won't render this intersection unless there's a value here once the value is here they'll go ahead and render it i'm going to say form class equals form dash inline there's a little bit of bootstrap stuff i'm going to do just make it look a little prettier select class equals form control and mr-2 whoops that goes inside the class mr mr-2 and we're also going to bind this bind equals selected culture okay so let's explain what i'm doing here um and why i'm doing like these classes here this is bootstrap 4. so in asp.net core we're using bootstrap as the default layout provider for our application that's what comes out of the box from microsoft no you don't have to use it however bootstrap is pretty common and it does a lot of great stuff and it's not very heavy on the overhead i see people often that really push back against using it because they think that somehow it's massive and bloated and all kind of stuff it's not you can use it they fine if you don't want to use it though that's fine the microsoft templates will all use it so you'll have to redo their layouts but you don't have to use it but this is saying apply the form inline to this form apply some styles to this form and then this select which i selected the drop down it's gonna apply the form control which is gonna make it uh be a bit bigger and the font be a little bit bigger and it just looks a little nicer than the standard blah select box would be from html mr2 that's saying the margin on the right i want to be the standard 2 width not 2 pixels not 2 em that's there's a setting from one two i believe it's five or six uh in fact we can find out real quick here if i said mr dash it's six so zero through five um so these are different margins on the right that you can apply with just a class so instead of doing um inline styles you can just say hey apply this class it's going to apply the standard margin the nice thing there is that if you use that then all your margins are standard and say you're saying oh well this one's two pixels this one's four pixels this one's eight pixels they're all standard and they're standardized on one of these six different sizes which you can again set what those would be there's also margin for left there's also um padding you know p r and p l for padding right and padding left this isn't a bootstrap class but i wanted to at least touch on that so we're going to bind this select the value is going to be bound to selected culture that starts off with a default of the current culture which is a string but then if we change it it's going to be whatever is selected now where i have an option which is select and they're going to have an ad for each let's say for age culture in cultures and we'll say in here option value equals at culture dot key and then inside of the the option itself or essay at culture dot value this is taking our oops capital k here this is taking our dictionary that's the dictionary right there the cultures which is our list of you know the um let's open up here this is our key this is our value so we're going to show the value so let's say usa spain or mexico and the key is going to be that en-us or e-s-e-s or e-s-m-x so the value is what gets put into this selected culture so the selected culture will say en-us or e-s-e-s and so on that's how we're going to do this select then afterwards i didn't want i toyed around the idea of having it automatically change the culture as soon as you change the drop down but i was finding that wasn't ideal so instead i create a button class again this is going to bootstrap stuff class equals btn for button then btn-outline dash uh primary and then at on click equals on no not on change we change it to request culture change let's call it change so this button now when you click it it's going to call the request culture change which will look at the selected culture that you selected from the drop down and then it's going to navigate appropriately now i don't have a check in here for well if it's an empty string i probably could um if selected culture actually let's just do this string is null or white space on selected culture return basically don't do anything so that was make sure that you don't select the option here had that you know that just a select dot dot as your selected value now we should never have this probably because the fact that we're going to highlight the current culture that's currently selected all right but that's that's it for that razer component which is a blazer component so now we're going to do is in our main layout.razer so this is where the the about link is right above this we're going to say span class equals pr-2 what is it stand for stands for padding right um of two we're gonna say site language so we're gonna have padding of right which means where i have a little bit of space on the right and then we'll say choose language and have a self-closing tag what is that tag well that's our component we just created in the shared folder choose language that's this thing we just worked on so we can use it now as a component and throw that on this um navigation or this spot up here at the very top which is right next to the about link now i want to show this to you um just you see it but you can't actually use it quite yet but that will at least see it um so you know what you're looking at so we load this up and now notice site language says usa that's what we detected as my current culture and we can select hey spain or mexico and hit change if we want to but again nothing will happen at this point if i were to choose spain nothing seems to happen so it did set that cookie and in fact let's go f12 here and if we go to our i believe it's application there we go under application f12 is your friend in the browser i mean just use f12 all the time it's the developer tools so if f12 doesn't work for you if you go to those triple ellipsis or this lifts this up here as three dots whatever it is and you look for more tools developer tools um see it says control shift uh is it an l or an i i'm not sure which um but f12 works for me for windows it may or may not work for you but just finally developer tools so more tools developer tools most bra all browsers have this um maybe be called a little bit different but it's usually developer tools so under this is chrome so under the application tab we have a number of things we have cookies expand this out you'll see i have a cookie for this site and in fact let's make it a little bit bigger so this is the asp.net core culture cookie if you notice the value it's right here in fact let's see if we can zoom in hey we can this right here is the entirety of the value of that cookie so that cookie is minuscule we're not taking up the user's storage space with this it's a few bytes not even kilobytes and it says c percent 3 d which i believe is equals so culture equals that's escaped character from html so culture equals en us and then we have percent seven c uh is that semicolon i'm not positive um but then we have uic or uh call ui ui culture again equals en us so it shows the culture and the ui culture that's set in the cookie that's what gets remembered from use to use so let's zoom back out here a little bit um i'm not even sure what the default was anymore i'll zoom in a little bit more but yeah size is 42 i believe it's in bytes we can do if you want to is you can right click and say clear and then that now you have no more cookie here or no more value for this cookie but the site so there's no cookies for this site anymore and we've reset it back to defaults so if you ever had a problem with you know testing something out you had a cookie that's you want to get reset that's how you do it under application tab okay close that out we'll close this out as well and we have a couple more things to do in here and then we're done one thing we have to do is add resource files so let's do that right click on resources and say add new item and search for resource let me get resource file it's got a dot resix extension we're going to name this app now the naming here is important i'm going to show you why in just a minute but name yours app dot resize this casing so capital a lowercase p name it like this it just is going to make it the simplest hit add now this is your your default file you don't have to have this default file if you don't want you don't have to put stuff in this default file if you want we're going to talk about how to kind of bypass the need for default file by how we name our keys so just note that you don't have to have this file but if you want to have this file now you can modify the name and the value so it's key value pair the comments is just for you so what i did when i used to use these resource files i worked at a company where we had i think four different languages we used arabic spanish french and english what i would do is i would create the default file in english because that's where our primary customer base was but i would create all the entries even though i didn't have to i'd cram in here and then put in the comments what that value is for then copy the file and create let's say the french version i would clear out the values but i'd keep the comments in english because that's for me so that the name and the comment help me understand what each piece is and the value is whatever uh translation whatever language that file is for so that's how i would do things just to make my life a little easier so in our case we're gonna create one hello world and the value is hello world sure it's called let's hit enter call it good and save that file so now we have the the key and the value and it seems pretty useless at this point i'm translating hello world into hello world but let's right click on resources and add another file so new item we're still on resource but if not you can type resource in the search box and again name is important here app dot e s dot resix and es is lower case so here is the hello world that's the same tag but in this case we're gonna say hola mundo i think i got that right let me know in the comments below if i did or not but that's going to be our spanish version in fact let's do this because again i want to show off this with that what happens not necessarily that the translation is correct because i'm again horrible at other languages so that's our spanish translation let's create one more so right click and say add new item again resource file has been selected already and this one we're going to call again name is important app dot e s dash m x all lower case there we go we're gonna say hello world let's say hola mundo i believe it's the same i believe the same for um you know mexico spanish versus or mexican spanish sorry uh versus uh spain spanish let's say um mexico version something like that and we're gonna hit save so now we know we have you know spanish and we have for mexico specific so let's save all of these and now let's close all of these so we have just that one translation all we've got now let's go to our main page so index.razer we've got hello world here i have the exclamation point oh well um we're going to say instead let's inject first add inject i string localizer which that is actually from microsoft.extensions.localization.i string logos a localizer we'll change it just a minute and we'll call and say of type app localizer so let's first move this over i'll cut this out and we'll go over to our imports.razer using and put there now we don't have to put it here you could put a user statement right here so you could say at using and paste it in there but the reason i do it that that file is because i'm expecting to use the i string localizer a lot therefore i put it in the imports instead so i said i string localizer which if you've done localization in other asp.net core like mvc or razer pages there's istring localizers i html localizer and a couple others with blazer server we can only use i string localizer at this time not a big deal but that's where i use and then we have to give it a type and so we're saying the type is app well app refers to this whole application it's a keyword it's called you know blazerapp.app if you look in the uh program you'll see that is it program we're gonna start up that it references app um so i'm gonna look for it now i don't want too much time but that's refers to this particular project that's standard across all projects it's called app you can if you want create localization files per uh grouping so for example you could say i want a localization file just for the index.razer page and so you could create a subfolder under resources for pages and then one for index and you can say in here you could pass in index instead and find that file name to find the index file we called everything app we're going to use everything under the app file but of course if you have a massive application you wouldn't want one resource file because that would just be hideously huge so instead you'd create one maybe per file or maybe per section or something like that but this has to refer to um an actual type in your application so just so you know that a little more depth we need to get into in this video but i want to point that out you don't have to just use app you can be more specific and then dial things in a little bit more all right so localizer we're right in here instead of saying hello world we're going to say is at localizer and then in here we'll say in square brackets hello world look familiar well that's the key we're saying localize here's the key go find the value based upon the current culture now if you don't have anything in your app.resist file like i don't um i thought that's interesting i think something happened here um but i have the spanish version hello world and this is the from mexico version let's save that these are a little touchy sometimes it's still there though and i don't have anything in the app.resistance let's leave it like that for now but i want to show off the fact that since it doesn't find it in the culture i'm currently in it's going to default back to the to the default if there is one in app.resist and if there isn't one in here it's going to default back to the actual key so if you name the key the actual value it should be in your primary language then you don't have to have these resource files yet you can go around saying localizer this key it's not going to find it it's going to fall back to the actual value you have inside quotes but then you're ready to create localization files so there's that let's also do one more tag let's do an h2 tag right below and we'll say at date time let's say datetime.now and twos are too long let's just say daytime now that should be everything we need to have a full date and time we could format if you want to uh you know what let's do two um two too short date short date string and then we'll say i know doing a lot of h2 tags here but we'll say at date time dot now dot to long date string so we can see both in there um oops their methods you gotta put your open close parens again so you can see that the valuable the short date string remember i said that uh we're uh flip those around based on the culture and then also the long date string will say you know uh january and it's of course we don't say january in spanish you say i'm not sure uh we're often what october is because that's what we're currently in so that's that's our setup let's run this again and once it starts we now have hello world we have 10 26 2020 and it's monday october 26 2020 and let's change the value from usa to spain hola mundo in spanish notice it's now 2610 and lunas and 26 day octubre day 2020 how horrible is my present pronunciation but there you go there is spain spanish if we change to mexico this hasn't changed but now it says hola mundo from mexico it's pulling from a different file now both spain and mexico speak spanish so how is that we have different translations up here well if we look we created a an app.es.resix file and that is just a spanish file but then we have an app.ese file this is the more specific file for mexico so we have a a default spanish file but then if we have more specific things we can put it in the the mexico version of spanish so we don't have to put everything in here if most of stuff's the same but if there's certain things that you might say differently in mexico than you would in spain then you could put those in the translation so it's going to fall back kind of like our app settings it's going to go most specific to least specific so now first look and say okay i've got a culture of es dash mx and it's gonna look and say oh i've got an es dash nx file let's go find the um the key in that file if it doesn't find it in that file it's gonna fall back to the es file just the first two letters if it doesn't find it there it's gonna fall back to just the app file if it doesn't file there it's going to use the key value as the actual value on the page now for we never even create an es es-es file so everything's falling back just to the es file so that's how that works but now if we run this app again you'll notice that i changed the the location and it still knows that it still thinks i'm in mexico therefore it still says hola mundo because i've got that cookie installed that says hey this is what you're looking for therefore we um we see that value so we can change the value notice it stays on this page but yet and nothing seemed to happen because we didn't do any kind of change here but if i change the us on here go back to home notice it's now in the usa format so it remembered how to redirect us back to the right page and does do a redirect because of blazer server but now we can change cultures based upon this drop down here and again if we assign you know what i want to support um a different culture let's say i want to support french so all you do for this entire application is two things one go to app settings.json put a comma here and say fr dash f r so it's the fringe from france hit save now if i didn't do anything else i could run this and the application would now ask me what language i could or what culture and france is one of the options if i get changed nothing seems to happen except notice it now says lundy 26 october and it flips these around but it still says hello world because it's fallen back to the defaults because i never specified a resource file so i right click i say add new item resource file and we're going to say we're going to do a generic french so app.fr.resex and hello world it will say hello from france or french version so i do not know french um so there's our our french it didn't say that we have to do is hit enter afterwards because enter hit enter after you've filled the value in and then hit save so if we run this now and we change well now it says hello french version because it found that resource file so those are the two things you have to do to add a a culture to your application now once you've added all the setup stuff that we've done i would encourage you go back and watch this video a couple times create some test projects but change your app settings to add that value whatever it is and then add the resource file with your translations done that's it you now can translate your entire application that way now there's a lot of work to do here because it's not like some kind of magic pill you can put in where all of a sudden all the wording is translated you notice that i just have hello world translated not welcome to your new app and not the survey prompt and not the counter page and not and there's a lot of stuff in this little app to translate yep there is and that is going to take some work but step one might be simply to just say at localizer and put the and wrap the value so you can say at localizer and then wrap this value done now what i've done is i haven't done any translation on this but what i could do and this is what i typically do i would come over to app and first i'd have hello world and then have and put in here the same value and then i'd put the um the next string welcome to your app i'd paste that value in again and enter so now i have a record of my defaults so let's make sure that's still there it is so what i have to recommend at false i just keep going i don't do anything else but when it's time to create translations i can hand somebody this file and just make a copy of it rename it to app.fr.resix and say just change just the values everything else will be set up and then go through and say okay hello worlds actually and then fill it in and so on and then it's going to change your entire application because you've already set it up for success so there's some work to be done to set up localization but once you get it set up it's really quick to work with so i encourage you to think this through with your application when you're building an application think of who you're reaching and who you can additionally reach if you were to meet them in their culture if you were to present things in a way that makes sense to them for example you know whenever you put date on a website if you're in the u.s it makes total sense to create us date format but in the rest of the world pretty much it seems like they look at and go huh because you know a month of 13 doesn't make sense or a month of 30 doesn't make sense and it's even worse like i said when it's february 12th because it makes sense it's october 2nd or i'm sorry december 2nd and that that's a confusion you don't want to add and so if you can present your application your website in the cultures where people are using it not just your own and the way i do that is like i showed right here once you set it up it's just a couple of setting tweaks and you're all set up for a new culture you can add them fairly quickly with that i think that's all the topic i want to cover in this video that's quite quite a lot i know but hopefully you got a lot of value out of this you can see how to make your web applications even better now there's a different way of doing this for blazer web assembly is actually a little easier and i like i said i showed it off in the exploring blazer course exploring blazer web assembly but you know try this out in blazer server try out see how it works for you see how easy it is to get started once you get through the initial setup again copy and paste my code for the most part it's just boilerplate once you've done that you can even create your own template that just starts with localization already in make your life even easier i have a video on how to create your own template as well thanks for listening if you have any more suggestions for topics to cover in c-sharp leave them down in the comments below if you have thoughts in this video leave those down in the comments below i appreciate your feedback i appreciate your encouragement i appreciate you suggesting new topics because it's because of those kind of things that i keep this channel going and i keep um doing things to help you as a developer become a better c-sharp developer easier thanks for listening as always i am tim corey you
Info
Channel: IAmTimCorey
Views: 15,426
Rating: undefined out of 5
Keywords: .net, C#, Visual Studio, code, programming, tutorial, training, how to, tim corey, C# training, C# tutorial, asp.net, .net core, localization in blazor server, localization in blazor, localization in asp.net core, localization in asp.net core 3.1, globalization and localization in asp.net core, globalization and localization in asp.net core mvc, c# translate, c# translate text, c# translate language, globalization and localization
Id: h82U0RQ9jtQ
Channel Id: undefined
Length: 80min 15sec (4815 seconds)
Published: Mon Oct 26 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.