first import
This commit is contained in:
90
sites/all/modules/i18n/i18n_field/i18n_field.i18n.inc
Normal file
90
sites/all/modules/i18n/i18n_field/i18n_field.i18n.inc
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Internationalization (i18n) hooks
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_object_info().
|
||||
*/
|
||||
function i18n_field_i18n_object_info() {
|
||||
$info['field'] = array(
|
||||
'title' => t('Field'),
|
||||
'class' => 'i18n_field',
|
||||
'key' => 'field_name',
|
||||
'load callback' => 'field_info_field',
|
||||
'placeholders' => array(
|
||||
'%field_ui_menu' => 'field_name',
|
||||
'%field_type' => 'type',
|
||||
),
|
||||
'edit path' => 'admin/structure/types/manage/%bundle/fields/%field_ui_menu/field-settings',
|
||||
// We can easily list all these objects
|
||||
'list callback' => 'field_read_fields',
|
||||
'string translation' => array(
|
||||
'textgroup' => 'field',
|
||||
'properties' => array(
|
||||
'label' => array(
|
||||
'title' => t('Label'),
|
||||
),
|
||||
),
|
||||
//'translate path' => 'admin/structure/block/manage/%module/%delta/translate/%i18n_language',
|
||||
)
|
||||
);
|
||||
$info['field_instance'] = array(
|
||||
'title' => t('Field instance'),
|
||||
'class' => 'i18n_field_instance',
|
||||
'key' => array('field_name', 'bundle'),
|
||||
'placeholders' => array(
|
||||
'%bundle' => 'bundle',
|
||||
'%field_ui_menu' => 'field_name',
|
||||
),
|
||||
'edit path' => 'admin/structure/types/manage/%bundle/fields/%field_ui_menu',
|
||||
// We can easily list all these objects.
|
||||
'list callback' => 'field_read_instances',
|
||||
// Metadata for string translation.
|
||||
'string translation' => array(
|
||||
'textgroup' => 'field',
|
||||
'properties' => array(
|
||||
'label' => array(
|
||||
'title' => t('Label'),
|
||||
),
|
||||
'description' => array(
|
||||
'title' => t('Description'),
|
||||
'format' => 'format',
|
||||
),
|
||||
'default_value' => array(
|
||||
'title' => t('Default value'),
|
||||
'format' => 'format',
|
||||
),
|
||||
),
|
||||
//'translate path' => 'admin/structure/types/manage/%bundle/fields/%field_ui_menu/translate/%i18n_language',
|
||||
)
|
||||
);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_string_info().
|
||||
*/
|
||||
function i18n_field_i18n_string_info() {
|
||||
$groups['field'] = array(
|
||||
'title' => t('Fields'),
|
||||
'description' => t('Configurable fields descriptions, defaults, options, etc.'),
|
||||
'format' => FALSE, // This group doesn't have formatted strings
|
||||
'list' => TRUE, // This group can list all strings
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_field_info().
|
||||
*/
|
||||
function i18n_field_i18n_field_info() {
|
||||
$info['text'] = $info['text_long'] = $info['text_with_summary'] = array(
|
||||
'translate_default' => 'i18n_field_translate_default',
|
||||
);
|
||||
$info['list_text'] = $info['list_boolean'] = $info['list_integer'] = array(
|
||||
'translate_options' => 'i18n_field_translate_allowed_values',
|
||||
);
|
||||
return $info;
|
||||
}
|
182
sites/all/modules/i18n/i18n_field/i18n_field.inc
Normal file
182
sites/all/modules/i18n/i18n_field/i18n_field.inc
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Field and field instance object handlers
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base object for field and field instance
|
||||
*/
|
||||
class i18n_field_base extends i18n_string_object_wrapper {
|
||||
/**
|
||||
* Get base path for object
|
||||
*/
|
||||
protected function get_base_path() {
|
||||
$info = entity_get_info($this->object['entity_type']);
|
||||
if (isset($info['bundles'][$this->object['bundle']]['admin'])) {
|
||||
$admin = $info['bundles'][$this->object['bundle']]['admin'];
|
||||
// Extract path information from the bundle.
|
||||
if (isset($admin['real path'])) {
|
||||
return $admin['real path'] . '/fields/' . $this->object['field_name'];
|
||||
}
|
||||
else {
|
||||
// We don't have real path, use path instead, may work or not.
|
||||
return $admin['path'] . '/fields/' . $this->object['field_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Field object
|
||||
*/
|
||||
class i18n_field extends i18n_field_base {
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* For convenience field objects can be built from field info and from field instance.
|
||||
*/
|
||||
public function __construct($type, $key, $object) {
|
||||
parent::__construct($type, $key, $object);
|
||||
|
||||
// If this is a field instance, get field info but add instance data too.
|
||||
// This instance data will be used to get the paths to get the edit/translate path.
|
||||
if (isset($this->object['bundle']) && isset($this->object['entity_type'])) {
|
||||
$this->object = field_info_field($this->object['field_name']) + array('bundle' => $this->object['bundle'], 'entity_type' => $object['entity_type']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get edit path for object
|
||||
*/
|
||||
public function get_edit_path() {
|
||||
return $this->get_base_path() . '/field-settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get translate path for object
|
||||
*/
|
||||
public function get_translate_path($langcode = NULL) {
|
||||
return $this->get_base_path() . '/translate/field' . ($langcode ? '/' . $langcode : '');
|
||||
}
|
||||
/**
|
||||
* Get string context
|
||||
*/
|
||||
public function get_string_context() {
|
||||
return array($this->object['field_name'], '#field');
|
||||
}
|
||||
/**
|
||||
* Get translatable properties
|
||||
*/
|
||||
protected function build_properties() {
|
||||
$properties = parent::build_properties();
|
||||
$object = $this->object;
|
||||
// For select fields field:field_name
|
||||
if (!empty($object['settings']['allowed_values']) && i18n_field_type_info($object['type'], 'translate_options')) {
|
||||
//return array('field', $field['field_name'], '#allowed_values');
|
||||
foreach ($object['settings']['allowed_values'] as $key => $value) {
|
||||
$properties[$this->get_textgroup()][$object['field_name']]['#allowed_values'][$key] = array(
|
||||
'title' => t('Option %name', array('%name' => $value)),
|
||||
'string' => $value,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context to be pre-loaded before translation.
|
||||
*/
|
||||
protected function get_translate_context($langcode, $options) {
|
||||
return array(
|
||||
$this->object['field_name'],
|
||||
array('#field', '#allowed_values'),
|
||||
'*'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field translation for object.
|
||||
*
|
||||
* Mot often, this is a direct field set, but sometimes fields may have different formats.
|
||||
*
|
||||
* @param $object
|
||||
* A clone of the object or array. Field instance.
|
||||
*/
|
||||
protected function translate_field(&$object, $i18nstring, $langcode, $options) {
|
||||
if ($i18nstring->objectid == '#allowed_values') {
|
||||
$object['settings']['#allowed_values'][$i18nstring->key] = $i18nstring->format_translation($langcode, $options);
|
||||
}
|
||||
else {
|
||||
parent::translate_field($object, $i18nstring, $langcode, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Field instance object
|
||||
*/
|
||||
class i18n_field_instance extends i18n_field_base {
|
||||
/**
|
||||
* Get edit path for object
|
||||
*/
|
||||
public function get_edit_path() {
|
||||
return $this->get_base_path();
|
||||
}
|
||||
/**
|
||||
* Get translate path for object
|
||||
*/
|
||||
public function get_translate_path($langcode = NULL) {
|
||||
return $this->get_base_path() . '/translate' . ($langcode ? '/' . $langcode : '');
|
||||
}
|
||||
/**
|
||||
* Get string context
|
||||
*/
|
||||
public function get_string_context() {
|
||||
return array($this->object['field_name'], $this->object['bundle']);
|
||||
}
|
||||
/**
|
||||
* Get translatable properties
|
||||
*/
|
||||
protected function build_properties() {
|
||||
$properties = parent::build_properties();
|
||||
$object = $this->object;
|
||||
$field = field_info_field($object['field_name']);
|
||||
// Only for text field types
|
||||
if (!empty($object['default_value']) && i18n_field_type_info($field['type'], 'translate_default')) {
|
||||
$format = isset($object['default_value'][0]['format']) ? $object['default_value'][0]['format'] : NULL;
|
||||
$properties[$this->get_textgroup()][$object['field_name']][$object['bundle']]['default_value']['string'] = $object['default_value'][0]['value'];
|
||||
$properties[$this->get_textgroup()][$object['field_name']][$object['bundle']]['default_value']['format'] = $format;
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field translation for object.
|
||||
*
|
||||
* Mot often, this is a direct field set, but sometimes fields may have different formats.
|
||||
*
|
||||
* @param $object
|
||||
* A clone of the object or array. Field instance.
|
||||
*/
|
||||
protected function translate_field(&$object, $i18nstring, $langcode, $options) {
|
||||
if ($i18nstring->property == 'default_value') {
|
||||
// Render string without applying format
|
||||
$object['default_value'][0]['value'] = $i18nstring->format_translation($langcode, array('sanitize' => FALSE) + $options);
|
||||
}
|
||||
else {
|
||||
parent::translate_field($object, $i18nstring, $langcode, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Context to be pre-loaded before translation.
|
||||
*/
|
||||
protected function get_translate_context($langcode, $options) {
|
||||
return array(
|
||||
$this->object['field_name'],
|
||||
array('#field', '#allowed_values', $this->object['bundle']),
|
||||
'*'
|
||||
);
|
||||
}
|
||||
}
|
14
sites/all/modules/i18n/i18n_field/i18n_field.info
Normal file
14
sites/all/modules/i18n/i18n_field/i18n_field.info
Normal file
@@ -0,0 +1,14 @@
|
||||
name = Field translation
|
||||
description = Translate field properties
|
||||
dependencies[] = field
|
||||
dependencies[] = i18n_string
|
||||
package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
files[] = i18n_field.inc
|
||||
files[] = i18n_field.test
|
||||
; Information added by drupal.org packaging script on 2013-01-13
|
||||
version = "7.x-1.8"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1358075001"
|
||||
|
85
sites/all/modules/i18n/i18n_field/i18n_field.install
Normal file
85
sites/all/modules/i18n/i18n_field/i18n_field.install
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the i18n_field module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function i18n_field_install() {
|
||||
// If updating from D6, module changed name
|
||||
if (variable_get('i18n_drupal6_update')) {
|
||||
i18n_field_update_7000();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_update_dependencies()
|
||||
*/
|
||||
function i18n_field_update_dependencies() {
|
||||
$dependencies['i18n_field'][7000] = array(
|
||||
'i18n_string' => 7001,
|
||||
);
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_drupal6_update().
|
||||
*
|
||||
* Update old string names
|
||||
*/
|
||||
function i18n_field_update_7000() {
|
||||
// @todo
|
||||
module_load_install('i18n_string');
|
||||
// Old CCK label and description
|
||||
$query = db_select('i18n_string', 's')
|
||||
->fields('s')
|
||||
->condition('textgroup', 'cck')
|
||||
->condition('type', 'field');
|
||||
foreach ($query->execute() as $string) {
|
||||
$string->textgroup = 'field';
|
||||
list($bundle, $field) = explode('-', $string->objectid);
|
||||
$string->type = $field;
|
||||
$string->objectid = $bundle;
|
||||
$string->property = str_replace('widget_', '', $string->property);
|
||||
i18n_string_install_update_string($string);
|
||||
}
|
||||
// @todo Field groups ??
|
||||
// Old Profile fields
|
||||
$query = db_select('i18n_string', 's')
|
||||
->fields('s')
|
||||
->condition('textgroup', 'profile')
|
||||
->condition('type', 'field');
|
||||
foreach ($query->execute() as $string) {
|
||||
$string->textgroup = 'field';
|
||||
$string->type = $string->property;
|
||||
if ($string->objectid == 'options') {
|
||||
// @todo Handle field options
|
||||
$string->objectid = '#allowed_values';
|
||||
}
|
||||
else {
|
||||
$string->objectid = 'user'; // Bundle for profile fields
|
||||
i18n_string_install_update_string($string);
|
||||
}
|
||||
}
|
||||
// @todo Profile categories ??
|
||||
}
|
||||
|
||||
/**
|
||||
* Old strings to update. All these will be handled by i18n_field module
|
||||
*
|
||||
* 'cck:field:'. $content_type .'-'. $field_name .':widget_label'
|
||||
* --> 'field:$field_name:$bundle:label' (though not used atm)
|
||||
* 'cck:field:'. $content_type .'-'. $field_name .':widget_description'
|
||||
* --> 'field:$field_name:$bundle:description'
|
||||
* 'cck:fieldgroup:'. $content_type .'-'. $group_name .':display_description'
|
||||
* 'cck:fieldgroup:'. $content_type .'-'. $group_name .':form_description', $group['settings']['form']['description']);
|
||||
*
|
||||
* Profile:
|
||||
* profile:field:$field_name:title|explanation|options
|
||||
* "profile:category", $field->category
|
||||
*
|
||||
*/
|
380
sites/all/modules/i18n/i18n_field/i18n_field.module
Normal file
380
sites/all/modules/i18n/i18n_field/i18n_field.module
Normal file
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Internationalization (i18n) module - Field handling
|
||||
*
|
||||
* For string keys we use:
|
||||
* - field:[field_name]:[bundle]:property, when it is an instance property (linked to bundle)
|
||||
* - field:[field_name]:#property..., when it is a field property (that may have multiple values)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function i18n_field_menu() {
|
||||
$items = array();
|
||||
|
||||
// Ensure the following is not executed until field_bundles is working and
|
||||
// tables are updated. Needed to avoid errors on initial installation.
|
||||
if (!module_exists('field_ui') || defined('MAINTENANCE_MODE')) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
// Create tabs for all possible bundles. From field_ui_menu().
|
||||
foreach (entity_get_info() as $entity_type => $entity_info) {
|
||||
if ($entity_info['fieldable']) {
|
||||
foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) {
|
||||
if (isset($bundle_info['admin'])) {
|
||||
// Extract path information from the bundle.
|
||||
$path = $bundle_info['admin']['path'];
|
||||
// Different bundles can appear on the same path (e.g. %node_type and
|
||||
// %comment_node_type). To allow field_ui_menu_load() to extract the
|
||||
// actual bundle object from the translated menu router path
|
||||
// arguments, we need to identify the argument position of the bundle
|
||||
// name string ('bundle argument') and pass that position to the menu
|
||||
// loader. The position needs to be casted into a string; otherwise it
|
||||
// would be replaced with the bundle name string.
|
||||
if (isset($bundle_info['admin']['bundle argument'])) {
|
||||
$bundle_arg = $bundle_info['admin']['bundle argument'];
|
||||
$bundle_pos = (string) $bundle_arg;
|
||||
}
|
||||
else {
|
||||
$bundle_arg = $bundle_name;
|
||||
$bundle_pos = '0';
|
||||
}
|
||||
// This is the position of the %field_ui_menu placeholder in the
|
||||
// items below.
|
||||
$field_position = count(explode('/', $path)) + 1;
|
||||
|
||||
// Extract access information, providing defaults.
|
||||
$access = array_intersect_key($bundle_info['admin'], drupal_map_assoc(array('access callback', 'access arguments')));
|
||||
$access += array(
|
||||
'access callback' => 'user_access',
|
||||
'access arguments' => array('administer site configuration'),
|
||||
);
|
||||
$items["$path/fields/%field_ui_menu/translate"] = array(
|
||||
'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
|
||||
'title' => 'Translate',
|
||||
'page callback' => 'i18n_field_page_translate',
|
||||
'page arguments' => array($field_position),
|
||||
'file' => 'i18n_field.pages.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
) + $access;
|
||||
|
||||
$items["$path/fields/%field_ui_menu/translate/%i18n_language"] = array(
|
||||
'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
|
||||
'title' => 'Instance',
|
||||
'page callback' => 'i18n_field_page_translate',
|
||||
'page arguments' => array($field_position, $field_position + 2),
|
||||
'file' => 'i18n_field.pages.inc',
|
||||
'type' => MENU_CALLBACK,
|
||||
) + $access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_hook_info().
|
||||
*/
|
||||
function i18n_field_hook_info() {
|
||||
$hooks['i18n_field_info'] = array(
|
||||
'group' => 'i18n',
|
||||
);
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_attach_form().
|
||||
*
|
||||
* After the form fields are built. Translate title and description for fields with multiple values.
|
||||
*/
|
||||
function i18n_field_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
|
||||
// Determine the list of instances to iterate on.
|
||||
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
|
||||
$instances = field_info_instances($entity_type, $bundle);
|
||||
foreach ($instances as $field_name => $instance) {
|
||||
if (isset($form[$field_name])) {
|
||||
$langcode = $form[$field_name]['#language'];
|
||||
$field = &$form[$field_name];
|
||||
// Note: cardinality for unlimited fields is -1
|
||||
if (isset($field[$langcode]['#cardinality']) && $field[$langcode]['#cardinality'] != 1) {
|
||||
$translated = i18n_string_object_translate('field_instance', $instance);
|
||||
if (!empty($field[$langcode]['#title'])) {
|
||||
$field[$langcode]['#title'] = $translated['label'];
|
||||
}
|
||||
if (!empty($field[$langcode]['#description'])) {
|
||||
$field[$langcode]['#description'] = $translated['description'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_info().
|
||||
*/
|
||||
function i18n_field_field_formatter_info() {
|
||||
$types = array();
|
||||
foreach (i18n_field_type_info() as $type => $info) {
|
||||
if (!empty($info['translate_options'])) {
|
||||
$types[] = $type;
|
||||
}
|
||||
}
|
||||
return array(
|
||||
'i18n_list_default' => array(
|
||||
'label' => t('Default translated'),
|
||||
'field types' => $types,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_formatter_view().
|
||||
*/
|
||||
function i18n_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
|
||||
$element = array();
|
||||
|
||||
switch ($display['type']) {
|
||||
case 'i18n_list_default':
|
||||
if (($translate = i18n_field_type_info($field['type'], 'translate_options'))) {
|
||||
$allowed_values = $translate($field);
|
||||
}
|
||||
else {
|
||||
// Defaults to list_default behavior
|
||||
$allowed_values = list_allowed_values($field);
|
||||
}
|
||||
foreach ($items as $delta => $item) {
|
||||
if (isset($allowed_values[$item['value']])) {
|
||||
$output = field_filter_xss($allowed_values[$item['value']]);
|
||||
}
|
||||
else {
|
||||
// If no match was found in allowed values, fall back to the key.
|
||||
$output = field_filter_xss($item['value']);
|
||||
}
|
||||
$element[$delta] = array('#markup' => $output);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_form_alter().
|
||||
*
|
||||
* Translate:
|
||||
* - Title (label)
|
||||
* - Description (help)
|
||||
* - Default value
|
||||
* - List options
|
||||
*/
|
||||
function i18n_field_field_widget_form_alter(&$element, &$form_state, $context) {
|
||||
global $language;
|
||||
|
||||
// Skip the node type edit fields by checking for existing entity
|
||||
if (empty($element['#entity'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if we are missing any of the parameters
|
||||
if (empty($context['field']) || empty($context['instance']) || empty($context['langcode'])) {
|
||||
return;
|
||||
}
|
||||
$field = $context['field'];
|
||||
$instance = $context['instance'];
|
||||
$langcode = $context['langcode'];
|
||||
|
||||
// The field language may affect some variables (default) but not others (description will be in current page language)
|
||||
$i18n_langcode = empty($element['#language']) || $element['#language'] == LANGUAGE_NONE ? $language->language : $element['#language'];
|
||||
|
||||
// Translate instance to current page language and set to form_state
|
||||
// so it will be used for validation messages later.
|
||||
$instance_current = i18n_string_object_translate('field_instance', $instance);
|
||||
if (isset($form_state['field'][$instance['field_name']][$langcode]['instance'])) {
|
||||
$form_state['field'][$instance['field_name']][$langcode]['instance'] = $instance_current;
|
||||
}
|
||||
|
||||
// Translate field title if set and it is the default one.
|
||||
// When cardinality is 1, $element['value'] is used instead.
|
||||
if (!empty($instance_current['label']) && $instance_current['label'] != $instance['label']) {
|
||||
if (!empty($element['#title']) && $element['#title'] == $instance['label']) {
|
||||
$element['#title'] = $instance_current['label'];
|
||||
}
|
||||
if (isset($element['value']) && !empty($element['value']['#title']) && $element['value']['#title'] == $instance['label']) {
|
||||
$element['value']['#title'] = $instance_current['label'];
|
||||
}
|
||||
}
|
||||
|
||||
// Translate field description if set and it is the default one.
|
||||
// When cardinality is 1, $element['value'] is used instead.
|
||||
if (!empty($instance_current['description']) && $instance_current['description'] != $instance['description']) {
|
||||
if (!empty($element['#description']) && $element['#description'] == $instance['description']) {
|
||||
$element['#description'] = $instance_current['description'];
|
||||
}
|
||||
if (isset($element['value']) && !empty($element['value']['#description']) && $element['value']['#description'] == $instance['description']) {
|
||||
$element['value']['#description'] = $instance_current['description'];
|
||||
}
|
||||
}
|
||||
|
||||
// Translate list options
|
||||
if (!empty($element['#options']) && ($translate = i18n_field_type_info($field['type'], 'translate_options')) && !empty($field['settings']['allowed_values'])) {
|
||||
$element['#options'] = $translate($field, $i18n_langcode);
|
||||
if (isset($element['#properties']) && !empty($element['#properties']['empty_option'])) {
|
||||
$label = theme('options_none', array('instance' => $instance, 'option' => $element['#properties']['empty_option']));
|
||||
$element['#options'] = array('_none' => $label) + $element['#options'];
|
||||
// For some elements, change title to new translated option
|
||||
if (!empty($element['#title']) && $field['type'] == 'list_boolean' && !empty($element['#on_value'])) {
|
||||
$on_value = $element['#on_value'];
|
||||
$element['#title'] = $element['#options'][$on_value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for more parameters, skip this part if missing.
|
||||
if (!isset($context['delta']) || !isset($context['items'])) {
|
||||
return;
|
||||
}
|
||||
$delta = $context['delta'];
|
||||
$items = $context['items'];
|
||||
|
||||
// Translate default value if exists and the current value is the default
|
||||
if (isset($element['value']['#default_value']) && ($translate = i18n_field_type_info($field['type'], 'translate_default')) &&
|
||||
!empty($instance['default_value'][$delta]['value']) && !empty($items[$delta]['value']) &&
|
||||
$instance['default_value'][$delta]['value'] === $items[$delta]['value']) {
|
||||
$element['value']['#default_value'] = $translate($instance, $items[$delta]['value'], $i18n_langcode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_attach_view_alter().
|
||||
*/
|
||||
function i18n_field_field_attach_view_alter(&$output, $context) {
|
||||
foreach (element_children($output) as $field_name) {
|
||||
$element = &$output[$field_name];
|
||||
if (!empty($element['#entity_type']) && !empty($element['#field_name']) && !empty($element['#bundle'])) {
|
||||
$instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
|
||||
|
||||
// Translate field title if set
|
||||
if (!empty($instance['label'])) {
|
||||
$element['#title'] = i18n_field_translate_property($instance, 'label');
|
||||
}
|
||||
|
||||
// Translate field description if set
|
||||
if (!empty($instance['description'])) {
|
||||
$element['#description'] = i18n_field_translate_property($instance, 'description');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_create_field().
|
||||
*/
|
||||
function i18n_field_field_create_field($field) {
|
||||
i18n_field_field_update_strings($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_create_instance().
|
||||
*/
|
||||
function i18n_field_field_create_instance($instance) {
|
||||
i18n_field_instance_update_strings($instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_delete_instance().
|
||||
*/
|
||||
function i18n_field_field_delete_instance($instance) {
|
||||
i18n_string_object_remove('field_instance', $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_update_instance().
|
||||
*/
|
||||
function i18n_field_field_update_instance($instance, $prior_instance) {
|
||||
i18n_field_instance_update_strings($instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_update_field().
|
||||
*/
|
||||
function i18n_field_field_update_field($field) {
|
||||
i18n_field_field_update_strings($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update field strings
|
||||
*/
|
||||
function i18n_field_field_update_strings($field) {
|
||||
i18n_string_object_update('field', $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update field instance strings
|
||||
*/
|
||||
function i18n_field_instance_update_strings($instance) {
|
||||
i18n_string_object_update('field_instance', $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of translated allowed values for a list field.
|
||||
*
|
||||
* The strings are not safe for output. Keys and values of the array should be
|
||||
* sanitized through field_filter_xss() before being displayed.
|
||||
*
|
||||
* @param $field
|
||||
* The field definition.
|
||||
*
|
||||
* @return
|
||||
* The array of allowed values. Keys of the array are the raw stored values
|
||||
* (number or text), values of the array are the display labels.
|
||||
*/
|
||||
function i18n_field_translate_allowed_values($field, $langcode = NULL) {
|
||||
if (!empty($field['settings']['allowed_values'])) {
|
||||
return i18n_string_translate(array('field', $field['field_name'], '#allowed_values'), $field['settings']['allowed_values'], array('langcode' => $langcode, 'sanitize' => FALSE));
|
||||
}
|
||||
else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate field default
|
||||
*/
|
||||
function i18n_field_translate_default($instance, $value, $langcode = NULL) {
|
||||
return i18n_string_translate(array('field', $instance['field_name'], $instance['bundle'], 'default_value'), $value, array('langcode' => $langcode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate field property
|
||||
*/
|
||||
function i18n_field_translate_property($instance, $property, $langcode = NULL) {
|
||||
// For performance reasons, we translate the whole instance once, which is cached.
|
||||
$instance = i18n_string_object_translate('field_instance', $instance, array('langcode' => $langcode));
|
||||
return $instance[$property];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get i18n information for fields
|
||||
*/
|
||||
function i18n_field_type_info($type = NULL, $property = NULL) {
|
||||
$info = &drupal_static(__FUNCTION__);
|
||||
if (!isset($info)) {
|
||||
$info = module_invoke_all('i18n_field_info');
|
||||
drupal_alter('i18n_field_info', $info);
|
||||
}
|
||||
if ($property) {
|
||||
return isset($info[$type]) && isset($info[$type][$property]) ? $info[$type][$property] : NULL;
|
||||
}
|
||||
elseif ($type) {
|
||||
return isset($info[$type]) ? $info[$type] : array();
|
||||
}
|
||||
else {
|
||||
return $info;
|
||||
}
|
||||
}
|
36
sites/all/modules/i18n/i18n_field/i18n_field.pages.inc
Normal file
36
sites/all/modules/i18n/i18n_field/i18n_field.pages.inc
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Translation page for fields.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Field translation page
|
||||
*
|
||||
* We need to translate field and field instance.
|
||||
*/
|
||||
function i18n_field_page_translate($instance, $language = NULL) {
|
||||
module_load_include('inc', 'i18n_string', 'i18n_string.pages');
|
||||
if (!$language) {
|
||||
// Overview page will be the regular one
|
||||
return i18n_string_translate_page_object('field_instance', $instance);
|
||||
}
|
||||
else {
|
||||
// Because of some weird menu mapping for comment fields language object loader is not working.
|
||||
$language = i18n_language_object($language);
|
||||
drupal_set_title(t('Translate to !language', array('!language' => i18n_language_name($language->language))));
|
||||
//return drupal_get_form('i18n_field_page_translate_form', $instance, $language->language);
|
||||
// Create form with two tabs, one for instance, once for field.
|
||||
$groups = array(
|
||||
'instance' => t('Field instance'),
|
||||
'field' => t('Field settings'),
|
||||
);
|
||||
// Field instance
|
||||
$instance_object = i18n_object('field_instance', $instance);
|
||||
$strings['instance'] = $instance_object->get_strings(array('empty' => TRUE));
|
||||
// Field settings
|
||||
$field_object = i18n_object('field', $instance);
|
||||
$strings['field'] = $field_object->get_strings(array('empty' => TRUE));
|
||||
return drupal_get_form('i18n_string_translate_page_form', $strings, $language->language, $groups);
|
||||
}
|
||||
}
|
129
sites/all/modules/i18n/i18n_field/i18n_field.test
Normal file
129
sites/all/modules/i18n/i18n_field/i18n_field.test
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Test case for multilingual fields.
|
||||
*/
|
||||
|
||||
|
||||
class i18nFieldTestCase extends Drupali18nTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Field translation',
|
||||
'group' => 'Internationalization',
|
||||
'description' => 'Field translation functions'
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('i18n_field', 'field_test');
|
||||
parent::setUpLanguages(array('access field_test content', 'administer field_test content'));
|
||||
$this->translator = $this->drupalCreateUser(array('translate interface', 'translate user-defined strings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the translation of list fields, including allowed values.
|
||||
*/
|
||||
function testListFieldTranslation() {
|
||||
$field_name = drupal_strtolower($this->randomName());
|
||||
$label = $this->randomName();
|
||||
$description = $this->randomName();
|
||||
$value = $this->randomName();
|
||||
|
||||
$field = array(
|
||||
'field_name' => $field_name,
|
||||
'type' => 'list_integer',
|
||||
'cardinality' => 1,
|
||||
'settings' => array(
|
||||
'allowed_values' => array(1 => $value),
|
||||
),
|
||||
);
|
||||
$field = field_create_field($field);
|
||||
|
||||
$instance = array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'label' => $label,
|
||||
'description' => $description,
|
||||
'widget' => array(
|
||||
'type' => 'options_buttons',
|
||||
),
|
||||
);
|
||||
$instance = field_create_instance($instance);
|
||||
|
||||
// Refresh i18n_strings.
|
||||
$edit = array('groups[field]' => TRUE);
|
||||
$this->drupalPost('admin/config/regional/translate/i18n_string', $edit, t('Refresh strings'));
|
||||
|
||||
// Save translations for each attribute.
|
||||
$label_translation = $this->createStringTranslation('field', $label);
|
||||
$description_translation = $this->createStringTranslation('field', $description);
|
||||
$value_translation = $this->createStringTranslation('field', $value);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
// Test untranslated values in default language.
|
||||
$this->drupalGet('test-entity/add/test-bundle');
|
||||
$this->assertText($label, 'Field label is not translated');
|
||||
$this->assertText($description, 'Field description is not translated');
|
||||
$this->assertText($value, 'Field allowed values are not translated');
|
||||
|
||||
// Test translated values in secondary language.
|
||||
$this->drupalGet($this->secondary_language . '/test-entity/add/test-bundle');
|
||||
$this->assertText($label_translation[$this->secondary_language], 'Field label is translated');
|
||||
$this->assertText($description_translation[$this->secondary_language], 'Field description is translated');
|
||||
$this->assertText($value_translation[$this->secondary_language], 'Field allowed values are translated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the translation of text fields, including default values.
|
||||
*/
|
||||
function testTextFieldTranslation() {
|
||||
$field_name = drupal_strtolower($this->randomName());
|
||||
$label = $this->randomName();
|
||||
$description = $this->randomName();
|
||||
$default_value = $this->randomName();
|
||||
|
||||
$field = array(
|
||||
'field_name' => $field_name,
|
||||
'type' => 'text',
|
||||
'cardinality' => 1,
|
||||
);
|
||||
$field = field_create_field($field);
|
||||
|
||||
$instance = array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'label' => $label,
|
||||
'description' => $description,
|
||||
'default_value' => array(0 => array('value' => $default_value)),
|
||||
'widget' => array(
|
||||
'type' => 'text_textfield',
|
||||
),
|
||||
);
|
||||
$instance = field_create_instance($instance);
|
||||
|
||||
// Refresh i18n_strings.
|
||||
$edit = array('groups[field]' => TRUE);
|
||||
$this->drupalPost('admin/config/regional/translate/i18n_string', $edit, t('Refresh strings'));
|
||||
|
||||
// Save translations for each attribute.
|
||||
$label_translation = $this->createStringTranslation('field', $label);
|
||||
$description_translation = $this->createStringTranslation('field', $description);
|
||||
$default_value_translation = $this->createStringTranslation('field', $default_value);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
// Test untranslated values in default language.
|
||||
$this->drupalGet('test-entity/add/test-bundle');
|
||||
$this->assertText($label, 'Field label is not translated');
|
||||
$this->assertText($description, 'Field description is not translated');
|
||||
$this->assertRaw($default_value, 'Default value is not translated');
|
||||
|
||||
// Test translated values in secondary language.
|
||||
$this->drupalGet($this->secondary_language . '/test-entity/add/test-bundle');
|
||||
$this->assertText($label_translation[$this->secondary_language], 'Field label is translated');
|
||||
$this->assertText($description_translation[$this->secondary_language], 'Field description is translated');
|
||||
$this->assertRaw($default_value_translation[$this->secondary_language], 'Default value translated');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user