From 9b4e84dad7e812448fc71e330185284f40521247 Mon Sep 17 00:00:00 2001 From: amadulhaxxani Date: Mon, 13 Apr 2026 16:13:15 +0200 Subject: [PATCH 1/5] Add lang attributes to description fields Set HTML lang attributes based on metadata language for various description and metadata display elements to improve i18n and accessibility. Updated templates to bind [attr.lang] on spans, links and browse links; metadata-values now passes mdValue.language into render templates; clarin description component now emits per-entry language and value pairs; ClarinItemBoxView stores itemDescriptionLang; SidebarSearchListElement supports descriptionLang with a getDescriptionLang() hook and OrgUnit implementation returns the description language. These changes ensure displayed metadata uses the correct language attribute when available. --- ...me-search-result-grid-element.component.html | 2 +- ...al-search-result-grid-element.component.html | 2 +- ...ct-search-result-grid-element.component.html | 2 +- ...it-search-result-list-element.component.html | 2 +- ...nit-sidebar-search-list-element.component.ts | 7 +++++++ ...it-item-metadata-list-element.component.html | 2 +- .../metadata-values.component.html | 17 +++++++++-------- .../full-file-section.component.html | 4 ++-- ...clarin-description-item-field.component.html | 4 +++- .../clarin-description-item-field.component.ts | 16 ++++++---------- .../clarin-item-box-view.component.html | 2 +- .../clarin-item-box-view.component.ts | 8 +++++++- .../sidebar-search-list-element.component.html | 1 + .../sidebar-search-list-element.component.ts | 15 +++++++++++++++ 14 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html index ebd8c5cb6ba..86b6328a8ed 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html @@ -31,7 +31,7 @@

- +

diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html index 698a401bba0..102f1967d8e 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html @@ -35,7 +35,7 @@

- +

diff --git a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html index a5936c0585d..07a01da8df8 100644 --- a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html +++ b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html @@ -25,7 +25,7 @@

- +

diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html index 8221a3608fa..4c48b4c28d2 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.html @@ -31,7 +31,7 @@ + [innerHTML]="firstMetadataValue('dc.description')" [attr.lang]="dso.firstMetadata('dc.description')?.language || null"> diff --git a/src/app/entity-groups/research-entities/item-list-elements/sidebar-search-list-elements/org-unit/org-unit-sidebar-search-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/sidebar-search-list-elements/org-unit/org-unit-sidebar-search-list-element.component.ts index 25ff6181b2d..35dc045dda6 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/sidebar-search-list-elements/org-unit/org-unit-sidebar-search-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/sidebar-search-list-elements/org-unit/org-unit-sidebar-search-list-element.component.ts @@ -24,4 +24,11 @@ export class OrgUnitSidebarSearchListElementComponent extends SidebarSearchListE getDescription(): string { return this.firstMetadataValue('dc.description'); } + + /** + * Get the language of the Org Unit description. + */ + getDescriptionLang(): string | null { + return this.dso.firstMetadata('dc.description')?.language || null; + } } diff --git a/src/app/entity-groups/research-entities/metadata-representations/org-unit/org-unit-item-metadata-list-element.component.html b/src/app/entity-groups/research-entities/metadata-representations/org-unit/org-unit-item-metadata-list-element.component.html index ec4dbd43236..7ca6ca2c02e 100644 --- a/src/app/entity-groups/research-entities/metadata-representations/org-unit/org-unit-item-metadata-list-element.component.html +++ b/src/app/entity-groups/research-entities/metadata-representations/org-unit/org-unit-item-metadata-list-element.component.html @@ -1,7 +1,7 @@ - + diff --git a/src/app/item-page/field-components/metadata-values/metadata-values.component.html b/src/app/item-page/field-components/metadata-values/metadata-values.component.html index de6f4139941..f2b21db938c 100644 --- a/src/app/item-page/field-components/metadata-values/metadata-values.component.html +++ b/src/app/item-page/field-components/metadata-values/metadata-values.component.html @@ -4,24 +4,25 @@ Choose a template. Priority: markdown, link, browse link. --> + context: {value: mdValue.value, lang: mdValue.language || null}"> - - + + - + {{value}} + [queryParams]="getQueryParams(value)" [attr.lang]="lang" role="link" tabindex="0">{{value}} diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.html b/src/app/item-page/full/field-components/file-section/full-file-section.component.html index d4b58742c4f..0a73c67e189 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.html +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.html @@ -28,7 +28,7 @@

{{"item.page.filesection.original.bund
{{"item.page.filesection.description" | translate}}
-
{{file.firstMetadataValue("dc.description")}}
+
{{file.firstMetadataValue("dc.description")}}

@@ -69,7 +69,7 @@

{{"item.page.filesection.license.bundl
{{"item.page.filesection.description" | translate}}
-
{{file.firstMetadataValue("dc.description")}}
+
{{file.firstMetadataValue("dc.description")}}

diff --git a/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.html b/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.html index fc0946b71e0..a2a8784d3eb 100644 --- a/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.html +++ b/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.html @@ -1 +1,3 @@ -
+
+ +
diff --git a/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.ts b/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.ts index da8c8d4a98b..f190c0770cd 100644 --- a/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.ts +++ b/src/app/item-page/simple/field-components/clarin-description-item-field/clarin-description-item-field.component.ts @@ -20,19 +20,15 @@ export class ClarinDescriptionItemFieldComponent implements OnInit { @Input() fields: string[]; /** - * The valid text metadata to display - updated with links + * Description entries with processed value and language, built from metadata. */ - validTextMetadata: string; + descriptionEntries: {value: string, language: string | null}[] = []; ngOnInit(): void { - // Store all description metadata values - let updatedMVs = []; - this.item.allMetadataValues(this.fields).forEach((value) => { - updatedMVs.push(makeLinks(value)); - }); - - // Join the metadata values with a line break - this.validTextMetadata = updatedMVs.join('
'); + this.descriptionEntries = this.item.allMetadata(this.fields).map(md => ({ + value: makeLinks(md.value), + language: md.language || null + })); } } diff --git a/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.html b/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.html index 50066833e28..1d050238a47 100644 --- a/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.html +++ b/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.html @@ -28,7 +28,7 @@
{{'item.view.box.description.message' | translate}}
-
{{itemDescription}}
+
{{itemDescription}}
diff --git a/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.ts b/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.ts index 566c2bf8dc3..3002ffb5d41 100644 --- a/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.ts +++ b/src/app/shared/clarin-item-box-view/clarin-item-box-view.component.ts @@ -67,6 +67,10 @@ export class ClarinItemBoxViewComponent implements OnInit { * Item's description text. */ itemDescription = ''; + /** + * Language of the item's description metadata value. + */ + itemDescriptionLang: string | null = null; /** * Items's handle redirection URI. */ @@ -145,7 +149,9 @@ export class ClarinItemBoxViewComponent implements OnInit { this.itemType = this.item?.firstMetadataValue('dc.type'); this.itemName = this.item?.firstMetadataValue('dc.title'); this.itemUri = getItemPageRoute(this.item); - this.itemDescription = this.item?.firstMetadataValue('dc.description'); + const descMeta = this.item?.firstMetadata('dc.description'); + this.itemDescription = descMeta?.value || null; + this.itemDescriptionLang = descMeta?.language || null; this.itemPublisher = this.item?.firstMetadataValue('dc.publisher'); this.itemDate = this.clarinDateService.composeItemDate(this.item); diff --git a/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html b/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html index 0e5cddb2b0d..cfe4bf8ab08 100644 --- a/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html +++ b/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html @@ -10,6 +10,7 @@
diff --git a/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.ts b/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.ts index 1fe93a3a2a7..2ec5cee7a6e 100644 --- a/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.ts +++ b/src/app/shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.ts @@ -34,6 +34,11 @@ export class SidebarSearchListElementComponent, K exte */ description: string; + /** + * Language of the description metadata value, used for the lang attribute. + */ + descriptionLang: string | null = null; + expandable = false; expanded = false; private truncatedStates: Map = new Map(); @@ -56,6 +61,7 @@ export class SidebarSearchListElementComponent, K exte if (hasValue(this.dso)) { this.parentTitle$ = this.getParentHierarchyTitle(); this.description = this.getDescription(); + this.descriptionLang = this.getDescriptionLang(); } } @@ -154,6 +160,15 @@ export class SidebarSearchListElementComponent, K exte return this.undefinedIfEmpty(description); } + /** + * Get the language of the description metadata value. + * Override in subclasses to return the language of the displayed description. + * Default: null (no lang attribute rendered) + */ + getDescriptionLang(): string | null { + return null; + } + /** * Return undefined if the provided string is empty * @param value Value to check From 0e1c1c8622ed48e9dbb3dfd27bfa17fda832b7a7 Mon Sep 17 00:00:00 2001 From: amadulhaxxani Date: Tue, 14 Apr 2026 12:34:07 +0200 Subject: [PATCH 2/5] Improve accessibility: add ARIA labels & i18n keys Add ARIA attributes and move icon markup to improve screen-reader support across several components. Updated templates to include aria-label on interactive buttons (info, calendar, remove/save/delete/clear actions) and aria-hidden on decorative icons. Adjusted calendar button markup to place the calendar icon inside the button element. Added corresponding i18n keys in many locale JSON5 files so the new labels are translatable (English provided and placeholder entries added across locales; some locales include TODO notes for translation). These changes are focused on accessibility and localization support. --- .../item-delete/item-delete.component.html | 3 ++- .../views-downloads-statistics.component.html | 4 ++-- .../access-control-array-form.component.html | 8 ++++++-- .../existing-relation-list-element.component.html | 1 + .../relation-group/dynamic-relation-group.component.html | 3 +++ .../submission-section-cc-licenses.component.html | 3 ++- src/assets/i18n/cs.json5 | 9 +++++++++ src/assets/i18n/en.json5 | 8 ++++++++ 8 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-delete/item-delete.component.html b/src/app/item-page/edit-item-page/item-delete/item-delete.component.html index 25780d989c0..07cec551193 100644 --- a/src/app/item-page/edit-item-page/item-delete/item-delete.component.html +++ b/src/app/item-page/edit-item-page/item-delete/item-delete.component.html @@ -38,8 +38,9 @@
diff --git a/src/app/item-page/views-downloads-statistics/views-downloads-statistics.component.html b/src/app/item-page/views-downloads-statistics/views-downloads-statistics.component.html index f722c7b4934..11afede317d 100644 --- a/src/app/item-page/views-downloads-statistics/views-downloads-statistics.component.html +++ b/src/app/item-page/views-downloads-statistics/views-downloads-statistics.component.html @@ -23,7 +23,7 @@

{{ getTitle() }}

[class.active]="activeMetric === 'views'" (click)="selectMetric('views')">
- +
{{ 'statistics.views-downloads.views' | translate }} @@ -35,7 +35,7 @@

{{ getTitle() }}

[class.active]="activeMetric === 'downloads'" (click)="selectMetric('downloads')">
- +
{{ 'statistics.views-downloads.downloads' | translate }} diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html index 69c49d61174..44e899d96b6 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html @@ -46,9 +46,11 @@ />
@@ -75,9 +77,11 @@ />
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html index 64ace2296e9..0c4b3c0a852 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html @@ -8,6 +8,7 @@
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html index 985d3187a66..c229a80ec93 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html @@ -32,6 +32,7 @@
diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index ac5476fd0db..e29f886f35e 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -8587,6 +8587,15 @@ "access-control-option-end-date": "Povolit přístup do", // "access-control-option-end-date-note": "Select the date until which the related access condition is applied", + + "item.delete.virtual-metadata.info": "Show virtual metadata information", + "access-control.start-date.calendar-button": "Open start date calendar", + "access-control.end-date.calendar-button": "Open end date calendar", + "form.remove-related-item": "Remove related item", + "form.relation-group.save": "Save relation group", + "form.relation-group.delete": "Delete relation group", + "form.relation-group.clear": "Clear relation group", + "submission.cc-license.field-info": "More information about this license field", "access-control-option-end-date-note": "Vyberte datum, do kterého má být typ přístupu aktivován", // "vocabulary-treeview.search.form.add": "Add", diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 472f95c978e..e14f129abd5 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5690,6 +5690,14 @@ "access-control-option-end-date-note": "Select the date until which the related access condition is applied", + "item.delete.virtual-metadata.info": "Show virtual metadata information", + "access-control.start-date.calendar-button": "Open start date calendar", + "access-control.end-date.calendar-button": "Open end date calendar", + "form.remove-related-item": "Remove related item", + "form.relation-group.save": "Save relation group", + "form.relation-group.delete": "Delete relation group", + "form.relation-group.clear": "Clear relation group", + "submission.cc-license.field-info": "More information about this license field", "vocabulary-treeview.search.form.add": "Add", "process.overview.unknown.user": "Unknown", From 06d2c0fd9bd17d2fc0747ea66581412e7293ee7d Mon Sep 17 00:00:00 2001 From: amadulhaxxani Date: Wed, 15 Apr 2026 14:02:02 +0200 Subject: [PATCH 3/5] Improve accessibility and semantic headings Replace several presentational heading tags with semantically appropriate heading levels (convert h4/h3/h5/h6 to h2/h3 with existing styling classes) across home, footer and item templates to improve document structure. Add aria-hidden to the hidden repository link and aria-live/aria-atomic to the pagination info for better accessibility. Update footer markup to group links into separate ULs (removing BRs) and adjust SCSS selectors to target both heading elements and .h4 class, plus spacing for stacked lists. Also add TranslateModule.forRoot() to an existing-relation-list-element spec to satisfy translations in tests. --- .../clarin-navbar-top.component.html | 2 +- src/app/footer/footer.component.html | 12 +++++++----- src/app/footer/footer.component.scss | 14 +++++++++++--- src/app/home-page/home-page.component.html | 14 +++++++------- .../clarin-files-section.component.html | 2 +- ...xisting-relation-list-element.component.spec.ts | 2 ++ .../shared/pagination/pagination.component.html | 2 +- 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/app/clarin-navbar-top/clarin-navbar-top.component.html b/src/app/clarin-navbar-top/clarin-navbar-top.component.html index 5b7de122232..1aa30c6ada6 100644 --- a/src/app/clarin-navbar-top/clarin-navbar-top.component.html +++ b/src/app/clarin-navbar-top/clarin-navbar-top.component.html @@ -16,7 +16,7 @@
- +
diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index 4f77afe7b88..6230ba2e434 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -2,25 +2,27 @@