1

I have a multilingual site with 3 languages where only 1 field (Description) is really multilingual, everything else is a translated interface and strings.

For the Description field, it has been my aim to replicate the functionality of Wordpress's "qTranslate" plugin so that the UI looks something like this: enter image description here

I have almost managed to achieve this using Fieldgroup module, 3 description fields, and Language Sections module (because I found no better way to assign each field to its language).

So far so good. But at the top of each field I have to put in default texts (=fr =en= =el=) so that Language Sections module knows which field is which language and displays the correct text depending on which is the current language. If the end-users delete those =en= and =fr= tags, then the whole thing falls apart.

So I need a module that will inject those =fr= and =en= tags at the beginning of each textfield's entered text, in a way that's completely transparent to the user. Is there such a module? Can Rules achieve a functionality like this?

Alternatively, if there is no such module, how would one go about creating one? Which function or which hook to use?


UPDATE I made this module called language_markers based on the answer given by Beebee ,but it didn't work. Can you pleasetellmewhat I'mdoing wrong? :

<?php

function language_markers_form_alter(&$form, &$form_state, $form_id) {
  if($form_id == 'property_for_sale_node_form' || $form_id == 'property_to_rent_node_form') {
    $form['#submit'][] = 'language_markers_submit_handler_function';
  }
}

function language_markers_submit_handler_function($form, &$form_state) {
  foreach($form_state['values'] as $field_name => $value) {
    switch($field_name) {
      case 'field_description_fr':
        $value = '=fr= '.$value;
        break;
      case 'field_description_nl':
        $value = '=nl= '.$value;
        break;
      case 'field_description_en':
        $value = '=en= '.$value;
        break;
    }
  }
}

UPDATE 2: I have managed to get this to work with Rules module:

Event: After updating existing content of type Property for Sale

Condition: none

Action: Set a data value Parameter: Data: [node:field-description-en..., Value: =en= [node:field-description-en:value]

It works,but when the end-user comes back to edit the node, he sees "=en=" in front of his text. That's a BAD User-Experience. This is a work-around, not a solution. I still need a solution.

  • What do you mean by invisible text? HTML <input> is what it is and it does not support locking and hiding parts of it. – Mołot Oct 11 '13 at 12:59
  • @Mołot =en= or =ru= are the tags that get filtered out by Language Sections module, which uses them to determine the language of the subsequent text and display the text incorrect language. Therefore, I want those =en= and =fr= texts to be stored in the database, but not visible to the end user. – drupalina Oct 11 '13 at 14:47
  • 2
    I've removed the word 'invisible' from the question because I think that was confusing things a bit. Could you review those small changes and make sure it still represents what you need to know? Thanks – Clive Oct 11 '13 at 16:28
  • Thanks @Clive ,I was beginning to wonder why people are voting down my question :) - it is not a stupid question. Yes, your changes are fine. By "invisible" I meant "automated" and also in away that the end-users won't be able to see when they come back to edit the node. – drupalina Oct 12 '13 at 2:51
  • Un-downvoted, now it makes sense to me. Usually invisible means style="display: none" or something analogous when talking HTML. Automated is a whole different story. – Mołot Oct 14 '13 at 8:59
2

Do your fields have a different field name per language? For example, maybe they follow some sort of convention like field_description_en, field_description_cn, field_description_de?

If so, then perhaps you can use hook_form_alter and add your own submit handler into the form like so :

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if($form_id == 'mytype_node_form') {
    $form['#submit'][] = 'my_custom_submit_handler_function';
  }
}

Then create a function my_custom_submit_handler_function($form, &$form_state). Inside the function you'll need to loop through $form_state['values'] like so and just append your language strings before the values:

function my_custom_submit_handler_function($form, &$form_state) {
  foreach($form_state['values'] as $field_name => &$value) { // <-- forgot the & here... oops
    switch($field_name) {
      case 'description_en':
        $value = '=en='.$value;
        break;
      case 'description_cn':
        $value = '=cn='.$value;
        break;
      case 'description_de':
        $value = '=de='.$value;
        break;
    }
  }
}

There's probably better ways to do it though.


Update

@drupalina I forgot to put the ampersand on the submit handler function which would have updated $form_state. Here's your code with a working version:

<?php

function language_markers_form_alter(&$form, &$form_state, $form_id) {
  if($form_id == 'property_for_sale_node_form' || $form_id == 'property_to_rent_node_form') {
    // You can remove the texts here too. Below is just an example.
    // Path inside $form may not be correct, so
    // do a var_dump($form) or dpm($form, 'form'); to check the array
    // To use dpm() you need to install "devel" module and enable it.
    #dpm($form, 'form');

    // Trim =fr= string from left side of the #value
    $form['field_description_fr']['#value'] = ltrim($form['field_description_fr']['#value'], '=fr=');
    // You might need to set the #default_value too
    $form['field_description_fr']['#default_value'] = ltrim($form['field_description_fr']['#default_value'], '=fr=');

    // Do this for each language... 
    // $form['field_description_de']['#value'] = .......


    $form['#submit'][] = 'language_markers_submit_handler_function';
  }
}

function language_markers_submit_handler_function($form, &$form_state) {
  // Note the ampersand before $value below, which allows the
  // modifications on $value to persist into $form_state
  foreach($form_state['values'] as $field_name => &$value) {
    switch($field_name) {
      case 'field_description_fr':
        $value = '=fr= '.$value;
        break;
      case 'field_description_nl':
        $value = '=nl= '.$value;
        break;
      case 'field_description_en':
        $value = '=en= '.$value;
        break;
    }
  }
}

In my opinion, this would quickly turn very unmaintainable as you get more and more fields & languages combinations. So if you are planning to have more than these description fields, I would suggest to use more general ways to find these fields and automatically remove/add the language strings. For example, using hook_field_attach_presave

  • 2
    Good answer, actually made me realise what the question was really asking :) I think you could probably do it with rules too, and also hook_field_presave(), hook_node_update(), hook_entity_update(), etc. Plenty of different places this code could go, the form submit handler seems like as good a place as any – Clive Oct 11 '13 at 16:31
  • @Beebee thanks for the code! Indeed, my 3 textarea fields are named field_description_fr field_description_nl field_description_en . I understand that I will need to create a module out of the first code, but where do I put the second code. Since I'm not much of a coder could you please rewrite your code as a module called "language_markers" for the forms IDs property_for_sale_node_form and property_to_rent_node_form . I REALLY appreciate your help! – drupalina Oct 12 '13 at 3:05
  • @Beebee I have updated my question with a custom module based on what you wrote, but it didn't work: the Language Sections module doesn't come into effect the way that it would if I actually had "=en=" and "=fr=" inside the textarea. I also tried both 'field_description_en' and 'description_en'. Can you please help? – drupalina Oct 12 '13 at 3:46
  • @drupalina check the updated answer. Sorry for late update I usually don't login to d.se on weekends :) – Beebee Oct 14 '13 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.