I've been using Pootle recently for translating a small PHP project. Our i18n files are as php arrays, example:
return array(
'word.in' => 'en',
'word.yes' => 'Sí',
'word.no' => 'No',
'word.with' => 'con',
);
So I created a Project in Pootle's admin panel and set the source files are PHP arrays. I can upload and translate files perfectly fine afterwards.
The problem comes when I try to export, the file rendered has the following syntax:
return array->'word.in'='for';
return array->'word.yes'='Yes';
return array->'word.no'='No';
return array->'word.with'='with';
Which afaik isn't even valid PHP syntax.
I've read through the Pootle and Translation Toolkit's documentations and I've found that it passes through some sort of 'template' to generate that crappy output.
Any ideas how I can fix this and be able to export my PHP array with exactly the same syntax I uploaded it? Any help greatly appreciated!
Any ideas how I can fix this and be able to export my PHP array with exactly the same syntax I uploaded it?
Before return statement, if You need to actually write that array to file and read it later again, I would do something like this ..
$arrayExport = var_export(
array(
'word.in' => 'en',
'word.yes' => 'Sí',
'word.no' => 'No',
'word.with' => 'con',
), true);
Than write down $arrayExport .. for example:
file_put_contents($filePathName,
'<?php $exportedArrayName = '.$arrayExport.";\n ?>",
LOCK_EX);
...than goes the rest of weird Pootle and translation ...
But if You need to read it again after a while without storing it, use $_SESSIONS and serialization.
$_SESSION['exportedArray'] = serialize(array(
'word.in' => 'en',
'word.yes' => 'Sí',
'word.no' => 'No',
'word.with' => 'con',
));
To read from session ..
$exportedArray = unserialize($_SESSION['exportedArray']);
Related
I have a MediaWiki 1.33.0 website with only one extension → ContactPage, with which I can have a simple contact form.
Using HTMLForms template engine (in which the default form-template for ContactPage is written), I have expanded the default form to include a selection menu.
My problem
Selection list array keys and values of this selection menu are written in English inside LocalSettings.php but my site isn't primarily in the LTR English, rather, it is in the RTL Hebrew and I would like them to appear in my site's native language for end users.
My own code pattern
wfLoadExtension( 'ContactPage' );
$wgContactConfig['default'] = array(
'RecipientUser' => 'Admin', // Must be the name of a valid account which also has a verified e-mail-address added to it.
'SenderName' => 'Contact Form on ' . $wgSitename, // "Contact Form on" needs to be translated
'SenderEmail' => null, // Defaults to $wgPasswordSender, may be changed as required
'RequireDetails' => true, // Either "true" or "false" as required
'IncludeIP' => false, // Either "true" or "false" as required
'MustBeLoggedIn' => false, // Check if the user is logged in before rendering the form
'AdditionalFields' => array(
'omgaselectbox' => [
'class' => 'HTMLSelectField',
'label' => 'Select an option',
'options' => [
'X' => 'X',
'Y' => 'Y',
'Z' => 'Z',
],
],
),
// Added in MW 1.26
'DisplayFormat' => 'table', // See HTMLForm documentation for available values.
'RLModules' => array(), // Resource loader modules to add to the form display page.
'RLStyleModules' => array(), // Resource loader CSS modules to add to the form display page.
);
possible solutions
1) Writing selection list array keys and values in Hebrew (which might be a bit messy due to LTR-RTL clashings):
'options' => [
'ס' => 'ס',
'ט' => 'ט',
'ז' => 'ז',
],
2) Translating English selection list array keys and values in client side JavaScript by some similar code:
document.getElementById('select').selectedIndex = 0;
document.getElementById('select').value = 'Default';
My desire
I desire an ordinal backend way to do so, and if there is one, than without an extension
In this discussion, a MediaWiki community member recommended using system message transclution but the chapter dealing with it was very unclear to me; I didn't understand what this is about and how can this help in my situation.
My question
What are the possible ways to translate in MediaWiki from "backend", without an extension?
The localisation system is working perfectly fine in the backend (php), as well in the frontend (JavaScript) parts of MediaWiki → staying with it backend is best as it is more minimal.
Assuming you take a backend only approach:
Translation with a predefined string
If your desired translations already exist in MediaWiki (e.g. on another page of form), you can "simply" re-use the key. So, let's assume, your current additional select field definition looks like this:
'Select' => [
'type' => 'select',
'options' => [
'The english message' => 'value'
]
],
Then, you would change it to something like this:
'Select' => [
'type' => 'select',
'options-messages' => [
'the-message-key' => 'test'
]
],
Please consider the changing of options into the options-messages key.
Also: Change the key the-message-key to the message key you want to reuse.
If you know a page where the message/string is used, you can just open that page with the GET option uselang and the value qqx, in order to see the message key. Example: If the string is used on the login page, simply open the login page with https://example.com/wiki/Special:Userlogin?uselang=qqx to show all the message keys used on the page.
However, one warning when doing that: It is mostly discouraged to re-use existing message keys, especially when they're used on other pages. The keys are translated to hundreds of languages with that specific context in mind. That could also mean, that a translation in a specific language does not fit when the string/message is used on the contact page. So I would suggest to use the second option below.
Translation without a predefined string
Usually it will be done by extension which can provide a specific directory where the JSON files with the message key translations are saved. However, as you're "just" customizing an extension, you need a way to put in the translations for your keys.
So, first of all, let's take over the changes from above. Change your select field definition to be something like:
'Select' => [
'type' => 'select',
'options-messages' => [
'my-fancy-key' => 'test'
]
],
Now, two ways to get the key translated:
On-Wiki
By saving the message on-wiki, the messages can also easily being changed simply by editing the respective page in the wiki. In our example, let's translate the key to english and hebrew:
English: Edit the page MediaWiki:My-fancy-key in your wiki and add the desired text.
Hebrew: Edit the page MediaWiki:My-fancy-key/he in your wiki and add the desired text.
As part of the deployed code
We need to register a directory with JSON files for the translations of these messages. We're using the same configuration variable as extensions would use as well, $wgMessagesDirs, even given that we don't create an extension. Add the following line to your LocalSettings.php:
$wgMessagesDirs['ContactPageCustomization'] = __DIR__ . '/customContactPage';
Now, create a directory customContactPage in the root folder of your MediaWiki installation and put in the following file with the following contents:
en.json
{
"my-fancy-key": "Default"
}
If you want to translate to another language, create a new file with the language code you want to translate to. In hebrew it should be he, so let's create a new language file:
he.json
{
"my-fancy-key": "ברירת מחדל"
}
If you then open the contact page, the message key my-fancy-key should be translated to the english Default and the same (at least based on Google Translate) for hebrew. This is a more stable way of adding custom translations, however, you now also need to take care of translating the keys into the languages you want to support on your own as well. If a key is not translated into the selected language of the user, the default language, english, is used.
I'm building a full website Using Laravel and this problem is facing me , I want to give the user full control to the site appearance and the ability to change website's layout without my help.
But when I'm thinking about someway to do so by database , there are several tables with tens of columns will be added beside the colors and sections that will be added to database every time the user will change something in the layout style.
Is there any other way to store the options of the theme in XML file or anything other than database?
** Note : when I checked the database of Wordpress I hadn't found any thing concerned to themes there , So where Wordpress store theme options?
For your XML-like storage you can use Laravel Config. Let's say you have the file config/templates.php. Inside you can have a lot of stuff like.
return [
'default_template' => 'layouts.templates.default',
'posts' => 'layouts.templates.post',
'footer' => 'layouts.includes.footer',
'options' => [
'full_with' => false,
'has_footer' => true,
'background_color' => '#fff',
'more_keys' => 'key_value'
]
];
Then anywhere in your app you can get the default template like
$view = config('templates.default_template'); //will get
return view($view, compact('params'));
To update a key, like has_footer, you do
config(['templates.options.has_footer' => false]); //will update
This should get you started I think
Simple Example
Let's say user changes default colour from and input and submit the form. You do
public function updateTheme(Request $request) {
if ( $request->has('background_colour') && $request->background_colour != '' ) {
config(['templates.options.background_colour' => $request->background_colour]);
}
}
I'm not sure if this is even possible but what the heck :) I have two URL, both trying to insert different data into the same table. Example
We have table "food" and two URL with functionality that insert into FOOD table some values
http://example.com/insert_food_1
http://example.com/insert_food_2
When loading both URLs in the same time, every one of them waits for the other one to finish first and afterwards inserts into the DB the specific values.
I know this is called multithreading or something... but i'm not sure if this can be done with PHP (or Laravel).
Any help would be much appreciated. My code looks like so ...
$postToInsert = Post::create(
array(
'service_id' => 1,
'custom_id' => $post->body->items[0]->id,
'url' => $post->body->items[0]->share_url,
'title' => $post->body->items[0]->title,
'title_tags' => $tags,
'media_type' => $mediaType,
'image_url' => $imageURL,
'video_url' => $videoURL
));
$postToInsert->save();
I kind of fix it. Opening them in separate browsers or php them via CURL from terminal solves the problem.
Thanks for all the help
Situation
I'm using a jQuery gantt plugin from here and integrating it with a PHP site I have. In terms of setting up the demo there are no problems; however when I try to feed the plugin some of my own data, it will throw up the following error:
TypeError: e is undefined
Now, I believe the above error is thrown due to the JSON object being unfamiliar to the plugin but, I just can't seem to package it correctly.
My JSON Data
Demo JSON Data
Now, you can see other than a few differences, I am pretty close to the mark. Up next is the PHP code I use to generate this.
$aryOutput = array('source' => array());
if($aryTasks) {
foreach($aryTasks as $aryTask) {
$aryOutput['source'][] = array(
'name' => $aryTask['task_stage'],
'desc' => $aryTask['task_title'],
'values' => array(array(
'to' => '/Date('.time($aryTask['task_projected_end_timestamp']).')',
'from' => '/Date('.time($aryTask['task_projected_start_timestamp']).')',
'desc' => $aryTask['task_description'],
'label' => $aryTask['task_description']
))
);
}
}
$strJSON = json_encode($aryOutput, JSON_UNESCAPED_SLASHES);
Please can anyone offer some pearls of wisdom to resolve this matter. On a side note, from another question, I saw that the class has to be gantt. This is not a problem, I can get the plugin working with a different data set.
Thank you
Edit
I noticed a small difference with the date field having an extra slash on it. After editing the code to add it, the error still occurs
Check the complete delivered JSON is structure as needs be. In the above example, it is likely this is the output:
source : { source : { ... } }
This causes confusion with the plugin as it is unexpected data.
Ok for sure this has been asked and answered already but i somehow can't find a proper tutorial.
I want to keep the text displayed to users somewhere else and to prevent my code from becoming too large and unreadable.
My site won't be internationalized. I just want to have some kind of file with key-value structure and get the text from there. I want to keep the text in files, not in the database as some tutorials suggest.
I found a solution which will work but i am not sure whether this is a good approach.
I am thinking of using parse_ini_file and to keep my texts in .ini file. Is there something wrong with this approach? Could you suggest something better?
I put all language data in arrays. Its easy and also we can add multi-language support
lang/en.php
<?php
return array(
'index' => 'Homepage',
'feedback' => 'Feedback'
'logout' => 'Logout from profile',
)
?>
lang/ru.php
<?php
return array(
'logout' => 'Выйти из профиля',
)
?>
Then we can load languages:
$lang = include('lang/en.php');
if(isset($_GET['lang']))
{
$lang = array_merge($lang, include('lang/ru.php'));
}
After all it $lang will look like:
Array
(
[index] => Homepage
[feedback] => Feedback
[logout] => Выйти из профиля
)
And we can very simple use it:
function __($name) {
global $lang;
return $lang[$name];
}
Somewhere in the site template:
...
<title><?=__('index')?></title>
</head>
<body>
<?=__('feedback')?>
why not use a plain text file with commas or some uncommon character to hold this data? you can read it and parse it into an array with
$file = file_get_contents("/path/to/file");
$lines = explode('\r', $file);
foreach($lines as $line) $message[substr($line, 0, strpos($line, ','))] = substr($line, strpos($line, ','));
then you should have an array like $messages[3] = "No soup for you!";
the file might look like:
1,The site is down.
2,Try again.
3,No soup for you!
4,Signs point to yes.
(I probably have some of the arguments misplaced in those functions - i always forget which is the needle and which the haystack.)
You can process your data in a script. In this script, you call a certain source (e.g. the ini file you suggest). Then you use a template engine. For this engine, you point towards a template file and give the template all the variables.
The template generates the html and inserts the variables at the right place. This way, you keep you php (business logic) code clean, away from the presentation (the template). Also you can manage the variables in one file (ini/xml but this can be something completely different).
For template engines, Smarty is the most known of all. There are also pure php-based template systems, just Google for them to find one that suits your needs.
I do like this:
$defaultLang = array('Home','Logout',etc)
$otherLang=array( 'ru' => array('Home_in_ru','logout_in_ru',etc);
you translate like this:
echo translate('Home');
function is:
function translate($msg) {
if ($_GET['lang']=='en')
return $msg;
return $otherLang[$_GET['lang']][array_search($msg,$defaultLang)];
}
// Note the function is simplified up there
As you can see the default case deosnt' need to load anything or do any operation, the function just returns back the argument passed
i like the answer with the lang/en.php file. but instead of a file for each language, i use a file for each web page (or class, etc). this keeps file sizes lower and i create a 3D array:
`return array( "EN" => array( "title" => "Welcome - Good Morning", ...),
"TG" => array( "title" => "Mabuhay - Magandang Umaga Po", ...)
);'
Real easy to add new language strings too...
This makes it real easy for language translation contractors since they can see the native language in close proximity to the foreign in 1 editor,,,