Magento, translate validation error messages - validation

I have successfully created new rules for the prototype validation, now I need to translate the error messages (Location: String in Javascript). However, I can only translate all the messages, my new custom ones don't appear to be translatable. How do I change this?

Maybe you need an jstranslator.xml file inside etc folder:
<?xml version="1.0" encoding="UTF-8"?>
<jstranslator>
<some-message-name translate="message" module="mymodule">
<message>This is the text in my own js validation</message>
</some-message-name>
</jstranslator>
With the following structure and meanings:
<jstranslator> - [one] XML root node.
<some-message-name> - [zero or more] root node child elements with a unique XML element name across all jstranslator.xml files (otherwise last in loading order based on module listing wins).
Attributes:
translate="message" - (optional) a hint that the child element(s) that is being translated is named "message", however this is hardencoded for the js translation XML files (Magento CE 1.9, search for "*/message") and this attribute does not need to be used.
module="mymodule" - (optional) name of the module, if left out the value is "core". It will be used to instantiate the data-helper later on (from that module) which then is reponsible to load the translations (e.g. from the CSV files).
<message> - [zero or one per parent] message to translate. the text value of this elements node-value is taken to be added to the javascript Translator object data.
All jstranslator.xml files of activated modules are processed.
Then put your translation line into the Something_Mymodule.csv file:
"This is the text in my own js validation", "(translated in a different language or speech)"
Then in your js scripts you can use your own translations via the Translator:
Translator.translate('This is the text in my own js validation');
Further References
Correct usage of jstranslator.xml

To translate custom javascript error messages you need also to add them to the following file:
\app\code\core\Mage\Core\Helper\Js.php
find a function _getTranslateData()
and you'll see a bunch of messages already in there.
just add your message somewhere in the array like this:
'This is my validation message' => $this->__('This is my validation message')
Don't forget a comma (,).
And then put translation in some translate file.
In the file where you use this message (I use it in opcheckout.js file) you need to wrap text in Translator.translate('This is my validation message').
I haven't figured out yet if it's important which translate file that is. You can try Mage_Core.csv .
I needed it in Mage_Checkout.csv and it works in there.
Anyway, for those who are interested in more, I noticed that these javascript messages are printed in header of every html page and some worrie that it messes with the SEO. Anyway this is printed in file
\app\design\frontend\bmled\default\template\page\html\head.phtml with the code.
<?php echo $this->helper('core/js')->getTranslatorScript() ?>
Check for more here:
I hope this helps, I just hope this works everywhere, so far I tested it on Onepage Checkout only.

You can edit app/local/ur_language/Mage_Core.csv file, adding original string in the first Column the translated one in the second. All the javascript translations are stored in this file.

What's helped me (Magento EE 1.6) -
I added new translation object:
<script>
var _data = {
'This is a required field.':
"<?php echo $this->__('This is a required field.'); ?>",
'Please make sure your passwords match.':
"<?php echo $this->__('Please make sure your passwords match');?>",
'validate telephone error':
"<?php echo $this->__('validate telephone error');?>"
};
var Translator = new Translate(_data);
</script>
if it is defined VarienForm uses it in js validation

We had exactly the same problem with one of our magento projects. We found that the function in app/design/frontend/default/default/template/page/htmlhead.phtml had been commented out:
<?php echo $this->helper('core/js')->getTranslatorScript() ?>
After putting this in, it still did not work, because translations had not been inserted into translate file. Check out those two things and it should start working.

To expand on this, you must add the translation strings to Mage/Core/Helper/Js.php.

Related

What rule should I follow to create a block (for block name,type etc)?

I'm confused while creating a block or call a block. in phtml file suppose in footer.phtml file if I want to call a static block then I write
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('static_block_name')->toHtml(); ?>
and for newsletter(which is in template folder in my theme folder)
<?php echo $this->getLayout()->createBlock('newsletter/subscribe')->setTemplate('newsletter/subscribe.phtml')->toHtml(); ?>
so what should I write in footer.phtml to call a built in block(which is in base folder) like calendar,captcha etc ?
please tell me how can I call those in phtml file and xml file.
please tell me
1. <?php echo $this->getLayout()->createBlock('**?**')->setTemplate('**?**')->toHtml(); ?>
2. xml block code and where to put the code
3. rules to write block type and name.
-Thanks.
The only difference between the two blocks that you are mentioning is the type. The cms/block type is a built in way for you to create arbitrary text blocks with optional references to additional content (additional information native to Magento via widgets such as links or calls to other blocks).
The second block that you list is that of a block that represents a specific block which is used to output a specific model with a specific template. If you dive into the structure of Magento, you will find that the code that is core to Magento exists in the app/code/core/Mage folder. Inside of that, you will find items such as catalog/category, catalog/product, newsletter/subscribe etc. Additionally, according to MVC, you will need a way to present that model to the user via a view, or template by Magento's terms. Views into models will exist in the app/design/frontend/{package}/{theme}/template/ folder. You should find some continuity between the two sets of folders and will arrive to a set of views that you can use to output a block. In this case of a product, you will find app/code/core/Mage/catalog/product/ and app/design/frontend/base/default/template/catalog/product/view.phtml.
Hopefully this will set you on your way to better understanding the beast that is Magento. Magento, as described by Alan Storm, is not your father's PHP.

Why are images uploaded through the admin panel of my custom module, having the file name of Array?

Here is my BrandController.php
https://gist.github.com/a958926883b9e7cc68f7#file-brandcontroller-php-L53
I've gone through all my files of my custom module, and compared them to the one given from the custom module maker, and I couldn't find much differences.
Are you attempting to upload multiple files? If you're using multiple fileupload elements with the same name you'll get an array of items.
So when the following line is called,
//this way the name is saved in DB
$data['filename'] = $_FILES['filename']['name'];
It will have the value
["name"]=>array(2) {
[0]=>string(9)"file0.txt"
[1]=>string(9)"file1.txt"
}
you'll need to update the code to loop through each $_FILES['filename']['name'] and upload and save the files separately.
You may unknowingly uploaded multiple files. If you that is not your intention, you may check your in your HTML and check the name attribute of the tag. It must not be an array (like this).
<input type="file" name="my_files[]" />
If you only see Array() in your database, it means you are indeed uploading a multiple files. You can process them by using loops.
If you are really sure that you are uploading 1 image, you may follow #Palanikumar's suggestion. Use a print_r() and display the $_FILES and paste it here. IF you don't want to use that, You can use
json_encode($the-data-you-are-going-to-insert-to-the-database);
If you don't know where to put the print_r() function, you may put it after line 56 of this file.
https://gist.github.com/desbest/a958926883b9e7cc68f7#file-brandcontroller-php-L53
if(isset($_FILES['filename']['name']) && $_FILES['filename']['name'] != '') {
print_r($_FILES);
die;
If saveAction() is being called inside an ajax function you need to log the ajax response. Assuming you are using jquery..
$ajaxResponse = $.POST({...});
console.log($ajaxResponse.responseText);
Then, you you can view it inside a browser's console. If nothing appears, you may use a non-async request
$ajaxResponse = $.POST({
// your options,
// your another option,
async: FALSE
});
Usually file upload will return in array format. So that each uploaded file will have the information like name, type, size, temporary name, error. You can get the file information using print function (print_r($_FILES)). So if you want to display name of the file you have to use something like this $_FILES['filename']['name']
Use print function and debugging tool then save file information using loops.
For more info please check here.
You aren't setting the enctype of the form so the image will never be sent. updated the code to
$form = new Varien_Data_Form(array( 'enctype' => 'multipart/form-data'));

How to use Dojo i18n in the SIMPLEST manner possible

I'm new to Dojo and i18n for that matter. I am looking to convert a couple of works to different languages in my app. I've read through a few articles and to be honest, I feel like a LOT of information is thrown at me to digest, and I'm struggling with it. Would someone be able to provide me with the simplest way I can possibly do this? Let's say I want to change the word 'Hello'. In my head it would be something like:
Dojo library ready for use
I define String 'hello' in my javascript file. It has the placeholder text of "hello"
I specify in my HTML that I want my page to be
"string specified here to display hello in a different language"
So that's as much as I can assimilate from my limited knowledge. How do I essentially get that sort of setup to work? I assume I need to require i18n on my page, but exactly how I execute this is still to be determined.
Any help would be super. Please bear in mind that I have a limited knowledge with your answer if at all possible, thanks!
The nls folder is normally used to store your translation strings and is usually a subdirectory next to the widget using it.
ie. If your widget is stored in myWidget.js within a folder called app, then your translation strings for myWidget.js are stored in a file with the same name (myWidget.js) in the directory app/nls.
This is just convention but is probably worth following as it makes your directory structure logical.
Here is an example of the myWidget.js widget:
define([
"dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/i18n!./nls/myWidget"
], function(
declare, _widget, _templated, strings, domAttr
){
"use strict";
var construct = declare([_widget, _templated], {
"i18n": strings,
"templateString": "<div>${i18n.hello}</div>"
});
return construct;
});
This is a very simple widget that creates a <div> (see templateString property) on the screen. The <div> should contain the text loaded from the translation file and assigned to the hello property.
The widget will need nls directory creating in the same directory as myWidget.js. In the nls directory you create another javascript file called myWidget.js (ie. same name as the parent). This file is you root translation file and looks like this:
define({
root: ({
"hello": "Hello"
})
});
Here you have assigned the string, "Hello" to the property hello. This is not very useful as no translations have been supplied. If you wanted to have a Norwegian translation then you would modify it like this:
define({
root: ({
"hello": "Hello"
}) ,
"no": true
});
Here you are saying that as well as the root translation strings you also have a Norwegian translation. You will then need to create your Norwegian translation file and place it in a subdirectory of nls called no. So you create another file called myWidget.js and place it in nls/no:
define({
"hello": "Hei"
});
The format for the translation file is slightly different to the root file. The default strings are used, unless a translation is available for the given string in the current browser language (ie. you do not need to translate every string, just the ones you want translating).
See the Dojo tutorial for internationalization for more help on this subject.
See sample project for the above code on Bitbucket
Loading translation-strings outside of widget:
The above examples show how to load translation text for a widget following the normal conventions. You can load any set of strings you want in any widget or any require statement. The dojo/i18n class is able to load any set of strings you specify.
eg:
require([
"dojo/i18n!<PATH TO TRANSLATION ROOT FILE YOU WANT TO LOAD>"
], function(string) {
// translation-string are stored in the 'strings' variable for the
// current browser language
});

Examining Magento's final XML structure

Anyway to examine the final XML structure magento comes up with after parsing & combining all the different XML files?
There is nothing of that sort which turned up on searching on the internet and I think for someone like me, magento layouts were a bit too much in the beginning & I would try to do everything on the code side.
Another thing which will help in picking up the name of different nodes that we can use, right away from the final XML structure.
Never ran into this but I believe we will have a better picture of what's overriding what.
The following will get you the merged configuration from app/etc/*.xml, app/etc/modules/*.xml, as well as each (active) module's config.xml file; when retrieving the config though there is no indication of what was overwritten, as the merges happen as each config file is being parsed:
Mage::getConfig()->getNode()->asNiceXml(); // or asXML() | asArray() | etc.
However, you seem to be asking about how the application makes use of this information. This is a function of application design.
Also, you mention "all of the different XML files." It's worth noting that these are not maintained in one massive object instance. For example, layout XML is accessed using the layout update object Mage_Core_Model_Layout_Update and can be accessed meaningfully after it's been loaded and manipulated for a given rendering scope (e.g. loadLayout() in a controller action):
Mage::app()->getLayout()->getUpdate()->asString(); // or asSimplexml() or asArray()
Yes - Commercebug. As well as a whole load of other useful features, you can also view the entire XML structure that Magento has produced.
http://store.pulsestorm.net/products/commerce-bug-2
I believe the following will output the XML: echo Mage::getConfig()->getXmlString();
You can create a script with something like this:
header("Content-Type:text/xml");
require_once '../app/Mage.php';
Mage::app();
echo Mage::getConfig()->getXmlString();
based on answer from benmarks I did
echo "<pre>".htmlspecialchars(Mage::getConfig()->getNode()->asNiceXml())."</pre>";
If you want for example to see the blocks configuration in Magento 1 you can put this in a file, place the file at the root of the site and navigate to it in a browser:
<?php
include("app/Mage.php");
Mage::app();
//just see blocks...
echo "<pre>".htmlspecialchars(Mage::getConfig()->getNode()->global->blocks->asNiceXml())."</pre>";
die();

Path to CKEditor in CakePHP app on Zeus server

I'm integrating CKEditor into a CakePHP app which is running on a Zeus server (and therefore can't use .htaccess - I have to use rewrite.script instead). Problem is, the paths that CKEditor puts into the head section of the page don't work, so the editor won't load.
For instance, one generated path is:
http://www.example.com/js/ckeditor/config.js?t=B8DJ5M3
If I go to
http://www.example.com/js/ckeditor/config.js
I can see the file, but as soon as I add the ?t=B8DJ5M3 on the end, Cake complains that it can't find the jsController.
I'm not sure what to do about this - whether to dig around in CakePHP, CKEditor or the rewrite.script files! What should I try next?
That query string on the end of your URL is used to make sure the file isn't cached. Seems like something in your GET request configuration/routing on the Zeus server is trying to locate that exact file including the query string. You're going to need to create a Rewrite that performs a goto on the URL minus the query string. I found a pretty solid article in the Drupal forums where someone put together a script that may help you: http://drupal.org/node/46508
RULE_0_START:
# get the document root
map path into SCRATCH:DOCROOT from /
# initialize our variables
set SCRATCH:ORIG_URL = %{URL}
set SCRATCH:REQUEST_URI = %{URL}
# see if theres any queries in our URL
match URL into $ with ^(.*)\?(.*)$
if matched then
set SCRATCH:REQUEST_URI = $1
set SCRATCH:QUERY_STRING = $2
endif
RULE_0_END:
And from there, handle your goto minus the query string. Hope that helps
You can do this
In the view where you want to display the editor, put the following script on the top of the page (or somewhere before textarea which you want to contain editor):
<?php echo $this->Html->script('ckeditor/ckeditor');?>
This scipt will include the "webroot/js/ckeditor.js" file to your view.
Create the textarea and give it a class named "ckeditor"
<?php echo $this->Form->textarea('content',array('class'=>'ckeditor'))?>
Voila! The editor is now displaying instead of raw textarea.

Resources