#nuxtjs/i18n redirect to the available translations - internationalization

I have 3 languages on my website but not all the pages support all that three languages.
Problem: a user visits my website and from the URL he changes the prefix to a language that the page does not have a translation to, the page will load with the key's names so the page content will look something like this: mypage_header etc...
What I tried :
1- according to nuxt/i18n docs there is an option to set the available languages on every page but the thing is: if the language is not available the user will be redirected to the 404 page, I want to change that, so he gets redirected to the available translation of that page.
2- There is an option called Locale fallback
Summary: Use fallbackLocale: '' to choose which language to use
when your preferred language lacks a translation
This worked with the problem that it changes to an existed language but the direction remains the same, so if I have an English translation for a page and the user changed the route to the Arabic version, the direction will not change from ltr to rtl .
Example:
If the page has English language and the user changes the URL from /en to /fr
I want the user to get redirected to the English version of that page since it is the only available language for this page.
How can I achieve such a thing?
nuxt.config.js
i18n: {
locales: [
{ code: "en", iso: "en", file: "en.js", dir: "ltr" },
{ code: "ar", iso: "ar", file: "ar.js", dir: "rtl" },
{ code: "fr", iso: "fr", file: "fr.js", dir: "ltr" },
],
lazy: true,
baseUrl: "https://example.com",
defaultLocale: "ar",
strategy: "prefix_and_default",
langDir: "~/lang/",
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root', // recommended
},
}

The Locale fallback was the right solution, it was my mistake, in the translation files which are en.js, fr.js, and ar.js : I was putting my translations in mixed formats: JSON and JS object formats rather than putting it in either JSON only or JS object only,
changing all the translations format to JS object only, fixed the problem for me.

Related

How to add custom route for user

I have created a books content type containg books. Each book in the collection belongs to a user (user content type provided by Strapi).
I want to return list of books owned by authenticated user at /users/me/books endpoint. Where can I add this route and handler as there is /api/books directory containing books related route, controllers, etc. but not /api/users directory.
You can extend or override using the extensions system.
extensions/users-permissions/controllers
Just add the controller you want to extend or override as a .js file like so:
So to override the me endpoint under User.js you only need to define the method again:
'use strict';
module.exports = {
//Override me
async me(ctx) {
//do your thing
}
};
To extend, not override, means to add another endpoint, therefor you need to define it, add a route and set permissions for it. The routes.js files should be created at:
extensions/users-permissions/config/routes.json
Like so:
{
"routes": [
{
"method": "GET",
"path": "/users/me/books",
"handler": "User.getUserBooks",
"config": {
"policies": [],
"prefix": "",
"description": "description",
"tag": {
"plugin": "users-permissions",
"name": "User",
"actionType": "find"
}
}
}
}
The controller this time (same location as in beginning):
module.exports = {
async getUserBooks(ctx) {
//add logic
}
}
OP correctly added:
After adding custom route and controller, one has to go to Admin Panel(log in as admin)>Roles and Permission> Users-Permission. There you can find the newly added route and have to enable it by checking it.
The originals(if you need examples) are located at:
/node_modules/strapi-plugin-users-permissions/config/routes.json
/node_modules/strapi-plugin-users-permissions/controllers/User.js
I don't think you should extend the User controller as it isn't logically correct. You are trying to GET books - you should extend the book api in the same way.
From what I can tell a ContentType doesn't contain information about its creator(you're welcome to educate me if it's not true).
So to tackle that you can add to your ContentType "books" a relation to User.
Then I think you should extend the books api with a endpoint that returns books "belonging" to that user using the ctx received.
Also - check this question out
Comment if you need more info.

Retaining File names when using Fine Uploader

I'm trying to implement the Fine Uploader for the first time and have a question. I've got the uploader pushing files to my S3 bucket. The issue I have is the file is being renamed to some sort of string.
Here's an example: 4f65aefe-c55b-42b0-afd4-b749c755e7e8.zip
I'd like to keep the original file name if possible. Is that possible?
Here is the script on the page with my current set of params:
var uploader = new qq.s3.FineUploader({
element: document.getElementById("fineUploader"),
request: {
endpoint: "mybucket.amazonaws.com",
accessKey: "ABCDEFGHIJKLMNOP"
},
signature: {
endpoint: "/wp-content/themes/zone/vendor/fineuploader/php-s3-server/endpoint.php"
},
iframeSupport: {
localBlankPagePath: "/wp-content/themes/zone/success.html"
},
cors: {
expected: true
},
chunking: {
enabled: true
},
resume: {
enabled: true
},
});
Am I missing something? Thanks in advance.
Yes, this is expected. By default, Fine Uploader S3 will use a UUID to name your object when sending it to an S3 bucket. In almost all cases, this is the safest behavior. If you change this value, you run the risk of overwriting existing files with new ones in the event of a name collision. The object is annotated with the original file name attached to an "x-amz-meta-qqfilename" header.
If you must save the object in S3 using a different name, you can modify the objectProperties.key option appropriately. A value of "filename" will save the object using the original filename. You can also set the value to a function where you can determine the name on-demand, even using values from some other location, provided your key function returns a Promise. Read more about this option at http://docs.fineuploader.com/api/options-s3.html#objectProperties.key.

CKEditor Turn Off Advanced Content Filter

I'm having difficulty deactivating the Advanced Content Filter (config.allowedContent = true; dosen't seem to work). I've tried everything that I've read on the forums, including clearing the cache, and making it an external file.
CKEditor 4.2.2 - allowedContent = true is not working
I've even added config.protectedSource.push lines, and they work to a point. The CKEditor still adds div tags and partially deletes other tags.
I'm creating a set of well designed templates for clients to use, so In the end I don't want CKEditor to touch my code at all. Here is what I have in the config.js. If anyone can see something I did wrong, or knows of a way to make it work, please help this somewhat stressed web guy.
Thanks,
Rusty
CKEDITOR.editorConfig = function( config ) {
config.toolbarGroups = [
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'insert' },
{ name: 'links' },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'tools' },
{ name: 'about' }
];
// Define changes to default configuration here. For example:
// config.uiColor = '#AADC6E';
// misc options
config.allowedContent = true; // allowedContent doesn't work :-(
// Protected Source
config.protectedSource.push(/<section>[\s\S]*?<\/section>/gi); // allow <section></section>
config.protectedSource.push(/<span>[\s\S]*?<\/span>/gi); // allow <span></span>
config.protectedSource.push( /<link[\s\S]*?\>/g ); // allow <link> tag
config.protectedSource.push( /<!--[\s\S]*?\>/g ); // allow <comment> tag
config.protectedSource.push( /<br[\s\S]*?\/>/g ); // allow BR Tags
config.protectedSource.push(/<script>[\s\S]*?<\/script>/gi); // allow <script></script>
config.protectedSource.push(/<div>[\s\S]*?<\/div>/gi); // allow <div></div>
config.removeButtons = 'Anchor,Iframe';
config.format_tags = 'p;h1;h2;h3;h4;h5;h6'; // format button options
config.height = '500px'; // edit window height
config.skin = 'moono';
config.stylesSet = 'vam_styles:/templates/admin/-css/vam_styles.js'; // style button options
// Only add rules for p and span elements.
config.stylesheetParser_validSelectors = /\^(p|span\div)\.\w+/;
config.stylesheetParser_skipSelectors
};
I'm creating a set of well designed templates for clients to use, so In the end I don't want CKEditor to touch my code at all.
This is not possible. CKEditor is not a web site builder into which you can load any possible HTML. It is a rich text editor. So you should use it to edit the textual part of the website, not the whole layout.
For instance, if you had a layout with two columns and some header above them, it would be best if there were 3 editors - one for each column and one for the header. Of course, in this basic case CKEditor could be used to edit or 3 sections at once, but the more complex the layout the more important it is to use CKEditor correctly.
PS. It's CKEditor, not ckEditor.
Thanks for your reply.
I wasn't talking about site design templates, but page design templates. On the Full featured version of CKEditor there is a template button that we've been able to enhance. We now are able to let our clients choose several well designed page layouts that are responsive for different devises. It is very effective.
After trying everything I found the culprit that was causing the problem. I was using <br> instead of <br />. As soon as I switched the editor left my code alone.
Best Wishes!
Rusty

Filter the grid data is not working in FF(mozilla) and IE

I am working with kendo ui controls.my functionality is to filter the grid based on date-time and drop down selection. This is working on chrome but not in FF and IE.
var gridResult = $('#Grid').data("kendoGrid");
var condition = {
logic: "and",
filters: [
{ field: "Category", operator: "equals", value: $("#nw").val() },
{ field: "Device", operator: "equals", value: $("#pro").val() },
{ field: "Orig", operator: "equals", value: $("#work").val() },
{ field: "Term", operator: "equals", value: $("#network").val() }
]
};
if (mindate !== null) {
condition.filters.push({ field: "Time", operator: "ge", value: new Date(mindate) });
}
if (maxdate !== null) {
maxdate = new Date(maxdate);
maxdate.setHours(23, 59, 59, 999);
condition.filters.push({ field: "Time", operator: "lt", value: maxdate });
}
gridResult.dataSource.filter(condition);
return false;
});
$('#fromdatetimepicker').attr('readonly', false);
$('#todatetimepicker').attr('readonly', false);
}
When i debug in firefox i didn't find aby bug can any one look at the code and please tell me where i am wrong?
I've been testing your code and I can't find any problems with it, besides that you have an extra ) at the end but that's probably because the function is cut from a larger section of code.
There are however several things that might be causing this problem and there's a lot of code missing so I can't say for sure. Some browsers try to help you out by ignoring errors you make. This can make it work in Chrome but not in FF and IE. The best way to deal with this is to go through the code and add validations that confirm the values every time the Filter method is call. Here are my suggestions for you:
When debugging in Internet Explorer, use IE 11 and use the F12 debugging tool.
You check that mindate and maxdate are not null, but if they're undefined or contain an empty value, they'll pass that test and will be added to the filters even though they're not set.
You don't have any check that mindate and maxdate are valid dates and that you successfully are able to create the JavaScript date variable, before adding it to the filter. This could be a source of error, depending on the other code in your script.
You use the values from $("#network").val() etc directly in your filter without validating them, and that could cause problems in the future. But this is not causing this error.
Edit: Encoding
You need to make sure the encoding of your webpage is correct. Please make sure these two lines exist in the head section of the html code. If you use ASP.NET MVC you can add these two files to the Views\Shared\_Layout.cshtml file. If you use ASP.NET Forms you can add them in your Masterfile. If you use PHP you just put them in the head section.
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">

How to use resource file for displaying column name in JQ grid

As by default the "colNames" property of the JQgrid displays the names that we harcode there like:
colNames: ['ProductID'],
//columns model
colModel: [
{ name: 'ProductID', index: 'ProductID', align: 'left', search: true, stype: 'text', searchoptions: { sopt: ['eq', 'ne'] } },
],
As here the "ProductID" in colnames property is harcoded here. Now my requirement is that this value should not be hard coded instead it should get the value from .resx file where we are maintaning the Translations.
Can we acheive this in jqgrid??
After reading of your question and thinking about all problems I made some minor changes in the localization files, made this and this demos and posted the feature request in the trirand forum. In the second demo I use less known column templates which was implemented in jqGrid based on one from my previous feature requests. The usage of templates can reduce and the length of JavaScript code used jqGrid and simplify it.
In your case you can probably simplify my demos and load all column headers (or lables of colModel) and the grid title (the caption) from the resource file. You can choose the language based on headers of the HTTP requests (Accept-Language) received from the client.
The exact implementation on the server side will be very depend on the technology which you use on the server.

Resources