Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkp/pkp-lib#7272 Simultaneously Displaying Multilingual Metadata on the Article Landing Page #4050

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jyhein
Copy link
Contributor

@jyhein jyhein commented Oct 2, 2023

Issue: pkp/pkp-lib#9373

  • Show multilingual metadata on the article landing page
  • In Website Settings > Theme, select title, keywords, and abstract metadata to show on the article landing page in other languages

@jyhein
Copy link
Contributor Author

jyhein commented Oct 2, 2023

Hey @asmecher,

I have PRs ready for review of the code...

OJS: #4050
OMP: pkp/omp#1466

@asmecher
Copy link
Member

asmecher commented Oct 3, 2023

Thanks, @jyhein! I'd like to start by passing this by @Devika008; can you add a couple of screenshots that show the changes?

@asmecher asmecher changed the title Simultaneously Displaying Multilingual Metadata on the Article Landing Page pkp/pkp-lib#9373 Simultaneously Displaying Multilingual Metadata on the Article Landing Page Oct 3, 2023
@asmecher asmecher changed the title pkp/pkp-lib#9373 Simultaneously Displaying Multilingual Metadata on the Article Landing Page pkp/pkp-lib#7272 Simultaneously Displaying Multilingual Metadata on the Article Landing Page Oct 3, 2023
@jyhein
Copy link
Contributor Author

jyhein commented Oct 4, 2023

Hey @Devika008 and @asmecher,

Here are some screenshots:

metadata_opts
landing_page

@Devika008
Copy link

Devika008 commented Nov 21, 2023

@jyhein @asmecher

I'm sorry for getting onto this late. I might have missed it. However, I believe that when users read through the data, they wont read data in a way that article title in french in Spanish in Portuguese and then move onto the next one. They will go through the metadata together in a language. Sometimes its easier to scout for metadata when you know the language you're looking for. Hence I propose the following reorder of data with respect to clubbing the metadata in one language togehter. Its easier to process and find

image

@jyhein jyhein force-pushed the f7272 branch 3 times, most recently from 5d41251 to a7ddb59 Compare November 27, 2023 20:21
->concat(['keywords', 'abstract'])->unique()->diff($titles->keys())->values();
$multilingualOpts = collect($showMultilingualMetadataOpts)
->when(in_array('title', $showMultilingualMetadataOpts), fn ($m) => $m->concat(['subtitle', 'fullTitle'])->unique()->values());
$primaryLocale = isset($titles->get('title')[$contextPrimaryLocale]) ? $contextPrimaryLocale : $publication->getData('locale');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not correct: why do we use the context primary locale?
See how the function DataObject::getLocalePrecedence() works (https://github.com/pkp/pkp-lib/blob/main/classes/core/DataObject.php#L97), used in DataObject::getLocalizedData() (https://github.com/pkp/pkp-lib/blob/main/classes/core/DataObject.php#L65):
First either preferred locale will be considered, if given (e.g. if you want to get a key/attribute in a specific locale).
If preferred locale is null, the UI locale is considered.
If there is no value for this locale, then the fallback locale (getDefaultLocale()) is considered. For Publication object it is the submission primary locale (s. e.g. PKPPublication::getDefaultLocale()). This value should actually always exist for required fields.
And if no value is found here, e.g. for keywords that do not necessarily need to be in the submission primary locale, then check context and then site primary locale.
If no value exists for any of these locale the function getLacalizedData() will return the first found value.

Thus, I think we should do the same here, no? Also, if possible to use that getLacalizedData() function.

Also, on the article view page:
With this implementation the context primary locale instead of UI locale (that exists) is displayed. For example, let say context primary locale is FR, and the article primary locale is EN, and metadata exist in both languages (EN and FR). When the UI locale is EN, the article is displayed in FR, although EN exist.
If the UI would be DE, and article does not have metadata in DE, the EN should be displayed, because EN is the submission primary locale.

I do not know if Devika said something about the situation when e.d. keywords only exist also in DE, additionally to the example above.
Currently it is so: if the UI = DE, then title and abstract are displayed in EN (because they do not exist in DE, but in submission primary locale), but keywords are displayed in DE.
I think for now we should keep this, if Devika has said nothing about it now, how it woks now. And I think Devika wanted to think further about how to improve it all...

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed context->getPrimaryLocale() to templateMgr->getTemplateVars('currentLocale'). If no "show multilingual metadata" options selected in the default theme settings and metadata does not exist in title's locale, then the metadata is shown in some other language.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jyhein, I have not taken a look into the code yet, but I tested it, and there is still some difference from how it was till now:
Lets say the journal has EN, FR, DE, and SP enabled as UI and submission languages.
Lets say the article primary locale is EN, and it has all metadata also in FR, and additionally it also has author metadata and keywords in SP.
When the reader select SP as UI language:
Now it is so:
The article title and abstract are displayed in EN, author metadata in SP, and the keywords also in EN, although the keywords in SP exist. Then the article metadata in SP are considered next, and there the keywords in SP are displayed.
If the new option to show metadata in all languages is not selected in Website Settings, then the SP keywords are never displayed.
Thus, I think it should be:
The article title and abstract are displayed in EN, author metadata and keywords in SP. Then the other languages are considered the data exists for, i.e. EN and FR.

Thus, could we do something like this:
For the first/main display of metadata use getLocalizedData as till now. This first/main display considers the selected UI language. It will return either the data in the UI language or the data in article primary language or any other existing language.
Then for the new functionality, to display metadata in further languages: Get all existing article languages for the selected metadata from the settings (title, abstract, keywords), remove the UI language from that list (because it is handled as first), then for each language from that list display existing metadata using getLocalizedData(key, language).

I am not 100% sure, but maybe in the handler class you would 'only' need to get those further languages that needs to be displayed (= get all existing article languages for the selected metadata from the settings (title, abstract, keywords), remove the UI language from that list). And then in the template this can be done: for each language from that list use getLocalizedData(key, language) to display metadata in additional languages.

Copy link
Contributor Author

@jyhein jyhein Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @bozana! Default view (no metadata options selected): the code tries to give the metadata based on the title language (if not ui then submission). If the metadata does not exist in title language, then the getLocalized data selects some found language. I tried to avoid to display a mix of languages as much as possible. I can change this to match the original logic, or I could display the other languages the same way like in the multilingual view.

Multilingual view (one or more options selected) : Using getLocalizedData won't work here because if in UI/submission language e.g. keywords do not exist, the function would show it in other language. In this view it would be inconsistent.

I have not included author metadata in to this but I can do that

Copy link
Contributor

@bozana bozana Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jyhein, I am hesitant to change how it worked till now -- it was so for a long time... :-) Also because maybe not all users will use this additional function and the system should behave as always. The keywords in SP from the example above should be visible. (Also, users could extend the default theme to also display other metadata (e.g. coverage, sponsoring agencies, etc.) and they would probably follow the same logic, and they all should be visible in default view).
And because Devika will maybe come with a fully different model/logic later... So lets keep this as it was, for now, i.e. with minimal changes, if possible.

Thus, I think default view (no metadata options selected) should work as till now.
The multilingual view (one or more options selected): the first metadata display should stay as it is, as in the default view, and only the other existing languages (different than selected UI language) should be added.

Sorry, I was wrong about getLocalizedData for additional (other than selected UI) languages: it should be getData(key, locale)....

You do not need to include author metadata -- it was just an example, that they can also be in other languages, i.e. in SP in the example above and would be visible...

@jyhein jyhein force-pushed the f7272 branch 3 times, most recently from f95676a to 0baa986 Compare December 6, 2023 17:10
@bozana
Copy link
Contributor

bozana commented Dec 8, 2023

Hi @Devika008,
Just to double check something with you:
Lets say the journal has EN, FR, DE, and SP enabled as UI and submission languages.
Lets say the article primary locale is EN, and it has all metadata also in FR, and additionally it also has author metadata and keywords in SP.
When the reader selects SP as UI language, it was so till now: Title and abstract are shown in EN (article primary language, because they do not exist in SP) and author metadata and keywords in SP.
With this new feature, when metadata are selected to be displayed in other languages too, it would look like this:
1)
Title EN
Author SP
Keywords SP
Abstract EN

Article Metadata in EN
Title EN
Author EN
Keywords EN
Abstract EN

Article Metadata in FR
Title FR
Author FR
Keywords FR
Abstract FR

That means under "Article Metadata in EN" the title and abstract will be shown, even they are also shown in the first element (for UI = SP) because they do not exist in SP.
Do you think it is OK so for now?
This would be the minimal change needed to be made for now.

Else, @jyhein, tried not to mix the languages, so that way it now would be:
2)
Title EN
Author SP
Keywords EN
Abstract EN

Article Metadata in SP
Keywords SP

Article Metadata in FR
Title FR
Author FR
Keywords FR
Abstract FR

This looks maybe OK when the option to show the metadata in multiple languages is selected, but when that option is not selected, the SP metadata will never be displayed, which I think is not a solution. Also, this changes the way how it was till now.

Thus, just to double check with you what do you think is better for now, and to let you know about this edge case when you work on the default theme further.

Thanks a lot!

EDIT: I think we could also consider authors metadata in the #2, so that not only they are displayed in UI=SP in the first element, and we could maybe differentiate the situation when the option to show the metadata in multiple languages is selected or not (so that the SP data are shown if that option is not selected), but it is all even a bigger complication.
I prefer #1 and minimal changes for now, till we find the right way for all this (also considering that submission and metadata locales can be fully different from UI locales - the feature that is coming).

@bozana
Copy link
Contributor

bozana commented Dec 8, 2023

@Devika008, maybe just a note: I have just spoken with @jyhein and we will then try to have separate solutions for those that have the multilingual view enabled and those that do not have it (which will work as till now). @jyhein will document it in the issue on Monday...

I still think that we are maybe investing too much time now, because we will need to rethink it all soon (when submission and metadata languages are separated from the UI languages), and eventually when UI language will be accessible via URL... but...

@jyhein jyhein force-pushed the f7272 branch 2 times, most recently from 4b735dc to aed56ac Compare December 10, 2023 17:14
@jyhein
Copy link
Contributor Author

jyhein commented Dec 11, 2023

Hey, @Devika008

Here are some some cases when metadata exist partially only:

  • Multilingual view
  • Show metadata in other languages: Title and abstract selected, keywords NOT selected
  • English as submission locale

Case 1: Only keywords in Swedish:

  • Swedish: UI (Abstract and ##plugins.themes...## headings are in Swedish) and keywords
  • English : Title, keywords, and abstract

landing_page_settings-title_and_abstract

Case 2: Only title in Swedish

  • Swedish: UI and title
  • English: Title, keywords, and abstract

landing_page-only_title_exists

@ajnyga
Copy link
Contributor

ajnyga commented Dec 18, 2023

@bozana I think your examples show that the real problem we have in OJS (and which is underlined now more) is the concept of mixing metadata based on the UI language. I mean this:

When the reader selects SP as UI language, it was so till now: Title and abstract are shown in EN (article primary language, because they do not exist in SP) and author metadata and keywords in SP.

This is confusing for the reader especially in cases where the two languages are close to eachother.

I still think that we are maybe investing too much time now, because we will need to rethink it all soon (when submission and metadata languages are separated from the UI languages), and eventually when UI language will be accessible via URL... but...

I do not think that having the UI language accessible via URL will affect this. It will just change the way language switching is happening. The real question is that should the UI language affect submission metadata view especially in cases where the full metadata is not available for the selected language. In my opinion such functionality should only happen when the full text is multilingual and in all other cases we should always respect the Submission Locale.

But I think this issue is separate from that. The real use case for this is a situation where only small parts of metadata (like the abstract) is available in other language and the editors want to show that on the same landing page. IMO we should not try to extend this further from that concept.

@bozana
Copy link
Contributor

bozana commented Dec 18, 2023

@ajnyga, yes... So what do you think is best for this issue, now?

EDIT: because according to the design, we do not display the abstracts one after another (which would be much easier), but first all metadata in one language and then in other, and then other,... (for all existing metadata languages)...

EDIT EDIT: I am not thinking about the way we will solve the UI, submission and metadata languages and URL languages now -- we will wait for Devika's concept...

@bozana
Copy link
Contributor

bozana commented Apr 26, 2024

Hi all, I believe this could be maybe the next issue we can finish :-)
I am not sure what we decided, how to proceed with the multilingual view. Thus, can someone -- it would be good if @Devika008 could also tell us what she thinks about it -- summarize what do you think would be the best way to display information for the following case:
The journal has EN, DE and ES enabled as UI and submission languages.
The article primary locale is EN. Additionally it also has author metadata and keywords in ES.

  1. For "Show metadata in other languages" all options (title, abstract and keywords) are selected.
    How would the page look like for each UI language (EN, DE, ES)?
  2. For "Show metadata in other languages" title and abstract are selected (keywords are not selected).
    How would the page look like for each UI language (EN, DE, ES)?

If the journal has additionally FR as submission and metadata locale, and FI as metadata locale. How would those be considered/displayed, if the article has all data in FR and some metadata in FI?

Thanks a lot!

@ajnyga
Copy link
Contributor

ajnyga commented Apr 26, 2024

The journal has EN, DE and ES enabled as UI and submission languages.
The article primary locale is EN. Additionally it also has author metadata and keywords in ES.

For "Show metadata in other languages" all options (title, abstract and keywords) are selected.
How would the page look like for each UI language (EN, DE, ES)?

  • UI EN: en metadata shown as usual, additionally es keywords visible in the bottom
  • UI DE: en metadata shown as usual, additionally es keywords visible in the bottom
  • UI ES: en metadata shown for most cases keywords shown if es, additionally en keywords visible in the bottom

For "Show metadata in other languages" title and abstract are selected (keywords are not selected).
How would the page look like for each UI language (EN, DE, ES)?

  • UI EN: en metadata shown as usual, es keywords not visible
  • UI DE: en metadata shown as usual, es keywords not visible
  • UI ES: en metadata shown for most cases keywords shown in es, en keywords not visible

If the journal has additionally FR as submission and metadata locale, and FI as metadata locale. How would those be considered/displayed, if the article has all data in FR and some metadata in FI?
This would depend on the settings they made and if the UI is available in both languages. If the UI is available just in French then it is quite clear: if the new setting is turned of for the metadata fields, then any content given for those in Finnish is shown in the bottom.

Just want to underline two things:

  1. We are sure to find obscure combinations with this setting. It is however good to note that it is entirely voluntary to turn on and it works best in a situation where publishing is happening in one language, the UI is in one language BUT the journal is producing some metadata in other languages as well and wants to display this without turning on the UI for a language they do not have for example any of the journal information available. It will not fit the needs of all journals and combinations.
  2. As a software OJS has opted to use the switching of the UI to display specific language metadata. We could argue that it would make more sense to show the metadata always based on the primary article locale especially in cases where the full text is just in one language and any other language metadata would always be available without changing the UI (I also think that if you publish multilingual full text that should be multiple submissions). But as long as we stick with the current model we need to implement solutions that are not transparent for the user: for example falling back to any available language when a specific field of metadata is missing for the current UI locale.

@jyhein jyhein force-pushed the f7272 branch 2 times, most recently from 65fd6ac to 7d7cde1 Compare April 29, 2024 15:47
@AhemNason
Copy link

Hey folks, I'm just getting caught up on this conversation and trying to wrap my head around it. 

I think any movement in this direction is good. Off the top. I just want to say that! Devika, I appreciate all the work you've put into these. 

I think there's more than one reason for journals to try to display multilingual metadata. 

Marc said this: 

 I understood that the main objective is to allow bilingual researchers to read two languages at the same time (for example because my knowledge of one language is not as good as the other and the translated text serves to clarify) but the current solution does not allow this.

I think this is only half true. The other objective is to give journal options for displaying multilingual metadata so that they're not tempted to jam all their metadata into one field to get them to display at the same time. 

When I see errors in this space it is almost always about display. "I want to see both". "I want our title to have both languages". "I want both abstracts to be viewable on one record without having to search for it." 

But, it's possible that this is a cultural difference between what I've seen with Canadian journals and what I've seen with other cultures where bilingualism is a lot less... uhhh... federally complex

But I also want to raise something that A-J said further down: 

 How would we define "all metadata available"
The central idea in the UI solution relies on our ability to say when metadata is "complete" or "partial". But in effect this is fairly hard to do. In most cases the metadata is never complete. I realize that in the UI it refers to a few specific fields to be complete, but I think we are leading the reader a bit off when we say that metadata is complete when we have title, abstract and keywords filled in.

This is where I think we start to run into problems with multilingual metadata for real. Downstream. When the metadata leaves OJS for other systems. 

There's two problems: 

  1. Multilingual Metadata Fidelity
  2. What metadata is displayed

And Devika has indicated this. 

And I think the side-by-side option for displayed stuff works. But I do think we need to figure out what we mean by "completeness" in the multilingual space before we figure out what "completeness" in the UI/UX space is. 

Basically, I don't really know if users need an at-a-glance multilingual view for, like, affiliations. They need titles, abstracts, and then galley labels. We know that much. And I think for major UI/UX refactors knowing what metadata users need, specifically, in this kind of view is good. I'm not confident it needs to be "all available metadata". And, actually, I almost think we should do something more like a DSpace or repository record where you can view all item metadata external to the article view UI. 

I think I'll also tag @mtub here. I do think the conversations around what's displayed for multilingual metadata and how users see it is a huge issue. There's such a balance between: 

  • metadata completeness and consistency
  • ui/ux best practice
  • reader needs
  • journal wants

@jyhein jyhein force-pushed the f7272 branch 2 times, most recently from 5a8eef9 to 2c87b0c Compare October 14, 2024 07:37
@jyhein jyhein force-pushed the f7272 branch 2 times, most recently from a35d0e6 to 6c3ab81 Compare October 23, 2024 12:02
@jardakotesovec
Copy link
Contributor

jardakotesovec commented Nov 22, 2024

Hi, just let you know, I have been reviewing the metadata switching on article page.

But still have not figure out how to proceed exactly with it yet.

Main issue I have there is with that metadata switcher.

From seeing the interactive mockup - it works exactly as html select element - just with custom look. You click on it, and than you can select other one and once you select other one it closes.

So I think best for accessibility would be to code it like that. Example of such component with correct accessibility is for example here - https://headlessui.com/v1/vue/listbox (when using for example such headless component its quite straightforward to have custom look as in mock up)

And ideally organise it is so the code of the select component itself is not entangled as much with the metadata changing use case.

On the reader side we have limited options (no vue.js yet). I have been looking to alpinej, which currently offers headless components and is good fit - does not require build step and is good for adding some JS interactivity.

I managed to make it work with it - avoiding any custom JS and relying on alpine for accessibility. But realised that the problem might be that even all alpine code is MIT - the documentation for components/headless components are paywalled, so I am not sure how much we would want to encourage using it going forward. So need to check with team and explore if I can come up with some other alternative. Basically to avoid re-implementing listbox correctly.

Ideas/thoughts welcomed.

@jardakotesovec
Copy link
Contributor

jardakotesovec commented Nov 28, 2024

@jyhein
Sorry for delay.. lets proceed with following:

Here is example how the alpine select can be used, so we don't have to reinvent accessible select - 4bf3847

Here are suggestions to improve things

  1. Move the select component to separate smarty component, so its not repeated and its simple to replace it with different implementation if we would depart with alpine
  2. select itself should not be inside h element
  3. lets keep more intricate logic in php realm, so we can keep the smarty templates as simple as possible, which makes it easier for downstream to update it and it also it makes easier once we would be moving from smarty. So for example its better to calculate which locales are available for each metadata in php
  4. Same with styling - default theme needs to be easy to understand and adjust. Lets keep it as simple as possible - I don't think we need animations there for example. The css I introduced is not something to follow neceserrarly - just wanted to illustrate that I can achieve custom styling with this headless component
  5. The alpine dependency should be handled from package.json.. thats something I can look into later on.

@jyhein
Copy link
Contributor Author

jyhein commented Dec 4, 2024

Thanks for the suggestions, @jardakotesovec

I have few comments:
1., 2. & 4.: I showed @Devika008 the current functionality and she seemed to approve it. Few things to note are: 1. h1 and h2 have the same language switcher. 2. The switcher list of languages stays open while clicking the language buttons (this seems better UX to me than re-clicking it open every time one wants to switch the language). 3. The animations are for better UX too, especially when more than one text changes language and the switcher isn't right next to the text that changes.

  1. Selecting the correct languages PHP-side will create multilevel array that may cause some trouble later but we'll see. Also note that I have to add all publication's multilingual properties including authors' too. I tried to avoid this and added some complexity to the smarty code instead.

@jardakotesovec
Copy link
Contributor

jardakotesovec commented Dec 4, 2024

@jyhein Hi Jyrki,
if you would like to discuss something more - we can setup call if you like.

Have you done some screen reader testing? Multiple suggestions is really motivated by testing voice over in safari. And thinking how to semantically encode this. I see there are some use of aria-expanded, but from testing did not seem that functional.

So first thing I was really trying come up with is how to encode the language switcher. And when checking Devikas interactive mock up I came to conclusion that it behaves same as html select component, just with different styling. Benefit is that with screen reader you will hear that there are multiple options (and how many) and that you are moving between them with clear understanding that you are selecting one of them.

Having in some cases the locale switcher inside h element and sometime outside is also concern about having good semantic html so its well interpreted by SR.

Your option when it closes on the outside click is nice - but not sure how to code that. If you come up with some SR friendly way I am not against it.

Other motivations are really just to keep the template and css changes minimal so its very easy to understand and customise as the default theme is the go to theme for making customisations and child themes.

Regarding animations I am somewhat indifferent - thing is that for multiline titles part of the page is jumpy anyway.. So my motivation here is just to keep things simple, but thats something we can get back to and also get Devika preference.

@jyhein
Copy link
Contributor Author

jyhein commented Dec 10, 2024

Screen reading part I can improve. I can move all the switchers outside of h-elements, it does not matter where they are in the code. Most of the template changes come from the foreach loops to add the multilingual texts, to add the switchers is just adding data-pkp-* -attributes and the element where to target the switcher. It is easy to understand from the examples. And one can choose to add just one switcher to change all the texts on the page.

@jardakotesovec
Copy link
Contributor

jardakotesovec commented Dec 10, 2024

@jyhein Oki, sounds good, looking forward to the update. Thanks.

@jardakotesovec
Copy link
Contributor

@jyhein wondering whether passing the other languages as json object to the page could help with simplifying the template part. So it would not need to iterate over languages - but instead it take it from JS object and replace the text inline. What you think?

@jyhein
Copy link
Contributor Author

jyhein commented Dec 11, 2024

OK, sounds good

@israelcefrin
Copy link
Contributor

israelcefrin commented Feb 13, 2025

Hello all,

I've been testing this feature on a sandbox OJS installation. It is a nice option to be able to switch the language of specific components to improve the accessibility of the content to users who can read in other languages. The built-in language switcher is pretty handy.
There are barriers we have to keep in mind, though. Users who rely on assistive technology, such as screen readers, will require that every critical visual information be announced as text. For instance, when focusing on the switcher, how many languages are available, and which one is currently selected? Also, the translated component will have to be turned on a live region to announce the change of status/context.

Focusing on the switcher only, this is the parsed HTML on the page:

<span aria-label="The article title and subtitle languages:" role="none" aria-orientation="horizontal" data-pkp-switcher="titles" aria-expanded="false">
<button type="button" class="pkpBadge pkpBadge--button" value="en" tabindex="0" role="option" aria-hidden="false" aria-pressed="false" aria-current="true">en</button>
<button type="button" class="pkpBadge pkpBadge--button" value="fr_CA" tabindex="-1" role="option" aria-hidden="true">fr-CA</button></span>

I've attempt to switch the language using keyboard navigation only, and it was possible, not easy though. Also, the HTML is semantically valid. However, there is a critical lack of accessibility that I noticed while testing with 2 screen readers (SR)(VoiceOver on MacOS and JAWS on Windows):

  • There is no clear information of the selected language
  • The options are announced as acronym instead the language, e.g. "en" instead "English"
  • The screen reader can't announce the total of languages available

Possible remediation to fix the issues above should include:

  • Adding UL element as container and each button contained by LI element - it should force the SR to announce the total of languages and which is the current item, e.g.: 1 element of 2 (or three, or four ...)
  • Insert a visually hidden label for each language to announce the language name, and an aria-hidden attribute to the acronym to prevent from being announced.
  • Turn the translated components into live-region to be announced the new context/status when the language is activated and changes the label to a new language. It will also require to update the lang attribute to be announce properly by SR using the correct language voice.

I will paste bellow a possible HTML remediation ( I changed the HTML only, the CSS will require further adjusting):

<div role="group" aria-label="The article title and subtitle languages">
    <ul role="listbox" aria-label="Select language" class="language-switcher">
        <li> <! -- <== It will be announced "One of two" --> 
            <button type="button" 
                    class="pkpBadge pkpBadge--button" 
                    value="en" 
                    role="option" 
                    aria-selected="true">
                <span class="visually-hidden">English</span> <!-- <== this will be announce by SR but not visible -->
                <span aria-hidden="true">en</span> <!-- <== this will be visible but it will not be announced by SR --> 
            </button>
        </li>
        <li> <!-- <== It will be announced "Two of two" -->
            <button type="button" 
                    class="pkpBadge pkpBadge--button" 
                    value="fr_CA" 
                    role="option" 
                    aria-selected="false">
                <span class="visually-hidden">French (Canada)</span>
                <span aria-hidden="true">fr-CA</span>
            </button>
        </li>
    </ul>
</div>

Key improvements made:

  1. Replaced span with semantic div and ul/li structure
  2. Added full language names with visually-hidden class for screen readers
  3. Used role="listbox" and role="option" for better semantic meaning
  4. Removed tabindex attributes as buttons are naturally focusable

This chunk can be simplified if we use links instead of buttons, but it will require to adjust the JS that makes all the changes. Also, we should consider a fallback solution too.

@jardakotesovec
Copy link
Contributor

jardakotesovec commented Feb 14, 2025

@israelcefrin Thanks Israel for the notes.

I also did some testing with voice over on mac and it does not behave as listbox (it does not announce the options)

It can be compared with some existing implementation like - https://react-spectrum.adobe.com/react-aria/Select.html

I suspect that the main reason is that once is clicked on the 'en' button - it will change the whole thing to be listbox. So there is no connection between having button thats opening listbox. And thats what I suspect confuses screen reader.

Its not trivial to get these things right.. thats why I was suggesting to use headless dependency for this, even though having additional dependency is also not great. But I still think it might be better choice than trying to reimplement listbox correctly.

@israelcefrin
Copy link
Contributor

israelcefrin commented Feb 14, 2025

Hello @jardakotesovec

I suspect that the main reason is that once is clicked on the 'en' button - it will change the whole thing to be listbox. So there is no connection between having button thats opening listbox. And thats what I suspect confuses screen reader.

That's is likely true. ARIA is a great way to implement accessibility features, but it may be tricky sometimes. Also, I've painfully learned that with OS / Browsers / Screen Readers, you always need to close all browser windows, open screen reader, and re-open the testing browser.

For some reason, SR may have an erratic behaviour to connect and read the DOM tree from already open browsers. At the end of the day, that's how actual SR users experience the interaction too.

If you run in some non-expected behaviour when testing a component/ARIA, try to close both SR and the browser, and re-test launching the SR first. In Linux this protocol is even documented since they recommend to launch ORCA before Firexof to navigate.

thats why I was suggesting to use headless dependency for this

What is headless dependency for this component? I am not familiar with the term. (and google didn't help much)

@jyhein
Copy link
Contributor Author

jyhein commented Feb 18, 2025

Hey @israelcefrin,
Thanks for the testing, comments and help!
I pushed updated version where I used your instructions. I tried other choices too but there always was something that didn't work with either Safari or Firefox using VO. That ul-li seemed to work the best.
Your 'HTML remediation' code worked quite well with some changes. I used span-elements still because the switchers should be inline elements instead of block. I also used buttons to keep the code simpler. Role and aria-selected are in li-element because Firefox says no

@jardakotesovec
Copy link
Contributor

@israelcefrin In react/vue ecosystem there is lots of headless libraries, that will handle accessibility and interactivity, while give you full power of custom styling. Outside of these ecosystems I came across alpinejs headless components https://alpinejs.dev/components , that are realtively easy to integrate with just html. Unfortunate is that the docs is behind paywall. But also understand that they need to support project somehow. Actual code is opensource.

I tried to apply it in our case - its covered in this comment - #4050 (comment) . Biggest pain point is that paywall. But in general these libraries are great if done well.. to avoid reinventing these patterns that have clear specification.

@israelcefrin
Copy link
Contributor

Hello @jyhein , I am running tests using ScreenReaders to emulate the user experience. There is one issue that I can't find the cause. After I change the Heading level 1 language, JAWS screenreader announces it 3 times. It happens only when I change the language. If I navigate the page, the component is announced only once (as it should be).
Maybe it is a JAWS bug and does not have anything on your end. Currently, I am testing how to switch languages using different OS/Browsers/SR.

@israelcefrin
Copy link
Contributor

Hello @jyhein , just confirming that removing the aria live region from h1 tag and adding it to a parent container has fixed the issue with JAWS screenreader.

@israelcefrin
Copy link
Contributor

israelcefrin commented Feb 24, 2025

Hello @jyhein , I've noticed that you've added tabindex="0" and tabindex="-1" to the elements of switching language components. The latter removes them from ScreenReader reach (DOM tree).

<ul role="listbox" aria-label="Select language">
<li role="option" aria-selected="true">
<button type="button"... tabindex="-1"><span class="pkp_screen_reader">French</span><span aria-hidden="true">fr-CA</span></button></li>

Is there any specific reason to add the attribute? I run a final test using keyboard only navigation + Windows SR (JAWS and NVDA) and I am not able to switch the languages. VoiceOVer in MacOS doesn't seem to bother though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants