Posted by plach on November 4, 2012 at 3:54pm
24 followers
| Project: | Drupal core |
| Version: | 8.x-dev |
| Component: | translation_entity.module |
| Category: | task |
| Priority: | normal |
| Assigned: | catch |
| Status: | closed (fixed) |
| Issue tags: | D8MI, language-content |
Issue Summary
The #1188388: Entity translation UI in core issue had its main patch committed in comment #265.
@catch and @sun were not completely happy with what was committed so here is a follow-up since the main issue is becoming unmanageable (it has a huge number of embedded images).
Here can be found a meta issue allowing to track follow-ups: #1836086: [meta] Entity Translation UI improvements.
Comments
#1
Quoting @catch:
#2
Quoting @sun:
#3
And here is me answering one of @catch's points:
Well, this is has been straightly ported from D7. I agree we could avoid worrying about alterations, but declaring items in the menu alter hook caused a lot of pain in D7 because of missing keys added by the menu system only to items returned by
hook_menu()implementations. Moreover some module could see the items in place and some other couldn't depending on the hook execution order.I'd be ok to remove the part messing with menu loaders and just leave the essentials in place, however I think this will be totally revamped by whatever we come up with in #1783964: Allow entity types to provide menu items.
#4
@catch:
Well, at the moment only nodes have a vertical tab for the transation settings: however I agree we could try to make ET expose it. Sounds as good follow-up for the guys sprinting in Zurich.
@sun:
I already said that there are several aspects in the current architecture that I'm not happy with, but I think committing the patch was the right choice because many of them rely on changes that are not in yet or do not have a proper solution either. I think we would could easily end up not having the Entity Translation UI in core even for D8 if we we were required to fix all of them before committing the initial patch.
Well, the basic idea is pretty simple: there is an entity translation controller that alters the form provided by the entity form controller and allows to specify which language translatable values should be saved in. Most of the translation capabilities are already baked into entity forms.
I'm totally willing to refactor things so that we leverage the right tools and adhere to the best core practices, the main problem is that in many cases they are not there yet. The menu_* entity info keys are a clear example of this: they are a one-off hackish solution that I'm sure will go away as soon as we come up with something that makes actual sense (I was discussing this with @tim.plunkett yesterday), but right now we have nothing yet. And ET cannot absolutely work without being able to attach itself to to router paths and to generate entity UI urls in an entity-agnostic fashion.
The plan is exactly to address the follow-ups bound to feature-freeze (not many I believe) in these last weeks and focus on the rest afterwards. See the issue summary for a full list.
Yes, I totally wish to leverage whatever comes up from those.
They serve a double purpose:
'entity/1/edit'hence we need something more reliable.I evaluated this possibility in the early days of the D7 stuff, but it has the drawback of requiring you to provide a new class instead of just defining a couple of info elements. That said, we need a better solution for this.
(I have to go now: I will complete this answer later and a provide a patch fixing everything that does not need more discussion)
#5
Well, I introduced it to keep consistency with the entity form title displayed when ET is not enabled: currently every entity has its own variant. A method call there avoids to rewrite the whole form alteration just to alter the title. Honestly I fail to see why the existence of this method is problematic and why we should remove it.
Maybe a UX test will tell us that we need more consistency among entity form titles, at the point the method will be useless.
Well, here I was not sure whether showing always the original title or the translated version: the translated value is already available in the form. However it should be just matter of passing the current form langcode to the
label()method, although the current Entity Field API has a problem with this because if you ask for value in a language for which there is no translation, it will create an empty value and thenEntityInterface::getTranslationLanguages()will say that you have a translation also for the missing translation. Mess :)This should be fixed in #1810370: Entity Translation API improvements.
Yeah, in D7 we are using module weight +
hook_module_implements_alter(). Would that work for you?Do you mean that we should detect through
drupal_installation_attempted()whether we are installing a profile and avoid to output the message?What about showing it everytime you enable ET but only if you have only one language enabled?
This is a warning IMHO: it's saying "Man, if you don't fix the current situation things won't work".
That's a remaining of the D7 code: already agreed with @catch to remove it.
Not sure I get what you mean, I'm no config expert :)
I just tried to stick close to what we did in #1739928: Generalize language configuration on content types to apply to terms and other entities. I also read #1783346: Determine how to identify and deploy related sets of configuration but it's not very helpful right now. Basically we need to store config for each entity and bundle and we are prefixing those settings with the entity_type and bundle names.
I'll fix the rest soon along with the stuff identified by @catch.
#6
#7
Could someone create issues for the usability problems there are like loads and loads of them. I generally fail at describing multilingual things.
#8
Bojhan we are creating them right now :)
The main one (the wizard!) is #1810386: Create workflow to setup multilingual for entity types, bundles and fields (didn't update the issue summary yet).
#9
@Bojhan:
Here is the full list.
#10
Suppose first we need to remove entity_id in favor of entity_uuid! D8 entities are always has uuid assigned so I see no reason to have enetity_id as integer or long varchar
#11
I created a few follow-up issues of this one:
#1831636: "Translation is not supported if language is always one of: Not specified, Not applicable, Multiple" reword to: "...."
#1831604: Change dropbutton labels on translations tab to "add translation" / "edit translation" / "delete translation"?
#1831608: Show or hide the "Make field translatable" checkbox on the add field form depending on translatability
#12
Opened #1833022: Only display interface language detection options to customize more granularity for usability improvements in language selection, related to this issue.
#13
Follow up issues created
#1833020: Polish help page for Entity translation UI
#1833038: put "display on user registration form" also in Manage Display tab for user account settings
#1833076: expand translation settings when editing outdated translation so remember to uncheck "needs updating"
#1833096: get good workflow for dealing with translations being marked outdated
#1833104: Add a "translatable" column to Manage Fields
#1833108: disabling translation of fields with data stalls and does not work
#1833112: Make translations consistant with other delete tab patterns
#1833126: Having the original language in bold text in the node "TRANSLATIONS" tab is not semantic. make representation accessible.
#1833180: decide on name of: Original content vs Original language vs Source language vs n/a in translations overview
#1833184: Find a consistent naming scheme for translation-related modules
#1833196: could not have interface in language A and create a translation from language B to language C
#14
Guys, we have now a proper component element to filter the queue with. No point in cluttering this issue whenever a new one is created.
Let's stay focused on fixing @sun's and @catch's concerns (I should be almost there, I have some failing tests).
#15
Well, several of the issues are not for the translation_entity.module component, eg. #1831846: arg() is using _current_path() instead of current_path() or #1498880: Theme language switcher for seven theme and numerous others, so in my view, its good to see these here. The overwhelming majority of them are *not bugs*, so don't feel offended for the length of the list of followups, it just means we care a lot about making this as great as possible :)
#16
Another follow-up: #1833604: Invalid string index notice in EntityTranslationController with PHP 5.4 (not sure if there already is one)
#17
I'm not offended, simply I created this issue with the goal of addressing the remaining concerns. Keeping posting follow-ups here just makes it hard to stay focused and follow what's happening.
If you feel the need for a meta issue where tracking the improvements let's create one, but I don't think this is the right place. At least let's just update the OP and avoid comment noise.
That said, here is a patch trying to fix everything I was able to address without clarifications.
@sun:
Just a couple of remarks:
I was not able to make the checkbox an item since wrapping it breaks the #tree structure and translatability is not magically saved anymore. We would need to introduce a submit handler just to fix this, not sure it's worth. However I used
theme_form_element_label()to avoid "futzing with HTML" :)From #1831608-14: Show or hide the "Make field translatable" checkbox on the add field form depending on translatability (I think it's more relevant here):
Not sure what you mean: we don't need any field info massaging since 'translatable' is already a property of the field data structure. If you mean there is no code actually updating it, it's just because Field UI takes care of that automatically. Are you suggesting to introduce an API function to switch translatability?
#18
The last submitted patch, et-ui2-1831530-17.patch, failed testing.
#19
Bot hiccup, I guess. Uploading a new patch fixing a typo:
+++ b/core/modules/translation_entity/translation_entity.module@@ -173,28 +190,19 @@ function translation_entity_menu() {
+ // for this entity type. Is some case the actual base path might not have
#20
Aw, it's still there, didn't save, sorry :(
#21
The last submitted patch, et-ui2-1831530-20.patch, failed testing.
#22
#20: et-ui2-1831530-20.patch queued for re-testing.
#23
@catch:
Meanwhile I created #1834250: Hide Content Translation module until we are able to remove it.
#24
I'm going to work on cleaning up the follow-up list in the issue summary. I'll copy the text that is accompanying the issue links into those issues and remove the text from here.
#25
@YesCT:
I'd like to create a proper meta issue to track improvements. Would you mind to wait for me to do it?
#26
oops. I didn't see your post. I dont mind at all. And you have so much more context of the overall picture.
Here I was really just cleaning. Revert here if you wish. :)
[edited]
#27
Here is a meta issue: #1836086: [meta] Entity Translation UI improvements.
#28
A small follow we noticed while refactoring taxonomy display.
Code:
<?php
$translate = !$new_translation && $entity->retranslate[$form_langcode];
if (!$translate) {
...
}
if ($language_widget) {
$form_langcode['#multilingual'] = TRUE;
}
?>
so $form_langcode is a string that is used as array afterwards. Sorry I did not investigate all the way. I am having difficulties at my own tests and don't want to disturb my head even more.
If you need more information, ping stalski or zuuperman on IRC
#29
That should be fixed by #20.
#30
Ok sorry, didn't review all patches. So great job :)
#31
Reviewed the patch. Looks like outstanding concerns are resolved and the new utility function to get the translatable entity types is good too :)
#32
I guess @catch will want to have a look to this.
#33
OK this looks good, I'm wondering why we keep having to check for the admin paths for entities that are translation enabled, rather than throwing an error somewhere if an entity is translation enabled without the path?
+++ b/core/modules/translation_entity/translation_entity.installundefined@@ -6,6 +6,33 @@
/**
+ * Implements hook_requirements().
+ */
+function translation_entity_requirements($phase) {
+ $requirements = array();
+ $t = get_t();
+
+ if ($phase == 'runtime') {
+ $entity_types = translation_entity_types_translatable();
+ foreach (entity_get_info() as $entity_type => $info) {
+ if (translation_entity_enabled($entity_type)) {
+ if (!isset($entity_types[$entity_type])) {
+ $label = isset($info['label']) ? $info['label'] : $entity_type;
+ $t_args = array('@entity_type' => $label);
+ $requirements['translation_entity_' . $entity_type] = array(
+ 'title' => $t('@entity_type translation', $t_args),
+ 'value' => $t('The entities of type @entity_type do not define a valid base path: it will not be possible to translate them.', $t_args),
+ 'severity' => REQUIREMENT_WARNING,
+ );
+ }
+ }
+ }
+ }
+
+ return $requirements;
+}
Who's this directed to? I'd expect the site administrator but they're not going to be able to fix this. If it's aimed at developers is there somewhere we could throw an exception instead - i.e. in translation_entity_enabled()?
+++ b/core/modules/translation_entity/translation_entity.moduleundefined@@ -342,6 +363,34 @@ function translation_entity_enabled($entity_type, $bundle = NULL, $skip_handler
+ foreach (entity_get_info() as $entity_type => $info) {
Why isn't this enough?
#34
This was my initial approach, but @sun made the following objection:
which looked sensible to me. OTOH you have a point too in:
Persoanlly I'd go either with an exception or better with a watchdog error. We don't want the page response to break just because an entity is not translatable when it should be.
If you are asking me why enabling an entity for translation is not enough for it to be translatable, the answer is that without at least a valid base path, the translation overview and all the links in it cannot be generated.
#35
ping?
#36
The part of this remaining to improve it a bit: #1870946: Improve target of entity needing to be translatable warning message by using watchdog
I think that means everything else is addressed.
#37
opps. this needs a re-roll. and to make sure it's passing tests. I'll work on that.
#38
Here is the reroll.
#39
#40
Put on sprint.
#41
#38: et-ui2-1831530-38.patch queued for re-testing.
#42
#38: et-ui2-1831530-38.patch queued for re-testing.
#43
#38: et-ui2-1831530-38.patch queued for re-testing.
#44
The last submitted patch, et-ui2-1831530-38.patch, failed testing.
#45
re-rolled. merged the condition for two languages and the link to the new entity translation workflow wizard/language config.
/**
* Implements hook_enable().
*/
function translation_entity_enable() {
$message = "";
// Translation works when at least two languages are enabled.
if (count(language_list()) < 2) {
$t_args = array('!language_url' => url('admin/config/regional/language'));
$message = t('Be sure to <a href="!language_url">enable at least two languages</a>. ', $t_args);
}
// Workflow for language settings can configure content translation settings.
$t_args = array(
'!settings_url' => url('admin/config/regional/content-language'),
);
$message .= t('<a href="!settings_url">Enable translation</a> for <em>content types</em>, <em>taxonomy vocabularies</em>, <em>accounts</em>, or any other element you wish to translate.', $t_args);
drupal_set_message($message, 'warning');
}
#46
here was the issue that caused the conflict: #1810386: Create workflow to setup multilingual for entity types, bundles and fields
#47
Thanks for keeping this up to date :)
#48
#45: et-ui2-1831530-45.patch queued for re-testing.
#49
Retesting since #1877048: Make Translation entity module JS follow newer core rules went in...
#50
The last submitted patch, et-ui2-1831530-45.patch, failed testing.
#51
#45: et-ui2-1831530-45.patch queued for re-testing.
#52
Previous fail was unrelated.
#53
+++ b/core/modules/translation_entity/translation_entity.installundefined
@@ -6,6 +6,33 @@
/**
+ * Implements hook_requirements().
+ */
+function translation_entity_requirements($phase) {
+ $requirements = array();
+ $t = get_t();
+
+ if ($phase == 'runtime') {
+ $entity_types = translation_entity_types_translatable();
+ foreach (entity_get_info() as $entity_type => $info) {
+ if (translation_entity_enabled($entity_type)) {
+ if (!isset($entity_types[$entity_type])) {
+ $label = isset($info['label']) ? $info['label'] : $entity_type;
+ $t_args = array('@entity_type' => $label);
+ $requirements['translation_entity_' . $entity_type] = array(
+ 'title' => $t('@entity_type translation', $t_args),
+ 'value' => $t('The entities of type @entity_type do not define a valid base path: it will not be possible to translate them.', $t_args),
+ 'severity' => REQUIREMENT_WARNING,
+ );
+ }
+ }
+ }
+ }
+
+ return $requirements;
+}
This hasn't changed, why not a watchdog message?
+++ b/core/modules/translation_entity/translation_entity.installundefined@@ -56,6 +83,7 @@ function translation_entity_schema() {
function translation_entity_install() {
+ module_set_weight('translation_entity', 10);
language_negotiation_include();
language_negotiation_set(LANGUAGE_TYPE_CONTENT, array(LANGUAGE_NEGOTIATION_URL => 0));
This puts most hook implementations near the end.
+++ b/core/modules/translation_entity/translation_entity.moduleundefined@@ -45,9 +45,26 @@ function translation_entity_help($path, $arg) {
/**
+ * Implements hook_module_implements_alter().
+ */
+function translation_entity_module_implements_alter(&$implementations, $hook) {
+ switch ($hook) {
+ case 'menu_alter':
+ case 'entity_info_alter':
+ // Move some of our hook implementations to the end of the list.
+ $group = $implementations['translation_entity'];
+ unset($implementations['translation_entity']);
+ $implementations['translation_entity'] = $group;
+ break;
+ }
Then this puts some specific hook implementations right at the end. Why both? If there's a good reason then it could use a comment explaining why both is necessary, if not then one could probably go?
#54
#1870946: Improve target of entity needing to be translatable warning message by using watchdog will address the watchdog concern.
That leaves only remaining task: the weights. ( Probably for @plach )
#55
I don't think we need a follow-up for that one, especially after that @catch asked for this change twice :)
Will look into this asap.
#56
This should address @catch's concerns, plus a small improvement to the field settings page:
4bc4fc9 Issue #1831530: Fixed translatable widget order.051b22e Issue #1831530: Improved comments.
eb0da4b Issue #1831530: Switched from status report to watchdog warning.
#57
+++ b/core/modules/comment/comment.module@@ -970,7 +970,6 @@ function comment_links(Comment $comment, Node $node) {
'title' => t('translations'),
...
- 'html' => TRUE,
This seems to stem from @sun's:
What setting
'html' => TRUEdoes is it avoids acheck_plain()on the title (see theme_link()). In addition to allowing HTML this can be considered a performance improvement if theme_link() is called often. I think this might have actually been done on purpose because comment_links() might be called quite a lot on pages and using thehtmloption avoids up to 8 calls to check_plain() per call to comment_links(). So this might actually be a performance-optimization. Anyway, I think we should discuss this in a separate issue and either do nothing or remove all the'html' => TRUEfrom comment_links().+++ b/core/modules/translation_entity/translation_entity.install@@ -56,6 +56,9 @@ function translation_entity_schema() {
+ // Assign a fairly low weight to ensure our implementation of
+ // hook_module_implements_alter() is run among the last ones.
+ module_set_weight('translation_entity', 10);
If I'm not mistaken, the default module weight is 0, so this is actually a rather *high* weight. The comment is otherwise correct, because the high weight causes module's hooks to be called last.
+++ b/core/modules/translation_entity/translation_entity.install@@ -64,10 +67,14 @@ function translation_entity_install() {
- $message = t('Content translation has been enabled. To use content translation, <a href="!language_url">enable at least two languages</a> and <a href="!settings_url">enable translation</a> for <em>content types</em>, <em>taxonomy vocabularies</em>, <em>accounts</em>, or any other element you wish to translate.', $t_args);
...
+ $message = t('Be sure to <a href="!language_url">enable at least two languages</a>.', $t_args);
...
+ $message .= t('<a href="!settings_url">Enable translation</a> for <em>content types</em>, <em>taxonomy vocabularies</em>, <em>accounts</em>, or any other element you wish to translate.', $t_args);
I might be mistaken, but I think this is missing a space between the two sentences. In general, I think this sort of string concatenation hurts translatability (no pun intended), but I couldn't think of a nicer way to do this, off the top of my head.
+++ b/core/modules/translation_entity/translation_entity.module@@ -45,9 +45,26 @@ function translation_entity_help($path, $arg) {
+ case 'menu_alter':
+ case 'entity_info_alter':
+ // Move some of our hook implementations to the end of the list.
I know this is really nitpicky but I find it strange that the comment about the hook implementations comes after the names of the actual hook implementations.
+++ b/core/modules/translation_entity/translation_entity.module@@ -176,30 +193,23 @@ function translation_entity_menu() {
+ // If the base path is not defined we cannot provide the translation UI
+ // for this entity type. In some cases the actual base path might not have
+ // a menu loader associated, hence we need to check also for the plain "%"
+ // variant.
+ if (!isset($items[$path]) && !isset($items[_translation_entity_menu_strip_loaders($path)])) {
So this code is to support setting a menu_base_path of foo/%bar in the entity info and then have a foo/% menu item in hook_menu()? What is the use-case for that, I don't get it. Above you said the following:
Can you please elaborate a bit more on the situation, i.e. what this is used for, etc.
+++ b/core/modules/translation_entity/translation_entity.module@@ -176,30 +193,23 @@ function translation_entity_menu() {
+ watchdog('entity translation', 'The entities of type @entity_type do not define a valid base path: it will not be possible to translate them.', $t_args, WATCHDOG_WARNING);
In relation to the above, it seems if I have reached this code the developer that wrote the entity type is doing something wrong and I have no way to fix it other than to patch the module. As a developer, it is nice to get a handy watchdog, so that I know there is this bug to fix, but I think this falls into the realm of "babysitting broken code". Also, if I'm not a coder, I will get pretty nervous about these mysterious warnings whenever I clear the cache. Unless I'm missing some use-case I think the entire hook_menu_alter() implementation can be removed.
Again some in-depth explanation would be much appreciated.
+++ b/core/modules/translation_entity/translation_entity.module@@ -369,6 +392,34 @@ function translation_entity_enabled($entity_type, $bundle = NULL, $skip_handler
+ // Check whether the required paths are defined. We need to strip out the
+ // menu loader and replace it with a plain "%" as router items have no
+ // menu loader in them.
+ $path = _translation_entity_menu_strip_loaders($info['menu_base_path']);
+ if (!empty($items[$path]) && !empty($items[$path . '/translations'])) {
+ $entity_types[$entity_type] = $entity_type;
+ }
See above.
#58
Here are some fixes:
91ca116 Issue #1831530: Fixed comment links.98a290f Issue #1831530: Improved warning on enable.
e07642b Issue #1831530: Improved inline comments.
@tstoeckler:
Thanks for the review!
Yes the alterations performed in
hook_entity_info_alter()are essential to make ET work, hence we need to be reasonably sure that nothing comes after and screw them or simply miss them. Modules with such a low weight and integrating with ET are responsible for providing all the required entity info.Actually they are two distinct messages so now we just output them as such.
We might have a mix of loaders and % placeholders in related paths. See for instance
comment_menu().Well, a module might alter the menu paths so that ET does not work anymore, without the entity-defining module being responsible for it. I'd call this reporting failing conditions, not babysitting code, which incidentally is exactly what logs are about :)
Moreover @catch explicitly asked for this twice, hence I won't present him a third patch missing this part. Obviously he'll be free to consider your argument before committing anything.
#59
Ahh, thanks! The pointer to comment_menu() was very helpful. I now get at least 80% of that :-). I still hope we can remove all that regexing after #1332058: Need a way to distinguish "public/final" URIs for entities from admin and redirected ones and #1783964: Allow entity types to provide menu items but I can live with it for now.
Since this was RTBC a couple times before already, I'm tempted to mark it that again, but I'll leave that to someone who understands the remaining 20% of the menu futzing.
#60
Sure, all that part will probably be revisited once we have an Operation API.
#61
Looks like concerns brought up were all resolved. Thanks!
#62
Thanks! Committed/pushed to 8.x.
I'd noticed the html => TRUE change here but failed to put it in a comment. iirc we did indeed add that at some point for performance since check_plain() was running a ridiculous number of times on comment links defined entirely in code (i.e. no user input). Since that's removed from the patch no problem here now.
#63
Thanks all!
#64
Automatically closed -- issue fixed for 2 weeks with no activity.