Greetings! I'm trying to solve a problem i have for 2 days already, but without luck. I checked every single thread on it could, but still didn't find an answer. Please help!
The question is: how to translate custom entity using Entity translation module?
P.S. i checked commerce product for reference, but really don't get it.
I have a custom entity module, and i want to make that custom entity multilingual (i want some fields to be translatable on my custom entity for different languages). So i thought i can use Entity Translation module to do just that. I create simple module to test things out. Here is complete code:
test.info:
name = Test module
description = Test module to test entity trasnlation
core = 7.x
test.install
<?php
/**
* Implements hook_schema().
*/
function test_schema() {
$schema = array();
$schema['test_custom_entity'] = array(
'description' => 'The base table for the Custom entity',
'fields' => array(
'id' => array(
'description' => 'Primary key of the Custom entity',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'name' => array(
'description' => 'Custom entity name.',
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
),
'primary key' => array('id'),
);
return $schema;
}
?>
test.module
<?php
/**
* Implements hook_entity_info().
*/
function test_entity_info()
{
$info = array();
$info['custom_entity'] = array(
'label' => t('Custom entity'),
'base table' => 'test_custom_entity',
'entity keys' => array(
'id' => 'id',
'label' => 'name',
),
'module' => 'test',
'entity class' => 'Entity',
'controller class' => 'EntityAPIController',
'admin ui' => array(
'path' => 'admin/custom_entities',
'controller class' => 'EntityDefaultUIController',
),
'access callback' => 'test_access_callback',
'fieldable' => TRUE,
'bundles' => array(
'custom_entity' => array(
'label' => t('Custom entity'),
'admin' => array(
'path' => 'admin/custom_entities',
),
),
),
'translation' => array(
'entity_translation' => array(
'class' => 'EntityTranslationDefaultHandler',
'default settings' => array(
'default_language' => LANGUAGE_NONE,
'hide_language_selector' => FALSE,
),
'base path' => 'admin/custom_entities/manage/%',
'path wildcard' => '%',
'access callback' => 'test_entity_translation_tab_access'
),
),
);
return $info;
}
function custom_entity_form($form, &$form_state, $entity = NULL)
{
$form['name'] = array(
'#title' => t('Entry name'),
'#type' => 'textfield',
'#default_value' => isset($entity->name) ? $entity->name : '',
'#required' => TRUE,
);
field_attach_form('custom_entity', $entity, $form, $form_state);
$form['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#value' => isset($crpc->id) ? t('Update') : t('Save'),
]
];
return $form;
}
/**
* Submit handler for the add/edit form.
*/
function custom_entity_form_submit($form, &$form_state)
{
$entity = entity_ui_form_submit_build_entity($form, $form_state);
$entity->save();
drupal_set_message(t('The entry: @name has been saved.', array('@name' => $entity->name)));
$form_state['redirect'] = 'admin/custom_entities';
}
function test_permission()
{
return [
'administer test' => [
t('Administer Test module')
]
];
}
/**
* Check access permissions for cr product compatibles
*/
function test_access_callback($op, $entity = null, $account = null)
{
if (user_access('administer test', $account)) {
return true;
}
return false;
}
/**
* Access callback: determines access to a product's translation tab.
*/
function test_entity_translation_tab_access($entity) {
return entity_translation_tab_access('custom_entity', $entity);
}
?>
I suspect that I have problem with 'base path'. I don't understand it's conception. I thought it will work like this:
'base path' => 'admin/custom_entities/%custom_entity'
but it doesn't. Also i don't understand what means %custom_entity, because i don't see it in the URL. Is it related to url at all?
Here is description of the problem i have:
Currently i was managed to get `Translate` tab only when i use following configuration. I came to this kinda randomly, but it works:
'base path' => 'admin/custom_entities/manage/%',
'path wildcard' => '%',
At the same time I don't know why it doesn't work like that: 'base path' => 'admin/custom_entities/%custom_entity'
But even if Translate tab is available, it still doesn't work:
Here is custom-entity-entry edit form:

Here is custom-entity-translate-tab:

Here is what happens when i go to `edit` link or `add` link, empty values, no content!:

I'm trying to understand what am i doing wrong in my custom entity so it doesn't show entity values in my entity-translation form (as far as i see when debugging it uses integer value instead of entity object, but i have no clue why, probably base path problem?) and how to understand what base path is? Thanks!
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | custom_entity_translate_tab_wrong_location.png | 19.66 KB | phpcoder2015 |
| custom_entity_edit_translation.png | 11.89 KB | phpcoder2015 | |
| custom_entity_translate_tab.png | 17.4 KB | phpcoder2015 | |
| custom_entity_edit_form.png | 10.74 KB | phpcoder2015 |
Comments
Comment #1
nickolas.wilson commentedLooking over your code, I'd give a good guess it is due to missing the following things. It took me many sleepless nights to get this to work myself. The Documentation on this area really does suck.
Anyway, this is what has worked for me...
yourmodule.install >
yourmodule.module >
hook_entity_info() >
hook_entity_form() >>
Hopefully that will fix your problems.
Also, make sure you have activated the custom entity on the Entity Translation config page (your.domain.com/admin/config/regional/entity_translation)... I've forgotten a few times and it drove me nuts... :)
EDIT:
After writing this, I thought I'd better go through my module. It turns out that, I have a problem with adding new translations.. So there may be problems with my answer above. Though, I do think it will fix some of the problems you are having. Soon as I have worked out my problems, I'll update it here.
Comment #2
phpcoder2015 commentedThank you Nickolas! Yeah, i tested it out and there are still problems. As I said probably something is wrong with 'base path' I use. In Commerce Product i see that during debugging Entity object is passed to edit form, while in my code it passes entity id, this is why i can't see entity-entry values. But i don't know how to fix it yet, unfortunately.
I also think that
should match, like
This is why i specify 'path wildcard' explicitly, to let system know that i use custom path wildcard. Probably this is also a point where problem happens. Still don't know why normal '%custom_entity' doesn't work. Actually translate tab only appears in each entity-entry (where it's needed) when i use that latest piece of code above:
but as i said, in that case only entity id instead of entity object is passed to translate-edit-trasnlation form which turns into empty entity-entry values. So this makes me think i need to adapt '%custom_entity' because it somehow says system to pass entity object instead of entity-id param like '3'. Probably another question is which mechanism causes param-to-entity-object conversion.
Comment #3
nickolas.wilson commentedOh, I made a mistake. (I'll change it above as well as noting it here.)
Should of been this >
From my understanding of the function of 'path wildcard' is to set your alias of your entity type so it can retrieve the entity id/identifier. This is only required when you have multiple bundles and need different alias for each one. I think your understanding of the function is incorrect.
From API info:
* - path wildcard: The menu router path wildcard identifying the entity.
* Defaults to %ENTITY_TYPE.
From what you just wrote, you are saying that your form does not retrieve the data from the DB?
Have you tested your entity with translate disabled?
Comment #4
phpcoder2015 commentedCRUD works fine on custom-entity-entries itself, but if i use:
or as you mentioned, we can simply specify 'base path' without 'path wildcard' since entity id is as expected - '%custom_entity':
However, in that case 'TRANSLATE' tab appears inside 'Custom entitys' list, instead of inside inside each custom-entity-entry:
This initially was a problem and i started to try different combinations with base path like 'admin/custom_entities/manage/%' after which 'TRANSLATE' tab appears where it's needed, but still doesn't work correctly.
Comment #5
nickolas.wilson commentedUmmm, how about adding 'translate path'...
This is a guess, but it might sort out the problem of the translate tab's location.
Comment #6
phpcoder2015 commentedNo, it unfortunately still displays 'TRANSLATE' tab on `custom-entitys` list page (as far as i know all other paths are based on 'base path' so we can omit it in configuration array). Maybe explicit hook_menu() entry is needed to make everything work, but i'm not sure. I'll try to re-investigate Commerce Product module and it's Commerce Product UI companion module.
Btw i'm surprised that custom entities translation is such an uncommon topic. I thought a lot of people need it or is there another way to store multilingual content in custom db table? I tried nodes for this but performance is so low that it takes a lot to load nodes i need on single page request, so i wanted to create custom entity instead (since i need custom db table and admin UI), but obviously it is troublesome at the moment since there are no good basic examples..
Comment #7
phpcoder2015 commentedDidn't fully test it yet because I'm heavily into Drupal 8 now, but this is what I did and now tab content appears correctly for both add and edit forms. Just needed to append these 2 functions inside test.module:
I took it from commerce product module and adapted to my custom-entity.
How did I came up to this? This is excerpt from Pro Drupal 7 Development book:
So this is why i had (for example) '1' (integer value) passed as $entity_object instead of actual object. So to fix this you need to use _load function as explained in the steps above.
Hope it will help to someone, since i spent several days trying to figure everything out :)
Comment #8
phpcoder2015 commentedComment #9
falco010This helped me out a lot guys, thank you very much!