How to set language file dynamicly in TinyMCE v4 - javascript

I try to set my script in a way that it's get the language from the <html> attribute. As a basic concept that works fine, the only problem is that I have a customized location where the localization files are located.
How do I have to set the parameter language_url for en_US. I tried a empty string '' as well as the value false with no success. I'm getting the error:
Failed to load plugin url: https://localhost/js/tinymce/langs/en_US.js
That is because there is no language file for en_US.
var lang = $('html').attr('lang');
tinymce.init({
selector: 'textarea',
language_url: (lang === 'en' ? '' : '/js/tinymce/langs/de.js'),
language: (lang === 'en' ? 'en_US' : 'de')
});
Is there no default value for language_url?

Two comments on this...
If you are placing the language files in the langs folder within TinyMCE you don't need to use the language_url configuration option at all. That is only needed if you want to store the files in a different location. Your example above seems to imply that you are placing the language files in the langs folder in your TinyMCE distribution and if that is the case you just don't need that setting at all.
If you really need that setting (but only sometimes) you can use JavaScript to make that happen...
You start by creating a "default" init object as a JavaScript variable on your page and then reference that later. For example:
var default_init = {
theme: "modern",
plugins....,
toolbar....
}
...then when you want to invoke a TinyMCE instance you can use that base object to make your init:
var lang = $('html').attr('lang');
if (lang !== 'en') {
default_init.language_url = '/js/tinymce/langs/' + lang + '.js';
}
tinymce.init(default_init);

Related

Use [hash:base64:5] in JavaScript / TypeScript file

I am using CSS Modules in an Angular Project with Webpack.
I had already transformed the class names in .css and .scss files with postcss-modules.
Then with posthtml-css-modules I had changed the values on the class property in html elements for his hash value defined by postcss-modules.
I can say that everything is working fine 💪.
Now, I have a new challenge to resolve.
Angular, has a feature that allows you to change dynamically the value of class in a html element depending on a condition:
https://angular.io/api/common/NgClass
For Example, I can do:
<div [className]="myVar ? 'myClass1' : 'myClass2' " >
If myVar = true, the html element will be:
<div class="myClass1" >
And if myVar = false, the html element will be:
<div class="myClass2" >
Like I do not know what is going to be the value of myVar during compilation time (because the value of myVar depends on user actions) I am not able to set the value for <div css-module="myClass1" > or <div css-module="myClass2" > in order to hash the class names of myClass1 or myClass2.
BUT (Here comes my solution)...
If I can invoke the same function that does [hash:base64:5] (https://github.com/css-modules/postcss-modules#generating-scoped-names)
I can create a function that receives a string as parameter and return the class name as a hash.
It would be something like this:
<div [className]="setMyClassNameInHash(myVar)">
Then in javascript:
function setMyClassNameInHash(condition) {
return condition ? doHash64('myClass1') : doHash64('myClass1');
}
doHash64() would be the function that takes a string and returns the hash using [hash:base64:5].
In conclusion, my question is:
¿How I can invoke the same function that does [hash:base64:5] in a javascript file?
Thanks!!!!
You'll need to integrate a templating step into your build process. The plugin exports the class names and their mapped names to a json file, so you can look up the hashed class name from the original.
Edit: Since the built in templating only works for a single class name and doesn't appear to support replacing class names in things like angular attributes, you could do the templating yourself using a templating library like lodash. If you're already using grunt or gulp, I'd recommend using their template tasks instead of this manual way because they do a lot of things for you, like supporting multiple files.
In your html, you would use lodash delimiters to get the hashed class name like:
<div [className]="myVar
? '<%= getHashedClass('myClass1') %>'
: '<%= getHashedClass('myClass2') %>' " >
Your node build script might look like this:
var fs = require('fs');
postcss([
require("postcss-modules")({
// Callback to get hashed class names
getJSON: function(cssFileName, classNames, outputFileName) {
var filePath = '/path/to/outputDir/file.html';
// Function to lookup hashed class names
var getHashedClass = function(unhashedClass) {
return classNames[unhashedClass];
}
// Read your html file as a string
var html = fs.readFileSync(path),
// Use lodash to template it, passing the class lookup function
var compiled = _.template(html);
var templated = compiled({
getHashedClass: getHashedClass
});
// Write the templated html
fs.writeFileSync(path, templated);
}
})
]);

using smarty template engine in registered javascript files with prestashop 1.7

I'm writing Prestashop 1.7.2.1 module.
In that module when I want to register a javascript file I connect to the hook actionFrontControllerSetMedia and use registerJavascript like so:
$this->context->controller->registerJavascript('module-tuxinmodcartype-carsearch-js','modules/'.$this->name.'/js/displaytop.js');
this loads the javascript properly but I can't use smarty template engine in those javascript files.
is there a way to do that ? :)
if not... should I just add all my javascript files inline ?
update
so I added this to my hook function:
Media::addJsDef(['tuxinmodcartype'=>array(
'car_companies'=>$this->tuxDb->getCompanyNamesArray()
)]);
and this my js file:
$(function() {
var options = {
data: tuxinmodcartype.car_companies,
list: {
match: {
enabled: true
}
}
};
$('#company-name-input').easyAutocomplete(options);
});
and I get the error ReferenceError: tuxinmodcartype is not defined
For accessing variables in javascript you can assign them in your controllers with:
Media::addJsDef(array(
'mymodule' => array(
'var1' => 'yes',
'var2' => 'no'
)
));
Then you can use them in your javascript or through console:
let var1 = mymodule.var1;
let var2 = mymodule.var2;
Building javascript files with smarty... I guess it's better to split javascript into more files and load them through controller based on conditions. Or use the above definition for variables to control execution path in your javascript.
Safer way to declare your vars without mymodule array,
Media::addJsDef(array('var1' => $myphpvar));
Media::addJsDef(array('var2' => $myphpvartwo));
this way you DONT need
let var1 = mymodule.var1;
Why this better? Because 'let var1' cause error in iphone safari browser.
You can simply do this in the tpl file:
<script>var = '{$var}';</script>
and use your var in the javascript file.
Source: https://www.prestashop.com/forums/topic/589645-unknown-tag-addjsdef-error/?tab=comments#comment-2490210

Can not read property of undefined i18n

When I try to pass language dynamically from select dropdown list, It shows following error
Uncaught TypeError: Cannot read property 'properties' of undefined at changeLanguage
Where changeLanguage is my function as follows:
function changeLanguage(lang)
{
lang = lang || "en_EN"; // if no language is set, use browser default
jQuery.i18n.properties({
path : 'language',
mode : 'both', language: lang,
name: 'Messages',
callback: refresh_i18n });
}
Following are the pictures of it:
Dropdown image
Console error
What is wrong with the code?
Please do suggest!
Thanks
UPDATE:
FOR MORE EXPLANATION:
This is my index file and initially I call it with onload it works fine.
<script>
function refresh_i18n() {
console.log('Some code...')
}
function changeLanguage(lang) {
lang = lang || "en_EN";
jQuery.i18n.properties({
path : 'js/libs/language',
mode : 'both',
language: lang,
callback: refresh_i18n
});
}
changeLanguage("en_US");
</script>
but when i call by changing dropdown like:
$('#selectLanguage').change(function(){
changeLanguage(this.value);
});
It gives above error
Probrably the i18n library is loading before the jquery (problems haha).
So, put the jQuery loading in the head of the html and the plugin i18n (and others, if you are using) in the body (I suggest in the end of body) of the html.
That must solve the problem.

How do I call upon my settings (array) listed in html using prototype in my javascript file?

I'm relatively new to javascript development and have tried to construct my own framework. I've been trying to convert my standard javascript functions to a framework. However I've been stuck at a relatively simple (I think), but nowhere explained issue.
In my HTML I call on the settings I want to use in my JavaScript (the user has to be able to edit them in html, not in js as it will be minified).
<script>
$(document).ready(function(){
var settings = {authenticFilter: 'on',
randomizeHeaders: {state: 'on', topHeader: 'h1', bottomHeader: 'h2'},
};
var papery = new Papery(settings);
});
</script>
But I can't seem to figure out how to use the settings I have given to my framework in the javascript file.
I know I can call upon this.settings = settings; in my javascript file, but in an if statement below, I want make use of specific settings in the given settings. However this option and several other ways I've tried to use the settings won't work. Can I even use the settings I give to the prototype from my html in an array?
var Papery = function (settings) {
Papery.authenticFilter = function() {
if (Papery.authenticFilter == 'on'){
$("img").addClass("authenticFilter");
$(".authenticFilter").css({"filter": "sepia(80%) grayscale(1) contrast(1) opacity(0.7)", "-webkit-filter": "sepia(80%) contrast(1) opacity(0.7)"});
}
}
}
You are using Papery.authenticFilter instead of settings.authenticFilter. Keep in mind that in usual libraries, a bunch of default settings are set in initialization in case they are not defined on the settings passed on the constructor.

Change javascript variable with jquery

In my MVC project i import a .js file in my shared layout.
<script src="#Url.Content("~/Scripts/bootbox.js")" type="text/javascript"></script>
This file has this variable
var locales = {
en: {
OK: "OK",
CANCEL: "Nej",
CONFIRM: "Ja"
}}
In one of the views i would like to change the OK value for en with jQuery. How can i do this?
Assuming the file defines locales as a global variable,
locales.en.OK = 'en';
To be clear, though, this has nothing to do with jQuery, razor, or model-view-controller. It's simply how you set the property of an object in native Javascript, there's no further technology required to do this.
I have now downloaded bootbox.js myself to look at what's going on here. locales is not defined as a global variable, it's scoped to the anonymous wrapper function that contains all of the contents of bootbox.js.
This means that there is no way to change the contents of that variable dynamically from outside of that scope. If you want to permanently change that text, then you can change it in bootbox.js manually. If you want to change it dynamically, then you can replace
var locales = ...
with
window.locales = ...
in bootbox.js, and then use my original suggestion in your own code.
You may declare locales in some scope, define locales outside of scope that is global or just remove var from locales as mentioned below.
locales = {
en: {
OK: "OK",
CANCEL: "Nej",
CONFIRM: "Ja"
}}
You can call it by locales.en.OK

Categories