Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 122 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,89 +40,183 @@ This extension is configured in *config.json* with the attributes that follow. T

The following attributes are set within *config.json*.

### \_languagePicker (object):
### \_languagePicker (object)

The languagePicker object that contains values for `_isEnabled`, `title`, `displayTitle`, `body`, `_showOnCourseLoad`, `_languagePickerIconClass` and `_restoreStateOnLanguageChange` settings and the `_languages` array.

#### \_isEnabled (boolean):
#### \_isEnabled (boolean)

Enables/disables this extension. The default value is `false`. Set this to `true` to enable this extension.

#### title (string):
#### title (string)

Browser window title text. For example, "Language selection".

#### displayTitle (string):
#### displayTitle (string)

Header text. For example, "Please select a language."

#### body (string):
#### body (string)

Introductory or explanatory text. For example, "Welcome to ACME Learning. This course is available in several languages. Please make a selection."

#### \_showOnCourseLoad (boolean):
#### graphic (object)

The graphic object that contains values for **\_src** and **alt**. Typically used to display a logo image

##### _src (string)

File name (including path) of the image. Path should be relative to the *src* folder (e.g., *course/en/images/logo.png*).

##### alt (string)

A description of the image; required when it has meaning that must be conveyed to the learner. For 'decorative' images, leave this blank

#### \_backgroundImage (object)

The backgroundImage object that contains values for `_xlarge`, `_large`, `_medium`, and `_small`.

##### \_xlarge (string)

File name (including path) of the image used with xlarge device width. Path should be relative to the *src* folder (e.g., *course/en/images/background.jpg*).

##### \_large (string)

File name (including path) of the image used with large device width. Path should be relative to the *src* folder (e.g., *course/en/images/background.jpg*).

##### \_medium (string)

File name (including path) of the image used with medium device width. Path should be relative to the *src* folder (e.g., *course/en/images/background.jpg*).

##### \_small (string)

File name (including path) of the image used with small device width. Path should be relative to the *src* folder (e.g., *course/en/images/background.jpg*).

#### \_backgroundStyles (object)

Additional attributes to customise how background images are displayed. The `_backgroundStyles` object can include the following properties:

##### \_backgroundRepeat (string)

Defines how the background image repeats. Options include:

* `repeat`: The background image is repeated both vertically and horizontally.
* `repeat-x`: The background image is repeated only horizontally.
* `repeat-y`: The background image is repeated only vertically.
* `no-repeat`: The background image is not repeated.

##### \_backgroundSize (string)

Defines the size of the background image. Options include:

* `auto`: The background image is displayed in its original size.
* `cover`: Resize the background image to cover the entire container, even if it has to stretch or crop the image.
* `contain`: Resize the background image to make sure the image is fully visible.
* `100% 100%`: Resize the background image to match the dimensions of the container.

##### \_backgroundPosition (string)

Sets the position of the background image. Options include:

* `left top`
* `left center`
* `left bottom`
* `center top`
* `center center`
* `center bottom`
* `right top`
* `right center`
* `right bottom`

The first value is the horizontal position and the second value is the vertical position.

#### \_showOnCourseLoad (boolean)

Determines whether the language picker will be displayed on course load. If set to `false`, the course will load with the default language selected and the user will need to use the icon in the navigation bar to change languages. The default value is `true`.

#### \_languagePickerIconClass (string):
#### \_languagePickerIconClass (string)

Defines which icon will be displayed in the navigation bar. The [vanilla theme](https://github.com/adaptlearning/adapt-contrib-vanilla) supports the following icon styles: `"icon-globe"`, `"icon-language-1"`, `"icon-language-2"`. The default value for this setting is `"icon-language-2"`.

#### \_restoreStateOnLanguageChange (boolean):
#### \_restoreStateOnLanguageChange (boolean)

Determines whether or not the language picker will try to restore the 'state' of the course when the user changes language. It is advised that you only set this to `true` if all course languages have exactly the same structure; if they do not, some loss of tracking data will occur. If set to `false`, all tracking data will be cleared when the user switches language - the warningMessage (see below) should be used to warn the user of this. The default value is `false`.

#### \_languages (array):
#### \_languages (array)

The languages array contains the list of the available languages and the various settings associated with each. Each entry in the array should be an object, containing the following settings:

##### \_language (string):
##### \_language (string)

This text must match the name of the language-specific folder located in the course root, for example, `"en"` from *course/en*. It is used as the value for the HTML `lang` attribute. It is highly recommended that codes for web languages be used. Reference a source such as the [IANA Language Subtag Registry](http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry).

##### \_direction (string):
##### \_direction (string)

Specifies the value of the HTML `dir` attribute and, consequently, the base direction of text. Acceptable values are `"rtl"` (right-to-left) and `"ltr"` (left-to-right). The default value is `"ltr"`.

##### \_isDisabled (boolean):
##### \_isDisabled (boolean)

Setting this to `true` allows the language to be shown in the list but in a 'disabled' state (so it cannot be selected). This can be useful in situations where localisation into a particular language has not yet been completed. The default value is `false`.

##### displayName (string):
##### displayName (string)

The display name of the language. This value is used as the button label.

##### warningTitle (string):
##### warningTitle (string)

This text appears as the header of the dialog confirming the learner's intent to change languages, for example, "Change language?".

##### warningMessage (string):
##### warningMessage (string)

This text appears as the body of the dialog confirming the learner's intent to change languages, for example, "Changing the language will reset course progress.<br><br>Would you like to proceed?".

##### \_buttons (object):
##### \_buttons (object)

The buttons object contains the following settings:

###### yes (string):
###### yes (string)

Label for the button that confirms the learner's intent to switch languages.

###### no (string):
###### no (string)

Label for the button that cancels the switch languages dialog.

<div float align=right><a href="#top">Back to Top</a></div>

## Attributes (course.json)

The following attributes should be added to _course.json_ under _\_globals.\_extensions_.
The following attributes should be added to *course.json* under *\_globals.\_extensions*.

### \_languagePicker (object)

### \_languagePicker (object):
The languagePicker object that contains values for `navigationBarLabel`, `languageSelector` and `_navTooltip` that contains `_isEnabled`, `text`.

#### navigationBarLabel (string):
#### navigationBarLabel (string)

Label shown next to the language picker button when navigation bar labels are enabled. Defaults to Language picker.

#### languageSelector (string):
#### languageSelector (string)

Aria label that appears at the top of the drawer displayed when language picker button is clicked. Defaults to Language selector.

#### \_navTooltip (object):
#### \_navTooltip (object)

The _navTooltip object that contains values for `_isEnabled` and `text`.

#### \_isEnabled (boolean):
#### \_isEnabled (boolean)

Enables/disables tooltips for the language picker button in the navigation bar. The default value is `true`.

#### text (string):
#### text (string)

Text to be displayed in the tooltip when the user hovers over the language picker button in the navigation bar. Defaults to 'Language selector'

## Limitations

- If the [**Spoor**](https://github.com/adaptlearning/adapt-contrib-spoor) extension is disabled (or not installed), **Language Picker** will not remember the learner's language choice from the previous session.
- Switching languages during an [**Assessment**](https://github.com/adaptlearning/adapt-contrib-assessment) will reset assessment attempts.
- Language Picker is not yet compatible with the Adapt Authoring Tool.
* If the [**Spoor**](https://github.com/adaptlearning/adapt-contrib-spoor) extension is disabled (or not installed), **Language Picker** will not remember the learner's language choice from the previous session.
* Switching languages during an [**Assessment**](https://github.com/adaptlearning/adapt-contrib-assessment) will reset assessment attempts.
* Language Picker is not yet compatible with the Adapt Authoring Tool.

## Notes

Expand Down
15 changes: 15 additions & 0 deletions example.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@
"title": "Language selection",
"displayTitle": "Please select a language",
"body": "This course is available in the following languages:",
"_graphic": {
"src": "course/en/images/logo.png",
"alt": ""
},
"_backgroundImage": {
"_xlarge": "course/en/images/background.jpg",
"_large": "course/en/images/background.jpg",
"_medium": "course/en/images/background.jpg",
"_small": "course/en/images/background.jpg"
},
"_backgroundStyles": {
"_backgroundSize": "cover",
"_backgroundRepeat": "no-repeat",
"_backgroundPosition": "center center"
},
"_showOnCourseLoad": true,
"_comment": "default class names are: icon-globe, icon-language-1, icon-language-2",
"_languagePickerIconClass": "icon-language-2",
Expand Down
47 changes: 45 additions & 2 deletions js/languagePickerView.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Adapt from 'core/js/adapt';
import NavigationView from './languagePickerNavigationView';
import device from 'core/js/device';
import router from 'core/js/router';

export default class LanguagePickerView extends Backbone.View {
Expand All @@ -15,16 +16,29 @@ export default class LanguagePickerView extends Backbone.View {
}

className() {
return 'languagepicker';
return [
'languagepicker',
this.setBackgroundImage() && 'has-bg-image'
].filter(Boolean).join(' ');
}

initialize() {
this.initializeNavigation();
$('html').addClass('in-languagepicker');
this.listenTo(Adapt, 'remove', this.remove);
this.addEventListeners();
this.setBackgroundImage();
this.setBackgroundStyles();
this.render();
}

addEventListeners() {
this.onScreenSizeChanged = _.debounce(this.onScreenSizeChanged.bind(this), 300);
this.listenTo(Adapt, {
remove: this.remove,
'device:resize': this.onScreenSizeChanged
});
}

render() {
const data = this.model.toJSON();
const template = Handlebars.templates[this.template];
Expand Down Expand Up @@ -54,6 +68,35 @@ export default class LanguagePickerView extends Backbone.View {
this.navigationView.remove();
}

onScreenSizeChanged() {
this.setBackgroundImage();
this.render();
}

setBackgroundImage() {
const backgroundImages = this.model.get('_backgroundImage');
if (!backgroundImages) return;

const backgroundImage = backgroundImages?.[`_${device.screenSize}`] ?? backgroundImages?._small;
this.model.set('backgroundImage', backgroundImage);

return backgroundImage;
}

setBackgroundStyles() {
const styles = this.model.get('_backgroundStyles');
if (!styles || !this.model.get('backgroundImage')) return;

const backgroundStyles = Object.entries({
'background-repeat': styles._backgroundRepeat,
'background-size': styles._backgroundSize,
'background-position': styles._backgroundPosition
}).map(([style, value]) => `${style}: ${value}`)
.join('; ');

this.model.set('backgroundStyles', backgroundStyles);
}

remove() {
$('html').removeClass('in-languagepicker');

Expand Down
20 changes: 20 additions & 0 deletions less/languagePicker.less
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
// Language Picker standalone page
// --------------------------------------------------
.languagepicker {
position: relative;
min-height: 100vh;

&.has-bg-image > .background {
position: absolute;
inset: 0;
background-repeat: no-repeat;
background-size: cover;
background-position: center top;
}

&__inner {
position: relative;
.l-container-responsive(@max-content-width);
}

&__image-container {
margin-bottom: @item-padding;
}

&__image {
min-width: auto;
}
}

// Notify direction amends
Expand Down
11 changes: 11 additions & 0 deletions templates/languagePickerView.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
{{#if backgroundImage}}
<div class="background" aria-hidden="true" style="background-image: url('{{backgroundImage}}');{{#if backgroundStyles}} {{backgroundStyles}}{{/if}}">
</div>
{{/if}}

<div class="languagepicker__inner">

{{#if _graphic.src}}
<div class="languagepicker__image-container">
<img class="languagepicker__image" src={{_graphic.src}}{{#if _graphic.alt}} alt={{_graphic.alt}}{{else}} aria-hidden="true"{{/if}} loading="eager" />
</div>
{{/if}}

{{#if displayTitle}}
<div class="languagepicker__title">
<div class="languagepicker__title-inner" role="heading" aria-level="1">
Expand Down