Current UI for string translation needs some love, there's initial work done in #532512-38: Plural string storage is broken, editing UI is missing

I'm trying to use Vertical tabs for languages see
locale_plural.png

From IRC

GaborHojtsy: andypost: no work yet on rebuilding the locale UI to be similar to l10n_server, I'd expect to start working on that later
GaborHojtsy: andypost: I don't think that should be part of this patch at all
andypost: GaborHojtsy : i'm going to fix tests but not sure about UI because without UI this patch seem uselees
GaborHojtsy: andypost: I think if you just have vertical tabs in every case for languages or just bare fieldsets for every case (more similar to what we had before), that is absolutely fine for now
andypost: GaborHojtsy : as for me VT looks much pretty
GaborHojtsy: andypost: this is hopefully not going to be the final UI so I'd not waste their time :)
GaborHojtsy: andypost: then apply the VT for the regular case too :)
GaborHojtsy: andypost: so I think the basic approach of how we do the editing form will likely change to in-line translations, basically 2 columns with the first being the source strings found for your search and the second with input fields for translations; if the string was plural, x input fields as your formula requires
GaborHojtsy: andypost: BUT, BUT that should not be the matter of this patch, so just consider this an interim UI
GaborHojtsy: andypost: yup, so the l.d.o UI is two columns (source; target) and target has as many input fields as needed (1 for singular, X for plural), and I think the core UI will work much like that in D8 if we get to that
GaborHojtsy: andypost: oh, we can definitely open one about it if you have someone to work on it :)
Files: 
CommentFileSizeAuthor
#234 locale-ui-changelog.patch686 bytesGábor Hojtsy
PASSED: [[SimpleTest]]: [MySQL] 37,025 pass(es). View
#224 1452188-new-lang-ui-224.patch67.15 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,878 pass(es). View
#222 1452188-new-lang-ui-222.patch67.17 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,876 pass(es). View
#220 1452188-new-lang-ui-220.patch32.7 KBSchnitzel
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-new-lang-ui-220.patch. Unable to apply patch. See the log in the details link for more information. View
#219 1452188-new-lang-ui-219.patch32.63 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,870 pass(es). View
#217 1452188-new-lang-ui-217.patch67.17 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,868 pass(es). View
#217 interdiff-212-217.txt12.13 KBSchnitzel
#212 1452188-new-lang-ui-212.patch75.4 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,880 pass(es). View
#210 1452188-new-lang-ui-208.patch75.53 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,881 pass(es). View
#204 1452188-new-lang-ui-204.patch133.31 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,883 pass(es). View
#204 interdiff-200-204.txt3.27 KBSchnitzel
#202 dbclick.png5.53 KBdroplet
#202 html_code.png41.65 KBdroplet
#202 context.png28.2 KBdroplet
#202 new_issue.png16.84 KBdroplet
#200 1452188-new-lang-ui-200.patch77.96 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,859 pass(es). View
#199 1452188-new-lang-ui-198.patch77.96 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,876 pass(es). View
#197 Language Links.jpg167.52 KBSchnitzel
#197 1452188-new-lang-ui-197.patch72.6 KBSchnitzel
FAILED: [[SimpleTest]]: [MySQL] 36,839 pass(es), 35 fail(s), and 0 exception(s). View
#197 interdiff-191-197.txt20.21 KBSchnitzel
#191 1452188-new-lang-ui-191.patch62.59 KBSchnitzel
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-new-lang-ui-191.patch. Unable to apply patch. See the log in the details link for more information. View
#191 interdiff-185-191.txt4.41 KBSchnitzel
#188 FormItem.png138.28 KBGábor Hojtsy
#185 1452188-new-lang-ui-184.patch62.11 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,860 pass(es). View
#185 interdiff-177-184.txt2.71 KBSchnitzel
#184 1452188-184-translate-ui.patch61.42 KBnod_
PASSED: [[SimpleTest]]: [MySQL] 36,867 pass(es). View
#182 1452188-182-translate-ui.patch59.96 KBnod_
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-182-translate-ui.patch. Unable to apply patch. See the log in the details link for more information. View
#177 1452188-new-lang-ui-177.patch62.02 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,858 pass(es). View
#177 interdiff-174-177.patch2.55 KBSchnitzel
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch interdiff-174-177_1.patch. Unable to apply patch. See the log in the details link for more information. View
#174 1452188-new-lang-ui-174.patch61.27 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,860 pass(es). View
#174 interdiff-166-174.txt5.64 KBSchnitzel
#173 AccessibilityReview.png69.53 KBGábor Hojtsy
#173 AccessibilityReview.mov531.17 KBGábor Hojtsy
#172 1452188-new-lang-ui-172.patch61.26 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,851 pass(es). View
#172 interdiff-166-172.txt4.6 KBSchnitzel
#169 1452188-new-lang-ui-169.patch61.03 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 36,868 pass(es). View
#169 interdiff-166-169.txt3.02 KBSchnitzel
#166 1452188-new-lang-ui-166.patch58.72 KBdroplet
PASSED: [[SimpleTest]]: [MySQL] 36,858 pass(es). View
#166 interdiff-to-145.patch23.7 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch interdiff-to-145_0.patch. Unable to apply patch. See the log in the details link for more information. View
#165 1452188-new-lang-ui-165.patch56.79 KBdroplet
PASSED: [[SimpleTest]]: [MySQL] 36,851 pass(es). View
#163 1452188-new-lang-ui.patch56.8 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] 36,843 pass(es), 3 fail(s), and 0 exception(s). View
#157 pluralform.png10.93 KBdroplet
#157 1452188-new-lang-ui-157.patch56.8 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-new-lang-ui-157.patch. Unable to apply patch. See the log in the details link for more information. View
#154 test.patch54.61 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] 36,673 pass(es), 14 fail(s), and 1 exception(s). View
#151 test-screen1.png16.14 KBdroplet
#151 test-screen2.png19.06 KBdroplet
#149 1452188-new-lang-ui-149.patch49.67 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] 36,828 pass(es), 50 fail(s), and 9 exception(s). View
#149 interdiff-145-do-not-test.patch9.9 KBdroplet
#145 1452188-new-lang-ui-145.patch42.47 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] 36,783 pass(es), 84 fail(s), and 13 exception(s). View
#145 local-ui-interdiff.patch12.51 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch local-ui-interdiff.patch. Unable to apply patch. See the log in the details link for more information. View
#141 interdiff.txt3.83 KBGábor Hojtsy
#141 locale-module-translate-table-140.patch33.7 KBGábor Hojtsy
FAILED: [[SimpleTest]]: [MySQL] 36,735 pass(es), 179 fail(s), and 13 exception(s). View
#140 1452188-locale-module-ui.patch38.95 KBdroplet
FAILED: [[SimpleTest]]: [MySQL] 36,723 pass(es), 178 fail(s), and 13 exception(s). View
#138 locale-module-translate-table-138.patch30.3 KBGábor Hojtsy
FAILED: [[SimpleTest]]: [MySQL] 36,639 pass(es), 155 fail(s), and 83 exception(s). View
#136 locale-module-translate-table-136.patch30.12 KBGábor Hojtsy
FAILED: [[SimpleTest]]: [MySQL] 36,485 pass(es), 250 fail(s), and 19 exception(s). View
#136 interdiff.txt1.57 KBGábor Hojtsy
#133 locale-module-translate-table.patch28.55 KBGábor Hojtsy
FAILED: [[SimpleTest]]: [MySQL] 36,464 pass(es), 252 fail(s), and 23 exception(s). View
#133 UITranslation.png64.16 KBGábor Hojtsy
#124 locale_module-new-ui-1452188-124.patch29.12 KBperusio
FAILED: [[SimpleTest]]: [MySQL] 34,882 pass(es), 196 fail(s), and 16 exception(s). View
#121 locale_module-new-ui-1452188-121.patch29.13 KBperusio
FAILED: [[SimpleTest]]: [MySQL] 34,874 pass(es), 196 fail(s), and 16 exception(s). View
#118 user_interface_d8.png72.6 KBperusio
#116 user_interface_d8.png67.99 KBperusio
#116 user_interface_d8_ff.png53.1 KBperusio
#110 1452188-110.patch27.4 KBrvilar
FAILED: [[SimpleTest]]: [MySQL] 35,302 pass(es), 159 fail(s), and 16 exception(s). View
#108 1452188-108.jpg39.46 KBSutharsan
#106 1452188-106.patch25.98 KBershov.andrey
FAILED: [[SimpleTest]]: [MySQL] 35,238 pass(es), 159 fail(s), and 16 exception(s). View
#106 new-ui.png18.56 KBershov.andrey
#102 1452188-102.patch24.73 KBershov.andrey
FAILED: [[SimpleTest]]: [MySQL] 35,220 pass(es), 190 fail(s), and 76 exception(s). View
#100 lang_list_translate_en.jpg6.71 KBandypost
#98 lang_list.jpg3.82 KBandypost
#98 lang_list_translate.jpg10.57 KBandypost
#95 filter-states.jpg15.08 KBandypost
#95 filter-states-1.jpg13.17 KBandypost
#91 1452188-91.patch3.59 KBershov.andrey
FAILED: [[SimpleTest]]: [MySQL] 35,238 pass(es), 67 fail(s), and 0 exception(s). View
#86 1452188-86.jpg173.55 KBSutharsan
#79 1452188-79-list-multiple.jpg96.77 KBSutharsan
#79 1452188-79-list-one.jpg87.72 KBSutharsan
#79 1452188-79-edit-one.jpg54.5 KBSutharsan
#79 1452188-79-edit-multiple.jpg132.24 KBSutharsan
#74 1452188-74-filter.png20.1 KBSutharsan
#62 Translate_2.png79.33 KBSchnitzel
#62 Translate_3.png74.27 KBSchnitzel
#62 Translate_4.png71.33 KBSchnitzel
#62 Translate_5.png82.28 KBSchnitzel
#61 CompetitivePluralPootle.png26.44 KBGábor Hojtsy
#61 CompetitivePluralPoedit.png36.52 KBGábor Hojtsy
#61 CompetitivePluralWebtranslateit.png31.67 KBGábor Hojtsy
#48 D7TranslateOverview.png294.89 KBGábor Hojtsy
#48 D7EditString.png54.29 KBGábor Hojtsy
#34 mockup.png44.42 KBdroplet
#30 1452188-29.png46.17 KBDjebbZ
#21 1452188-21.png18.22 KBklonos
#11 1452188-11.png50.51 KBSutharsan
#5 locale_edit_list.png23.18 KBandypost
#2 LocaleUI.png81.13 KBGábor Hojtsy
#1 locale_ldo.png16.74 KBandypost
#1 locale_ldo_edit.png25.9 KBandypost

Comments

andypost’s picture

FileSize
25.9 KB
16.74 KB

here the screens from l.d.o

locale_ldo.png

locale_ldo_edit.png

Gábor Hojtsy’s picture

FileSize
81.13 KB

I think we can go directly to only have textares in the right column but otherwise this l.d.o approach is better. Ie. editing one language at a time but more strings. Like so:

LocaleUI.png

andypost’s picture

Suppose Language should be a part of right because it's already in filter
about right part I think better to use interaction used for FieldUI (formatter settings)

Gábor Hojtsy’s picture

You mean right == subtabs on the page? I'm not sure that scales well to many languages. Like l.d.do (although it is an edge case) would totally blow up if the languages were subtabs. I think its fine if it is a select box right now, just make it required and loose the "any language" option (default to the site language). AFAIS that sounds best.

andypost’s picture

FileSize
23.18 KB

I mean that we displaying strings and links (languages or translations itself)

locale_edit_list.png

Gábor Hojtsy’s picture

@andypost: I don't think we should be that fancy and require the user to click on actual links to get to translation forms. As said, people are much more likely to care about translating to one language (in which case the tiny links to click are a lot of hassle). So instead of the links to languages and the extra click to translate in a popup, IMHO we should just include the textareas inline right there and only show the whole thing for one language at a time, letting you to switch languages if you want to.

I think this approach is much more useful for the 80%, the fastest to use to translate stuff and is nicely UI-compatible with the localize.d.o UI so lets people move seamlessly from one to the other.

Sounds like a win-win? :)

Sutharsan’s picture

I agree with Gábor that translation is usually per language, therefore quick switching between languages is not required.
I expect this interface to be used for minor translation changes, usually late in the building process. It will be used to fix untranslated strings, improve translation consistency, changing translation style and simplify some strings. Strings are translated one-by-one (fixes, simplify), or translated multiple strings together (consistency, untranslated strings).
I'll make a wireframe based on this.

Gábor Hojtsy’s picture

I don't want to turn down all the creativity :) Just wanted to say I think it would make most sense to have a sufficiently similar UI on localize.drupal.org vs. the Drupal site, so people use a tool familiar to them when contributing to the community and editing their own stuff. Also, we can port some of the goodness like the placeholder matching to core from localize.drupal.org for example. I'm wondering if the l.d.o UI (minus the multiple suggestions possibility and differentiation between suggestions and translations) is not good for local editing, then any improvements we want to make to that model would also be good for l.d.o, so we can enhance in that direction?

Sutharsan’s picture

No time to waste ;)
The l.d.o interface would be a good starting point. Perhaps a bit less bells and whistles. The l.d.o interface is made for larger numbers of translations, the site translation is (and should be) for less. If we want people to translate large numbers of strings on their site, we should make it easy to contribute it back to l.d.o like l10n_client does. But lets leave that to contrib space.

Gábor Hojtsy’s picture

Yes, I think if we can have a simple UI in core, we can build in the l.d.o contribution backend via a contrib module still :)

Sutharsan’s picture

FileSize
50.51 KB

I've taken elements from the existing interface and the l.d.o interface and tried to keep it compact.

Gábor Hojtsy’s picture

@Sutharsan: that looks fabulous. I wanted to say that even though people might only want to translate one thing at once, putting the edit control right there when they found the string is the quickest way to go, vs. the current method of needing to click a link and get a page reload and @andypost's proposal above to click a link and get a popup. I think your proposal merges the benefits of the immediacy of the l.d.o UI with the possible need of cross-language editing, and people will just see if they actually need this feature :) It should not be hard to implement.

The only thing I'm wondering about is the reset link. What would that do? Reset to community translations (we might have those) or reset to built-in English (basically empty out the input)?

Also, if you don't mind I'm going to use this mockup in my D8MI session in Denver. Its great :)

Sutharsan’s picture

I deliberately did not explain the design. If it explains itself it is good. The reset link is not obvious. It is meant to revert the change back to the status when the page was loaded. Multiple textfields came from the requirement to make changes for consistency, usually multiple translations at the time. But when making multiple changes one may want to revert a single translation and not trash the whole page. We could hide the 'reset' until the field content is modified.

Gábor Hojtsy’s picture

Showing the link once you chnage the field sounds good, it would let you discover what it is about IMHO.

andypost’s picture

I think we should implement inline edit (textfields should appear only on click to text or edit link)
Reset - confusing

Gábor Hojtsy’s picture

@andypost: I don't think people would understand inline editing until it is introduced later in Drupal core. Anyway, inline editing would be a more advanced version of Sutharsan's design, right? It would still need to be able to save multiple textareas from the page in different languages for different strings.

Sutharsan’s picture

If inline editing would be excellent here. But if it is not in core we should not try lifting it from this edge. The design was not made for inline editing.
'reset' is the same as 'cancel' We can try it if people understand and/or need this concept. But it is not a vital part of the design and can be left out.

Gábor Hojtsy’s picture

The reset link would work in the webpage context in the browser (JS only) I assume so it is pretty easy to remove/add I guess as we see fit.

yoroy’s picture

Gábor Hojtsy’s picture

Issue tags: +sprint

#532512: Plural string storage is broken, editing UI is missing landed, so thtat unblocks this issue. Yay!

klonos’s picture

FileSize
18.22 KB

As I understand it we are going with the UI design shown in #11. Right>? If so, then I'd like to ask if it is obvious for translators for languages with complex plural formats what they need to enter in the multiple fields.

Gábor Hojtsy’s picture

@klonos: it is the same UI we have on localize.drupal.org for years (see screeensho in #1) and nobody complained yet :) we are just merging the best of both worlds here, cycling back the experience from localize.drupal.org to core.

klonos’s picture

Thanx for taking the time to explain this Gábor. I never checked localize.drupal.org so to know though. You see, I intent to use this feature in my D8 sites in order to allow specific roles to localize/translate the UI. These users won't (necessarily) be familiar with localize.drupal.org and I'm gonna have to train them. I just thought we could use some help text explaining things for languages with complex plural forms. That's why I asked in the first place.

PS: If you think that adding help text to languages with complex plural rules would be a UI bloat, then how about we add it in the fields with jQuery like we do with the search field in d.o (help text or example goes away on field focus).

Sutharsan’s picture

Have a look at the Localization client for interface translation. It also has an option to contribute the translation back to l.d.o.

Greek (like Dutch, my native language) has only one plural form. We should not ask ourselves whether it is a problem. We should ask native speakers of languages with multiple plural forms how they perceive the interface.

klonos’s picture

Thanx Erik. I already know about Localization client (never used it though - just saw screenshots/screencasts and read the project's description), this work here though is for D8 core.

We should ask native speakers of languages with multiple plural forms how they perceive the interface.

That's what I'm asking back in #21:

...I'd like to ask if it is obvious for translators for languages with complex plural formats what they need to enter in the multiple fields.

I'd also like to add to the suggestion that we should ask people with no previous Drupal experience. The UI might make sense to Drupal site admins, but I guess that the intention here is for it to be used by people that simply require an easy to understand and use translation interface. Right? They don't need to get a Drupal admin crash course too. Will they?

Gábor Hojtsy’s picture

@klonos: lets get translators here to provide feedback then! Can you help get some? Also remember, that we are building in l10n_update in Drupal 8, at least that is our plan, so this UI in core would be used more for touch-ups and quick local modifications, since translations will be fed from localize.drupal.org directly. That is definitely not a reason to make this obscure :) but it means this UI will not be used as heavily.

botris’s picture

The mockup looks good. But what are the goals for the new UI?
If it's solving the singular / plural, then this is it.
This might be off topic, but what I'm missing in the UI is the possibility to specify different translations for different contexts/modules. As words don't always have the same meaning in every context.

Dragan Eror’s picture

It looks pretty useful to me...

Gábor Hojtsy’s picture

@Boriss: indeed, the context would be displayed with the source string (if the developer provided it).

DjebbZ’s picture

FileSize
46.17 KB

Giving feedback : The UI is great. I agree with klonos, help text could help understand the purposes of the multiple fields. I must admit that I still don't understand the part in #21. Why 3 text fields with plural forms when the 'source' column has one singular form and one plural form ?

About the help text : having a help text for each plural form text field could lead to UI bloat, I agree. So why not hardcode just a single message at the top of the translations, saying something like "@count is for the plural form" ? Like that : Translation UI proposal

Gábor Hojtsy’s picture

@DjeebZ: @count is used in non-plural items too (although not often). Also, if you look at the Croatian example (which was pulled from their real translation), they need to use @count in the "singular" version too because it is used for many cases of plurals too. Really where these values get used depend on the plural formula for the language. Those not familiar with the language will definitely not know what the fields mean, I don't think that is an issue per say.

For example, Croatian has this plural formula (pulled from localize.drupal.org): ((($n%10)==1)&&(($n%100)!=11))?(0):((((($n%10)>=2)&&(($n%10)<=4))&&((($n%100)<10)||(($n%100)>=20)))?(1):2)); So the first version is used for every number which divided by 10 gives but bot divided by 100 does not give 1, so 1, 11, 21, 31, 41, 51, 61, 71, 81, 91 (but not 101), 111, 121, etc. So it is not even the singular version for Croatian, it is the singular and then used at many other instances too. Not sure how to express this in a concise help text especially that multiple languages with different rules might be displayed. Therefore my proposal to let people understand what pertains to them which I naturally expect them to understand without complicated descriptions.

I might be wrong, in which case we need to figure out how to describe pieces of a mathematic formula that is dynamically provided for Drupal. We might be able to do that with t('Singular form'), t('First plural'), t('Second plural'), t('Third plural'), etc, so each can be translated properly individually as applicable to the language, so we toss the problem of how to explain the use of the textfield input to the translation team :)

Sutharsan’s picture

It is like explaining the ocean to a goldfish in a bowl. As non Croatian speaker I can not imagine how it is for them to have three plural forms. But it would not supprise me if a native speaker would require only a minimal suggestion. It would probably need much more effort to get the proper translations for 'Singular form', 'First plural', 'Second plural', 'Third plural'. Because, what word would the goldfish use for the ocean?

I thought about transforming the plural formula's to some meaning full instruction to the translator. But this is programmatic reverse engineering and would be very, very hard to do.

Gábor Hojtsy’s picture

Right, good point. We'd need to explain *in English* for this UI what does the different plural variants are for Croatian and how are they applied. Depending on the translation is not an option because we are displaying the UI in a language used for translation, not in Croatian.

droplet’s picture

FileSize
44.42 KB

Here is my mockup:
mockup.png

#1: All columns should be fixed width. Source & translation columns should be equal.
#2: Preferred show Lang code instead long name. eg. "Chinese Traditional" taken too much space. (the best is remove it, how many users translate more than 2 lang at same time ?)
#3: " COPY=> " between source & translation string. more visible directly
#4: KISS, but prepare it to integrate LDO features. eg. add upload to LDO button, get suggestion from LDO..etc. It is good for whole community.
#5: "Submit and go to next page", save your time to click page #2. It placed on the right bottom of page because we more focus on translation column and moving down. (I guess its broken Drupal core design pattern)
#6 If really needed, we can add Singular / Plurals help text above inputs ( or use javascript to show hint when users focus on the input fields), html5 placeholder is another choose.

Gábor Hojtsy’s picture

@droplet: just a quick note that "singular" is not singular in some languages, see the Croatian example in http://drupal.org/node/1452188#comment-5724880 above. Otherwise this looks like a slight variation of @Sutharsan's, basically you moved the language to first column and shortened it. I agree with the save and go to next page button suggestion (been also working on that for a while for l.d.o).

Ranko’s picture

I might be wrong on the specific case of Croatian, but we have only one plural; but this looks like an issue with cases the word is used in. There are seven cases in Croatian, but that issue is present in other languages (4 in German, up to 18 in Hungarian...).

Can you point me to the source you pulled in #31? Maybe I can shine some light on what it tries to do and then extrapolate a more global comment :)

Gábor Hojtsy’s picture

@Rnako: yes, see http://translate.sourceforge.net/wiki/l10n/pluralforms for a list of various languages with their plural logic. Irish has 5 plurals while Arabic has 6, so imagine the plural UI with 5, 6, etc. fields respectively for those languages. Granted, most languages have much less variants. I think for someone know *knows* Irish or Arabic, their natural expectation is they get 5/6 input fields to enter their translation for singular/plural strings and that they likely know exactly how to use each. But I'm no Irish or Arabic.

DjebbZ’s picture

Didn't know Croatian was so complex :) But now I think of it, in Arab for instance there 2 plural forms : one for a couple (2) of items, one for 3 or more... Babel tower...

Now I understand that various languages have various plural formulas. Can we just write at the bottom of the screen a small instruction (so that the UI don't blow up) explaining why some translations have several input fields ? It could be useful, because sometimes the people who input the translations are not the translator themselves (think of external services, where one send back and forth an Excel file etc). Sometimes it's the developer himself who inputs the translation for all languages.

I admit it's a very complex human/machine problem, so no perfect solution exists.

xjm’s picture

Regarding #36 and the question about cases: in general which case should be used would be given by the context of the particular string; the UI is needed for when there are different forms of the noun depending on the number in the same sentence.

All the same sentence, "I have X cat(s)," with a count of 1, 2, and 5:

  • У меня есть 1 кошка
  • У меня есть 2 кошки
  • У меня есть 5 кошек

The forms would be different in a different sentence (where the cats were not the grammatical subject) but that would be indicated by the specific context of the string.

Many languages have at least a special form for a dual, and a special form for 10x + 1 is not uncommon either, but there's no general rule to extrapolate. :)

Is it possible to add an "Add @count" button that adds a new field, so that we don't have to display a fixed number? Edit: And then on a per-language basis allow a label for example numbers with that plural form. (In the case of Russian it might be 1, 2, and 5; in the case of another language 1, 2, and 3; or 1/11 and 2; etc.)

Gábor Hojtsy’s picture

@xjm: Drupal should already know the number of plural variants used (and the formula for when is each of them used) for the language when this UI is displayed, so it should not be possible to enter more variants. We'd not have a formula to decide when that extra variant would be used.

Pasqualle’s picture

singular form -> plural formula 0 #1295792: document misuse of format_plural

Sutharsan’s picture

We should distinguish between languages with simple and with complex forms. Languages with one plural form can be served with a t('Singular') and t('Plural') label. Languages without plural form may not need a label at all.

But, the Russian example in Pasqualle's post in the above issue gives me the idea that a strict translation of t('Singular form'), t('First plural'), t('Second plural'), t('Third plural') will not work for languages with complex (>1) plural forms. Every plural form (plural_formula[n]) requires a short description and/or example. In some languages these plural forms may have a name, but certainly not in every language. I expect it to quickly exceed the limits of the user interface or bloat it. And since the interface language of the website is independent of the language being translated, we can not rely on t() to do the job. Languages with complex plural forms could be served with a short label plus an help link to documentation on (l.)d.o.

andypost’s picture

+1 to #41

We actually need to use @count in singular form because of
format_plural($count, '@count kitten', '@count kittens')
for russian:
1 kitten => 1 котёнок
21 kittens => 21 котёнок

Gábor Hojtsy’s picture

@andypost: yeah, @count is introduced in translations, where needed, see the Croatian example. Also @count is replaced in the singular form too, right, so there is all the flexibility there for supporting Russian and any other languages. I think the '1 kitten', '@count kittens' in the original English version in fact helps people understand how it is supposed to be used and suggesting to use '@count kittens' and '@count kittens' would confuse it on the original API side. Since it works either way, it is more down to coding standards. Would translators not understand that they can introduce @count as needed as translation of '1 something'? (I can imagine that might be true, but not sure 'obfuscating' the suggested use of format_plural() in the coding standards is the way to solve it.) Maybe a little help text under the singular form saying 'You can use @count here too if needed' or something along those lines would be good?

andypost’s picture

@Gábor Hojtsy: I know about @count replacement. Suppose having docs for translation teams is enough and there's already #1295792: document misuse of format_plural

About #42

t('Singular form'), t('First plural'), t('Second plural'), t('Third plural')

I don't think it's a good idea about naming inputs because source string always a singular or plural after #532512: Plural string storage is broken, editing UI is missing
In case of plural source string: all translations are plural forms (there's no singular) - first plural, second plural.
In case of single string label "translation" just eats a screen place.

Also we should take into account the tablet and mobile users for D8 - they should have ability to translate strings too!

All mock-ups from #11 have language column in table - I think this bad idea because it makes this table bigger. Source string has many duplicate lines for each language. For example "reset" string for site with 10 languages eats a whole screen just for 1 word.
So language should live in filter or in translation part (preferable) my example in #5 shows this - 1 line per source string and many links (having textfields or textareas by default also makes screen bigger) to translate per language also this links shows actual status of translation. All operations in this screen are attached to one single form with current translation to 1 language so no problems to send this translation to server.

Watching tremendous disqus about module's page I think we should have this listings in same maner #538904: D8UX: Redesign Modules Page
For this purpose don't forget about #1475204: [META] Provide a generic search/filter UI interface pattern for listing pages

Gábor Hojtsy’s picture

@andypost: I'd argue that for the translations of singular/plural pairs, the first variant is always the "first plural" and that there would be no singular. If you look at the formulas in http://translate.sourceforge.net/wiki/l10n/pluralforms, you'll see that an overwhelming number of them have the nplurals=2; plural=(n != 1) rule, which is exactly equal to English. It means that number 1 and all other numbers (positive, negative) use different variants. So there is a singular and a plural variant for these languages. Other languages have all kinds of other rules, but for those using nplurals=2; plural=(n != 1), the first variant *is* *the* singular and the second is *the* plural. So its not easy to make such assumptions wholesale.

Interesting you mention tablet and mobile users for translation. First of all, this UI is once again targeted as a touch-up interface for fixing things you don't like with the translation coming from localize.drupal.org. So it is not likely to be used daily. Second, your mockup from #5 in fact uses pretty tiny links for the language names, which are clickable to reveal a popup textarea. Tiny links are very hard to click on small mobile devices, while the textarea provide a convenient big touch area to tap for typing. Also, the point is that people come to this screen to translate stuff. Why hide their tools of translation (the textareas) under extra clicks, when we can lead them directly to their tool and let them edit.

Bojhan’s picture

Issue tags: -Needs usability review

I remember reviewing this multiple times before, in earlier revisions. Are we planning on completely redesigning it again? Will/should it actually be part of core?

Gábor Hojtsy’s picture

Issue tags: +Needs usability review
FileSize
54.29 KB
294.89 KB

@Bojhan: I don't think you reviewed it, maybe you mix it up with #1282018: Improve UX of language-aware entity forms which is for entities. This UI is for strings displayed on the interface, like 'Save', 'Home', etc. We already have a pretty bad UI in core. Do you want to have a before/after comparison? :)

Here are two quick screenshots from l.d.o (D6). Sorry, this is a bit extreme, there are many languages, but you get the idea. The D7 UI is essentially the same.

D7TranslateOverview.png

D7EditString.png

The current D8 UI uses vertical tabs for the languages, so its much more compact (and also allows for editing of singular/plural translation). Reproducing the picture from the OP:

The main problems we are trying to solve is that when you go to translate stuff, you want to do it as soon as possible. What the UI provides instead is a summary of languages and then you need to go edit. Both the summary of languages and the edit page uses all languages, while you likely care about a specific language. So instead pulling in the translation textfields into the results UI and making it possible to edit right away looked like a great idea. Surtharsan proposed on top of this to keep the possibility to handle multiple languages at once (or you can focus on one language only with the filter on the top of the form). Reproducing his proposed UI:

Is this clear to understand the goals? (Adding back tag to get your feedback again, let me know if this is not the right procedure).

Bojhan’s picture

Before I provide redesign possibilites, can you please clarify further why this UI should be part of core? I am not completely following the 80% usecase for this one.

EDIT: I have had a chat with sutha, who explained to me what the goal of this functionality is - which primarily comes down to adjusting badly translated strings or simplifying existing text.

My biggest concern with this use case, is that from my perspective it isn't a very big one. Especially with the many improvements down the line regarding updating and locally changing translations. This functionality will used even less. Is this really an 80% use case in the context of translation? If its not, should reconsider adding this to core?

I am also concerned that the UI, although sutha's improvements go a long way - still requires a few large iterations to be useful. It's a UI that is very much a one-off in core, which will make it harder to maintain and improve. Has this gotten accessibility review?

Bojhan’s picture

Issue tags: -Needs usability review
andypost’s picture

This functionality will used even less. Is this really an 80% use case in the context of translation? If its not, should reconsider adding this to core?

From this point I've started to think different, do we really need string translation in core?

D8 planned to be released with following (Gabor please correct me if I wrong)
- l10n_server client
- strings import
- internal string translation & community bit on strings to mark overriden string (which could help to select mostly used translations)

Also we have a nice l10n_client whick could be refactored to join force with core's string translation probably with a usage of Contextual module. We really need to refactor a way of string overrides - UI to overrides of LDO community provided strings

Actually string overrides looks absolute in context of downloadable translations from LDO and ability to upload custom strings

Gábor Hojtsy’s picture

@andypost: looks like you want #1445004: Implement customized translation bit on translations to be in core? :) Good for us :)

@Bojhan: well, it is already in core. Question is why would we want to remove it. If we could rely on the community providing full translations for Drupal core and all kinds of modules (and/or the translation process to be as smooth so if you push to the community, it would almost immediately be reviewed/approved and available), you'd be able to run with just the localize.drupal.org translations feeding your site. Since that is not really reality, looks like we cannot really say we have a multilingual CMS if you need to do obscure things to add/change interface translations. We will have UI for all other language/translations things, so I'm not seeing a good reason to remove this one.

Gábor Hojtsy’s picture

Issue tags: +Needs design review

So putting back the tag with that.

Bojhan’s picture

@Gábor I was guessing, we would not really have a discussion over this. I am not necessarily convinced that because there are a couple of modules, that don't have a translation - that we need to provide a full translation interface for them - and that core is the best place to do this. Anyways, I know these strategy discussions have always been futile on the i18n front - I have tried many times, so I will stop and just review UI's.

In terms of actual review, I definitely like a lot of the improvements over the messy l.d.o interface;

1) The screenshot in #48 is that a normal use case? It seems to show only, 2 strings? Isn't it common to find a whole lot, and also plenty of false positives? Aren't a lot of strings long?

2) The screen could make use of additional visual hierarchy, for example the language could be bold, or make use of extra spacing to denote its importance in the table.

3) How do specific interactions work, for example copy or reset? Like l.d.o or do they require a page load? If not, is this approved from an accessibility standpoint?

4) The operations are somewhat strangely placed and seem to attract to much emphasis. Could we move them to a upon hover contextual link placed on the right?

5) Filter and reset have equal importance, while filter is far more important. Can we make use of Drupal's blue button state, and or change filter into visually a link?

6) The fact that using the pager, triggers a loss of changed form data seems rather destructive. Something we are constantly trying to battle in core. Are there possible solutions for this?

7) The search form on top, could probably use some visual hierarchy. Putting an emphasis on the search box, and aligning the elements better. Clearly we do not have a good pattern for this in core, I hope with further iterations over the content listing we can provide you with one.

8) Is there a reason, we have repetition? Could we for example have just one "reset" but still visually (but not semantically) - and list all language translations of that one string?

This is all for now, I do wish to note that this probably requires accessibility review.

mbyrnes’s picture

Hello,

Just summarizing my conversation with Gabor and a few points at the DrupalCon Sprint.

Please Note: I'm coming at this with experience using the Drupal 6 translation interface and managing training and confusion for translators comments related to that specific experience of managing large global websites with many localizers. I am probably making a few assumptions and I am not familiar with the inner workings of the code.

1) Regarding the (reset/ copy) - From the interface, this is unclear what action this is doing to me. Even after Gabor walked me through it, I still had a few comments and thoughts. First off, if the field is prefilled- why would i need to copy anything into it? In fact, they are sort of similar, if I want to copy the current base string into the field that shows up, that could also be akin to resetting it. I agree with @klonos on #21. As far as UI, I wonder if it may be more clear to see the actions that a translator could perform on a field be possibly in a drop down on the right of the field. As it stands now, copy and reset are both actions and should maybe be updated with more descriptive text. Reset may be more clear if copy wasn't also there.
From my understanding now:
copy = taking source string and moving it into the field
reset=when clicked removes changes on that one in line field so that when the page is saved the value gets returned. Akin to an 'undo' function

If these assumptions are true, it may make sense to think about alternative names of options here and making these a bit more clear what is exactly happening.

2) Special characters: I don't think that having a @count link hardcoded is the answer since this does seem like an edge case. If an @ term does show up, it would be helpful at this time to have the help text. I would extend this to other codeish looking strings too ie it would make sense to have some sort of clear indication or description that pops up a long with these specific strings that contain (%, ! and @). Whether when they appear there be some sort of indicator or colorful flag that the user could click into for more information. I think that this should be unobtrusive maybe some sort of help icon or when special characters appear in the search results then a "note on special characters ! @ and % could appear to explain. While users on localize.drupal.org may understand this specifically, I think it is a stretch that some site users would understand this code convention as exposed in the UI.

3) Plural fields - when a @ string requires plural fields specific to languages such as Croation, would it make sense to indent or give context for the 2nd line after the base string or some sort of indication that the multiple fields are required. I also agree that it would make sense to find someone who can test this from the perspective of using it who speaks a language with actual plural rules.

4) Written language vs language code: I do think that the printing of the language code and language in that column may generate issues down the line. For both long languages and for implementations that end up with localization/ country combined this could end up being difficult. Printing language code in the column because it may also match the browser code and perhaps adding a rollover with the text may help Responding to also #34 which discussed this issue as well.

5) Removal of summary screen: For those site managers who do have a need to view the status of a string or track down a string and viewing all the work on it (this is tricky with the current state of case sensitive search, but I know that is another issue), would it be possible to include some sort of view or way to see what others have done? I think that the crossed out language codes are useful for this type of audit or review, so maybe while the translation screen doesn't need it as the main use case is for one language, but could this be in some sort of advanced option area?

Kristen Pol’s picture

Here is some more DrupalCon Denver sprint feedback based on reviewing the design (first) and then reading through all the most recent comments.

  1. Top search form area
    • The actions/elements included seem adequate.
    • I agree with @Bojhan that it can use some visually improvements (alignment, etc.). Particularly, I agree with the "Reset" being a link (like how "Cancel" links are used).
  2. Plural and placeholder handling
    • I find the current plural layout a bit confusing but I'm not a translator and haven't used localize.drupal.org.
    • I think the indenting idea from @mbyrnes might work well. Probably worth a mockup to see.
    • I agree with @mbyrnes that having a special icon (e.g. question mark) next to the lines with special formatting would be very useful while not cluttering up the interface too much.
    • Additionally, hover/tooltip text might be useful for particular special placeholders. For example, if "@count" had hover/tooltip text so when you hover/mouse-over then it gives some useful help text.
  3. copy/reset actions
    • I personally don't like the placement of the copy action. I'd like it with the reset (or combined like @mbyrnes suggested).
    • As explained in earlier comments, expanding the name of the actions might be best for clarity, e.g. "copy source". Additionally (or alternatively), hover/tooltip text can be used on this/these links.
    • I would like it if these actions were executed via ajax to not require a full page load.
    • If there are 2 or more actions, one possible UI change would be to use a drop-down/select list with the actions like what is done on the views admin page. It keeps the UI compact while providing a way to expand actions as needed.
  4. Language code vs. language
    • In principle, I like the idea of using the language code instead of the language due to space constraints and better visually alignment. But, this might not be best in terms of user-experience.
    • This could be made into either a search form option, or could be made as an admin setting (though I doubt search settings is something that would normally be included in core).
  5. Pager
    • I would like the number of items on the page to be configurable. This could be done via the search form or through an admin setting (though, again, the latter is probably not standard core practice).
    • It would be good if the pager results were retrieved via ajax so the full page doesn't load and search form settings aren't lost (as explained previously by @Bojhan).
  6. Translation/progress summary
    • I agree with @mbyrnes that there should still be a way to quickly compare all the languages for a particular string.
    • I don't have a good idea of how this would integrate with the proposed UI.
pixelite’s picture

My suggestions on the UI in #48:

  • Change 'copy' to 'copy from source language'. I know this is probably too long, so perhaps could be used as the title of the link.
  • Move the 'copy' column next to 'reset'.
  • It's not clear to me that the two translations of 'reset' are translations of the same source string. Could results be grouped by the source string?
  • I think the 'Language' column could be changed to the language code to make the table more concise (given that language names can be quite long).
  • In response to #54, point 6, is it possible to use a UI like the one for block configuration where you get a message that you need to click 'save translations' to save your changes.
Sutharsan’s picture

Summarizing #54 - #58 and my consclusions:

General

  • Editing one language per page. Rationale: Translators usually translate one language only. No need have the language in the table.
  • One overview page with links to translation page (as per current situation). Rationale: no risk of data loss by using a pager. More space for explanation.

Filter area

  • Clear button as tekst link
  • Visual hierarchy and alignment

Translation area

  • Design on a realistic scenario. Not just the ideal case.
  • Use visual hierachy (bold, space)
  • Operations links: Move to the right. Perhaps enable them conditionally. Execution with ajax. Perhaps combine them Views UI style.
  • 'Copy' -> 'Copy source'. Only is the target is empty? Does this really require an interface element?
  • 'Reset' -> 'Revert' or 'Undo'. Only display/enable if field is changed.
  • Indented plural fields?
  • Add collaped fieldset with explation. Conditionally when source contains (@, ! and %) or is plural. Optionally use icon + JS + on-hover
  • Add validation check if @, ! and % tokens are included in the translation. Optionally add icon + JS + in-hover

Research

  • Accessibility fallback for 'copy' and 'reset'
  • How to clarify the plural entry fields in languages with more than one plural form. Usability test with native speakers.
Schnitzel’s picture

I hade a short Chat with Sutharsan in IRC. Here your conclusions:

- We have two usecases:
1st People which never used this interface
-> they need a lot of explanation how everything works, especially the placeholders, singular/plural
-> for this we suggest not to use inline editing and keep the current single edit screen.

2nd People which use this interface every day and have to translate a lot of strings, also into multiple languages
-> they don't need too much help and especially inline editing, which is a huge speed improve

Because we cannot handle both cases in Core, we agreed that we will focus in Core for the 1st Case and try to fix the 2nd Case in Contrib (probably with Ctools Ajax stuff, etc).

I'm now working on updating the current D8 Overview to provide a better UX there.

Gábor Hojtsy’s picture

Here is some competitive review.

Pootle:
CompetitivePluralPootle.png

PoEdit:
CompetitivePluralPoedit.png

Webtranslateit:
CompetitivePluralWebtranslateit.png

Schnitzel’s picture

FileSize
82.28 KB
71.33 KB
74.27 KB
79.33 KB

Had a chat with Gabor again.
He convinced me that we should provide the fast translation already in core.
- The not explaning Issue of Placeholders can be fixxed with some text on top
- The direct visibillity of the translations also adds a Translations Review possibility, where a Translator can see if the Translations are equal done.
- The Problem of not saved changes with a pager can be fixxed as Fields and Blocks are doing it: After the User changed something we show him a yellow bar, that he has unsaved changes

1

1
The same as already posted, with slightly changes:
- Context column added because of i18n
- added labels to the singular/plural
- moved textlinks
- renamed "reset" to "revert"

Pros

- everything in one place, everything visible

Cons

- bad using of space, SourceStrings are showed multiple times
- could get really huge

2

2
Inline Editing after clicking on an source string row

Pros

- less forms
- pretty clear, that is has to be saved
- better using of space

Cons

- no good overview of translations

3

3
Language mandatory for search

Pros

- easier interface

Cons

- no possibility to translate to multiple target translations

4

4
removed table for overview

Pros

- easier interface

Cons

- maybe a bit hard to get a good overview of source strings

I would suggest to use ether 1 or 4

droplet’s picture

few suggestion:

  • remove context col (that's less than 20 context and only around 100 rows in total in all projects)
  • what is the copy link ?? for translated string ??
  • I don't think we need to show (n<1).
    • - some lang's conditions are super complex, a long text hints ?
    • - a TIPs text linking to a help explain is good enough (or JS popup hints)
Schnitzel’s picture

remove context col (that's less than 20 context and only around 100 rows in total in all projects)

No, you need this because with i18n enabled you can have the same string in multiple context/textgroups. So you need a possibility to differentiate between the same strings.

what is the copy link ?? for translated string ??

it copies the sourcestring in the textfield. Also used in other systems: http://drupal.org/files/CompetitivePluralPootle.png

I don't think we need to show (n<1).

yes this is optional and depends if we will have a parser of Pluralforms like here: http://translate.sourceforge.net/wiki/l10n/pluralforms
But if we have a parser we should definetly use it and give the translator some hints which textfield is for which pluralform. Because some Languages have 6 (!) different Pluralforms

- some lang's conditions are super complex, a long text hints ?

yes agree, this really also depends on the pluralform parser

- a TIPs text linking to a help explain is good enough (or JS popup hints)

I don't get this, so don't show the fieldlabel at all?

pixelite’s picture

My feedback on screenshots in #62:

  • Screenshot 2: Provides a nice overview of strings matching the search, but isn't as efficient for editing since you have to click 'edit' and 'save' for each translation. Too much overhead when there is only one target language.
  • Screenshot 3: I think this option should be ruled out. The ability to add multiple languages at once when translating UI strings is an important use case to support, especially when target languages are very similar (i.e. Portuguese and Brazilian Portuguese).
  • Screenshot 4: I like this option the best. It provides more space for each translation string. Ideally, I think there would be a single 'save translations' button instead of a 'save' button for string.
Schnitzel’s picture

Just had a short Skypechat with dania.gerhardt:

- She preferes Nr. 2 in favour of simplicity and cheerful interface, and also because she is used to this Interface from Drupal 6 and 7
- So the argument of a good overview of equal translations is not so important for her. Maybe we could put this functionality in a Contrib Module?

Kristen Pol’s picture

My feedback on #62:

  • General
    • Although I understand the need to include the context, I think it would be good to include the context information in the Source column rather than creating a new column.
    • The search form uses "reset" and the individual translation items use "revert". Although, I like "revert", it might be best to stick with "reset" for both. They are resetting back to the default. Revert makes it sound more like they are "undoing" their last change.
  • Option 1
    • Compared to the other options, this one feels the "heaviest".
  • Option 2
    • I like that this would look very lightweight but understand the comment from @pixelite that it is an extra step to open the form which is undesirable.
  • Option 3
    • This option seems the least desirable since you can only deal with one language at a time.
  • Option 4
    • This seems the most visually user-friendly due to the separation of the strings into their own tables.
    • I agree with @pixelite that it would be nice to have one "save" button for all strings.

Overall, I would go with 4 or 1.

nonsie’s picture

Completely agree with the general comments made by Kristen Pol.
Since we are focusing on 1st case users I'd say #4 is the most usable at the first glance followed by #1.

SebCorbin’s picture

I would go for the 2 with all translations already shown.

- pretty clear, that is has to be saved
- better using of space

So let's use this space to have a good overview (show all translations at first sight), with an option to hide all translations tables to have only source strings.

Although I'm not very fond of having a Save button by string, I would really like a fixed button that stays at the same position while scrolling and save all translations at once.

Sutharsan’s picture

Let me try reduce the number of options we have. A few things we seem to agree upon:

  • The search/filter panel is good as in the designs. 'reset' must be a text link to make it less prominent.
  • 'copy' is unclear. If we use this, we should use 'copy source'.
  • 'content' is used with few source strings only. But if it is applicable, it should be visible. Combine it with the source string.
  • Operations links will be placed on the right of a table layout.
  • Plural fields need a label.
  • We should not waist screen real estate.

In this discussion I see people choosing for translating multiple languages at the same time. Is translating multiple languages at once an 80% use case? All translation tools I know of, including l.d.o, present one language at a time. We should not make things too complex by putting all the possible flexibilities into it.

gumanist’s picture

General
1. We have missed context filtering (or I missed something why it was done)
2. Maybe it would be better replace 'Copy' text with smth like 'Fill'...

Option 1
1. It is very complicate to understand that you have edited anything.
But it could be fixed by adding color on edited lines + add something like 'edited' text.
2. The form looks too difficult

Option 2
As for me looks the best, because
- you see translations
- workflow is clear: you press edit when you need it and press save ones you've finished
But you don't see translations

Option 3
Having only one language is not enough for a lot of people

Option 4
Looks great for editing (instead of not clear when you edit something)
But difficult for overview

I would suggest to use something similar to Translations overview page http://drupal.org/node/261292 with marks
- Utranslated
- LDO translation
- LDO outdated translation
- Custom translation
And translation workflow from Option 2

Schnitzel’s picture

In this discussion I see people choosing for translating multiple languages at the same time. Is translating multiple languages at once an 80% use case? All translation tools I know of, including l.d.o, present one language at a time. We should not make things too complex by putting all the possible flexibilities into it.

I disagree with 80%, because I see two Usecases for the Translate Functionality in Core:

  1. For Translatiors: Users which go in and translate to a specific language. This is the Case which is also handled by l.d.o, by PO Files and other Translator Tools. Because in Translation Business you are only allowed to translate to your mother tongue language. For them it would make sense that we show only 1 target language
  2. For Sitebuilders/Translation Manager: Users which don't translate themselfs, but manage translations provided by translators. With our clients we have a lot of time this case: Website with 5 Languages, we introduce a new Module which adds 2 strings, these will be translated by different Translationproviders (unfortunately not in PO Files, because there is no possibility to easily export a PO file with only just created strings). All Translations per Language are comming back and are added by a Sitebuilder for each SourceString.

The 2nd Usecase would be killed by having only 1 Targetlanguage and I see the 2nd Usecase happen more then 60% with our clients.

'reset' must be a text link to make it less prominent.

agree

'copy' is unclear. If we use this, we should use 'copy source'.

agree

'content' is used with few source strings only. But if it is applicable, it should be visible. Combine it with the source string.

you probably mean "context" and I agree

Although I'm not very fond of having a Save button by string, I would really like a fixed button that stays at the same position while scrolling and save all translations at once.

If the Form opens via AJAX (Screen 2) we should directly provide a Save button. If no AJAX: agree.

1. It is very complicate to understand that you have edited anything.
But it could be fixed by adding color on edited lines + add something like 'edited' text.

as said in http://drupal.org/node/1452188#comment-5777686 we would use the same functionality as blocks and fields are using to mark Forms as dirty

I would suggest to use something similar to Translations overview page http://drupal.org/node/261292 with marks
- Utranslated
- LDO translation
- LDO outdated translation
- Custom translation

How is the plan to add status informations about l.d.o Translations? There is #1445004: Implement customized translation bit on translations, but it does not really get status information from l.d.o.

Sutharsan’s picture

How is the plan to add status informations about l.d.o Translations?

I'm not aware of any plans.

@all, I like to have your 80% use cases too. What is the minimum requirement. We want to come to a consensus and use the 80% use case as a guide line.

Sutharsan’s picture

FileSize
20.1 KB

We have missed context filtering

No, I left it out. Less than 1% of the translations have a context. I see no use case for filtering on context.

In the design I tried to limit the filter to its minimum requirement. The search string, no doubt, must be there. 'Language' too. The remaining options are:
1. Include (f.k.a. 'Search in'): [x] Translated strings, [x] Untranslated strings
2. Translation type: [x] Base translation, [x] Customized translation
(No 2. is introduced by #1445004: Implement customized translation bit on translations)

After discussion in IRC with Schnitzel, we chosen to keep 'Include' and not implement a filter for 'Translation type'. The latter can probably be missed. But we can put the translation type in a column of the results table.

I've redrawn the filter area separately, and leaving the results + form for later. Used core's blue button pattern for the buttons. Tried different layouts for the (un)translated checkboxes and this result looks best.

klonos’s picture

Just a note here since we're discussing searching/filter on a list here, this issue might be of interest: #1475204: [META] Provide a generic search/filter UI interface pattern for listing pages

I'm not saying we should wait on that issue or anything. Merely saying that if that one is accepted and implemented, we should revisit the filtering UI part and incorporate whatever is the outcome of that issue. So perhaps a todo/reminder note there?

Gábor Hojtsy’s picture

Yeah, well, I thought we'll handle the translation UI here, and ignore redoing the filter for this issue :) I mean the translation UI in itself is well debated here, so why do debates for the filter at the same time :) Basically none of the UI plans mean any (or any substantial) changes to the filters, so we can debate those later, no? :)

klonos’s picture

Yeah, I thought that if/when we include a generic search/filter UI in D8 core, we'll surely file separate follow up issues for each page that we need to redo its filter UI. We'll just need to remember that this is one of those pages ;)

Anonymous’s picture

Hi, one question:

Where do you place the "show (translations server) suggerences" in all those proposals? (as a translator I like most option 1 by Schnitzel , BTW).

And one idea:

As well, I would keep at top of my usability list the idea of having very clear in the UI when you are, as an administrator-translator user, about to erase with no backup your translations/changes on your site.

Just my 2c.

Gustavo.

Sutharsan’s picture

I've combined the various ideas in this thread in a new wire frame design. The primary user group are system administrators and translators with limited Drupal experience who are working on websites with up to five languages. The majority of the work to be done with this interface is to make changes to one or a few translations in one language at the time. A secondary audience of experienced administrators may not be fully served with this interface.

List all languages

List one language

Edit one translation

Edit multiple translation

Remarks

  • The search/filter section is not included. The #74 wireframe can be used.
  • The edit forms are on a different pages as it is in D7.
Sutharsan’s picture

Some background info with this design.

  • Only existing Drupal core interface patterns are used for better acceptance by new users. No new patters such as a form instead of an overview table (#2, #11, #62-1, #62-3) or a form within a table (#62-2).
  • The "delete" link is removed from the results table because it is not frequently used. Further it is confusing; does it remove the translation or does it remove the source string too?
  • The language column is in the results table is hidden when the results are filtered on one language and when only one language is enabled in the site. This creates more space for the text strings.
  • In the edit form the source and the translation are formatted equally (font, width) and located close to each other. This makes it visually easy to compare the two. e.g. Is my translation to short, too long, did I translate everything?.
  • Translations information is added by means of an collapsible field set.
  • For advanced uses an "update options" section is added in combination with check boxes for each translation. This pattern is taken from the content and and users admin pages. It allows the editing of multiple translations at once. The delete option is placed here, now in two flavors delete the translation or delete both translation and source.
  • Plural description in this design is kept to a minimum. I propose to rebuild the translation UI in this issue and open a new one for the improvement of the plural labels.
Schnitzel’s picture

some feedback for the newest wirefreames:

- Overall I like them. It still gives the overview how things are translated and is still an easy overview.

- I would show the Language Column also when only 1 language is selected. From Usability point this could lead into confusion, when suddenly the user does not see the translation language anymore. What do the others think? Or maybe change the column Header "Translation" to "[language] Translation" ?

- Is there a possibility to delete translations or sources per item? Or is this only available by selecting only 1 item in the bulk operations?

- In the first screen it is not cleary visible that 1,2,3 items are the same source language (I only saw it after the 3rd look). Maybe add a bigger separator line between different sources as in my 1st screen?

- the sources column is missing? Or would you suggest to remove it? What happens when i18n is enabled and multiple sources have the same text? Or is this behavior also removed because of #1188430: Rip out textgroup support from locale module

- in the "Edit multiple translation" screen: shouldn't there be a "copy" link per plural form?

droplet’s picture

- As an admin & translator, I prefer EDIT it directly. "Choose and edit" is slow down my work.
- "In context: XXX", I'd move to top of strings.

Sutharsan’s picture

@Schnitzel:

Is there a possibility to delete translations or sources per item?

You are right, the current delete option deletes both source and all translations. I see no requirement to more fine grained delete options. So, we should have only one delete operation.

In the first screen it is not cleary visible that 1,2,3 items are the same source language

Agree, we need some visual separation here.

the sources column is missing?

Text groups are removed from core. This column was not added by i18n, but was D7 core's own.

in the "Edit multiple translation" screen: shouldn't there be a "copy" link per plural form

I expect this to be an overkill. Localization Server fill all plurals at once too.

@droplet:

As an admin & translator, I prefer EDIT it directly. "Choose and edit" is slow down my work.

You can do both. The edit link on the right for the one click solution and with three clicks you can edit multiple.

"In context: XXX", I'd move to top of strings.

There are only a hand full of contexts, but if it is there it should make a difference to the translator. You are right in making it more visible.

droplet’s picture

@Sutharsan,

ONE and more than ONE click both are indirect way. We'd translate 100 or more than 1000 strings. I prefer "Edit multiple translation" screen for all cases (and ONE source string VS multiple langs translations). Or introduce EDIT and VIEW mode.

Gábor Hojtsy’s picture

I agree with @droplet, that this design introduces quite a bit of indirection which http://drupal.org/node/1452188#comment-5697524 nicely avoided. If we scale that down to one language only and fix the link placement that was debated, I think we have a great solution. Otherwise we clearly demonstrated we can debate this endlessly. If we don't want to move forward with this, we can just say what we have now in D8 is what is going to be released (which I don't think is good). We are debating this for 6 weeks with no convergence in sight. Newer and newer mockups are more and more different. Can we go back to the simple mockup from http://drupal.org/node/1452188#comment-5697524 and scale it down even more as discussed so that it keeps being simple?

Sutharsan’s picture

Issue tags: +needs accessibility review
FileSize
173.55 KB

I had a long discussion with Gábor in IRC. We agreed we should continue on the path of with the #11 "seach & edit" design. The one-by-one editing has become the default in Drupal, but is a pain in this cases where a large numbers of small tasks need to be performed. The translation touch-ups we design for is such a case.

To reduce the complexity for inexperienced users, the 'all languages' option is removed and only one language can be edited at the time. For advanced users this is probably still acceptable.

For readability and scalability of the page the height of text areas is adjusted to match the size of the translation. Without translation the area is reduced to a text field as l.d.o does. When the field gets the focus the text area is restored. Operations links are only visible when their row is being hovered or when the translation is being edited.
The design needs accessibility review.

I have more advanced ideas for both the filter and the edit page, but will leave that for later or for a separate issue.


[edit] image added

Gábor Hojtsy’s picture

All, right, let's build this! :)

Kristen Pol’s picture

Good job on #86! I definitely don't want to open this up for more debate, but I am wondering if/how the translators will know the overall status of the translation for a particular string since their are restricted to one language (e.g. the string "hello world" has been translated to fr/de/es and not pl/ar). I didn't see this explicitly addressed in recent comments, but I might have missed it. Perhaps this could be in contrib.

Gábor Hojtsy’s picture

@Kristen: yes we are currently planning to make this screen more useful for actual translation, and on the way that kind of overview is going to be lost. Contribs will likely need to fill in that space I think.

Kristen Pol’s picture

Thanks for the clarification... so now who's going to build it? I can test it once it's ready.

ershov.andrey’s picture

Status: Active » Needs review
FileSize
3.59 KB
FAILED: [[SimpleTest]]: [MySQL] 35,238 pass(es), 67 fail(s), and 0 exception(s). View

Changed Filter Translatable Strings form

Status: Needs review » Needs work

The last submitted patch, 1452188-91.patch, failed testing.

Sutharsan’s picture

@ershov.andrey, thanks for kicking this off :)

Some remarks. No urgent need for code changes, only UI considerations.
The search fields above the select lists was on my mind, but not yet in the design. Looks good. It give the search field the priority and attention it deserves. But may need the submit button to be next to it.
Search option 'Translation type' attracts a too much attention when presented as checkboxes. I'm even wandering if we should include it at all.
We need to think what the search form should look like if 1. only one language is available, 2. only the system language is available.

Looking forward to more of your code ;)

Schnitzel’s picture

okay, not that I would prefer this UI but I agree that if we don't decide we will never find a solution.

1 question:
What will you show with the "translation information" link? Is this a general information or a dedicated depending on the placeholders in the source string?
If it's a general why not showing this at the bottom or at the top of the whole page?
And maybe show this link below the sourcetext, because this is the area where a person would have a question lke :"what is '@count' for"

andypost’s picture

FileSize
13.17 KB
15.08 KB

Another problem with this filter that checkboxes give us a 4 states each but actually there's only 5 :
1 no filter,
2 filter untranslated
3 filter translated (hides customized checkboxes)
4 filter translated customized
5 filter translated not customized

filter-states.jpg

filter-states-1.jpg

Sutharsan’s picture

@andypost,

What will you show with the "translation information" link? ...

I have not detailed this yet, but context specific would be best. I moved it out of the bottom because it can easily be overlooked when the page is long and requires a lot of scrolling when te page is long.

And maybe show this link below the sourcetext ...

The links are combined on the right for consistency. Links are only shown on hover and when the row is in use by the translator, having links pop up 'all over the place' is not desirable. The content is not only related to the source, it will also contain information about the plurals (if applicable), and I expect the amount that much text that it requires the full with (2 - 6 lines).

Another problem with this filter that checkboxes give us a 4 states each ...

Good catch. The no checkboxes selected state is an oversight. Lets go back to fieldsets (and wait for #1475204: [META] Provide a generic search/filter UI interface pattern for listing pages to come with a generic pattern).

andypost’s picture

I found another confusing moment!
When we disable all languages except one (SL site) screen1
We still have System language in filter list... screen2

Checkboxes purpose:

  • Untranslated strings indicates us to make search within locales_source
  • Translated strings to make search in locales_target
    1. Customized translation
    2. Non-customized translation

suppose "translation information" - location field of locales_source

link below the sourcetext

Core places all action links at the top of acting element, the only possible exception done for contextual links which are "hovered"

andypost’s picture

Status: Needs work » Active
FileSize
10.57 KB
3.82 KB

Language list (system-english disabled)
lang_list.jpg

string translation
lang_list_translate.jpg

Gábor Hojtsy’s picture

What do you suggest to explain System English better? :)

andypost’s picture

FileSize
6.71 KB

I think Internal(System) or System(Source) makes more sense then we have for now

lang_list_translate_en.jpg

Gábor Hojtsy’s picture

@andypost: I think Drupal 7 has "Built in English". I think its better to somehow expose that it is English. Anyhow, I don't think that belongs in this issue. It is not really a question of how it is filtered, but more a general naming discussion. It was introduced as System English when we introduced deletability for English (#1266318: Make English a first class language). There seems like Clemens also suggested "Internal (English)". I'm not sure we want to debate this here, unless we have an instant favorite.

ershov.andrey’s picture

Status: Active » Needs review
FileSize
24.73 KB
FAILED: [[SimpleTest]]: [MySQL] 35,220 pass(es), 190 fail(s), and 76 exception(s). View

#91 plus translations table changed to plain form with proper validation and submission.

Status: Needs review » Needs work

The last submitted patch, 1452188-102.patch, failed testing.

Everett Zufelt’s picture

I can give this UI an accessibility review if a demo URL and credentials are provided.

Sutharsan’s picture

@ershov.andrey,

  • Notice: Undefined index: locale_translation_filter in locale_translation_edit_form()
  • Dutch language imported, but is not default. Language select list on "System (English)". Form shows Dutch translation.
  • With the above, form submission fails with "PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'language' cannot be null: INSERT INTO"
  • Change the "Search in" checkboxes back to select list. See #96. Label "With/without translation"
  • Change the "Translation type" checkboxes back to select list. See #96.
  • Only translated strings listed, regardless of the filter.
ershov.andrey’s picture

Status: Needs work » Needs review
FileSize
18.56 KB
25.98 KB
FAILED: [[SimpleTest]]: [MySQL] 35,238 pass(es), 159 fail(s), and 16 exception(s). View

Fixed almost all known bugs, added table UI to form, deleted System language from languages select list

Known bugs:

  • Deleted string not shown - querybuilder need some love

Status: Needs review » Needs work

The last submitted patch, 1452188-106.patch, failed testing.

Sutharsan’s picture

FileSize
39.46 KB
  • Search on "files within a translation" give no results when searching in translated strings, no results when searching in untranslated strings. But a source string is found when searching in All strings.
  • Source string and translated string should align visually, this makes comparing the two strings easier. Width of source string and target string should be approximately equal (table column width). Both vertical (vertical position in the table cell) and horizontally (font size, line wrapping position) position of the text should align.
  • Trim the translated string to trim leading and trailing spaces. You may have a look at Localization Server which may do more post processing and/or string validations.
  • Form filter theming and copy, see below.
  • Gábor Hojtsy’s picture

    @ershov.andrey, @andypost: are you still working on this?

    rvilar’s picture

    Status: Needs work » Needs review
    FileSize
    27.4 KB
    FAILED: [[SimpleTest]]: [MySQL] 35,302 pass(es), 159 fail(s), and 16 exception(s). View

    Fixed all bugs, theming issues and copys.

    Status: Needs review » Needs work

    The last submitted patch, 1452188-110.patch, failed testing.

    Sutharsan’s picture

    Small steps, but we are moving in the right direction :)
    * In Google Crome there is a large gap between the buttons and the search field
    * Purposely I did not include the version data. The content is inconsistent (either the URL the string was found or the module and version it was found in) and (in case of the module version) not relevant to the translator. Pls remove
    Now it is time for the operation links and JS dynamics.
    I'll make a proposal for the "translation information".

    Sutharsan’s picture

    ershov.andrey’s picture

    Unfortunately, I'm busy right now. I hope, I'll join as soon as I can.

    perusio’s picture

    Picking this up.

    perusio’s picture

    The placement of the Filter button is different in each browser. This needs fixing.

    Distance between textfield and button:

    1. Opera: 91px
    2. Chromium: 121 px

    In Iceweasel/Firefox the button placement is misaligned. See attached images:

    Gábor Hojtsy’s picture

    @perusio: right, fixing those would be great. Also, as Sutharsan pointed out, the location information should be removed; it is mostly useless and can be very different. Thanks for taking this on!

    perusio’s picture

    FileSize
    72.6 KB

    Ok. Reinstated English and removed the ugly absolute stuff. Now it works with width and float using the #suffix and #prefix attributes of the form elements in question.

    There's some issues still. Chrome places more space between the search box and the buttons than FF or Opera. There's some oddity here. Perhaps is related to the client stylesheet. The calculated style seems to be similar though. I have to look further into this. I'll reroll the patch this evening.

    droplet’s picture

    +++ b/core/modules/locale/locale.cssundefined
    @@ -20,6 +20,11 @@
    +  position: absolute;
    

    style with "position: absolute" isn't a good pattern.

    perusio’s picture

    Yes indeed. That's why removed it. Current CSS:

    #locale-translation-filter-search-dropdowns .form-item-search {
      float: left;
      width: 35%;
    }
    
    #locale-translation-filter-search-dropdowns div#locale-translation-filter-actions {
      float: left;
      width: 62%;
      margin: 2% 0 0 2%;
    }
    
    #locale-translation-filter-search-dropdowns .form-item-language {
      clear: left;
    }
    
    perusio’s picture

    FileSize
    29.13 KB
    FAILED: [[SimpleTest]]: [MySQL] 34,874 pass(es), 196 fail(s), and 16 exception(s). View

    Here's the patch with the new mods. Please bear in mind that up until now I'm ignorant of i18n stuff in D8. If there's a roadmap, please point me to it. Thanks.

    perusio’s picture

    @Everett Zufelt I can, if you wish, setup a host with D8 on my small Linode and give you access for you to evaluate the acessability of the interface. Let me know.

    Everett Zufelt’s picture

    @perusio

    That would be great. Can you please suggest a couple of user stories (a couple of sentences each) to guide my tests? I can do the testing on Friday.

    perusio’s picture

    FileSize
    29.12 KB
    FAILED: [[SimpleTest]]: [MySQL] 34,882 pass(es), 196 fail(s), and 16 exception(s). View

    Removed the width: 100% for the dropdowns. it gives problems on firefox.

    perusio’s picture

    Assigned: Unassigned » perusio

    Assigning this to me.

    perusio’s picture

    Status: Needs work » Needs review

    Changing status.

    Status: Needs review » Needs work

    The last submitted patch, locale_module-new-ui-1452188-124.patch, failed testing.

    perusio’s picture

    This needs to be reworked from the ground up. I just made some cosmetic changes, which being important, don't contribute to test passing. I'll look into it this next weekend.

    andypost’s picture

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -12,23 +12,28 @@ function locale_translate_seek_screen() {
     function _locale_translate_seek() {
    -  $output = '';
     
       // We have at least one criterion to match
       if (!($query = _locale_translate_seek_query())) {
    +    $languages = language_list(TRUE);
    +    $default = language_default();
    +    /* if ($default->langcode == 'en' && !locale_translate_english() && count($languages) > 1) { */
    +    /*   unset($languages['en']); */
    +    /* } */
    +    $default_language = array_shift($languages);
         $query = array(
           'translation' => 'all',
    -      'language' => 'all',
    +      'language' => $default_language->langcode,
           'customized' => 'all',
           'string' => '',
    

    The loginc begind this quiery is mirrored into UI!

    Current query-builder should follow new UI login too.

    Suppose we use:

    1) search in locales_source when System language selected
    2) always search in locales_target with different filters

    Gábor Hojtsy’s picture

    @perusio: are you still working on this one? Would be great to make some progress here.

    perusio’s picture

    Hello Gábor,

    If not before at the code sprint at Drupalcamp Lyon. I had any time to work on this lately.
    That's why sprints are important IMHO. You're forced to just do it.

    Gábor Hojtsy’s picture

    Assigned: perusio » Unassigned

    Anybody else interested in working on this then?

    Gábor Hojtsy’s picture

    Status: Needs work » Needs review
    FileSize
    64.16 KB
    28.55 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,464 pass(es), 252 fail(s), and 23 exception(s). View

    Ok, since there is nobody to take this on, here is a reroll/rework.

    1. I dropped all changes related to the filter form UI. I said above we should focus on the editing table, its enough of a pain.
    2. The patch had inconsistent use of locale_translate_* and locale_translation_*, used the former since others use that too (eg. import/export).
    3. Changed the query builder to include langcode in left join and always search in both source and translation if a search string was provided. This balances the loss of searching in source text only (which did not make sense in this UI since you don't know which language to save the translation to).
    4. Renamed the _seek_ functions to _filter_ appropriately. I think their names make a lot more sense now. Built in security filtering to the session handling code.
    5. Used the editing table code as-is from the previous patch. The form validator did not have langcode but it used it, and the submission code had broken whitespace, fixed those.
    6. Dropped the operations columns for now, we can add them back later. This is already a huge improvement.
    7. Did not work on fixing any tests, but on visual testing, all filters work, the translation works, etc. Will definitely fail with tests but please review.

    UITranslation.png

    Status: Needs review » Needs work

    The last submitted patch, locale-module-translate-table.patch, failed testing.

    perusio’s picture

    Like I wrote above I'll pick this up next sunday the 27th of May.

    Gábor Hojtsy’s picture

    Status: Needs work » Needs review
    FileSize
    1.57 KB
    30.12 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,485 pass(es), 250 fail(s), and 19 exception(s). View

    @perusio: perfect, here is an update with one two of the tests fixed (uninstall en and fr). Note that instead of editing a string directly, now you can filter to that string via search and then edit it on the table. See the new code in the interdiff. The rest of the test fails should be possible to fix with similar ways. I will not work on this in the coming weekend, so please pick it back up :) I think better focus on test fails and then getting this in as-is with followups for further functionality (filter layout rework, JS operations, etc), before we reach 200 or more comments and everybody gets way too tired of the whole thing. We already lost several people here possibly :/

    Status: Needs review » Needs work

    The last submitted patch, locale-module-translate-table-136.patch, failed testing.

    Gábor Hojtsy’s picture

    Status: Needs work » Needs review
    FileSize
    30.3 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,639 pass(es), 155 fail(s), and 83 exception(s). View

    Rerolled same patch since it did not apply due to Kernel patch changes. Should still fail tests about the same way. Just a reroll for now.

    Status: Needs review » Needs work

    The last submitted patch, locale-module-translate-table-138.patch, failed testing.

    droplet’s picture

    Status: Needs work » Needs review
    FileSize
    38.95 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,723 pass(es), 178 fail(s), and 13 exception(s). View

    Quick question.
    - does it remove "ALL Language" option in Language filter ?

    90% tests error on Language filter "ALL"
    "Failed to set field langcode to all"

    Patch
    - use PagerSelectExtender
    - fixed few tests

    Gábor Hojtsy’s picture

    FileSize
    33.7 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,735 pass(es), 179 fail(s), and 13 exception(s). View
    3.83 KB

    - Pager class needs to be referenced differently. This made the uninstall tests fixed again, like above.

    - Language field changed to 'langcode' from 'language', fixing tests for that. Also, untranslated indicators are not used anymore, fixing that too to filter to untranslated instead. Works just as well :) These should fix the import test case.

    Gábor Hojtsy’s picture

    @droplet: ha! Looks like you fixed some more tests than I did and also fixed the pager. Thanks. Looking for those test results :)

    Indeed, the "All languages" option is purposefully removed, since the language selector governs what language values you have for translation in the table. For simplicity, we don't have a mixed language translation table. Contrib will be able to do that :)

    Status: Needs review » Needs work

    The last submitted patch, locale-module-translate-table-140.patch, failed testing.

    Gábor Hojtsy’s picture

    @droplet: are you going to work more on this issue? You can take my changes from http://drupal.org/files/interdiff_315.txt for the 'all' case being used to check untranslated strings. Similarly can be applied to other places where 'all' seems to be used, which looks like a recurring pattern in the failures now.

    droplet’s picture

    Status: Needs work » Needs review
    FileSize
    12.51 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch local-ui-interdiff.patch. Unable to apply patch. See the log in the details link for more information. View
    42.47 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,783 pass(es), 84 fail(s), and 13 exception(s). View

    It's all today :) will itbring down half errors ?!

    - Remaining errors are related to edit form ( admin/config/regional/translate/edit/ )

    ( I'm rarely write tests, need to study the DOC first, LOL )

    Status: Needs review » Needs work

    The last submitted patch, local-ui-interdiff.patch, failed testing.

    droplet’s picture

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -168,11 +168,13 @@
    +      $empty_option = isset( $filter['options'][$filter['default']]) ? $filter['options'][$filter['default']] : array();
    ...
    +        '#empty_option' => $empty_option,
    

    Remark: I think we need a translatable langs counter check on locale_translate_screen() rather than this.

    Gábor Hojtsy’s picture

    Status: Needs work » Needs review

    The changes in the interdiff look good except:

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -168,11 +168,13 @@
    +
    +      $empty_option = isset( $filter['options'][$filter['default']]) ? $filter['options'][$filter['default']] : array();
    

    Whitespace issues. The newline is not needed, the space after isset( should not be there.

    Otherwise feel free to add a 'default' on each options, I'm surprised select lists don't have defaults, I think I solved this problem earlier by assigning defaults, no?

    +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.phpundefined
    @@ -160,29 +160,25 @@ class LocalePluralFormatTest extends WebTestBase {
    -    $this->assertFieldById('edit-translations-hr-0', '@count sat');
    -    $this->assertFieldById('edit-translations-hr-1', '@count sata');
    -    $this->assertFieldById('edit-translations-hr-2', '@count sati');
    -    $this->assertNoFieldById('edit-translations-hr-3');
    -    $this->assertFieldById('edit-translations-fr-0', '1 heure');
    -    $this->assertFieldById('edit-translations-fr-1', '@count heures');
    -    $this->assertNoFieldById('edit-translations-fr-2');
    +    $this->assertText('@count sat');
    +    $this->assertText('@count sata');
    +    $this->assertText('@count sati');
    +    $this->assertNoText('3. plural form');
     
         // Edit some translations and see if that took effect.
         $edit = array(
    -      'translations[fr][0]' => '1 heure edited',
    -      'translations[hr][1]' => '@count sata edited',
    

    We are losing the checks for Croatian stuff here. You should download the page for Croatian too and check the strings to retain the tests.

    droplet’s picture

    FileSize
    9.9 KB
    49.67 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,828 pass(es), 50 fail(s), and 9 exception(s). View

    Drupal\locale\Tests\LocalePluralFormatTest

    - Leave ONE error. I have no idea.

    format_plural(1, '1 day', '@count days', array(), array('langcode' => 'fr'));
    

    the UI only shown 2 plural to manual inject string, is it a known bug or what I missed ?

    Drupal\locale\Tests\LocaleTranslationTest
    - testStringTranslation failed
    - No "delete" link any more ??

    Basically only 2 test function still have errors now. anyone take care of it?

    Gábor Hojtsy’s picture

    @droplet: for delete, if you empty the field for the translation, it will delete it (an empty translation for something does not make sense, it is used in the form as well to designate untranslated strings, right?). I don't understand your first question before this "the UI only shown 2 plural to manual inject string".

    droplet’s picture

    FileSize
    16.14 KB
    19.06 KB
    16.14 KB

    see images:

    It's same langcode, but 2nd screen missing 2. plural form.
    test-screen1.png

    test-screen2.png

    D7 "Del Link" removes both source & translations

    Gábor Hojtsy’s picture

    Indeed, if it is the same language and the plurals are not showing up consistently, that looks like a bug.

    For the delete feature, we are not doing cross language edits here, especially not any changes to sources, so we should not loose the source string in any case. The updated functionality allows to remove the translation only for the language picked for the table, that should be tested.

    Status: Needs review » Needs work

    The last submitted patch, 1452188-new-lang-ui-149.patch, failed testing.

    droplet’s picture

    Status: Needs work » Needs review
    FileSize
    54.61 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,673 pass(es), 14 fail(s), and 1 exception(s). View

    Oh. for some reason. I go an SQL error in LanguageUILanguageNegotiationTest. Can't help to fix this part.

    [08-Jun-2012 11:10:02 UTC] Uncaught PHP Exception Drupal\Core\Database\DatabaseExceptionWrapper: "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'drupal8x.simpletest28341locales_source' doesn't exist: SELECT s.source, s.context, t.translation, t.language FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.version = :version AND LENGTH(s.source) < :length; Array 
    

    How about you, testbot ?

    Gábor Hojtsy’s picture

    Is that happening on your test system? Does not seem to happen in testing above.

    Status: Needs review » Needs work

    The last submitted patch, test.patch, failed testing.

    droplet’s picture

    Status: Needs work » Needs review
    FileSize
    56.8 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-new-lang-ui-157.patch. Unable to apply patch. See the log in the details link for more information. View
    10.93 KB

    @Gábor,
    Seems like my virtualbox cached the files ..etc

    Plural form
    I can reproduce same bug with old UI:

    pform

    Gábor Hojtsy’s picture

    Catalan would need to have more plural forms? I believe Catalan uses two.

    Gábor Hojtsy’s picture

    In other words, I don't think that looks like a bug for Catalan at all.

    droplet’s picture

    Sorry. wrong screen. tested "Croatian" (hr).. same bug. Is it a hard list for the plural forms ?

    EDIT: Okay. I found the files
    \core\modules\system\tests\upgrade\drupal-7.language.database.php

    Gábor Hojtsy’s picture

    Until you import a .po file for a language, the plural form will not be known. If the screenshot is from the update tests, then the file you qouted is relevant, otherwise it is not.

    Status: Needs review » Needs work

    The last submitted patch, 1452188-new-lang-ui-157.patch, failed testing.

    droplet’s picture

    Status: Needs work » Needs review
    FileSize
    56.8 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,843 pass(es), 3 fail(s), and 0 exception(s). View
    git rebase origin/HEAD
    git diff origin/HEAD > 1452188-new-lang-ui.patch

    Status: Needs review » Needs work

    The last submitted patch, 1452188-new-lang-ui.patch, failed testing.

    droplet’s picture

    Status: Needs work » Needs review
    FileSize
    56.79 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,851 pass(es). View

    I found myself never use translate UI before.

    Dig deeper and found a new bug: #1623564: Wrong text at translation UI

    droplet’s picture

    FileSize
    23.7 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch interdiff-to-145_0.patch. Unable to apply patch. See the log in the details link for more information. View
    58.72 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,858 pass(es). View

    Between #145 - #165:

    - Fixed all tests.
    - Set Language filter to "<none>" if no translatable language enabled.
    - Fixed spelling "Sigular" -> "Singular"
    - Also included bug fix from #1623564: Wrong text at translation UI
    - Source String & Translation columns split into 50%/50% of the width
    - Fixed Filter form space issue. Now more close to others form in Seven.
    - ..etc

    Please review :)

    Status: Needs review » Needs work

    The last submitted patch, interdiff-to-145.patch, failed testing.

    droplet’s picture

    Status: Needs work » Needs review
    Schnitzel’s picture

    FileSize
    3.02 KB
    61.03 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,868 pass(es). View

    Applied to my drupal 8 testinstallation and patch looks good!

    Tested creation of translations, editing, etc.
    Filters also worked, tested the "non-customization translation" filter with setting customized in the database to 0.

    Also tested when no translatable language is available.

    found a small thing in the patch:

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -10,152 +10,79 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    +  $sql_query->leftJoin('locales_target', 't', "t.lid = s.lid AND t.language = '" . $filter_values['langcode'] . "'");
    

    This should probably be:

    $sql_query->leftJoin('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", array(':langcode' => $filter_values['langcode']));
    

    (is fixxed in the new patch)

    I also updated the code to implement the "dirty" marking features as shown in #86.
    I'm using own code, which is in some parts copied of the tabledrag.js, if we ever make a more global implementation of dirty marking, this would be good to be refactored.
    As discussed with Gabor we will not implement yet the more fancy functionalities like "copy source", "undo changes", etc.

    Status: Needs review » Needs work
    Issue tags: -Needs usability review, -needs accessibility review, -D8MI, -sprint, -language-ui

    The last submitted patch, 1452188-new-lang-ui-169.patch, failed testing.

    Schnitzel’s picture

    Status: Needs work » Needs review
    Issue tags: +Needs usability review, +needs accessibility review, +D8MI, +sprint, +language-ui

    #169: 1452188-new-lang-ui-169.patch queued for re-testing.

    Schnitzel’s picture

    FileSize
    4.6 KB
    61.26 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,851 pass(es). View

    updated patch with two accessibility features:

    - showing the language in the translation column
    - hidden label for the translation textareas

    Gábor Hojtsy’s picture

    This is a quick accessibility test report of the patch. We discussed adding the above two things as we realized we need to provide more context for text to speech browsers. Here is the navigation path that I followed to show that information is available as needed. My navigation path was (starting from one of the translations accidentally and then hitting a bug with step 8 where it did not announce the text - it normally does, as the later steps show, it was a local bug in Chrome Vox that I used for the testing).

    Note the tool allows you to move "down to the next thing" or "into the next thing". People can easily reproduce this by installing Chrome Vox (a Google Chrome extension) and then navigating through the page with Ctrl+Cmd+cursors.

    PS. I recognize the irony of posting a .mov without video, audio only.

    Schnitzel’s picture

    FileSize
    5.64 KB
    61.27 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,860 pass(es). View

    during listening to the video without video (;)) we realized that currently both "original" and "source", and also "text" and "strings" are used.
    Because Source and Strings is more often used, we decided to use this too.

    attached patch fixxes this (code comments and UI text), for the help text we decided to wait with this, we have to make a whole help text review for all parts of locale/language module

    droplet’s picture

    Status: Needs review » Needs work
    Issue tags: +JavaScript
    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -232,6 +232,8 @@ function locale_translate_filter_form_submit($form, &$form_state) {
    +  drupal_static_reset('language_list');
    +  $languages = language_list();
    
    @@ -241,6 +243,7 @@ function locale_translate_edit_form($form, &$form_state) {
    +    '#language' => $languages[$filter_values['langcode']]->name,
    
    @@ -421,9 +425,9 @@ function locale_translate_edit_form_submit($form, &$form_state) {
    +  $header = array(t('Source string'), t('Translation for @language', array('@language' => $form['#language'])));
    

    $filter_values contains language name ?

    The dirty change make me sick.
    1. add "a" into textarea
    2. remove "a"
    This is no changes. (but the UI said its changed)

    +++ b/core/modules/locale/locale.jsundefined
    @@ -0,0 +1,39 @@
    +    $("#edit-strings textarea").change(function(){
    

    It should start with locale ID and use find().

    +++ b/core/modules/locale/locale.jsundefined
    @@ -0,0 +1,39 @@
    +  return '<abbr class="warning tabledrag-changed" title="' + Drupal.t('Changed') + '">*</abbr>';
    ...
    +  return '<div class="tabledrag-changed-warning messages warning">' + Drupal.theme('localeTranslateChangedMarker') + ' ' + Drupal.t('Changes made in this table will not be saved until the form is submitted.') + '</div>';
    

    remove/rename tabledrag (.ajax-changed)

    tagging JS, @_nod may interested :)

    Gábor Hojtsy’s picture

    Yeah, feedback from some people using it would be good. The change handler works elsewhere the same way as you described. Whether it is Views or the field UI, if you change something and then you change it back, it will still tell you that you changed it. Other UIs where we have change handlers are less often used. We don't have a change handler in the node form for example, because we assume people understand it does not save itself. We do have change handlers at places like the field UI.

    Schnitzel’s picture

    FileSize
    2.55 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch interdiff-174-177_1.patch. Unable to apply patch. See the log in the details link for more information. View
    62.02 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,858 pass(es). View

    $filter_values contains language name ?

    nope, unfortunately not, it only contains the keys:

    array (
      'string' => '',
      'langcode' => 'en',
      'translation' => 'all',
      'customized' => 'all',
    )
    

    Attached a patch which fixes the classes and also the JS find. but I'm not sure if I'm using the ID you would suggest.

    also renamed locale.js and locale.css to locale.admin.js and locale.admin.css.

    Schnitzel’s picture

    Status: Needs work » Needs review

    Status: Needs review » Needs work

    The last submitted patch, interdiff-174-177.patch, failed testing.

    nod_’s picture

    Thanks droplet, you're right, I'm interested.

    If I'm following #edit-strings textarea is likely to match a lot of textarea, in that case we should be using event delegation as the current way of doing things will quickly slow things down. I'll make some time to work on the JS bits, hopefully tonight.

    droplet’s picture

    +++ b/core/modules/locale/locale.cssundefined
    @@ -29,3 +29,6 @@
    +  background: #FFB;
    

    @nod_, can you also fix the color hex, to lowercase. thanks :)

    nod_’s picture

    Status: Needs work » Needs review
    FileSize
    59.96 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-182-translate-ui.patch. Unable to apply patch. See the log in the details link for more information. View

    Here is the rewrite for local.admin.js profiling shows delegation takes half the time of the previous behavior (half of not much though :) and it'll scale to however many textarea are displayed. Hopefully it's simpler to understand too.

    Var declarations might seems weird, we don't have standards for those yet if you want to ague about this please go to #1483396: [policy, no patch] JavaScript coding standards for variable declarations and let's find a generic solution for that.

    I fixed the CSS droplet mentioned as well. My interdiff-foo is weak, the changes are localized in the previous areas: local.admin.js and local.admin.css.

    Status: Needs review » Needs work

    The last submitted patch, 1452188-182-translate-ui.patch, failed testing.

    nod_’s picture

    Status: Needs work » Needs review
    FileSize
    61.42 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,867 pass(es). View
    Schnitzel’s picture

    Status: Needs review » Needs work
    FileSize
    2.71 KB
    62.11 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,860 pass(es). View

    thanks to @nod_ for the fixxes, looks like the patch did miss some parts, here a rerolled patch which should work to apply.
    also found, that ajax-changedshould be used, which removes the ugly border of the abbr tag

    Schnitzel’s picture

    droplet’s picture

    Status: Needs work » Needs review

    Great!!

    Should it use LABEL? (Only use label for form controls)

    <div class="form-item form-type-item" id="edit-strings-2-original">
      <label for="edit-strings-2-original" class="element-invisible">Source string </label>
     HTTP Result Code: !status
    <abbr title="Changed" class="warning ajax-changed localetranslate-changed">*</abbr></div>

    also, can it remove the DIV layer and move the #id to TD. Good for theming too.

    Gábor Hojtsy’s picture

    FileSize
    138.28 KB

    It was a form item in Drupal 7 too. See attached. I think it logically makes sense for it to be a form item (it pairs up with the input field) plus it also gives us the invisible label, which is standard on forms.

    andypost’s picture

    Status: Needs review » Needs work
    +++ b/core/modules/locale/locale.module
    @@ -111,7 +111,7 @@ function locale_menu() {
    -    'page callback' => 'locale_translate_seek_screen',
    +    'page callback' => 'locale_translate_screen',
    

    let's rename this to locale_translate_page() to follow core's pattern

    +++ b/core/modules/locale/locale.pages.inc
    @@ -10,152 +10,79 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    -function locale_translate_seek_screen() {
    +function locale_translate_screen() {
       // Add CSS.
    

    Comment is useless

    +++ b/core/modules/locale/locale.pages.inc
    @@ -10,152 +10,79 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    +  drupal_add_css(drupal_get_path('module', 'locale') . '/locale.admin.css');
    +  drupal_add_js(drupal_get_path('module', 'locale') . '/locale.admin.js');
    

    Should we change this #attached to allow aggregation?

    +++ b/core/modules/locale/locale.pages.inc
    @@ -493,55 +410,39 @@ function locale_translate_edit_form_submit($form, &$form_state) {
    +      $source = drupal_render($string['original_singular']) .'<br />'. drupal_render($string['original_plural']);
    +    }
    +    else {
    +      $source = drupal_render($string['original']);
    +    }
    +    $source .= empty($string['context']) ? '' : '<br /><small>'. t('In Context') .':&nbsp;'. $string['context']['#value'] .'</small>';
    

    I think <br /> should be changed to <br> because doc-type now is not xhtml

    nod_’s picture

    As andypost pointed out, the JS needs a detach function. I've namespaced the events to make it easier to unbind.

    Drupal.behaviors.localeTranslateDirty = {
      attach: function () {
        var $form = $("#locale-translate-edit-form").once('localeTranslateDirty');
        if ($form.length) {
          // Display a notice if any row changed.
          $form.one('change.localeTranslateDirty', 'table', function () {
            var $marker = $(Drupal.theme('localeTranslateChangedWarning')).hide();
            $(this).addClass('changed').before($marker);
            $marker.fadeIn('slow');
          });
          // Highlight changed row.
          $form.on('change.localeTranslateDirty', 'tr', function (e) {
            var
              $row = $(this),
              $rowToMark = $row.once('localeMark'),
              marker = Drupal.theme('localeTranslateChangedMarker');
    
            $row.addClass('changed');
            // Add an asterisk only once if row changed.
            if ($rowToMark.length) {
              $rowToMark.find('td:first-child .form-item').append(marker);
            }
          });
        }
      },
      detach: function (context, settings, trigger) {
        if (trigger === 'unload') {
          var $form = $("#locale-translate-edit-form").removeOnce('localeTranslateDirty');
          if ($form.length) {
            $form.off('change.localeTranslateDirty');
          }
        }
      }
    };

    (not rerolling the patch. With D8MI I end up messing it up every single time)

    Schnitzel’s picture

    FileSize
    4.41 KB
    62.59 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-new-lang-ui-191.patch. Unable to apply patch. See the log in the details link for more information. View

    thanks for the feedback, new version of the patch:

    - renamed locale_translate_screen() to locale_translate_page()
    - using #attached
    - removed comment
    - using

    - new version of JS by @nod_

    Schnitzel’s picture

    Status: Needs work » Needs review
    droplet’s picture

    It should be <br />. It has an issue about this topic (sorry. can't find it). But GREP all source
    you'll see the answer :)

    EDIT:
    #1388926: Remove all references to "self-closing" void elements in core

    @#188
    Label everywhere is validated code. But I don't think this is semantic markup.

    Schnitzel’s picture

    Just did a short Usability Review with @Marinero

    It worked overall, but it had some clitches.

    The Task was:
    Translate the "No front page content has been created yet." string to Spanish.
    He went to the User interface translation page, searched for the string and realized with the Table Column Name "TRANSLATION FOR ENGLISH" that he would translate to English. To get rid of this, he changed the language of the Drupal to Spanish and went again into the User interface translation page, but was surprised that it still shows "TRANSLATION FOR ENGLISH". So he went in the form and after some clicking around he saw the "Language" Dropdown, changed to Spanish and was finally able to translate the string.

    Conclusion:

    • Use the current site language as default for the language dropdown (which doesn't fix this for every case, because after submitting the form it is saved in the Session and will not use the current site language anymore, but at least a small step).
    • Change the Label of the Language dropdown to: "Translation language"

    After translating the string, the left the cursor in the textfield and scrolled to the safe button, but with trying to click the button, the change() handler is called and it shows the warning bar on top, which then moves the whole form down and also the button, so the button wasn't clicked.

    Conclusion:

    • Remove the warning bar and add the "Changes made in this table will not be saved until the form is submitted." text to the abbr tag

    The next task was to review existing translations, imaginated he is on the 14th page and change some existing translations. After clicking saving, he is back in on the first pager page and has to use the pager again to go to the 14th page. Using browser back (which is faster) could lead into strange behaviors, with overwritten existing strings, etc.

    Conclusion:

    • When saving on a specific pager page, the user should stay there. Good thing here, if the page does not exist anymore (because of "search in" filters, it just shows the latest existing page)

    will wait for some feedback and will start implementing the conclusions in couple of hours

    Status: Needs review » Needs work

    The last submitted patch, 1452188-new-lang-ui-191.patch, failed testing.

    LoMo’s picture

    I've done another set of usability tasks with @Schnitzel, as in #194. I'll summarize in the same format:

    Task 1:
    Translate the "Add content" string to German (looking at the "Navigation" menu block on the home page).

    It had been a while since I'd done string translations, so it took me a moment to find the right place to look. Of course I was also experimenting to see if there were any new "tricks" implemented. And trying to pretend I was newer to Drupal admin/site-building than I really am. Soo.... I started by looking at the "configuration" for the block. Could it be there might be settings there? Nope. How about if I follow the link; anything useful there? Nope. Hmmm... Let's look at the "configuration" link in the toolbar then. The "Language" link jumped out at me before I saw the "User interface translation" so I clicked on it first, which did allow me to get to the translations (through clicking on the link in the Interface translation column), but there could be some improvements to the interface and functionality…

    Conclusion:
    On admin/config/regional/language, there is text which says "Interface text can be translated." This is not currently linked to the translations admin page: admin/config/regional/translate/translate and providing this link might be helpful.

    Conclusion:
    In the "Interface translation" column, there are links to the translations for each language… at least they appear to be links to translate each language, but in fact they all go to translating from English to English. If a site has, e.g. German, enabled, the link for German translations the “Interface translation” column should be to the "User interface translation page (admin/config/regional/translate/translate) page, but with the "Translation language" already set to German (or whatever language is clicked).

    Conclusion:
    The filter system allows us to look for a string and filter by "Search in", but the options could be more clear or at least more consistent. Currently the options are:

    • Both translated and untranslated
    • Only translated strings
    • Untranslated strings

    We should change the third option to "Only untranslated strings" to be consistent.

    Conclusion:
    On the "User interface translation" page, when filtering by language and "Only translated strings", there is another selector which becomes visible: "Translation type". This selector has three options:

    • All
    • Non-customized translation
    • Customized translation

    If you don't already known what the "non-customized translation" means (if you don't know that you can import translations), you won't know what these options mean. Since I'd already made some custom translations, I was able to understand what this meant by changing the settings and seeing the results, but some "help text" more clear options for the selector (i.e. "Imported translations" instead of "non-customized translations") might be more clear.

    Schnitzel’s picture

    Status: Needs work » Needs review
    FileSize
    20.21 KB
    72.6 KB
    FAILED: [[SimpleTest]]: [MySQL] 36,839 pass(es), 35 fail(s), and 0 exception(s). View
    167.52 KB

    Updated version of the patch, thx to @Marinero and @LoMo for the Usability tests and again @LoMo for some Code contributions!

    Changelog:

    • Codestyle fixes of locale.module and locale.pages.inc
    • Changed the Links in the Language overview (see Screenshot: http://drupal.org/files/Language%20Links.jpg)
    • Limited the string results to 30 instead of 50 (can be pretty big with long strings)
    • Filter defaults in the string translation page can be overwritten by parameters in the URL (needed for the links in the language overview)
    • Default language in the filters on the string translation page is now the current interface language (if no other defaults in parameter or Session)
    • Changed "Untranslated strings" to "Only Untranslated strings"
    • User Stays on the current pager page when saving strings
    • Changed Warning Message is added at the end of the Form (not visible in the interdiff because of some git fails by me)

    Status: Needs review » Needs work

    The last submitted patch, 1452188-new-lang-ui-197.patch, failed testing.

    Schnitzel’s picture

    Status: Needs work » Needs review
    FileSize
    77.96 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,876 pass(es). View

    grml, had some old tests in here, now it should work.

    Schnitzel’s picture

    FileSize
    77.96 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,859 pass(es). View

    just had a IRC chat with @nod_ and he ponted me that we should use closest() instead of parents(), this is fixxed now.

    nod_’s picture

    Status: Needs review » Needs work

    Actually you can make that simpler, since you want to manipulate form and not the table you can remove the delegation and just bind to the form so that you'll go from:

    $form.one('change.localeTranslateDirty', 'table', function () {
      var $marker = $(Drupal.theme('localeTranslateChangedWarning')).hide();
      $(this).closest("form").addClass('changed').after($marker);
      $marker.fadeIn('slow');
    });
    

    to

    $form.one('change.localeTranslateDirty', function () {
      var $marker = $(Drupal.theme('localeTranslateChangedWarning')).hide();
      $(this).addClass('changed').after($marker);
      $marker.fadeIn('slow');
    });

    (It's the same as the initial code, I just remove the extra table parameter from the .one() call)

    droplet’s picture

    FileSize
    16.84 KB
    28.2 KB
    41.65 KB
    5.53 KB
        Notice: Undefined index: in locale_translate_edit_form() (line 267 of /var/www/drupal8x/core/modules/locale/locale.pages.inc).
        Notice: Trying to get property of non-object in locale_translate_edit_form() (line 267 of /var/www/drupal8x/core/modules/locale/locale.pages.inc).

    #1. (will testbot warning it too ?)

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -10,155 +10,89 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    +  $sql_query = $sql_query->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit(30);
    

    #2. can it rewrite to $sql_query->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit(30);
    I think no errors ?

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -264,168 +214,156 @@ function locale_translation_filter_form() {
    +    drupal_get_path('module', 'locale') . '/locale.admin.css',
    ...
    +    drupal_get_path('module', 'locale') . '/locale.admin.js',
    

    #3. cached it ?

    $path = drupal_get_path('module', 'locale');
    

    dbclick.png
    #4. double click included "*" ? might be add a own layer to strings ?

    html_code.png
    #5. wrong labels here too.
    is it better if it use CSS for the padding ?

    context.png
    #6. expected result?

    new_issue.png
    #7. (NOTHING) New separated issue I think ?

    droplet’s picture

    also

    • #8. should it aslo handle Double space, 2+ spaces " " at "Source string" side ?
    • #9. class="odd localeMark-processed changed", every classes should be lowercase ?
    Schnitzel’s picture

    Status: Needs work » Needs review
    FileSize
    3.27 KB
    133.31 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,883 pass(es). View

    thx for the Review @droplet and @nod_

    Here a new patch

    Changelog:
    - fixed JS as suggested by nod_
    - fixxed notices on string form if no language enabled
    - $sql_query->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit(30); instead of $sql_query = $sql_query->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit(30); does not work, it shows all strings without pager
    - $path = drupal_get_path('module', 'locale'); is now used for caching
    - #4 => Good point, found a way to fix it in Webkit, but not in Firefox he all the time selects also the *
    - #5 => this is quite hard, because there is no possibility to add attributes to 'item' form elements, and giving all form-type-item a padding (also the one which are not singular/plural) I think is a bad idea.
    - #9 => fixxed

    Some responses (by Gabor and me):
    - #6 => what you actually mean? that it is twice there? yes, because the second one in is another context (but it is actually a bug in the datepicker.js, so we will open another issue)
    - #7 => this comes from en empty source string, which shouldn't be the case, but another issue.
    - #8 => this is how it should be, the source string should not be touched at all.

    Gábor Hojtsy’s picture

    @droplet: opened a new issue at #1634190: Long month names in locale.datepicker.js not using context properly for the long month name problem (your #6), will get someone on it :)

    droplet’s picture

    - #6 => what you actually mean? that it is twice there? yes, because the second one in is another context (but it is actually a bug in the datepicker.js, so we will open another issue)
    I was thought it merge into one row.

    Singular:
    1 day
    
    Plural:
    @ count 
    
    Context:
    Long monthy..
    
    ..etc

    - #8 => this is how it should be, the source string should not be touched at all.

    But if the source string have 2+ spaces. UI only display ONE space. Translator will trust it as ONE space only.

    and browsers will remove beginning & ending space, 2+ space between words

    Orig string:
    <-beginning SPACE |2+-> <-2+| SPACE ending->

    UI:
    <-beginning SPACE |2+-> <-2+| SPACE ending->

    Schnitzel’s picture

    #6

    ??? no, this was never the idea, we combine only singular/plural in one row, what you showed us is actually a bug and will be fixxed with http://drupal.org/node/1634190

    #8

    This was the case in Drupal 6, and Drupal 7, so it has nothing to do with this Issue. So please create another issue for this.

    Nick_vh’s picture

    Apart from the 0/19 link that causes confusions (not clear enough) and was made clear that it needed to be reverted at the Drupal Dev Days sprint, this patch looks good to me! Well done!

    droplet’s picture

    Schnitzel’s picture

    FileSize
    75.53 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,881 pass(es). View

    okayyyy, somehow was the patch pretty wrong, this is fixxed now and contains only the stuff it should do.

    also removed the separate links in the language list page, because it confused some people.

    go testbot go

    aspilicious’s picture

    +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.phpundefined
    @@ -323,4 +346,4 @@ msgid "Monday"
    \ No newline at end of file
    

    newline needed

    +++ b/core/modules/locale/locale.admin.cssundefined
    @@ -0,0 +1,38 @@
    \ No newline at end of file
    

    add a newline at the end of your files

    13 days to next Drupal core point release.

    Schnitzel’s picture

    FileSize
    75.4 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,880 pass(es). View

    thanks aspilicious!
    fixxing "No newline at end of file"

    Bojhan’s picture

    Alright so I gave this a relatively quick usability review by show-tell with Gabor and Schnitzel. In general I think the patch looks good, its definitively simplifying big parts of this interaction. I noticed two major problems;

    1) The "click the save button" notice is now displayed below the table, this is a big issue - because people do often forget to Save and just the yellow communicates nothing to most users. A bit of white space, would allow for it and fix this quite easily.

    2) The filter/search functionality is a bit awkwardly designed. People don't notice critical functionality, but from my point of view this should be fixed more broadly later. I imagine we fix how we do filters in core, then apply it here or visa versa. But this should definitely be a follow up.

    Other than that, this looks ready to go!

    droplet’s picture

    Status: Needs review » Needs work
    +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.phpundefined
    @@ -61,11 +61,13 @@ class LocaleUninstallTest extends WebTestBase {
    +    $string = db_query('SELECT min(lid) AS lid, source FROM {locales_source} WHERE location LIKE :location', array(
    
    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -183,8 +126,9 @@ function locale_translation_filters() {
           'translated' => t('Only translated strings'),
    ...
    +      'untranslated' => t('Only Untranslated strings'),
    

    Missing this one ? "Untranslated " -> 'untranslated '

    +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.phpundefined
    @@ -160,32 +160,41 @@ class LocalePluralFormatTest extends WebTestBase {
    +     $this->assertText('Singular form');
    +     $this->assertText('First plural form');
    +     $this->assertText('2. plural form');
    +    $this->assertNoText('3. plural form');
    

    miss aligned.

    +++ b/core/modules/locale/locale.pages.incundefined
    @@ -10,155 +10,89 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    +      ->condition('s.source', '%' . db_like($filter_values['string']) . '%', 'LIKE')
    
    +++ b/core/modules/translation/translation.jsundefined
    @@ -0,0 +1,21 @@
    +      if ((default_language == 'und' || default_language == 'zxx' || default_language == 'mul') && $('#edit-node-type-language-locked').attr('checked')) {
    

    maybe use prop() ? any thought @nod_ ?

    Gábor Hojtsy’s picture

    +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePluralFormatTest.phpundefined
    @@ -160,32 +160,41 @@ class LocalePluralFormatTest extends WebTestBase {
    +     // Labels for plural editing elements.
    +     $this->assertText('Singular form');
    +     $this->assertText('First plural form');
    +     $this->assertText('2. plural form');
    +    $this->assertNoText('3. plural form');
    +
    

    Whitespace issues.

    +++ b/core/modules/locale/locale.moduleundefined
    @@ -2,13 +2,13 @@
     /**
      * @file
    - *   Add language handling functionality and enables the translation of the
    - *   user interface to languages other than English.
    + * Add language handling functionality and enables the translation of the
    + * user interface to languages other than English.
    

    File summary comments should be on one line!

    +++ b/core/modules/locale/locale.moduleundefined
    @@ -292,11 +279,11 @@ function locale_field_language_alter(&$display_langcode, $context) {
      *
    - * @param $field_langcodes
    + * @param array $field_langcodes
      *   A reference to an array of language codes keyed by field name.
    - * @param $entity
    + * @param object $entity
      *   The entity to be displayed.
    - * @param $langcode
    + * @param string $langcode
      *   The language code $entity has to be displayed in.
      */
     function locale_field_language_fallback(&$field_langcodes, $entity, $langcode) {
    @@ -368,26 +355,21 @@ function locale_language_delete($language) {
    
    @@ -368,26 +355,21 @@ function locale_language_delete($language) {
       // Changing the language settings impacts the interface:
       cache('page')->flush();
     
    -  // Clearing all locale cache from database
    +  // Clearing all locale cache from database.
       cache()->delete('locale:' . $language->langcode);
     }
     
    -
    -// ---------------------------------------------------------------------------------
    -// Locale core functionality
    -
     /**
      * Provides interface translation services.
    - *
      * This function is called from t() to translate a string if needed.
      *
    - * @param $string
    + * @param string $string
      *   A string to look up translation for. If omitted, all the
      *   cached strings will be returned in all languages already
      *   used on the page.
    - * @param $context
    + * @param string $context
      *   The context of this string.
    - * @param $langcode
    + * @param string $langcode
      *   Language code to use for the lookup.
      */
     function locale($string = NULL, $context = NULL, $langcode = NULL) {
    @@ -402,7 +384,7 @@ function locale($string = NULL, $context = NULL, $langcode = NULL) {
    
    @@ -402,7 +384,7 @@ function locale($string = NULL, $context = NULL, $langcode = NULL) {
     
     
       if (!isset($string)) {
    -    // Return all cached strings if no string was specified
    +    // Return all cached strings if no string was specified.
         return $locale_t;
       }
     
    @@ -428,12 +410,14 @@ function locale_reset() {
    
    @@ -428,12 +410,14 @@ function locale_reset() {
      *
      * The index is computed from the formula of this language.
      *
    - * @param $count
    + * @param int $count
      *   Number to return plural for.
    - * @param $langcode
    + *
    + * @param string $langcode
      *   Optional language code to translate to a language other than
      *   what is used to display the page.
    - * @return
    + *
    + * @return int
      *   The numeric index of the plural variant to use for this $langcode and
      *   $count combination or -1 if the language was not found or does not have a
      *   plural formula.
    @@ -499,7 +483,7 @@ function locale_themes_enabled($themes) {
    
    @@ -499,7 +483,7 @@ function locale_themes_enabled($themes) {
      * This function will either import translation for the component change
      * right away, or start a batch if more files need to be imported.
      *
    - * @param $components
    + * @param array $components
      *   An array of component (theme and/or module) names to import
      *   translations for.
      *
    @@ -579,7 +563,7 @@ function locale_js_alter(&$javascript) {
    
    @@ -579,7 +563,7 @@ function locale_js_alter(&$javascript) {
     }
     
     /**
    - * Implement hook_library_info_alter().
    + * Implements hook_library_info_alter().
    
    @@ -654,7 +640,7 @@ function locale_form_language_admin_overview_form_alter(&$form, &$form_state) {
     /**
    - * Implements hook_form_FORM_ID_alter() for language_admin_add_form(().
    + * Implements hook_form_FORM_ID_alter() for language_admin_add_form().
      */
     function locale_form_language_admin_add_form_alter(&$form, &$form_state) {
       $form['predefined_submit']['#submit'][] = 'locale_form_language_admin_add_form_alter_submit';
    @@ -725,7 +711,7 @@ function locale_form_system_file_system_settings_alter(&$form, $form_state) {
    
    @@ -725,7 +711,7 @@ function locale_form_system_file_system_settings_alter(&$form, $form_state) {
     }
     
     /**
    - * Implements hook_preprocess_HOOK() for node.tpl.php.
    + * Implements hook_preprocess_HOOK().
      */
     function locale_preprocess_node(&$variables) {
       if ($variables['langcode'] != LANGUAGE_NOT_SPECIFIED) {
    @@ -836,7 +822,8 @@ function _locale_parse_js_file($filepath) {
    
    @@ -836,7 +822,8 @@ function _locale_parse_js_file($filepath) {
           'context' => $plural_matches[3][$key],
         );
     
    -    // If there is also a plural version of this string, add it to the strings array.
    +    // If there is also a plural version of this string,
    

    Not related to this patch. :/

    Also, no newline at end of file at the end.

    nod_’s picture

    Actually I still need to go through translate.js, talked a bit about it yesterday with Schnitzel I'm hoping to simplify it, seems complicated.

    But yes, here .prop is what should be used.

    Schnitzel’s picture

    Status: Needs work » Needs review
    FileSize
    12.13 KB
    67.17 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,868 pass(es). View

    Not related to this patch. :/

    well, right, okay I removed it :)

    Changelog:

    • Warning Bar is not on top of Table
    • Fixxed "Untranslated " -> 'untranslated '
    • Fixxed Whitespace issues
    • removed all the not relevant codestyle changes
    svenryen’s picture

    I applied the 1452188-new-lang-ui-217 patch from Schnitzel to the d8 branch.
    I was able to load the interface for content translation, as well as search for strings.

    I verified that the translated strings appeared on the installed site and I also
    successfully translated both singular and plural forms of a string.

    To confirm it shows up as intended in the interface, I created an article and then i posted one comment, followed by another comment. I was able to see both singular and plural versions of the string.

    I added multiple languages and added various translations successfully.

    Schnitzel’s picture

    FileSize
    32.63 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,870 pass(es). View

    reroll because of PSR-0 patches which went in.

    Schnitzel’s picture

    FileSize
    32.7 KB
    FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1452188-new-lang-ui-220.patch. Unable to apply patch. See the log in the details link for more information. View

    Status: Needs review » Needs work

    The last submitted patch, 1452188-new-lang-ui-220.patch, failed testing.

    Schnitzel’s picture

    Status: Needs work » Needs review
    FileSize
    67.17 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,876 pass(es). View

    ohoh, the #219 was a renaming issue of me, this is the same patch as in #217 which still applies even with the recently PSR-0

    Gábor Hojtsy’s picture

    No newline at end of file still.

    Schnitzel’s picture

    FileSize
    67.15 KB
    PASSED: [[SimpleTest]]: [MySQL] 36,878 pass(es). View

    grml...

    fixxed No Newline

    Gábor Hojtsy’s picture

    Status: Needs review » Reviewed & tested by the community

    RTBC since the previous came back green and this is just a newline change :)

    In summary, there is 4 months of development in this on several sprints including Denver and Barcelona. It had multiple users testing it and providing feedback (3-4 just here in Barcelona alone), various lead developers on it throughout, we did accessibility reviews, we did UX review with Bojhan, extensive JS review with _nod, and everybody agrees all around that its a better solution then we had before. There are likely still ways for improvement, but its a huge step already, and we should move on with followups now.

    webchick’s picture

    Status: Reviewed & tested by the community » Fixed

    Schnitzel was kind enough to walk me through this patch and the old 7.x UI. GREAT job on this folks!!

    COMMITTED AND PUSHED TO 8.X WOOO :D

    Can we please get some follow-up issues to apply these nice UI patterns elsewhere in core's admin UI?

    aspilicious’s picture

    Gábor Hojtsy’s picture

    Crosspost I think.

    Bojhan’s picture

    Bojhan’s picture

    Schnitzel’s picture

    Gábor Hojtsy’s picture

    We should have a changelog entry for this as well as a change notice node. Anybody up for those?

    Gábor Hojtsy’s picture

    Title: New UI for string translation » CHANGELOG: New UI for string translation
    Status: Fixed » Needs review
    FileSize
    686 bytes
    PASSED: [[SimpleTest]]: [MySQL] 37,025 pass(es). View

    Added change notice node at http://drupal.org/node/1647466, attaching changelog patch suggestion. If it looks good, let's get it in.

    Schnitzel’s picture

    Status: Needs review » Reviewed & tested by the community

    looks good for me!

    RTBC if it gets green ;)

    webchick’s picture

    Title: CHANGELOG: New UI for string translation » New UI for string translation
    Status: Reviewed & tested by the community » Fixed

    Committed and pushed to 8.x. Thanks!

    Gábor Hojtsy’s picture

    Issue tags: -sprint

    Done, moving off sprint. Who wants to open a followup or two for improving the UI even more (eg. operations links, highlighting placeholders, etc). Would be good to have a list of all followups in one place too.

    Automatically closed -- issue fixed for 2 weeks with no activity.